aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-01-20 20:58:25 -0800
committerTor Norbye <tnorbye@google.com>2012-01-23 07:37:53 -0800
commitfefa8b7d47b787d2250dc2fd0f35cac5540241e2 (patch)
treedb67ea2694d46698ebe93f344e92c4e0000af2f6 /eclipse/plugins
parent121e7e305d8dc179bce1267b0ccef2741706262d (diff)
downloadsdk-fefa8b7d47b787d2250dc2fd0f35cac5540241e2.tar.gz
Add quick fix for the UseCompoundDrawable lint warning
This changeset adds a quickfix for the "Use Compound Drawable" lint warning. That warning identifies a LinearLayout which contains exactly one TextView and one ImageView (in either order, and the linear layout can be in either orientation), and suggests replacing it by just the single TextView along with a drawable attribute. The description alone wasn't clear, so the quickfix performs the conversion automatically. In addition to the conversion it also needs to transfer any layout param references from the old LinearLayout to the TextView (and assign it an id if necessary), so the quickfix is implemented as a visual refactoring. It's also made available from the Visual Refactoring menu. This changeset also updates a couple of unrelated golden files in the refactoring unit tests to track a message change a few months back. Change-Id: Iecb544d196fdd4bcabf13a3fdb82ef1ea063f4c2
Diffstat (limited to 'eclipse/plugins')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java18
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableAction.java48
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java359
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableWizard.java31
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java13
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/UseCompoundDrawableDetectorFix.java95
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java71
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1-expected-1.xml16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.info4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.xml25
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2-expected-2.xml16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.info5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.xml25
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3-expected-3.xml16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.info4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.xml25
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4-expected-4.xml16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.info4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.xml25
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-5.xml73
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-6.xml74
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.info13
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.xml83
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant1.txt4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant2.txt12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant3.txt12
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant4.txt2
31 files changed, 1092 insertions, 22 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java
index c6a5ba841..1b9f815f2 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java
@@ -83,6 +83,12 @@ public class LayoutConstants {
public static final String ATTR_LAYOUT_MARGIN_TOP = "layout_marginTop"; //$NON-NLS-1$
public static final String ATTR_LAYOUT_MARGIN_BOTTOM = "layout_marginBottom"; //$NON-NLS-1$
+ // TextView
+ public static final String ATTR_DRAWABLE_RIGHT = "drawableRight"; //$NON-NLS-1$
+ public static final String ATTR_DRAWABLE_LEFT = "drawableLeft"; //$NON-NLS-1$
+ public static final String ATTR_DRAWABLE_BOTTOM = "drawableBottom"; //$NON-NLS-1$
+ public static final String ATTR_DRAWABLE_TOP = "drawableTop"; //$NON-NLS-1$
+
// RelativeLayout layout params:
public static final String ATTR_LAYOUT_ALIGN_LEFT = "layout_alignLeft"; //$NON-NLS-1$
public static final String ATTR_LAYOUT_ALIGN_RIGHT = "layout_alignRight"; //$NON-NLS-1$
@@ -242,6 +248,12 @@ public class LayoutConstants {
/** The fully qualified class name of a Space */
public static final String FQCN_SPACE = "android.widget.Space"; //$NON-NLS-1$
+ /** The fully qualified class name of a TextView view */
+ public static final String FQCN_TEXT_VIEW = "android.widget.TextView"; //$NON-NLS-1$
+
+ /** The fully qualified class name of an ImageView view */
+ public static final String FQCN_IMAGE_VIEW = "android.widget.ImageView"; //$NON-NLS-1$
+
public static final String ATTR_SRC = "src"; //$NON-NLS-1$
// like fill_parent for API 8
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java
index 33475fe0b..a5bbb8594 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/DynamicContextMenu.java
@@ -20,6 +20,9 @@ import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
import static com.android.ide.common.layout.LayoutConstants.EXPANDABLE_LIST_VIEW;
import static com.android.ide.common.layout.LayoutConstants.FQCN_GESTURE_OVERLAY_VIEW;
+import static com.android.ide.common.layout.LayoutConstants.FQCN_IMAGE_VIEW;
+import static com.android.ide.common.layout.LayoutConstants.FQCN_LINEAR_LAYOUT;
+import static com.android.ide.common.layout.LayoutConstants.FQCN_TEXT_VIEW;
import static com.android.ide.common.layout.LayoutConstants.GRID_VIEW;
import static com.android.ide.common.layout.LayoutConstants.LIST_VIEW;
import static com.android.ide.common.layout.LayoutConstants.SPINNER;
@@ -40,6 +43,7 @@ import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.ChangeVie
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.ExtractIncludeAction;
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.ExtractStyleAction;
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.UnwrapAction;
+import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.UseCompoundDrawableAction;
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.WrapInAction;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
@@ -240,6 +244,20 @@ class DynamicContextMenu {
// Only include the menu item if you are not right clicking on a root,
// or on an included view, or on a non-contiguous selection
mMenuManager.insertBefore(endId, new Separator());
+ if (selection.size() == 1 && selection.get(0).getViewInfo() != null
+ && selection.get(0).getViewInfo().getName().equals(FQCN_LINEAR_LAYOUT)) {
+ CanvasViewInfo info = selection.get(0).getViewInfo();
+ List<CanvasViewInfo> children = info.getChildren();
+ if (children.size() == 2) {
+ String first = children.get(0).getName();
+ String second = children.get(1).getName();
+ if ((first.equals(FQCN_IMAGE_VIEW) && second.equals(FQCN_TEXT_VIEW))
+ || (first.equals(FQCN_TEXT_VIEW) && second.equals(FQCN_IMAGE_VIEW))) {
+ mMenuManager.insertBefore(endId, UseCompoundDrawableAction.create(
+ mEditorDelegate));
+ }
+ }
+ }
mMenuManager.insertBefore(endId, ExtractIncludeAction.create(mEditorDelegate));
mMenuManager.insertBefore(endId, ExtractStyleAction.create(mEditorDelegate));
mMenuManager.insertBefore(endId, WrapInAction.create(mEditorDelegate));
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java
index b18ef16a3..a4306fa7c 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gre/NodeProxy.java
@@ -190,8 +190,9 @@ public class NodeProxy implements INode {
@Override
public INode[] getChildren() {
if (mNode != null) {
- ArrayList<INode> nodes = new ArrayList<INode>();
- for (UiElementNode uiChild : mNode.getUiChildren()) {
+ List<UiElementNode> uiChildren = mNode.getUiChildren();
+ List<INode> nodes = new ArrayList<INode>(uiChildren.size());
+ for (UiElementNode uiChild : uiChildren) {
if (uiChild instanceof UiViewElementNode) {
nodes.add(mFactory.create((UiViewElementNode) uiChild));
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableAction.java
new file mode 100644
index 000000000..84d3e7ee8
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableAction.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 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.layout.refactoring;
+
+import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+
+/**
+ * Action executed when the "Convert Layout" menu item is invoked.
+ */
+public class UseCompoundDrawableAction extends VisualRefactoringAction {
+ @Override
+ public void run(IAction action) {
+ if ((mTextSelection != null || mTreeSelection != null) && mFile != null) {
+ UseCompoundDrawableRefactoring ref = new UseCompoundDrawableRefactoring(
+ mFile, mDelegate, mTextSelection, mTreeSelection);
+ RefactoringWizard wizard = new UseCompoundDrawableWizard(ref, mDelegate);
+ RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
+ try {
+ op.run(mWindow.getShell(), wizard.getDefaultPageTitle());
+ } catch (InterruptedException e) {
+ // Interrupted. Pass.
+ }
+ }
+ }
+
+ public static IAction create(LayoutEditorDelegate editorDelegate) {
+ return create("Convert to a Compound Drawable...", editorDelegate,
+ UseCompoundDrawableAction.class);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
new file mode 100644
index 000000000..aeea32873
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
@@ -0,0 +1,359 @@
+/*
+ * 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.layout.refactoring;
+
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_DRAWABLE_BOTTOM;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_DRAWABLE_LEFT;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_DRAWABLE_RIGHT;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_DRAWABLE_TOP;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_GRAVITY;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_HEIGHT;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_WIDTH;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_ORIENTATION;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_SRC;
+import static com.android.ide.common.layout.LayoutConstants.LAYOUT_PREFIX;
+import static com.android.ide.common.layout.LayoutConstants.LINEAR_LAYOUT;
+import static com.android.ide.common.layout.LayoutConstants.VALUE_VERTICAL;
+import static com.android.ide.eclipse.adt.AdtConstants.EXT_XML;
+import static com.android.tools.lint.detector.api.LintConstants.IMAGE_VIEW;
+import static com.android.tools.lint.detector.api.LintConstants.TEXT_VIEW;
+
+import com.android.annotations.VisibleForTesting;
+import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
+import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
+import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
+import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
+import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
+import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Converts a LinearLayout with exactly a TextView child and an ImageView child into
+ * a single TextView with a compound drawable.
+ */
+@SuppressWarnings("restriction") // XML model
+public class UseCompoundDrawableRefactoring extends VisualRefactoring {
+ /**
+ * Constructs a new {@link UseCompoundDrawableRefactoring}
+ *
+ * @param file the file to refactor in
+ * @param editor the corresponding editor
+ * @param selection the editor selection, or null
+ * @param treeSelection the canvas selection, or null
+ */
+ public UseCompoundDrawableRefactoring(IFile file, LayoutEditorDelegate editor,
+ ITextSelection selection, ITreeSelection treeSelection) {
+ super(file, editor, selection, treeSelection);
+ }
+
+ /**
+ * This constructor is solely used by {@link Descriptor}, to replay a
+ * previous refactoring.
+ *
+ * @param arguments argument map created by #createArgumentMap.
+ */
+ private UseCompoundDrawableRefactoring(Map<String, String> arguments) {
+ super(arguments);
+ }
+
+ @VisibleForTesting
+ UseCompoundDrawableRefactoring(List<Element> selectedElements, LayoutEditorDelegate editor) {
+ super(selectedElements, editor);
+ }
+
+ @Override
+ public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException,
+ OperationCanceledException {
+ RefactoringStatus status = new RefactoringStatus();
+
+ try {
+ pm.beginTask("Checking preconditions...", 6);
+
+ if (mSelectionStart == -1 || mSelectionEnd == -1) {
+ status.addFatalError("Nothing to convert");
+ return status;
+ }
+
+ // Make sure the selection is contiguous
+ if (mTreeSelection != null) {
+ List<CanvasViewInfo> infos = getSelectedViewInfos();
+ if (!validateNotEmpty(infos, status)) {
+ return status;
+ }
+
+ // Enforce that the selection is -contiguous-
+ if (!validateContiguous(infos, status)) {
+ return status;
+ }
+ }
+
+ // Ensures that we have a valid DOM model:
+ if (mElements.size() == 0) {
+ status.addFatalError("Nothing to convert");
+ return status;
+ }
+
+ // Ensure that we have selected precisely one LinearLayout
+ if (mElements.size() != 1 ||
+ !(mElements.get(0).getTagName().equals(LINEAR_LAYOUT))) {
+ status.addFatalError("Must select exactly one LinearLayout");
+ return status;
+ }
+
+ Element layout = mElements.get(0);
+ List<Element> children = DomUtilities.getChildren(layout);
+ if (children.size() != 2) {
+ status.addFatalError("The LinearLayout must have exactly two children");
+ return status;
+ }
+ Element first = children.get(0);
+ Element second = children.get(1);
+ boolean haveTextView =
+ first.getTagName().equals(TEXT_VIEW)
+ || second.getTagName().equals(TEXT_VIEW);
+ boolean haveImageView =
+ first.getTagName().equals(IMAGE_VIEW)
+ || second.getTagName().equals(IMAGE_VIEW);
+ if (!(haveTextView && haveImageView)) {
+ status.addFatalError("The LinearLayout must have exactly one TextView child " +
+ "and one ImageView child");
+ return status;
+ }
+
+ pm.worked(1);
+ return status;
+
+ } finally {
+ pm.done();
+ }
+ }
+
+ @Override
+ protected VisualRefactoringDescriptor createDescriptor() {
+ String comment = getName();
+ return new Descriptor(
+ mProject.getName(), //project
+ comment, //description
+ comment, //comment
+ createArgumentMap());
+ }
+
+ @Override
+ protected Map<String, String> createArgumentMap() {
+ return super.createArgumentMap();
+ }
+
+ @Override
+ public String getName() {
+ return "Convert to Compound Drawable";
+ }
+
+ @Override
+ protected List<Change> computeChanges(IProgressMonitor monitor) {
+ String androidNsPrefix = getAndroidNamespacePrefix();
+ IFile file = mDelegate.getEditor().getInputFile();
+ List<Change> changes = new ArrayList<Change>();
+ TextFileChange change = new TextFileChange(file.getName(), file);
+ MultiTextEdit rootEdit = new MultiTextEdit();
+ change.setTextType(EXT_XML);
+
+ // (1) Build up the contents of the new TextView. This is identical
+ // to the old contents, but with the addition of a drawableTop/Left/Right/Bottom
+ // attribute (depending on the orientation and order), as well as any layout
+ // params from the LinearLayout.
+ // (2) Delete the linear layout and replace with the text view.
+ // (3) Reformat.
+
+ // checkInitialConditions has already validated that we have exactly a LinearLayout
+ // with an ImageView and a TextView child (in either order)
+ Element layout = mElements.get(0);
+ List<Element> children = DomUtilities.getChildren(layout);
+ Element first = children.get(0);
+ Element second = children.get(1);
+ final Element text;
+ final Element image;
+ if (first.getTagName().equals(TEXT_VIEW)) {
+ text = first;
+ image = second;
+ } else {
+ text = second;
+ image = first;
+ }
+
+ // Horizontal is the default, so if no value is specified it is horizontal.
+ boolean isVertical = VALUE_VERTICAL.equals(layout.getAttributeNS(ANDROID_URI,
+ ATTR_ORIENTATION));
+
+ // The WST DOM implementation doesn't correctly implement cloneNode: this returns
+ // an empty document instead:
+ // text.getOwnerDocument().cloneNode(false/*deep*/);
+ // Luckily we just need to clone a single element, not a nested structure, so it's
+ // easy enough to do this manually:
+ Document tempDocument = DomUtilities.createEmptyDocument();
+ Element newTextElement = tempDocument.createElement(text.getTagName());
+ tempDocument.appendChild(newTextElement);
+
+ NamedNodeMap attributes = text.getAttributes();
+ for (int i = 0, n = attributes.getLength(); i < n; i++) {
+ Attr attribute = (Attr) attributes.item(i);
+ if (attribute.getLocalName().startsWith(LAYOUT_PREFIX)
+ && ANDROID_URI.equals(attribute.getNamespaceURI())) {
+ // Ignore layout params: the parent layout is going away
+ } else {
+ newTextElement.setAttribute(attribute.getName(), attribute.getValue());
+ }
+ }
+
+ // Apply all layout params from the parent (except width and height),
+ // as well as android:gravity
+ List<Attr> layoutAttributes = findLayoutAttributes(layout);
+ for (Attr attribute : layoutAttributes) {
+ String name = attribute.getLocalName();
+ if ((name.equals(ATTR_LAYOUT_WIDTH) || name.equals(ATTR_LAYOUT_HEIGHT))
+ && ANDROID_URI.equals(attribute.getNamespaceURI())) {
+ // Already handled specially
+ continue;
+ }
+ newTextElement.setAttribute(attribute.getName(), attribute.getValue());
+ }
+ String gravity = layout.getAttributeNS(ANDROID_URI, ATTR_GRAVITY);
+ if (gravity.length() > 0) {
+ setAndroidAttribute(newTextElement, androidNsPrefix, ATTR_GRAVITY, gravity);
+ }
+
+ String src = image.getAttributeNS(ANDROID_URI, ATTR_SRC);
+
+ // Set the drawable
+ String drawableAttribute;
+ if (isVertical) {
+ if (first == image) {
+ drawableAttribute = ATTR_DRAWABLE_TOP;
+ } else {
+ drawableAttribute = ATTR_DRAWABLE_BOTTOM;
+ }
+ } else {
+ if (first == image) {
+ drawableAttribute = ATTR_DRAWABLE_LEFT;
+ } else {
+ drawableAttribute = ATTR_DRAWABLE_RIGHT;
+ }
+ }
+
+ setAndroidAttribute(newTextElement, androidNsPrefix, drawableAttribute, src);
+
+ // Update any layout references to the layout to point to the text view
+ String layoutId = getId(layout);
+ if (layoutId.length() > 0) {
+ String id = getId(text);
+ if (id.length() == 0) {
+ id = ensureHasId(rootEdit, text, null, false);
+ setAndroidAttribute(newTextElement, androidNsPrefix, ATTR_ID, id);
+ }
+
+ IStructuredModel model = mDelegate.getEditor().getModelForRead();
+ try {
+ IStructuredDocument doc = model.getStructuredDocument();
+ if (doc != null) {
+ List<TextEdit> replaceIds = replaceIds(androidNsPrefix,
+ doc, mSelectionStart, mSelectionEnd, layoutId, id);
+ for (TextEdit edit : replaceIds) {
+ rootEdit.addChild(edit);
+ }
+ }
+ } finally {
+ model.releaseFromRead();
+ }
+ }
+
+ XmlFormatPreferences formatPrefs = XmlFormatPreferences.create();
+ XmlPrettyPrinter printer = new XmlPrettyPrinter(formatPrefs, XmlFormatStyle.LAYOUT,
+ null /*lineSeparator*/);
+ StringBuilder sb = new StringBuilder(300);
+ printer.prettyPrint(-1, tempDocument, null, null, sb, false /*openTagOnly*/);
+ String xml = sb.toString();
+
+
+ TextEdit replace = new ReplaceEdit(mSelectionStart, mSelectionEnd - mSelectionStart, xml);
+ rootEdit.addChild(replace);
+
+ if (AdtPrefs.getPrefs().getFormatGuiXml()) {
+ MultiTextEdit formatted = reformat(rootEdit, XmlFormatStyle.LAYOUT);
+ if (formatted != null) {
+ rootEdit = formatted;
+ }
+ }
+
+ change.setEdit(rootEdit);
+ changes.add(change);
+ return changes;
+ }
+
+ /**
+ * Sets an Android attribute (in the Android namespace) on an element
+ * without a given namespace prefix. This is done when building a new Element
+ * in a temporary document such that the namespace prefix matches when the element is
+ * formatted and replaced in the target document.
+ */
+ private static void setAndroidAttribute(Element element, String prefix, String name,
+ String value) {
+ element.setAttribute(prefix + ':' + name, value);
+ }
+
+ @Override
+ public VisualRefactoringWizard createWizard() {
+ return new UseCompoundDrawableWizard(this, mDelegate);
+ }
+
+ @SuppressWarnings("javadoc")
+ public static class Descriptor extends VisualRefactoringDescriptor {
+ public Descriptor(String project, String description, String comment,
+ Map<String, String> arguments) {
+ super("com.android.ide.eclipse.adt.refactoring.usecompound", //$NON-NLS-1$
+ project, description, comment, arguments);
+ }
+
+ @Override
+ protected Refactoring createRefactoring(Map<String, String> args) {
+ return new UseCompoundDrawableRefactoring(args);
+ }
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableWizard.java
new file mode 100644
index 000000000..3ffd6b5ea
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableWizard.java
@@ -0,0 +1,31 @@
+/*
+ * 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.layout.refactoring;
+
+import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
+
+class UseCompoundDrawableWizard extends VisualRefactoringWizard {
+ UseCompoundDrawableWizard(UseCompoundDrawableRefactoring ref, LayoutEditorDelegate editor) {
+ super(ref, editor);
+ setDefaultPageTitle("Use Compound Drawable");
+ }
+
+ @Override
+ protected void addUserInputPages() {
+ // This refactoring takes no parameters
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java
index 03a79687d..cde99543a 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/VisualRefactoring.java
@@ -27,6 +27,7 @@ import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX;
import static com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor.XMLNS;
import static com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor.XMLNS_COLON;
+import com.android.annotations.NonNull;
import com.android.annotations.VisibleForTesting;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
@@ -232,6 +233,7 @@ public abstract class VisualRefactoring extends Refactoring {
mElements = initElements();
}
+ @NonNull
protected abstract List<Change> computeChanges(IProgressMonitor monitor);
@Override
@@ -878,6 +880,11 @@ public abstract class VisualRefactoring extends Refactoring {
}
protected String ensureHasId(MultiTextEdit rootEdit, Element element, String prefix) {
+ return ensureHasId(rootEdit, element, prefix, true);
+ }
+
+ protected String ensureHasId(MultiTextEdit rootEdit, Element element, String prefix,
+ boolean apply) {
String id = mGeneratedIdMap.get(element);
if (id != null) {
return NEW_ID_PREFIX + id;
@@ -890,8 +897,10 @@ public abstract class VisualRefactoring extends Refactoring {
mGeneratedIds.add(id);
mGeneratedIdMap.put(element, id);
id = NEW_ID_PREFIX + id;
- setAttribute(rootEdit, element,
- ANDROID_URI, getAndroidNamespacePrefix(), ATTR_ID, id);
+ if (apply) {
+ setAttribute(rootEdit, element,
+ ANDROID_URI, getAndroidNamespacePrefix(), ATTR_ID, id);
+ }
return id;
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java
index a58f84bb9..f6f447de8 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java
@@ -47,6 +47,7 @@ import com.android.tools.lint.checks.ScrollViewChildDetector;
import com.android.tools.lint.checks.SecurityDetector;
import com.android.tools.lint.checks.TextFieldDetector;
import com.android.tools.lint.checks.TypographyDetector;
+import com.android.tools.lint.checks.UseCompoundDrawableDetector;
import com.android.tools.lint.checks.UselessViewDetector;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.LintConstants;
@@ -201,6 +202,7 @@ abstract class LintFix implements ICompletionProposal {
sFixes.put(TypographyDetector.FRACTIONS.getId(), TypographyFix.class);
sFixes.put(TypographyDetector.OTHER.getId(), TypographyFix.class);
sFixes.put(TypographyDetector.QUOTES.getId(), TypographyFix.class);
+ sFixes.put(UseCompoundDrawableDetector.ISSUE.getId(), UseCompoundDrawableDetectorFix.class);
}
public static boolean hasFix(String id) {
@@ -230,7 +232,7 @@ abstract class LintFix implements ICompletionProposal {
return null;
}
- private abstract static class DocumentFix extends LintFix {
+ abstract static class DocumentFix extends LintFix {
protected DocumentFix(String id, IMarker marker) {
super(id, marker);
@@ -265,7 +267,7 @@ abstract class LintFix implements ICompletionProposal {
}
}
- private abstract static class SetPropertyFix extends DocumentFix {
+ abstract static class SetPropertyFix extends DocumentFix {
private Region mSelect;
private SetPropertyFix(String id, IMarker marker) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/UseCompoundDrawableDetectorFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/UseCompoundDrawableDetectorFix.java
new file mode 100644
index 000000000..939aacfcb
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/UseCompoundDrawableDetectorFix.java
@@ -0,0 +1,95 @@
+/*
+ * 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.lint;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.AdtUtils;
+import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
+import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.UseCompoundDrawableRefactoring;
+import com.android.tools.lint.checks.UseCompoundDrawableDetector;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.w3c.dom.Node;
+
+/** Quickfix for the {@link UseCompoundDrawableDetector} */
+@SuppressWarnings("restriction") // DOM model
+class UseCompoundDrawableDetectorFix extends LintFix.DocumentFix {
+ protected UseCompoundDrawableDetectorFix(String id, IMarker marker) {
+ super(id, marker);
+ }
+
+ @Override
+ public String getDisplayString() {
+ return "Convert to a compound drawable";
+ }
+
+ @Override
+ public Image getImage() {
+ return AdtPlugin.getAndroidLogo();
+ }
+
+ @Override
+ public boolean needsFocus() {
+ return false;
+ }
+
+ @Override
+ public boolean isCancelable() {
+ return false;
+ }
+
+ @Override
+ public boolean isBulkCapable() {
+ return false;
+ }
+
+ @Override
+ protected void apply(IDocument document, IStructuredModel model, Node node,
+ int start, int end) {
+
+ // Invoke refactoring
+ LayoutEditorDelegate delegate =
+ LayoutEditorDelegate.fromEditor(AdtUtils.getActiveEditor());
+
+ if (delegate != null) {
+ IFile file = (IFile) mMarker.getResource();
+ ITextSelection textSelection = new TextSelection(start,
+ end - start);
+ UseCompoundDrawableRefactoring refactoring =
+ new UseCompoundDrawableRefactoring(file, delegate, textSelection, null);
+ RefactoringWizard wizard = refactoring.createWizard();
+ RefactoringWizardOpenOperation op =
+ new RefactoringWizardOpenOperation(wizard);
+ try {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().
+ getActiveWorkbenchWindow();
+ op.run(window.getShell(), wizard.getDefaultPageTitle());
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java
index 57bb6e5cf..d2b59abda 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java
@@ -61,7 +61,7 @@ import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
-@SuppressWarnings("restriction")
+@SuppressWarnings({"restriction", "javadoc"})
public class AdtProjectTest extends SdkTestCase {
private static final int TARGET_API_LEVEL = 12;
public static final String TEST_PROJECT_PACKAGE = "com.android.eclipse.tests"; //$NON-NLS-1$
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java
new file mode 100644
index 000000000..04b9b1a3d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 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.layout.refactoring;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+@SuppressWarnings("javadoc")
+public class UseCompoundDrawableRefactoringTest extends RefactoringTest {
+
+ public void test1() throws Exception {
+ // Test converting an image above a text view
+ checkRefactoring("refactoring/usecompound/compound1.xml", "@+id/layout1");
+ }
+
+ public void test2() throws Exception {
+ // Test converting an image below a text view
+ checkRefactoring("refactoring/usecompound/compound2.xml", "@+id/layout2");
+ }
+
+ public void test3() throws Exception {
+ // Test converting an image to the left of a text view
+ checkRefactoring("refactoring/usecompound/compound3.xml", "@+id/layout3");
+ }
+
+ public void test4() throws Exception {
+ // Test converting an image to the right of a text view
+ checkRefactoring("refactoring/usecompound/compound4.xml", "@+id/layout4");
+ }
+
+ public void test5() throws Exception {
+ // Test converting an image where the LinearLayout is referenced (in a relative layout)
+ // and the text view has an id
+ checkRefactoring("refactoring/usecompound/compound_all.xml", "@+id/layout2");
+ }
+
+ public void test6() throws Exception {
+ // Test converting an image where the LinearLayout is referenced (in a relative layout)
+ // and the text view does not have an id
+ checkRefactoring("refactoring/usecompound/compound_all.xml", "@+id/layout3");
+ }
+
+ private void checkRefactoring(String basename, String id) throws Exception {
+ IFile file = getLayoutFile(getProject(), basename);
+ TestContext info = setupTestContext(file, basename);
+ TestLayoutEditorDelegate layoutEditor = info.mLayoutEditorDelegate;
+ List<Element> selectedElements = getElements(info.mElement, new String[] { id });
+
+ UseCompoundDrawableRefactoring refactoring = new UseCompoundDrawableRefactoring(
+ selectedElements, layoutEditor);
+ List<Change> changes = refactoring.computeChanges(new NullProgressMonitor());
+ checkEdits(basename, changes);
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1-expected-1.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1-expected-1.xml
new file mode 100644
index 000000000..e72638f57
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1-expected-1.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/TextView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableTop="@drawable/ic_launcher"
+ android:gravity="center"
+ android:text="Hello World" >
+ </TextView>
+
+</LinearLayout> \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.info b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.info
new file mode 100644
index 000000000..4f0aea55e
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.info
@@ -0,0 +1,4 @@
+android.widget.LinearLayout [0,121,800,480] <LinearLayout>
+ android.widget.LinearLayout [0,0,109,97] <LinearLayout>
+ android.widget.ImageView [18,0,90,72] <ImageView>
+ android.widget.TextView [0,72,109,97] <TextView>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.xml
new file mode 100644
index 000000000..e4f5bf20e
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound1.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/layout1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2-expected-2.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2-expected-2.xml
new file mode 100644
index 000000000..2b9d338d1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2-expected-2.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/TextView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableBottom="@drawable/ic_launcher"
+ android:gravity="center"
+ android:text="Hello World" >
+ </TextView>
+
+</LinearLayout> \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.info b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.info
new file mode 100644
index 000000000..37084fb88
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.info
@@ -0,0 +1,5 @@
+android.widget.LinearLayout [0,121,800,480] <LinearLayout>
+ android.widget.LinearLayout [0,0,109,97] <LinearLayout>
+ android.widget.TextView [0,0,109,25] <TextView>
+ android.widget.ImageView [18,25,90,97] <ImageView>
+
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.xml
new file mode 100644
index 000000000..c24fb211c
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound2.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/layout2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3-expected-3.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3-expected-3.xml
new file mode 100644
index 000000000..ac8ffa8ce
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3-expected-3.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/TextView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@drawable/ic_launcher"
+ android:gravity="center"
+ android:text="Hello World" >
+ </TextView>
+
+</LinearLayout> \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.info b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.info
new file mode 100644
index 000000000..01d1127f1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.info
@@ -0,0 +1,4 @@
+android.widget.LinearLayout [0,121,800,480] <LinearLayout>
+ android.widget.LinearLayout [0,0,181,72] <LinearLayout>
+ android.widget.ImageView [0,0,72,72] <ImageView>
+ android.widget.TextView [72,23,181,48] <TextView>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.xml
new file mode 100644
index 000000000..2444e4830
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound3.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/layout3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4-expected-4.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4-expected-4.xml
new file mode 100644
index 000000000..af9b1c922
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4-expected-4.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/TextView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableRight="@drawable/ic_launcher"
+ android:gravity="center"
+ android:text="Hello World" >
+ </TextView>
+
+</LinearLayout> \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.info b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.info
new file mode 100644
index 000000000..4b39be81e
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.info
@@ -0,0 +1,4 @@
+android.widget.LinearLayout [0,121,800,480] <LinearLayout>
+ android.widget.LinearLayout [0,0,181,72] <LinearLayout>
+ android.widget.TextView [0,23,109,48] <TextView>
+ android.widget.ImageView [109,0,181,72] <ImageView>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.xml
new file mode 100644
index 000000000..2f6afd2f7
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound4.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <LinearLayout
+ android:id="@+id/layout4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-5.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-5.xml
new file mode 100644
index 000000000..35bebf5f1
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-5.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/RelativeLayout1"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <LinearLayout
+ android:id="@+id/layout1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/textView2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/layout1"
+ android:drawableBottom="@drawable/ic_launcher"
+ android:gravity="center"
+ android:text="Hello World" >
+ </TextView>
+
+ <LinearLayout
+ android:id="@+id/layout3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/textView2"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/layout4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/layout3"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+ </LinearLayout>
+
+</RelativeLayout> \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-6.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-6.xml
new file mode 100644
index 000000000..6d9925674
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all-expected-6.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/RelativeLayout1"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <LinearLayout
+ android:id="@+id/layout1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/layout2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/layout1"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/textView2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/TextView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/layout2"
+ android:drawableLeft="@drawable/ic_launcher"
+ android:gravity="center"
+ android:text="Hello World" >
+ </TextView>
+
+ <LinearLayout
+ android:id="@+id/layout4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/TextView1"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+ </LinearLayout>
+
+</RelativeLayout> \ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.info b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.info
new file mode 100644
index 000000000..57508bd72
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.info
@@ -0,0 +1,13 @@
+android.widget.RelativeLayout [0,121,800,480] <RelativeLayout>
+ android.widget.LinearLayout [0,0,109,97] <LinearLayout>
+ android.widget.ImageView [18,0,90,72] <ImageView>
+ android.widget.TextView [0,72,109,97] <TextView>
+ android.widget.LinearLayout [0,97,109,194] <LinearLayout>
+ android.widget.TextView [0,0,109,25] <TextView>
+ android.widget.ImageView [18,25,90,97] <ImageView>
+ android.widget.LinearLayout [0,194,181,266] <LinearLayout>
+ android.widget.ImageView [0,0,72,72] <ImageView>
+ android.widget.TextView [72,23,181,48] <TextView>
+ android.widget.LinearLayout [0,266,181,338] <LinearLayout>
+ android.widget.TextView [0,23,109,48] <TextView>
+ android.widget.ImageView [109,0,181,72] <ImageView>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.xml
new file mode 100644
index 000000000..0406b171d
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound_all.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/RelativeLayout1"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <LinearLayout
+ android:id="@+id/layout1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/layout2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/layout1"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/textView2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/layout3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/layout2"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/layout4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/layout3"
+ android:gravity="center"
+ android:orientation="horizontal" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_launcher" />
+ </LinearLayout>
+
+</RelativeLayout>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant1.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant1.txt
index 457239f9c..8eccdfc52 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant1.txt
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant1.txt
@@ -1,3 +1,3 @@
Quick assistant in sample1a.xml for <Button android:text="Fir^stButton":
-Extract Android String : Initiates the given refactoring operation
-Extract Style : Initiates the given refactoring operation
+Extract Android String : Initiates the "Extract Android String" refactoring
+Extract Style : Initiates the "Extract Style" refactoring
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant2.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant2.txt
index e96374875..b435ef49c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant2.txt
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant2.txt
@@ -1,7 +1,7 @@
Quick assistant in sample1a.xml for <Bu^tton android:text:
-Wrap in Container : Initiates the given refactoring operation
-Remove Container : Initiates the given refactoring operation
-Change Widget Type : Initiates the given refactoring operation
-Change Layout : Initiates the given refactoring operation
-Extract as Include : Initiates the given refactoring operation
-Extract Style : Initiates the given refactoring operation
+Wrap in Container : Initiates the "Wrap in Container" refactoring
+Remove Container : Initiates the "Remove Container" refactoring
+Change Widget Type : Initiates the "Change Widget Type" refactoring
+Change Layout : Initiates the "Change Layout" refactoring
+Extract as Include : Initiates the "Extract as Include" refactoring
+Extract Style : Initiates the "Extract Style" refactoring
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant3.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant3.txt
index 63dab948c..a7c46c026 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant3.txt
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant3.txt
@@ -1,7 +1,7 @@
Quick assistant in sample1a.xml for <Button andr^oid:text="FirstButton":
-Wrap in Container : Initiates the given refactoring operation
-Remove Container : Initiates the given refactoring operation
-Change Widget Type : Initiates the given refactoring operation
-Change Layout : Initiates the given refactoring operation
-Extract as Include : Initiates the given refactoring operation
-Extract Style : Initiates the given refactoring operation
+Wrap in Container : Initiates the "Wrap in Container" refactoring
+Remove Container : Initiates the "Remove Container" refactoring
+Change Widget Type : Initiates the "Change Widget Type" refactoring
+Change Layout : Initiates the "Change Layout" refactoring
+Extract as Include : Initiates the "Extract as Include" refactoring
+Extract Style : Initiates the "Extract Style" refactoring
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant4.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant4.txt
index 46accd93d..be08a13fb 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant4.txt
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-assistant4.txt
@@ -1,2 +1,2 @@
Quick assistant in sample1a.xml for android:id="@+id/Linea^rLayout2":
-Extract Style : Initiates the given refactoring operation
+Extract Style : Initiates the "Extract Style" refactoring