Search in sources :

Example 96 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project android by JetBrains.

the class RtlSupportProcessor method getLayoutRefactoringForTag.

private List<UsageInfo> getLayoutRefactoringForTag(@NotNull XmlTag tag, boolean createV17, int minSdk) {
    final DomElement domElement = DomManager.getDomManager(myProject).getDomElement(tag);
    if (!(domElement instanceof LayoutViewElement)) {
        return Collections.emptyList();
    }
    final List<UsageInfo> result = new ArrayList<UsageInfo>();
    final XmlAttribute[] attributes = tag.getAttributes();
    for (XmlAttribute attributeToMirror : attributes) {
        final String localName = attributeToMirror.getLocalName();
        final String namespacePrefix = attributeToMirror.getNamespacePrefix();
        final String mirroredLocalName = ourMapMirroredAttributeName.get(localName);
        // Check if this is a RTL attribute to mirror or if it is a Gravity attribute
        if (mirroredLocalName != null) {
            // Mirror only attributes that has not been mirrored before
            final XmlAttribute attributeMirrored = tag.getAttribute(namespacePrefix + ":" + mirroredLocalName);
            if (attributeMirrored == null) {
                final int startOffset = 0;
                final int endOffset = attributeToMirror.getTextLength();
                RtlRefactoringUsageInfo usageInfoForAttribute = new RtlRefactoringUsageInfo(attributeToMirror, startOffset, endOffset);
                usageInfoForAttribute.setType(LAYOUT_FILE_ATTRIBUTE);
                usageInfoForAttribute.setCreateV17(createV17);
                usageInfoForAttribute.setAndroidManifestMinSdkVersion(minSdk);
                result.add(usageInfoForAttribute);
            }
        } else if (localName.equals(ATTR_GRAVITY) || localName.equals(ATTR_LAYOUT_GRAVITY)) {
            final String value = attributeToMirror.getValue();
            if (value != null && (value.contains(GRAVITY_VALUE_LEFT) || value.contains(GRAVITY_VALUE_RIGHT))) {
                final int startOffset = 0;
                final int endOffset = attributeToMirror.getTextLength();
                RtlRefactoringUsageInfo usageInfoForAttribute = new RtlRefactoringUsageInfo(attributeToMirror, startOffset, endOffset);
                usageInfoForAttribute.setType(LAYOUT_FILE_ATTRIBUTE);
                usageInfoForAttribute.setCreateV17(createV17);
                result.add(usageInfoForAttribute);
            }
        }
    }
    return result;
}
Also used : DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) XmlAttribute(com.intellij.psi.xml.XmlAttribute) ArrayList(java.util.ArrayList) UsageInfo(com.intellij.usageView.UsageInfo)

Example 97 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project android by JetBrains.

the class RtlSupportProcessor method performRefactoringForLayoutFile.

