Search in sources :

Example 1 with ResourceValue

use of org.jetbrains.android.dom.resources.ResourceValue in project android by JetBrains.

the class AndroidResourceReference method handleElementRename.

@Override
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
    if (newElementName.startsWith(SdkConstants.NEW_ID_PREFIX)) {
        newElementName = AndroidResourceUtil.getResourceNameByReferenceText(newElementName);
    }
    ResourceValue value = myValue.getValue();
    assert value != null;
    final ResourceType resType = value.getType();
    if (resType != null && newElementName != null) {
        // todo: do not allow new value resource name to contain dot, because it is impossible to check if it file or value otherwise
        final String newResName;
        // Does renamed resource point to a file?
        ResourceFolderType folderType = AndroidResourceUtil.XML_FILE_RESOURCE_TYPES.get(resType);
        if (folderType != null && newElementName.contains(".")) {
            // If it does, we need to chop off its extension when inserting the new value.
            newResName = AndroidCommonUtils.getResourceName(resType.getName(), newElementName);
        } else {
            newResName = newElementName;
        }
        // Note: We're using value.getResourceType(), not resType.getName() here, because we want the "+" in the new name
        myValue.setValue(ResourceValue.referenceTo(value.getPrefix(), value.getNamespace(), value.getResourceType(), newResName));
    }
    return myValue.getXmlTag();
}
Also used : ResourceFolderType(com.android.resources.ResourceFolderType) ResourceValue(org.jetbrains.android.dom.resources.ResourceValue) ResourceType(com.android.resources.ResourceType)

Example 2 with ResourceValue

use of org.jetbrains.android.dom.resources.ResourceValue in project android by JetBrains.

the class ParentStyleConverter method getReferencesInStyleName.

@NotNull
private static PsiReference[] getReferencesInStyleName(@NotNull GenericDomValue<?> value, @NotNull AndroidFacet facet) {
    String s = value.getStringValue();
    if (s == null) {
        return PsiReference.EMPTY_ARRAY;
    }
    int start = 0;
    final int idx = s.indexOf('/');
    if (idx >= 0) {
        start = idx + 1;
        s = s.substring(start);
    }
    final String[] ids = s.split("\\.");
    if (ids.length < 2) {
        return PsiReference.EMPTY_ARRAY;
    }
    final List<PsiReference> result = new ArrayList<>(ids.length - 1);
    int offset = s.length();
    for (int i = ids.length - 1; i >= 0; i--) {
        final String styleName = s.substring(0, offset);
        if (i < ids.length - 1) {
            final ResourceValue val = ResourceValue.referenceTo((char) 0, null, ResourceType.STYLE.getName(), styleName);
            result.add(new ResourceNameConverter.MyParentStyleReference(value, new TextRange(1 + start, 1 + start + offset), val, facet));
        }
        if (ResourceNameConverter.hasExplicitParent(facet, styleName)) {
            break;
        }
        offset = offset - ids[i].length() - 1;
    }
    return result.toArray(new PsiReference[result.size()]);
}
Also used : ResourceNameConverter(org.jetbrains.android.dom.resources.ResourceNameConverter) ArrayList(java.util.ArrayList) ResourceValue(org.jetbrains.android.dom.resources.ResourceValue) PsiReference(com.intellij.psi.PsiReference) TextRange(com.intellij.openapi.util.TextRange) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with ResourceValue

use of org.jetbrains.android.dom.resources.ResourceValue in project android by JetBrains.

the class ResourceReferenceConverter method fromString.

@Override
public ResourceValue fromString(@Nullable @NonNls String s, ConvertContext context) {
    if (s == null)
        return null;
    if (DataBindingUtil.isBindingExpression(s))
        return ResourceValue.INVALID;
    ResourceValue parsed = ResourceValue.parse(s, true, myWithPrefix, true);
    final ResolvingConverter<String> additionalConverter = getAdditionalConverter(context);
    if (parsed == null || !parsed.isReference()) {
        if (additionalConverter != null) {
            String value = additionalConverter.fromString(s, context);
            if (value != null) {
                return ResourceValue.literal(value);
            } else if (!myAdditionalConverterSoft) {
                return null;
            }
        } else if (!myAllowLiterals) {
            return null;
        }
    }
    if (parsed != null) {
        final String resType = parsed.getResourceType();
        if (parsed.getPrefix() == '?') {
            if (!myAllowAttributeReferences) {
                return null;
            }
            if (resType == null) {
                parsed.setResourceType(ResourceType.ATTR.getName());
            } else if (!ResourceType.ATTR.getName().equals(resType)) {
                return null;
            }
        } else if (resType == null) {
            if (parsed.isReference()) {
                if (myWithExplicitResourceType && !NULL_RESOURCE.equals(s)) {
                    return null;
                }
                if (myResourceTypes.size() == 1) {
                    parsed.setResourceType(myResourceTypes.iterator().next().getName());
                }
            } else {
                Set<ResourceType> types = getResourceTypes(context);
                if (types.contains(ResourceType.BOOL) && types.size() < VALUE_RESOURCE_TYPES.size()) {
                    // flagging colors (#ff00ff) as unresolved etc.
                    if (!(VALUE_TRUE.equals(s) || VALUE_FALSE.equals(s))) {
                        return null;
                    }
                }
            }
        }
    }
    return parsed;
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) ResourceValue(org.jetbrains.android.dom.resources.ResourceValue)

