diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java | 439 |
1 files changed, 0 insertions, 439 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java deleted file mode 100644 index 07b00b8da..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/WrapInRefactoring.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * 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 static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX; -import static com.android.SdkConstants.ANDROID_URI; -import static com.android.SdkConstants.ANDROID_WIDGET_PREFIX; -import static com.android.SdkConstants.ATTR_ID; -import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT; -import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH; -import static com.android.SdkConstants.EXT_XML; -import static com.android.SdkConstants.VALUE_FILL_PARENT; -import static com.android.SdkConstants.VALUE_MATCH_PARENT; -import static com.android.SdkConstants.VALUE_WRAP_CONTENT; - -import com.android.annotations.NonNull; -import com.android.annotations.VisibleForTesting; -import com.android.ide.common.xml.XmlFormatStyle; -import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; -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.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.DeleteEdit; -import org.eclipse.text.edits.InsertEdit; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.TextEdit; -import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; -import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; -import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Inserts a new layout surrounding the current selection, migrates namespace - * attributes (if wrapping the root node), and optionally migrates layout - * attributes and updates references elsewhere. - */ -@SuppressWarnings("restriction") // XML model -public class WrapInRefactoring extends VisualRefactoring { - private static final String KEY_ID = "name"; //$NON-NLS-1$ - private static final String KEY_TYPE = "type"; //$NON-NLS-1$ - - private String mId; - private String mTypeFqcn; - private String mInitializedAttributes; - - /** - * This constructor is solely used by {@link Descriptor}, - * to replay a previous refactoring. - * @param arguments argument map created by #createArgumentMap. - */ - WrapInRefactoring(Map<String, String> arguments) { - super(arguments); - mId = arguments.get(KEY_ID); - mTypeFqcn = arguments.get(KEY_TYPE); - } - - public WrapInRefactoring( - IFile file, - LayoutEditorDelegate delegate, - ITextSelection selection, - ITreeSelection treeSelection) { - super(file, delegate, selection, treeSelection); - } - - @VisibleForTesting - WrapInRefactoring(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("No selection to wrap"); - return status; - } - - // Make sure the selection is contiguous - if (mTreeSelection != null) { - // TODO - don't do this if we based the selection on text. In this case, - // make sure we're -balanced-. - - 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 wrap"); - 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() { - Map<String, String> args = super.createArgumentMap(); - args.put(KEY_TYPE, mTypeFqcn); - args.put(KEY_ID, mId); - - return args; - } - - @Override - public String getName() { - return "Wrap in Container"; - } - - void setId(String id) { - mId = id; - } - - void setType(String typeFqcn) { - mTypeFqcn = typeFqcn; - } - - void setInitializedAttributes(String initializedAttributes) { - mInitializedAttributes = initializedAttributes; - } - - @Override - protected @NonNull List<Change> computeChanges(IProgressMonitor monitor) { - // (1) Insert the new container in front of the beginning of the - // first wrapped view - // (2) If the container is the new root, transfer namespace declarations - // to it - // (3) Insert the closing tag of the new container at the end of the - // last wrapped view - // (4) Reindent the wrapped views - // (5) If the user requested it, update all layout references to the - // wrapped views with the new container? - // For that matter, does RelativeLayout even require it? Probably not, - // it can point inside the current layout... - - // Add indent to all lines between mSelectionStart and mEnd - // TODO: Figure out the indentation amount? - // For now, use 4 spaces - String indentUnit = " "; //$NON-NLS-1$ - boolean separateAttributes = true; - IStructuredDocument document = mDelegate.getEditor().getStructuredDocument(); - String startIndent = AndroidXmlEditor.getIndentAtOffset(document, mSelectionStart); - - String viewClass = getViewClass(mTypeFqcn); - String androidNsPrefix = getAndroidNamespacePrefix(); - - - IFile file = mDelegate.getEditor().getInputFile(); - List<Change> changes = new ArrayList<Change>(); - if (file == null) { - return changes; - } - TextFileChange change = new TextFileChange(file.getName(), file); - MultiTextEdit rootEdit = new MultiTextEdit(); - change.setTextType(EXT_XML); - - String id = ensureNewId(mId); - - // Update any layout references to the old id with the new id - if (id != null) { - String rootId = getRootId(); - IStructuredModel model = mDelegate.getEditor().getModelForRead(); - try { - IStructuredDocument doc = model.getStructuredDocument(); - if (doc != null) { - List<TextEdit> replaceIds = replaceIds(androidNsPrefix, - doc, mSelectionStart, mSelectionEnd, rootId, id); - for (TextEdit edit : replaceIds) { - rootEdit.addChild(edit); - } - } - } finally { - model.releaseFromRead(); - } - } - - // Insert namespace elements? - StringBuilder namespace = null; - List<DeleteEdit> deletions = new ArrayList<DeleteEdit>(); - Element primary = getPrimaryElement(); - if (primary != null && getDomDocument().getDocumentElement() == primary) { - namespace = new StringBuilder(); - - List<Attr> declarations = findNamespaceAttributes(primary); - for (Attr attribute : declarations) { - if (attribute instanceof IndexedRegion) { - // Delete the namespace declaration in the node which is no longer the root - IndexedRegion region = (IndexedRegion) attribute; - int startOffset = region.getStartOffset(); - int endOffset = region.getEndOffset(); - String text = getText(startOffset, endOffset); - DeleteEdit deletion = new DeleteEdit(startOffset, endOffset - startOffset); - deletions.add(deletion); - rootEdit.addChild(deletion); - text = text.trim(); - - // Insert the namespace declaration in the new root - if (separateAttributes) { - namespace.append('\n').append(startIndent).append(indentUnit); - } else { - namespace.append(' '); - } - namespace.append(text); - } - } - } - - // Insert begin tag: <type ...> - StringBuilder sb = new StringBuilder(); - sb.append('<'); - sb.append(viewClass); - - if (namespace != null) { - sb.append(namespace); - } - - // Set the ID if any - if (id != null) { - if (separateAttributes) { - sb.append('\n').append(startIndent).append(indentUnit); - } else { - sb.append(' '); - } - sb.append(androidNsPrefix).append(':'); - sb.append(ATTR_ID).append('=').append('"').append(id).append('"'); - } - - // If any of the elements are fill/match parent, use that instead - String width = VALUE_WRAP_CONTENT; - String height = VALUE_WRAP_CONTENT; - - for (Element element : getElements()) { - String oldWidth = element.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH); - String oldHeight = element.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT); - - if (VALUE_MATCH_PARENT.equals(oldWidth) || VALUE_FILL_PARENT.equals(oldWidth)) { - width = oldWidth; - } - if (VALUE_MATCH_PARENT.equals(oldHeight) || VALUE_FILL_PARENT.equals(oldHeight)) { - height = oldHeight; - } - } - - // Add in width/height. - if (separateAttributes) { - sb.append('\n').append(startIndent).append(indentUnit); - } else { - sb.append(' '); - } - sb.append(androidNsPrefix).append(':'); - sb.append(ATTR_LAYOUT_WIDTH).append('=').append('"').append(width).append('"'); - - if (separateAttributes) { - sb.append('\n').append(startIndent).append(indentUnit); - } else { - sb.append(' '); - } - sb.append(androidNsPrefix).append(':'); - sb.append(ATTR_LAYOUT_HEIGHT).append('=').append('"').append(height).append('"'); - - if (mInitializedAttributes != null && mInitializedAttributes.length() > 0) { - for (String s : mInitializedAttributes.split(",")) { //$NON-NLS-1$ - sb.append(' '); - String[] nameValue = s.split("="); //$NON-NLS-1$ - String name = nameValue[0]; - String value = nameValue[1]; - if (name.startsWith(ANDROID_NS_NAME_PREFIX)) { - name = name.substring(ANDROID_NS_NAME_PREFIX.length()); - sb.append(androidNsPrefix).append(':'); - } - sb.append(name).append('=').append('"').append(value).append('"'); - } - } - - // Transfer layout_ attributes (other than width and height) - if (primary != null) { - List<Attr> layoutAttributes = findLayoutAttributes(primary); - 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; - } - - if (attribute instanceof IndexedRegion) { - IndexedRegion region = (IndexedRegion) attribute; - int startOffset = region.getStartOffset(); - int endOffset = region.getEndOffset(); - String text = getText(startOffset, endOffset); - DeleteEdit deletion = new DeleteEdit(startOffset, endOffset - startOffset); - rootEdit.addChild(deletion); - deletions.add(deletion); - - if (separateAttributes) { - sb.append('\n').append(startIndent).append(indentUnit); - } else { - sb.append(' '); - } - sb.append(text.trim()); - } - } - } - - // Finish open tag: - sb.append('>'); - sb.append('\n').append(startIndent).append(indentUnit); - - InsertEdit beginEdit = new InsertEdit(mSelectionStart, sb.toString()); - rootEdit.addChild(beginEdit); - - String nested = getText(mSelectionStart, mSelectionEnd); - int index = 0; - while (index != -1) { - index = nested.indexOf('\n', index); - if (index != -1) { - index++; - InsertEdit newline = new InsertEdit(mSelectionStart + index, indentUnit); - // Some of the deleted namespaces may have had newlines - be careful - // not to overlap edits - boolean covered = false; - for (DeleteEdit deletion : deletions) { - if (deletion.covers(newline)) { - covered = true; - break; - } - } - if (!covered) { - rootEdit.addChild(newline); - } - } - } - - // Insert end tag: </type> - sb.setLength(0); - sb.append('\n').append(startIndent); - sb.append('<').append('/').append(viewClass).append('>'); - InsertEdit endEdit = new InsertEdit(mSelectionEnd, sb.toString()); - rootEdit.addChild(endEdit); - - if (AdtPrefs.getPrefs().getFormatGuiXml()) { - MultiTextEdit formatted = reformat(rootEdit, XmlFormatStyle.LAYOUT); - if (formatted != null) { - rootEdit = formatted; - } - } - - change.setEdit(rootEdit); - changes.add(change); - return changes; - } - - String getOldType() { - Element primary = getPrimaryElement(); - if (primary != null) { - String oldType = primary.getTagName(); - if (oldType.indexOf('.') == -1) { - oldType = ANDROID_WIDGET_PREFIX + oldType; - } - return oldType; - } - - return null; - } - - @Override - VisualRefactoringWizard createWizard() { - return new WrapInWizard(this, mDelegate); - } - - 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.wrapin", //$NON-NLS-1$ - project, description, comment, arguments); - } - - @Override - protected Refactoring createRefactoring(Map<String, String> args) { - return new WrapInRefactoring(args); - } - } -} |