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;
}
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);
}
}
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);
}
}
}
}
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);
}
}
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;
}
Aggregations