Example 4 with ResourceValue

use of org.jetbrains.android.dom.resources.ResourceValue in project android by JetBrains.

the class AndroidInlineUtil method getStyleUsageData.

@Nullable
static StyleUsageData getStyleUsageData(@NotNull XmlTag tag) {
    final DomElement domElement = DomManager.getDomManager(tag.getProject()).getDomElement(tag);
    if (domElement instanceof LayoutViewElement) {
        final GenericAttributeValue<ResourceValue> styleAttribute = ((LayoutViewElement) domElement).getStyle();
        final AndroidResourceReferenceBase reference = AndroidDomUtil.getAndroidResourceReference(styleAttribute, true);
        if (reference != null) {
            return new ViewStyleUsageData(tag, styleAttribute, reference);
        }
    } else if (domElement instanceof Style) {
        final AndroidResourceReferenceBase reference = AndroidDomUtil.getAndroidResourceReference(((Style) domElement).getParentStyle(), true);
        if (reference != null) {
            return new ParentStyleUsageData((Style) domElement, reference);
        }
    }
    return null;
}
Also used : DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) AndroidResourceReferenceBase(org.jetbrains.android.dom.converters.AndroidResourceReferenceBase) ResourceValue(org.jetbrains.android.dom.resources.ResourceValue) Style(org.jetbrains.android.dom.resources.Style) Nullable(org.jetbrains.annotations.Nullable)

Example 5 with ResourceValue

use of org.jetbrains.android.dom.resources.ResourceValue in project android by JetBrains.

the class AndroidExtractStyleAction method doExtractStyle.

