WrapInRefactoring.java revision f5256a38ef2e429b5efd4482808bc902bf7634e3
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
189e6db060854d0e890190919a27a1846f50f69d1aTor Norbyeimport static com.android.ide.common.layout.LayoutConstants.ANDROID_NS_NAME_PREFIX;
198dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
200757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbyeimport static com.android.ide.common.layout.LayoutConstants.ANDROID_WIDGET_PREFIX;
218dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport static com.android.ide.common.layout.LayoutConstants.ATTR_ID;
228dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_HEIGHT;
238dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_WIDTH;
248dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport static com.android.ide.common.layout.LayoutConstants.VALUE_FILL_PARENT;
258dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport static com.android.ide.common.layout.LayoutConstants.VALUE_MATCH_PARENT;
268dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport static com.android.ide.common.layout.LayoutConstants.VALUE_WRAP_CONTENT;
27c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohetimport static com.android.ide.eclipse.adt.AdtConstants.EXT_XML;
288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
290757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbyeimport com.android.annotations.VisibleForTesting;
308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
31f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
34f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbyeimport com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.resources.IFile;
378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.runtime.CoreException;
388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.runtime.IProgressMonitor;
398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.core.runtime.OperationCanceledException;
408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.jface.text.ITextSelection;
418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.jface.viewers.ITreeSelection;
428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.Change;
438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.Refactoring;
448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.RefactoringStatus;
458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.ltk.core.refactoring.TextFileChange;
468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.DeleteEdit;
478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.InsertEdit;
488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.MultiTextEdit;
498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.text.edits.TextEdit;
508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.w3c.dom.Attr;
548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport org.w3c.dom.Element;
558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport java.util.ArrayList;
578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport java.util.List;
588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyeimport java.util.Map;
598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye/**
618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * Inserts a new layout surrounding the current selection, migrates namespace
628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * attributes (if wrapping the root node), and optionally migrates layout
638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye * attributes and updates references elsewhere.
648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye */
658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye@SuppressWarnings("restriction") // XML model
668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbyepublic class WrapInRefactoring extends VisualRefactoring {
678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private static final String KEY_ID = "name";                           //$NON-NLS-1$
688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private static final String KEY_TYPE = "type";                         //$NON-NLS-1$
698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
708dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private String mId;
718dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    private String mTypeFqcn;
729e6db060854d0e890190919a27a1846f50f69d1aTor Norbye    private String mInitializedAttributes;
738dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
748dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    /**
758dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     * This constructor is solely used by {@link Descriptor},
768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     * to replay a previous refactoring.
778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     * @param arguments argument map created by #createArgumentMap.
788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye     */
798dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    WrapInRefactoring(Map<String, String> arguments) {
808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        super(arguments);
818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mId = arguments.get(KEY_ID);
828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mTypeFqcn = arguments.get(KEY_TYPE);
838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    public WrapInRefactoring(IFile file, LayoutEditor editor, ITextSelection selection,
868dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            ITreeSelection treeSelection) {
878dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        super(file, editor, selection, treeSelection);
888dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
898dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
900757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    @VisibleForTesting
910757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    WrapInRefactoring(List<Element> selectedElements, LayoutEditor editor) {
920757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        super(selectedElements, editor);
930757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    }
940757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye
958dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
968dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException,
978dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            OperationCanceledException {
988dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        RefactoringStatus status = new RefactoringStatus();
998dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1008dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        try {
1018dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            pm.beginTask("Checking preconditions...", 6);
1028dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1038dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (mSelectionStart == -1 || mSelectionEnd == -1) {
1048dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                status.addFatalError("No selection to wrap");
1058dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                return status;
1068dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
1078dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1088dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            // Make sure the selection is contiguous
1098dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (mTreeSelection != null) {
1108dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // TODO - don't do this if we based the selection on text. In this case,
1118dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // make sure we're -balanced-.
1128dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1138dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                List<CanvasViewInfo> infos = getSelectedViewInfos();
1148dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (!validateNotEmpty(infos, status)) {
1158dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    return status;
1168dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
1178dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1188dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // Enforce that the selection is -contiguous-
1198dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (!validateContiguous(infos, status)) {
1208dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    return status;
1218dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
1228dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
1238dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1240757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            // Ensures that we have a valid DOM model:
1258dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (mElements.size() == 0) {
1268dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                status.addFatalError("Nothing to wrap");
1278dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                return status;
1288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
1298dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            pm.worked(1);
1318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            return status;
1328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        } finally {
1348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            pm.done();
1358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
1368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    protected VisualRefactoringDescriptor createDescriptor() {
1408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String comment = getName();
1418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return new Descriptor(
1428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                mProject.getName(), //project
1438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                comment, //description
1448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                comment, //comment
1458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                createArgumentMap());
1468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    protected Map<String, String> createArgumentMap() {
1508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        Map<String, String> args = super.createArgumentMap();
1518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        args.put(KEY_TYPE, mTypeFqcn);
1528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        args.put(KEY_ID, mId);
1538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return args;
1558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
1588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    public String getName() {
1598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return "Wrap in Container";
1608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    void setId(String id) {
1638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mId = id;
1648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    void setType(String typeFqcn) {
1678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        mTypeFqcn = typeFqcn;
1688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1709e6db060854d0e890190919a27a1846f50f69d1aTor Norbye    void setInitializedAttributes(String initializedAttributes) {
1719e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        mInitializedAttributes = initializedAttributes;
1728dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
1738dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1748dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    @Override
175eacf5a536e29b366e6e2dcf6a80d86ad5241734cTor Norbye    protected List<Change> computeChanges(IProgressMonitor monitor) {
1768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (1) Insert the new container in front of the beginning of the
1778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      first wrapped view
1788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (2) If the container is the new root, transfer namespace declarations
1798dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      to it
1808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (3) Insert the closing tag of the new container at the end of the
1818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      last wrapped view
1828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (4) Reindent the wrapped views
1838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // (5) If the user requested it, update all layout references to the
1848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //      wrapped views with the new container?
1858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //   For that matter, does RelativeLayout even require it? Probably not,
1868dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        //   it can point inside the current layout...
1878dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1888dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Add indent to all lines between mSelectionStart and mEnd
1898dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // TODO: Figure out the indentation amount?
1908dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // For now, use 4 spaces
1918dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String indentUnit = "    "; //$NON-NLS-1$
1928dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        boolean separateAttributes = true;
1938dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        IStructuredDocument document = mEditor.getStructuredDocument();
1948dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String startIndent = AndroidXmlEditor.getIndentAtOffset(document, mSelectionStart);
1958dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
1968dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String viewClass = getViewClass(mTypeFqcn);
1979e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        String androidNsPrefix = getAndroidNamespacePrefix();
1989e6db060854d0e890190919a27a1846f50f69d1aTor Norbye
1998dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2008dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        IFile file = mEditor.getInputFile();
2018dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        List<Change> changes = new ArrayList<Change>();
2028dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        TextFileChange change = new TextFileChange(file.getName(), file);
2038dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        MultiTextEdit rootEdit = new MultiTextEdit();
2048dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        change.setTextType(EXT_XML);
2058dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2068dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String id = ensureNewId(mId);
2078dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2088dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Update any layout references to the old id with the new id
2099e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        if (id != null) {
2108dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            String rootId = getRootId();
2118dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            IStructuredModel model = mEditor.getModelForRead();
2128dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            try {
2138dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                IStructuredDocument doc = model.getStructuredDocument();
2148dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (doc != null) {
2159e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                    List<TextEdit> replaceIds = replaceIds(androidNsPrefix,
2169e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                            doc, mSelectionStart, mSelectionEnd, rootId, id);
2178dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    for (TextEdit edit : replaceIds) {
2188dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        rootEdit.addChild(edit);
2198dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
2208dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
2218dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            } finally {
2228dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                model.releaseFromRead();
2238dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2248dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2258dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2268dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Insert namespace elements?
2278dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        StringBuilder namespace = null;
2288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        List<DeleteEdit> deletions = new ArrayList<DeleteEdit>();
2298dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        Element primary = getPrimaryElement();
2308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (primary != null && getDomDocument().getDocumentElement() == primary) {
2318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            namespace = new StringBuilder();
2328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            List<Attr> declarations = findNamespaceAttributes(primary);
2348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            for (Attr attribute : declarations) {
2358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (attribute instanceof IndexedRegion) {
2368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    // Delete the namespace declaration in the node which is no longer the root
2378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    IndexedRegion region = (IndexedRegion) attribute;
2388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int startOffset = region.getStartOffset();
2398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int endOffset = region.getEndOffset();
2408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    String text = getText(startOffset, endOffset);
2418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    DeleteEdit deletion = new DeleteEdit(startOffset, endOffset - startOffset);
2428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    deletions.add(deletion);
2438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    rootEdit.addChild(deletion);
2448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    text = text.trim();
2458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    // Insert the namespace declaration in the new root
2478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    if (separateAttributes) {
2488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        namespace.append('\n').append(startIndent).append(indentUnit);
2498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    } else {
2508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        namespace.append(' ');
2518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
2528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    namespace.append(text);
2538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
2548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Insert begin tag: <type ...>
2588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        StringBuilder sb = new StringBuilder();
2598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('<');
2608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(viewClass);
2618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (namespace != null) {
2638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(namespace);
2648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Set the ID if any
2678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (id != null) {
2688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (separateAttributes) {
2698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                sb.append('\n').append(startIndent).append(indentUnit);
2708dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            } else {
2718dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                sb.append(' ');
2728dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2738dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(androidNsPrefix).append(':');
2748dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(ATTR_ID).append('=').append('"').append(id).append('"');
2758dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // If any of the elements are fill/match parent, use that instead
2788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String width = VALUE_WRAP_CONTENT;
2798dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String height = VALUE_WRAP_CONTENT;
2808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        for (Element element : getElements()) {
2828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            String oldWidth = element.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH);
2838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            String oldHeight = element.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT);
2848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (VALUE_MATCH_PARENT.equals(oldWidth) || VALUE_FILL_PARENT.equals(oldWidth)) {
2868dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                width = oldWidth;
2878dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2888dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (VALUE_MATCH_PARENT.equals(oldHeight) || VALUE_FILL_PARENT.equals(oldHeight)) {
2898dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                height = oldHeight;
2908dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
2918dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2928dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
2938dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Add in width/height.
2948dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (separateAttributes) {
2958dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append('\n').append(startIndent).append(indentUnit);
2968dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        } else {
2978dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(' ');
2988dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
2998dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(androidNsPrefix).append(':');
3008dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(ATTR_LAYOUT_WIDTH).append('=').append('"').append(width).append('"');
3018dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3028dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        if (separateAttributes) {
3038dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append('\n').append(startIndent).append(indentUnit);
3048dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        } else {
3058dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            sb.append(' ');
3068dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
3078dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(androidNsPrefix).append(':');
3088dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append(ATTR_LAYOUT_HEIGHT).append('=').append('"').append(height).append('"');
3098dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3109e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        if (mInitializedAttributes != null && mInitializedAttributes.length() > 0) {
3119e6db060854d0e890190919a27a1846f50f69d1aTor Norbye            for (String s : mInitializedAttributes.split(",")) { //$NON-NLS-1$
3129e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                sb.append(' ');
3139e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                String[] nameValue = s.split("="); //$NON-NLS-1$
3149e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                String name = nameValue[0];
3159e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                String value = nameValue[1];
3169e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
3179e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                    name = name.substring(ANDROID_NS_NAME_PREFIX.length());
3189e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                    sb.append(androidNsPrefix).append(':');
3199e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                }
3209e6db060854d0e890190919a27a1846f50f69d1aTor Norbye                sb.append(name).append('=').append('"').append(value).append('"');
3219e6db060854d0e890190919a27a1846f50f69d1aTor Norbye            }
3229e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        }
3239e6db060854d0e890190919a27a1846f50f69d1aTor Norbye
3248dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Transfer layout_ attributes (other than width and height)
3259e6db060854d0e890190919a27a1846f50f69d1aTor Norbye        if (primary != null) {
3268dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            List<Attr> layoutAttributes = findLayoutAttributes(primary);
3278dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            for (Attr attribute : layoutAttributes) {
3288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                String name = attribute.getLocalName();
3298dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if ((name.equals(ATTR_LAYOUT_WIDTH) || name.equals(ATTR_LAYOUT_HEIGHT))
3308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        && ANDROID_URI.equals(attribute.getNamespaceURI())) {
3318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    // Already handled specially
3328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    continue;
3338dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3348dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3358dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (attribute instanceof IndexedRegion) {
3368dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    IndexedRegion region = (IndexedRegion) attribute;
3378dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int startOffset = region.getStartOffset();
3388dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    int endOffset = region.getEndOffset();
3398dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    String text = getText(startOffset, endOffset);
3408dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    DeleteEdit deletion = new DeleteEdit(startOffset, endOffset - startOffset);
3418dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    rootEdit.addChild(deletion);
3428dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    deletions.add(deletion);
3438dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3448dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    if (separateAttributes) {
3458dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        sb.append('\n').append(startIndent).append(indentUnit);
3468dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    } else {
3478dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        sb.append(' ');
3488dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
3498dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    sb.append(text.trim());
3508dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3518dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
3528dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
3538dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3548dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Finish open tag:
3558dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('>');
3568dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('\n').append(startIndent).append(indentUnit);
3578dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3588dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        InsertEdit beginEdit = new InsertEdit(mSelectionStart, sb.toString());
3598dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        rootEdit.addChild(beginEdit);
3608dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3618dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        String nested = getText(mSelectionStart, mSelectionEnd);
3628dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        int index = 0;
3638dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        while (index != -1) {
3648dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            index = nested.indexOf('\n', index);
3658dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            if (index != -1) {
3668dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                index++;
3678dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                InsertEdit newline = new InsertEdit(mSelectionStart + index, indentUnit);
3688dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // Some of the deleted namespaces may have had newlines - be careful
3698dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                // not to overlap edits
3708dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                boolean covered = false;
3718dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                for (DeleteEdit deletion : deletions) {
3728dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    if (deletion.covers(newline)) {
3738dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        covered = true;
3748dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                        break;
3758dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    }
3768dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3778dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                if (!covered) {
3788dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    rootEdit.addChild(newline);
3798dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                }
3808dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            }
3818dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
3828dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
3838dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        // Insert end tag: </type>
3848dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.setLength(0);
3858dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('\n').append(startIndent);
3868dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        sb.append('<').append('/').append(viewClass).append('>');
3878dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        InsertEdit endEdit = new InsertEdit(mSelectionEnd, sb.toString());
3888dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        rootEdit.addChild(endEdit);
3898dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
390f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye        if (AdtPrefs.getPrefs().getFormatGuiXml()) {
391f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye            MultiTextEdit formatted = reformat(rootEdit, XmlFormatStyle.LAYOUT);
392f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye            if (formatted != null) {
393f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye                rootEdit = formatted;
394f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye            }
395f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye        }
396f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye
397f5256a38ef2e429b5efd4482808bc902bf7634e3Tor Norbye        change.setEdit(rootEdit);
3988dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        changes.add(change);
3998dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        return changes;
4008dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
4018dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
4020757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    String getOldType() {
4030757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        Element primary = getPrimaryElement();
4040757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        if (primary != null) {
4050757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            String oldType = primary.getTagName();
4060757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            if (oldType.indexOf('.') == -1) {
4070757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye                oldType = ANDROID_WIDGET_PREFIX + oldType;
4080757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            }
4090757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye            return oldType;
4100757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        }
4110757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye
4120757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye        return null;
4130757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye    }
4140757ce4af2764e4dd564acc0b1a013e910abc8daTor Norbye
415891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye    @Override
416891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye    VisualRefactoringWizard createWizard() {
417891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye        return new WrapInWizard(this, mEditor);
418891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye    }
419891fe684c31864eab0ef4372ea6379f2c3b5fb4fTor Norbye
4208dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    public static class Descriptor extends VisualRefactoringDescriptor {
4218dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        public Descriptor(String project, String description, String comment,
4228dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                Map<String, String> arguments) {
4238dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            super("com.android.ide.eclipse.adt.refactoring.wrapin", //$NON-NLS-1$
4248dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye                    project, description, comment, arguments);
4258dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
4268dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye
4278dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        @Override
4288dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        protected Refactoring createRefactoring(Map<String, String> args) {
4298dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye            return new WrapInRefactoring(args);
4308dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye        }
4318dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye    }
4328dc4366bbaad39d56e1c2ded4046c86a95a17666Tor Norbye}
433