18dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye/*
28dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * Copyright (C) 2011 The Android Open Source Project
38dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye *
48dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License");
58dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * you may not use this file except in compliance with the License.
68dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * You may obtain a copy of the License at
78dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye *
88dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye *      http://www.eclipse.org/org/documents/epl-v10.php
98dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye *
108dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * Unless required by applicable law or agreed to in writing, software
118dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS,
128dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * See the License for the specific language governing permissions and
148dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * limitations under the License.
158dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye */
168dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyepackage com.android.ide.eclipse.adt.internal.editors.layout.refactoring;
178dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1812d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
1912d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ANDROID_URI;
2012d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ANDROID_WIDGET_PREFIX;
2112d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ATTR_ID;
2212d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
2312d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
2412d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.EXT_XML;
2512d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.VALUE_FILL_PARENT;
2612d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.VALUE_MATCH_PARENT;
2712d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.VALUE_WRAP_CONTENT;
288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
297e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbyeimport com.android.annotations.NonNull;
300757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbyeimport com.android.annotations.VisibleForTesting;
3113a9256cbb601228887eea910ce1dbd68a776b17Tor Norbyeimport com.android.ide.common.xml.XmlFormatStyle;
328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
33e50549f54810c29bffc681e39d33158ab2a8f26eRaphaelimport com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
35f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbyeimport com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.resources.IFile;
388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.runtime.CoreException;
398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.runtime.IProgressMonitor;
408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.runtime.OperationCanceledException;
418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.jface.text.ITextSelection;
428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.jface.viewers.ITreeSelection;
438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.Change;
448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.Refactoring;
458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.RefactoringStatus;
468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.TextFileChange;
478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.DeleteEdit;
488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.InsertEdit;
498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.MultiTextEdit;
508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.TextEdit;
518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.w3c.dom.Attr;
558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.w3c.dom.Element;
568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport java.util.ArrayList;
588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport java.util.List;
598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport java.util.Map;
608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye/**
628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * Inserts a new layout surrounding the current selection, migrates namespace
638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * attributes (if wrapping the root node), and optionally migrates layout
648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * attributes and updates references elsewhere.
658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye */
668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye@SuppressWarnings("restriction") // XML model
678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyepublic class WrapInRefactoring extends VisualRefactoring {
688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private static final String KEY_ID = "name";                           //$NON-NLS-1$
698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private static final String KEY_TYPE = "type";                         //$NON-NLS-1$
708dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
718dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private String mId;
728dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private String mTypeFqcn;
739e6db060854d0e890190919a27a1846f50f69d1aTor Norbye    private String mInitializedAttributes;
748dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
758dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    /**
768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     * This constructor is solely used by {@link Descriptor},
778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     * to replay a previous refactoring.
788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     * @param arguments argument map created by #createArgumentMap.
798dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     */
808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    WrapInRefactoring(Map<String, String> arguments) {
818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        super(arguments);
828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mId = arguments.get(KEY_ID);
838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mTypeFqcn = arguments.get(KEY_TYPE);
848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
86e50549f54810c29bffc681e39d33158ab2a8f26eRaphael    public WrapInRefactoring(
87e50549f54810c29bffc681e39d33158ab2a8f26eRaphael            IFile file,
88e50549f54810c29bffc681e39d33158ab2a8f26eRaphael            LayoutEditorDelegate delegate,
89e50549f54810c29bffc681e39d33158ab2a8f26eRaphael            ITextSelection selection,
908dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            ITreeSelection treeSelection) {
91e50549f54810c29bffc681e39d33158ab2a8f26eRaphael        super(file, delegate, selection, treeSelection);
928dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
938dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
940757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    @VisibleForTesting
95e50549f54810c29bffc681e39d33158ab2a8f26eRaphael    WrapInRefactoring(List<Element> selectedElements, LayoutEditorDelegate editor) {
960757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        super(selectedElements, editor);
970757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    }
980757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye
998dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1008dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException,
1018dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            OperationCanceledException {
1028dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        RefactoringStatus status = new RefactoringStatus();
1038dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1048dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        try {
1058dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            pm.beginTask("Checking preconditions...", 6);
1068dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1078dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (mSelectionStart == -1 || mSelectionEnd == -1) {
1088dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                status.addFatalError("No selection to wrap");
1098dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                return status;
1108dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
1118dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1128dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            // Make sure the selection is contiguous
1138dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (mTreeSelection != null) {
1148dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // TODO - don't do this if we based the selection on text. In this case,
1158dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // make sure we're -balanced-.
1168dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1178dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                List<CanvasViewInfo> infos = getSelectedViewInfos();
1188dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (!validateNotEmpty(infos, status)) {
1198dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    return status;
1208dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
1218dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1228dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // Enforce that the selection is -contiguous-
1238dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (!validateContiguous(infos, status)) {
1248dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    return status;
1258dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
1268dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
1278dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1280757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            // Ensures that we have a valid DOM model:
1298dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (mElements.size() == 0) {
1308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                status.addFatalError("Nothing to wrap");
1318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                return status;
1328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
1338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            pm.worked(1);
1358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            return status;
1368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        } finally {
1388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            pm.done();
1398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
1408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    protected VisualRefactoringDescriptor createDescriptor() {
1448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String comment = getName();
1458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return new Descriptor(
1468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                mProject.getName(), //project
1478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                comment, //description
1488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                comment, //comment
1498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                createArgumentMap());
1508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    protected Map<String, String> createArgumentMap() {
1548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        Map<String, String> args = super.createArgumentMap();
1558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        args.put(KEY_TYPE, mTypeFqcn);
1568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        args.put(KEY_ID, mId);
1578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return args;
1598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    public String getName() {
1638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return "Wrap in Container";
1648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    void setId(String id) {
1678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mId = id;
1688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1708dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    void setType(String typeFqcn) {
1718dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mTypeFqcn = typeFqcn;
1728dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1738dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1749e6db060854d0e890190919a27a1846f50f69d1aTor Norbye    void setInitializedAttributes(String initializedAttributes) {
1759e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        mInitializedAttributes = initializedAttributes;
1768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1797e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye    protected @NonNull List<Change> computeChanges(IProgressMonitor monitor) {
1808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (1) Insert the new container in front of the beginning of the
1818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      first wrapped view
1828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (2) If the container is the new root, transfer namespace declarations
1838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      to it
1848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (3) Insert the closing tag of the new container at the end of the
1858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      last wrapped view
1868dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (4) Reindent the wrapped views
1878dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (5) If the user requested it, update all layout references to the
1888dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      wrapped views with the new container?
1898dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //   For that matter, does RelativeLayout even require it? Probably not,
1908dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //   it can point inside the current layout...
1918dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1928dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Add indent to all lines between mSelectionStart and mEnd
1938dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // TODO: Figure out the indentation amount?
1948dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // For now, use 4 spaces
1958dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String indentUnit = "    "; //$NON-NLS-1$
1968dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        boolean separateAttributes = true;
197e50549f54810c29bffc681e39d33158ab2a8f26eRaphael        IStructuredDocument document = mDelegate.getEditor().getStructuredDocument();
1988dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String startIndent = AndroidXmlEditor.getIndentAtOffset(document, mSelectionStart);
1998dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2008dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String viewClass = getViewClass(mTypeFqcn);
2019e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        String androidNsPrefix = getAndroidNamespacePrefix();
2029e6db060854d0e890190919a27a1846f50f69d1aTor Norbye
2038dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
204e50549f54810c29bffc681e39d33158ab2a8f26eRaphael        IFile file = mDelegate.getEditor().getInputFile();
2058dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        List<Change> changes = new ArrayList<Change>();
206f14914e59366377316c70f068347d3e34a1dea3cTor Norbye        if (file == null) {
207f14914e59366377316c70f068347d3e34a1dea3cTor Norbye            return changes;
208f14914e59366377316c70f068347d3e34a1dea3cTor Norbye        }
2098dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        TextFileChange change = new TextFileChange(file.getName(), file);
2108dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        MultiTextEdit rootEdit = new MultiTextEdit();
2118dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        change.setTextType(EXT_XML);
2128dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2138dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String id = ensureNewId(mId);
2148dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2158dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Update any layout references to the old id with the new id
2169e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        if (id != null) {
2178dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            String rootId = getRootId();
218e50549f54810c29bffc681e39d33158ab2a8f26eRaphael            IStructuredModel model = mDelegate.getEditor().getModelForRead();
2198dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            try {
2208dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                IStructuredDocument doc = model.getStructuredDocument();
2218dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (doc != null) {
2229e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                    List<TextEdit> replaceIds = replaceIds(androidNsPrefix,
2239e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                            doc, mSelectionStart, mSelectionEnd, rootId, id);
2248dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    for (TextEdit edit : replaceIds) {
2258dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        rootEdit.addChild(edit);
2268dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
2278dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
2288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            } finally {
2298dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                model.releaseFromRead();
2308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Insert namespace elements?
2348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        StringBuilder namespace = null;
2358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        List<DeleteEdit> deletions = new ArrayList<DeleteEdit>();
2368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        Element primary = getPrimaryElement();
2378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (primary != null && getDomDocument().getDocumentElement() == primary) {
2388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            namespace = new StringBuilder();
2398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            List<Attr> declarations = findNamespaceAttributes(primary);
2418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            for (Attr attribute : declarations) {
2428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (attribute instanceof IndexedRegion) {
2438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    // Delete the namespace declaration in the node which is no longer the root
2448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    IndexedRegion region = (IndexedRegion) attribute;
2458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int startOffset = region.getStartOffset();
2468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int endOffset = region.getEndOffset();
2478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    String text = getText(startOffset, endOffset);
2488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    DeleteEdit deletion = new DeleteEdit(startOffset, endOffset - startOffset);
2498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    deletions.add(deletion);
2508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    rootEdit.addChild(deletion);
2518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    text = text.trim();
2528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    // Insert the namespace declaration in the new root
2548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    if (separateAttributes) {
2558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        namespace.append('\n').append(startIndent).append(indentUnit);
2568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    } else {
2578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        namespace.append(' ');
2588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
2598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    namespace.append(text);
2608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
2618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Insert begin tag: <type ...>
2658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        StringBuilder sb = new StringBuilder();
2668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('<');
2678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(viewClass);
2688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (namespace != null) {
2708dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(namespace);
2718dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2728dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2738dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Set the ID if any
2748dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (id != null) {
2758dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (separateAttributes) {
2768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                sb.append('\n').append(startIndent).append(indentUnit);
2778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            } else {
2788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                sb.append(' ');
2798dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(androidNsPrefix).append(':');
2818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(ATTR_ID).append('=').append('"').append(id).append('"');
2828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // If any of the elements are fill/match parent, use that instead
2858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String width = VALUE_WRAP_CONTENT;
2868dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String height = VALUE_WRAP_CONTENT;
2878dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2888dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        for (Element element : getElements()) {
2898dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            String oldWidth = element.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH);
2908dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            String oldHeight = element.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT);
2918dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2928dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (VALUE_MATCH_PARENT.equals(oldWidth) || VALUE_FILL_PARENT.equals(oldWidth)) {
2938dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                width = oldWidth;
2948dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2958dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (VALUE_MATCH_PARENT.equals(oldHeight) || VALUE_FILL_PARENT.equals(oldHeight)) {
2968dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                height = oldHeight;
2978dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2988dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2998dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3008dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Add in width/height.
3018dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (separateAttributes) {
3028dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append('\n').append(startIndent).append(indentUnit);
3038dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        } else {
3048dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(' ');
3058dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
3068dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(androidNsPrefix).append(':');
3078dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(ATTR_LAYOUT_WIDTH).append('=').append('"').append(width).append('"');
3088dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3098dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (separateAttributes) {
3108dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append('\n').append(startIndent).append(indentUnit);
3118dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        } else {
3128dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(' ');
3138dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
3148dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(androidNsPrefix).append(':');
3158dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(ATTR_LAYOUT_HEIGHT).append('=').append('"').append(height).append('"');
3168dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3179e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        if (mInitializedAttributes != null && mInitializedAttributes.length() > 0) {
3189e6db060854d0e890190919a27a1846f50f69d1aTor Norbye            for (String s : mInitializedAttributes.split(",")) { //$NON-NLS-1$
3199e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                sb.append(' ');
3209e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                String[] nameValue = s.split("="); //$NON-NLS-1$
3219e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                String name = nameValue[0];
3229e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                String value = nameValue[1];
3239e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
3249e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                    name = name.substring(ANDROID_NS_NAME_PREFIX.length());
3259e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                    sb.append(androidNsPrefix).append(':');
3269e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                }
3279e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                sb.append(name).append('=').append('"').append(value).append('"');
3289e6db060854d0e890190919a27a1846f50f69d1aTor Norbye            }
3299e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        }
3309e6db060854d0e890190919a27a1846f50f69d1aTor Norbye
3318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Transfer layout_ attributes (other than width and height)
3329e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        if (primary != null) {
3338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            List<Attr> layoutAttributes = findLayoutAttributes(primary);
3348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            for (Attr attribute : layoutAttributes) {
3358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                String name = attribute.getLocalName();
3368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if ((name.equals(ATTR_LAYOUT_WIDTH) || name.equals(ATTR_LAYOUT_HEIGHT))
3378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        && ANDROID_URI.equals(attribute.getNamespaceURI())) {
3388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    // Already handled specially
3398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    continue;
3408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (attribute instanceof IndexedRegion) {
3438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    IndexedRegion region = (IndexedRegion) attribute;
3448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int startOffset = region.getStartOffset();
3458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int endOffset = region.getEndOffset();
3468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    String text = getText(startOffset, endOffset);
3478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    DeleteEdit deletion = new DeleteEdit(startOffset, endOffset - startOffset);
3488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    rootEdit.addChild(deletion);
3498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    deletions.add(deletion);
3508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    if (separateAttributes) {
3528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        sb.append('\n').append(startIndent).append(indentUnit);
3538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    } else {
3548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        sb.append(' ');
3558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
3568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    sb.append(text.trim());
3578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
3598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
3608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Finish open tag:
3628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('>');
3638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('\n').append(startIndent).append(indentUnit);
3648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        InsertEdit beginEdit = new InsertEdit(mSelectionStart, sb.toString());
3668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        rootEdit.addChild(beginEdit);
3678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String nested = getText(mSelectionStart, mSelectionEnd);
3698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        int index = 0;
3708dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        while (index != -1) {
3718dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            index = nested.indexOf('\n', index);
3728dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (index != -1) {
3738dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                index++;
3748dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                InsertEdit newline = new InsertEdit(mSelectionStart + index, indentUnit);
3758dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // Some of the deleted namespaces may have had newlines - be careful
3768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // not to overlap edits
3778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                boolean covered = false;
3788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                for (DeleteEdit deletion : deletions) {
3798dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    if (deletion.covers(newline)) {
3808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        covered = true;
3818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        break;
3828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
3838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (!covered) {
3858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    rootEdit.addChild(newline);
3868dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3878dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
3888dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
3898dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3908dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Insert end tag: </type>
3918dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.setLength(0);
3928dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('\n').append(startIndent);
3938dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('<').append('/').append(viewClass).append('>');
3948dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        InsertEdit endEdit = new InsertEdit(mSelectionEnd, sb.toString());
3958dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        rootEdit.addChild(endEdit);
3968dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
397f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye        if (AdtPrefs.getPrefs().getFormatGuiXml()) {
398f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye            MultiTextEdit formatted = reformat(rootEdit, XmlFormatStyle.LAYOUT);
399f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye            if (formatted != null) {
400f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye                rootEdit = formatted;
401f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye            }
402f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye        }
403f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye
404f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye        change.setEdit(rootEdit);
4058dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        changes.add(change);
4068dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return changes;
4078dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
4088dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
4090757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    String getOldType() {
4100757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        Element primary = getPrimaryElement();
4110757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        if (primary != null) {
4120757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            String oldType = primary.getTagName();
4130757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            if (oldType.indexOf('.') == -1) {
4140757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye                oldType = ANDROID_WIDGET_PREFIX + oldType;
4150757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            }
4160757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            return oldType;
4170757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        }
4180757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye
4190757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        return null;
4200757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    }
4210757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye
422891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye    @Override
423891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye    VisualRefactoringWizard createWizard() {
424e50549f54810c29bffc681e39d33158ab2a8f26eRaphael        return new WrapInWizard(this, mDelegate);
425891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye    }
426891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye
4278dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    public static class Descriptor extends VisualRefactoringDescriptor {
4288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        public Descriptor(String project, String description, String comment,
4298dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                Map<String, String> arguments) {
4308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            super("com.android.ide.eclipse.adt.refactoring.wrapin", //$NON-NLS-1$
4318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    project, description, comment, arguments);
4328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
4338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
4348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        @Override
4358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        protected Refactoring createRefactoring(Map<String, String> args) {
4368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            return new WrapInRefactoring(args);
4378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
4388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
4398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye}
440