@Nullable
public static String doExtractStyle(@NotNull Module module, @NotNull final XmlTag viewTag, final boolean addStyleAttributeToTag, @Nullable MyTestConfig testConfig) {
    final PsiFile file = viewTag.getContainingFile();
    if (file == null) {
        return null;
    }
    final String dialogTitle = AndroidBundle.message("android.extract.style.title");
    final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STYLE);
    assert fileName != null;
    final List<String> dirNames = Collections.singletonList(ResourceFolderType.VALUES.getName());
    final List<XmlAttribute> extractableAttributes = getExtractableAttributes(viewTag);
    final Project project = module.getProject();
    if (extractableAttributes.size() == 0) {
        AndroidUtils.reportError(project, "The tag doesn't contain any attributes that can be extracted", dialogTitle);
        return null;
    }
    final LayoutViewElement viewElement = getLayoutViewElement(viewTag);
    assert viewElement != null;
    final ResourceValue parentStyleValue = viewElement.getStyle().getValue();
    final String parentStyle;
    boolean supportImplicitParent = false;
    if (parentStyleValue != null) {
        parentStyle = parentStyleValue.getResourceName();
        if (ResourceType.STYLE != parentStyleValue.getType() || parentStyle == null || parentStyle.length() == 0) {
            AndroidUtils.reportError(project, "Invalid parent style reference " + parentStyleValue.toString(), dialogTitle);
            return null;
        }
        supportImplicitParent = parentStyleValue.getNamespace() == null;
    } else {
        parentStyle = null;
    }
    final String styleName;
    final List<XmlAttribute> styledAttributes;
    final VirtualFile chosenDirectory;
    final boolean searchStyleApplications;
    if (testConfig == null) {
        final ExtractStyleDialog dialog = new ExtractStyleDialog(module, fileName, supportImplicitParent ? parentStyle : null, dirNames, extractableAttributes);
        dialog.setTitle(dialogTitle);
        if (!dialog.showAndGet()) {
            return null;
        }
        searchStyleApplications = dialog.isToSearchStyleApplications();
        chosenDirectory = dialog.getResourceDirectory();
        if (chosenDirectory == null) {
            AndroidUtils.reportError(project, AndroidBundle.message("check.resource.dir.error", module.getName()));
            return null;
        }
        styledAttributes = dialog.getStyledAttributes();
        styleName = dialog.getStyleName();
    } else {
        testConfig.validate(extractableAttributes);
        chosenDirectory = testConfig.getResourceDirectory();
        styleName = testConfig.getStyleName();
        final Set<String> attrsToExtract = new HashSet<String>(Arrays.asList(testConfig.getAttributesToExtract()));
        styledAttributes = new ArrayList<XmlAttribute>();
        for (XmlAttribute attribute : extractableAttributes) {
            if (attrsToExtract.contains(attribute.getName())) {
                styledAttributes.add(attribute);
            }
        }
        searchStyleApplications = false;
    }
    final boolean[] success = { false };
    final Ref<Style> createdStyleRef = Ref.create();
    final boolean finalSupportImplicitParent = supportImplicitParent;
    new WriteCommandAction(project, "Extract Android Style '" + styleName + "'", file) {

        @Override
        protected void run(@NotNull final Result result) throws Throwable {
            final List<XmlAttribute> attributesToDelete = new ArrayList<XmlAttribute>();
            if (!AndroidResourceUtil.createValueResource(project, chosenDirectory, styleName, null, ResourceType.STYLE, fileName, dirNames, new Processor<ResourceElement>() {

                @Override
                public boolean process(ResourceElement element) {
                    assert element instanceof Style;
                    final Style style = (Style) element;
                    createdStyleRef.set(style);
                    for (XmlAttribute attribute : styledAttributes) {
                        if (SdkConstants.NS_RESOURCES.equals(attribute.getNamespace())) {
                            final StyleItem item = style.addItem();
                            item.getName().setStringValue("android:" + attribute.getLocalName());
                            item.setStringValue(attribute.getValue());
                            attributesToDelete.add(attribute);
                        }
                    }
                    if (parentStyleValue != null && (!finalSupportImplicitParent || !styleName.startsWith(parentStyle + "."))) {
                        final String aPackage = parentStyleValue.getNamespace();
                        style.getParentStyle().setStringValue((aPackage != null ? aPackage + ":" : "") + parentStyle);
                    }
                    return true;
                }
            })) {
                return;
            }
            ApplicationManager.getApplication().runWriteAction(new Runnable() {

                @Override
                public void run() {
                    for (XmlAttribute attribute : attributesToDelete) {
                        attribute.delete();
                    }
                    if (addStyleAttributeToTag) {
                        final LayoutViewElement viewElement = getLayoutViewElement(viewTag);
                        assert viewElement != null;
                        viewElement.getStyle().setStringValue("@style/" + styleName);
                    }
                }
            });
            success[0] = true;
        }

        @Override
        protected UndoConfirmationPolicy getUndoConfirmationPolicy() {
            return UndoConfirmationPolicy.REQUEST_CONFIRMATION;
        }
    }.execute();
    if (!success[0]) {
        return null;
    }
    final Style createdStyle = createdStyleRef.get();
    final XmlTag createdStyleTag = createdStyle != null ? createdStyle.getXmlTag() : null;
    if (createdStyleTag != null) {
        final AndroidFindStyleApplicationsAction.MyStyleData createdStyleData = AndroidFindStyleApplicationsAction.getStyleData(createdStyleTag);
        if (createdStyleData != null && searchStyleApplications) {
            ApplicationManager.getApplication().invokeLater(new Runnable() {

                @Override
                public void run() {
                    AndroidFindStyleApplicationsAction.doRefactoringForTag(createdStyleTag, createdStyleData, file, null);
                }
            });
        }
    }
    return styleName;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) XmlAttribute(com.intellij.psi.xml.XmlAttribute) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) StyleItem(org.jetbrains.android.dom.resources.StyleItem) Result(com.intellij.openapi.application.Result) UndoConfirmationPolicy(com.intellij.openapi.command.UndoConfirmationPolicy) ResourceValue(org.jetbrains.android.dom.resources.ResourceValue) Style(org.jetbrains.android.dom.resources.Style) PsiFile(com.intellij.psi.PsiFile) HashSet(com.intellij.util.containers.HashSet) ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) Project(com.intellij.openapi.project.Project) XmlTag(com.intellij.psi.xml.XmlTag) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

ResourceValue (org.jetbrains.android.dom.resources.ResourceValue)10 Nullable (org.jetbrains.annotations.Nullable)4 ResourceType (com.android.resources.ResourceType)3 PsiReference (com.intellij.psi.PsiReference)3 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)3 NotNull (org.jetbrains.annotations.NotNull)3 ResourceFolderType (com.android.resources.ResourceFolderType)2 Project (com.intellij.openapi.project.Project)2 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)2 DomElement (com.intellij.util.xml.DomElement)2 AndroidResourceType (org.jetbrains.android.dom.AndroidResourceType)2 AndroidResourceReferenceBase (org.jetbrains.android.dom.converters.AndroidResourceReferenceBase)2 LayoutViewElement (org.jetbrains.android.dom.layout.LayoutViewElement)2 Style (org.jetbrains.android.dom.resources.Style)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)1 Result (com.intellij.openapi.application.Result)1 UndoConfirmationPolicy (com.intellij.openapi.command.UndoConfirmationPolicy)1 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)1 Module (com.intellij.openapi.module.Module)1