private void performRefactoringForLayoutFile(@NotNull final RtlRefactoringUsageInfo usageInfo) {
    final PsiElement element = usageInfo.getElement();
    assert element != null;
    final XmlAttribute attribute = (XmlAttribute) element;
    final int minSdk = usageInfo.getAndroidManifestMinSdkVersion();
    if (!usageInfo.isCreateV17()) {
        updateAttributeForElement(attribute, minSdk);
    } else {
        // We need first to create the v17 layout file, so first get our initial layout file
        final PsiFile psiFile = element.getContainingFile();
        final VirtualFile layoutFile = psiFile.getVirtualFile();
        assert layoutFile != null;
        final VirtualFile layoutDir = layoutFile.getParent();
        assert layoutDir != null;
        final VirtualFile layoutV17Dir = getLayoutV17(layoutDir, true);
        assert layoutV17Dir != null;
        final String layoutFileName = layoutFile.getName();
        // Create the v17 file if needed (should be done only once)
        if (layoutV17Dir.findChild(layoutFileName) == null) {
            ApplicationManager.getApplication().runWriteAction(new Runnable() {

                @Override
                public void run() {
                    try {
                        layoutFile.copy(this, layoutV17Dir, layoutFileName);
                    } catch (IOException e) {
                        LOG.error("Cannot copy layout file " + quote(layoutFileName) + " from " + quote(layoutDir.getName()) + " directory to " + quote(layoutV17Dir.getName()) + " directory");
                    }
                }
            });
        }
        final VirtualFile layoutV17File = layoutV17Dir.findChild(layoutFileName);
        assert layoutV17File != null;
        final XmlFile xmlV17File = (XmlFile) PsiManager.getInstance(myProject).findFile(layoutV17File);
        assert xmlV17File != null;
        LOG.info("Processing refactoring for attribute: " + attribute.getName() + " into file: " + layoutV17File.getPath());
        if (DomManager.getDomManager(myProject).getDomFileDescription((XmlFile) xmlV17File) instanceof LayoutDomFileDescription) {
            xmlV17File.accept(new XmlRecursiveElementVisitor() {

                @Override
                public void visitXmlTag(XmlTag tag) {
                    super.visitXmlTag(tag);
                    final XmlAttribute attribute = tag.getAttribute(((XmlAttribute) element).getName());
                    if (attribute == null) {
                        return;
                    }
                    updateAttributeForElement(attribute, minSdk);
                }
            });
        }
        layoutV17File.refresh(true, /* asynchronous */
        false);
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) LayoutDomFileDescription(org.jetbrains.android.dom.layout.LayoutDomFileDescription) XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlFile(com.intellij.psi.xml.XmlFile) IOException(java.io.IOException) XmlTag(com.intellij.psi.xml.XmlTag)

Example 98 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project android by JetBrains.

the class RtlSupportProcessor method addManifestRefactoring.

private void addManifestRefactoring(List<UsageInfo> list) {
    // For all non library modules in our project
    for (Module module : ModuleManager.getInstance(myProject).getModules()) {
        AndroidFacet facet = AndroidFacet.getInstance(module);
        if (facet == null || facet.isLibraryProject()) {
            continue;
        }
        for (VirtualFile manifestFile : IdeaSourceProvider.getManifestFiles(facet)) {
            XmlFile manifestPsiFile = (XmlFile) PsiManager.getInstance(myProject).findFile(manifestFile);
            try {
                if (manifestPsiFile == null) {
                    continue;
                }
                XmlTag root = manifestPsiFile.getRootTag();
                if (root == null) {
                    continue;
                }
                // First, deal with "supportsRtl" into the <application> tag
                XmlTag[] applicationNodes = root.findSubTags(NODE_APPLICATION);
                if (applicationNodes.length > 0) {
                    assert applicationNodes.length == 1;
                    XmlTag applicationTag = applicationNodes[0];
                    XmlAttribute supportsRtlAttribute = applicationTag.getAttribute(AndroidManifest.ATTRIBUTE_SUPPORTS_RTL, ANDROID_URI);
                    if (supportsRtlAttribute == null || VALUE_FALSE.equals(supportsRtlAttribute.getValue())) {
                        final int startOffset;
                        final int endOffset;
                        if (supportsRtlAttribute == null) {
                            XmlAttribute[] applicationTagAttributes = applicationTag.getAttributes();
                            XmlAttribute lastAttribute = applicationTagAttributes[applicationTagAttributes.length - 1];
                            PsiElement nextSibling = lastAttribute.getNextSibling();
                            assert nextSibling != null;
                            // Will position the caret just before the ">" for the application tag
                            startOffset = nextSibling.getStartOffsetInParent() + nextSibling.getTextLength();
                            endOffset = startOffset;
                        } else {
                            // Will position the caret at the beginning of the "supportsRtl" attribute
                            startOffset = supportsRtlAttribute.getStartOffsetInParent();
                            endOffset = startOffset + supportsRtlAttribute.getTextLength();
                        }
                        RtlRefactoringUsageInfo usageInfo = new RtlRefactoringUsageInfo(applicationTag, startOffset, endOffset);
                        usageInfo.setType(MANIFEST_SUPPORTS_RTL);
                        list.add(usageInfo);
                    }
                }
                // Second, deal with targetSdkVersion / minSdkVersion
                XmlTag[] usesSdkNodes = root.findSubTags(NODE_USES_SDK);
                if (usesSdkNodes.length > 0) {
                    assert usesSdkNodes.length == 1;
                    XmlTag usesSdkTag = usesSdkNodes[0];
                    XmlAttribute targetSdkAttribute = usesSdkTag.getAttribute(ATTRIBUTE_TARGET_SDK_VERSION, ANDROID_URI);
                    int targetSdk = (targetSdkAttribute != null) ? Integer.parseInt(targetSdkAttribute.getValue()) : 0;
                    // Will need to set existing targetSdkVersion to 17
                    if (targetSdk == 0 || targetSdk < RTL_TARGET_SDK_START) {
                        // Will position the caret just at the start of
                        final int startOffset = (targetSdkAttribute != null) ? targetSdkAttribute.getStartOffsetInParent() : usesSdkTag.getStartOffsetInParent();
                        final int endOffset = startOffset + ((targetSdkAttribute != null) ? targetSdkAttribute.getTextLength() : usesSdkTag.getTextLength());
                        RtlRefactoringUsageInfo usageInfo = new RtlRefactoringUsageInfo(usesSdkTag, startOffset, endOffset);
                        usageInfo.setType(MANIFEST_TARGET_SDK);
                        list.add(usageInfo);
                    }
                }
            } catch (Exception e) {
                LOG.error("Could not read Manifest data", e);
            }
        }
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlFile(com.intellij.psi.xml.XmlFile) Module(com.intellij.openapi.module.Module) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) IOException(java.io.IOException) XmlTag(com.intellij.psi.xml.XmlTag)

Example 99 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project android by JetBrains.

the class RtlSupportProcessor method performRefactoringForAndroidManifestApplicationTag.

private static void performRefactoringForAndroidManifestApplicationTag(@NotNull UsageInfo usageInfo) {
    PsiElement element = usageInfo.getElement();
    assert element != null;
    XmlTag applicationTag = (XmlTag) element;
    XmlAttribute supportsRtlAttribute = applicationTag.getAttribute(ATTRIBUTE_SUPPORTS_RTL, ANDROID_URI);
    if (supportsRtlAttribute != null) {
        supportsRtlAttribute.setValue(SdkConstants.VALUE_TRUE);
    } else {
        applicationTag.setAttribute(ATTRIBUTE_SUPPORTS_RTL, ANDROID_URI, SdkConstants.VALUE_TRUE);
    }
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlTag(com.intellij.psi.xml.XmlTag)

Example 100 with XmlAttribute

use of com.intellij.psi.xml.XmlAttribute in project android by JetBrains.

the class AddMissingAttributesFix method definesHeight.

public static boolean definesHeight(@NotNull XmlTag tag, @Nullable ResourceResolver resourceResolver) {
    XmlAttribute height = tag.getAttribute(ATTR_LAYOUT_HEIGHT, ANDROID_URI);
    boolean definesHeight = height != null;
    if (definesHeight) {
        String value = height.getValue();
        if (value == null || value.isEmpty()) {
            return false;
        }
        return value.equals(VALUE_WRAP_CONTENT) || value.equals(VALUE_FILL_PARENT) || value.equals(VALUE_MATCH_PARENT) || value.startsWith(PREFIX_RESOURCE_REF) || value.startsWith(PREFIX_THEME_REF) || Character.isDigit(value.charAt(0));
    } else if (resourceResolver != null) {
        String style = tag.getAttributeValue(ATTR_STYLE);
        if (style != null) {
            ResourceValue st = resourceResolver.findResValue(style, false);
            if (st instanceof StyleResourceValue) {
                StyleResourceValue styleValue = (StyleResourceValue) st;
                definesHeight = resourceResolver.findItemInStyle(styleValue, ATTR_LAYOUT_HEIGHT, true) != null;
            }
        }
    }
    return definesHeight;
}
Also used : StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue) XmlAttribute(com.intellij.psi.xml.XmlAttribute) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue)

Aggregations

XmlAttribute (com.intellij.psi.xml.XmlAttribute)220 XmlTag (com.intellij.psi.xml.XmlTag)116 PsiElement (com.intellij.psi.PsiElement)60 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)57 NotNull (org.jetbrains.annotations.NotNull)44 XmlFile (com.intellij.psi.xml.XmlFile)37 Nullable (org.jetbrains.annotations.Nullable)27 Project (com.intellij.openapi.project.Project)25 VirtualFile (com.intellij.openapi.vfs.VirtualFile)20 TextRange (com.intellij.openapi.util.TextRange)18 XmlAttributeDescriptor (com.intellij.xml.XmlAttributeDescriptor)18 ArrayList (java.util.ArrayList)18 PsiFile (com.intellij.psi.PsiFile)17 PsiReference (com.intellij.psi.PsiReference)17 IncorrectOperationException (com.intellij.util.IncorrectOperationException)10 DomElement (com.intellij.util.xml.DomElement)10 Result (com.intellij.openapi.application.Result)9 XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)9 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)8 XmlElement (com.intellij.psi.xml.XmlElement)6