Search in sources :

Example 6 with Style

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

the class AndroidResourceRenameResourceProcessor method prepareValueResourceRenaming.

private static void prepareValueResourceRenaming(PsiElement element, String newName, Map<PsiElement, String> allRenames, final AndroidFacet facet) {
    ResourceManager manager = facet.getLocalResourceManager();
    XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
    assert tag != null;
    String type = manager.getValueResourceType(tag);
    assert type != null;
    Project project = tag.getProject();
    DomElement domElement = DomManager.getDomManager(project).getDomElement(tag);
    assert domElement instanceof ResourceElement;
    String name = ((ResourceElement) domElement).getName().getValue();
    assert name != null;
    List<ResourceElement> resources = manager.findValueResources(type, name);
    for (ResourceElement resource : resources) {
        XmlElement xmlElement = resource.getName().getXmlAttributeValue();
        if (!element.getManager().areElementsEquivalent(element, xmlElement)) {
            allRenames.put(xmlElement, newName);
        }
    }
    if (getResourceType(element) == ResourceType.STYLE) {
        // For styles, try also to find child styles defined by name (i.e. "ParentName.StyleName") and add them
        // to the rename list. This will allow the rename processor to also handle the references to those. For example,
        // If you rename "MyTheme" and your manifest theme is "MyTheme.NoActionBar", this will make sure that
        // the reference from the manifest is also updated by adding "MyTheme.NoActionBar" to the rename list.
        // We iterate the styles in order to cascade any changes to children down the hierarchy.
        // List of styles that will be renamed.
        HashSet<String> renamedStyles = Sets.newHashSet();
        renamedStyles.add(name);
        final String stylePrefix = name + ".";
        Collection<String> renameCandidates;
        ResourceType resourceType = ResourceType.getEnum(type);
        if (resourceType == null) {
            renameCandidates = Collections.emptyList();
        } else {
            renameCandidates = Collections2.filter(manager.getResourceNames(resourceType), new Predicate<String>() {

                @Override
                public boolean apply(String input) {
                    return input.startsWith(stylePrefix);
                }
            });
        }
        for (String resourceName : ORDER_BY_LENGTH.sortedCopy(renameCandidates)) {
            // resourceName.lastIndexOf will never return -1 because we've filtered all names that
            // do not contain stylePrefix
            String parentName = resourceName.substring(0, resourceName.lastIndexOf('.'));
            if (!renamedStyles.contains(parentName)) {
                // This resource's parent wasn't affected by the rename
                continue;
            }
            for (ResourceElement resource : manager.findValueResources(type, resourceName)) {
                if (!(resource instanceof Style) || ((Style) resource).getParentStyle().getXmlAttributeValue() != null) {
                    // This element is not a style or does have an explicit parent so we do not rename it.
                    continue;
                }
                XmlAttributeValue xmlElement = resource.getName().getXmlAttributeValue();
                if (xmlElement != null) {
                    String newStyleName = newName + StringUtil.trimStart(resourceName, name);
                    allRenames.put(new ValueResourceElementWrapper(xmlElement), newStyleName);
                    renamedStyles.add(resourceName);
                }
            }
        }
    }
    PsiField[] resFields = AndroidResourceUtil.findResourceFieldsForValueResource(tag, false);
    for (PsiField resField : resFields) {
        String escaped = AndroidResourceUtil.getFieldNameByResourceName(newName);
        allRenames.put(resField, escaped);
    }
    // Also rename the dependent fields, e.g. if you rename <declare-styleable name="Foo">,
    // we have to rename not just R.styleable.Foo but the also R.styleable.Foo_* attributes
    PsiField[] styleableFields = AndroidResourceUtil.findStyleableAttributeFields(tag, false);
    if (styleableFields.length > 0) {
        String tagName = tag.getName();
        boolean isDeclareStyleable = tagName.equals(TAG_DECLARE_STYLEABLE);
        boolean isAttr = !isDeclareStyleable && tagName.equals(TAG_ATTR) && tag.getParentTag() != null;
        assert isDeclareStyleable || isAttr;
        String style = isAttr ? tag.getParentTag().getAttributeValue(ATTR_NAME) : null;
        for (PsiField resField : styleableFields) {
            String fieldName = resField.getName();
            String newAttributeName;
            if (isDeclareStyleable && fieldName.startsWith(name)) {
                newAttributeName = newName + fieldName.substring(name.length());
            } else if (isAttr && style != null) {
                newAttributeName = style + '_' + newName;
            } else {
                newAttributeName = name;
            }
            String escaped = AndroidResourceUtil.getFieldNameByResourceName(newAttributeName);
            allRenames.put(resField, escaped);
        }
    }
}
Also used : ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) ResourceType(com.android.resources.ResourceType) ResourceManager(org.jetbrains.android.resourceManagers.ResourceManager) LocalResourceManager(org.jetbrains.android.resourceManagers.LocalResourceManager) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) Predicate(com.google.common.base.Predicate) Project(com.intellij.openapi.project.Project) DomElement(com.intellij.util.xml.DomElement) XmlElement(com.intellij.psi.xml.XmlElement) Style(org.jetbrains.android.dom.resources.Style) XmlTag(com.intellij.psi.xml.XmlTag) LazyValueResourceElementWrapper(org.jetbrains.android.dom.wrappers.LazyValueResourceElementWrapper) ValueResourceElementWrapper(org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper)

Example 7 with Style

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

the class AndroidFindStyleApplicationsAction method getStyleData.

@Nullable
static MyStyleData getStyleData(@NotNull XmlTag tag) {
    final DomElement element = DomManager.getDomManager(tag.getProject()).getDomElement(tag);
    if (!(element instanceof Style)) {
        return null;
    }
    final Style style = (Style) element;
    final GenericAttributeValue<String> styleNameDomAttr = style.getName();
    final String styleName = styleNameDomAttr.getStringValue();
    final XmlAttributeValue styleNameAttrValue = styleNameDomAttr.getXmlAttributeValue();
    if (styleName == null || styleName.length() == 0 || styleNameAttrValue == null) {
        return null;
    }
    final AndroidFacet facet = AndroidFacet.getInstance(tag);
    if (facet == null) {
        return null;
    }
    return new MyStyleData(style, styleName, facet, styleNameAttrValue);
}
Also used : DomElement(com.intellij.util.xml.DomElement) Style(org.jetbrains.android.dom.resources.Style) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) Nullable(org.jetbrains.annotations.Nullable)

Example 8 with Style

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

the class AndroidInlineUtil method doInlineStyleDeclaration.

static void doInlineStyleDeclaration(@NotNull Project project, @NotNull MyStyleData data, @Nullable final StyleUsageData usageData, @NotNull ErrorReporter errorReporter, @Nullable AndroidInlineTestConfig testConfig) {
    final Style style = data.myStyleElement;
    final Map<AndroidAttributeInfo, String> attributeValues = AndroidRefactoringUtil.computeAttributeMap(style, errorReporter, AndroidBundle.message("android.inline.style.title"));
    if (attributeValues == null) {
        return;
    }
    final StyleRefData parentStyleRef = AndroidRefactoringUtil.getParentStyle(style);
    boolean inlineThisOnly;
    if (testConfig != null) {
        inlineThisOnly = testConfig.isInlineThisOnly();
    } else {
        final boolean invokedOnReference = usageData != null;
        final AndroidInlineStyleDialog dialog = new AndroidInlineStyleDialog(project, data.myReferredElement, style.getXmlTag(), data.myStyleName, attributeValues, parentStyleRef, invokedOnReference, invokedOnReference);
        if (!dialog.showAndGet()) {
            return;
        }
        inlineThisOnly = dialog.isInlineThisOnly();
    }
    if (inlineThisOnly) {
        assert usageData != null;
        final PsiFile file = usageData.getFile();
        if (file == null) {
            return;
        }
        new WriteCommandAction(project, AndroidBundle.message("android.inline.style.command.name", data.myStyleName), file) {

            @Override
            protected void run(@NotNull final Result result) throws Throwable {
                usageData.inline(attributeValues, parentStyleRef);
            }

            @Override
            protected UndoConfirmationPolicy getUndoConfirmationPolicy() {
                return UndoConfirmationPolicy.REQUEST_CONFIRMATION;
            }
        }.execute();
    } else if (testConfig != null) {
        final AndroidInlineAllStyleUsagesProcessor processor = new AndroidInlineAllStyleUsagesProcessor(project, data.myReferredElement, style.getXmlTag(), data.myStyleName, attributeValues, parentStyleRef, testConfig);
        processor.setPreviewUsages(false);
        processor.run();
    }
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) Result(com.intellij.openapi.application.Result) UndoConfirmationPolicy(com.intellij.openapi.command.UndoConfirmationPolicy) Style(org.jetbrains.android.dom.resources.Style) PsiFile(com.intellij.psi.PsiFile)

Example 9 with Style

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

the class AndroidInlineUtil method getInlinableStyleData.

@Nullable
static MyStyleData getInlinableStyleData(@NotNull XmlTag tag) {
    final DomElement domElement = DomManager.getDomManager(tag.getProject()).getDomElement(tag);
    if (!(domElement instanceof Style)) {
        return null;
    }
    final Style style = (Style) domElement;
    final XmlAttributeValue nameAttrValue = style.getName().getXmlAttributeValue();
    if (nameAttrValue == null) {
        return null;
    }
    final String styleName = style.getName().getStringValue();
    if (styleName == null || styleName.length() == 0) {
        return null;
    }
    return new MyStyleData(styleName, style, nameAttrValue);
}
Also used : DomElement(com.intellij.util.xml.DomElement) Style(org.jetbrains.android.dom.resources.Style) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) Nullable(org.jetbrains.annotations.Nullable)

Example 10 with Style

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

the class ThemeAttributeResolverTest method createNewStyle.

public boolean createNewStyle(@NotNull final VirtualFile resourceDir, @NotNull final String newStyleName, @NotNull final String parentStyleName, @Nullable final String colorPrimaryValue, @NotNull final List<String> folders) {
    return new WriteCommandAction<Boolean>(getProject(), "Create new style " + newStyleName) {

        @Override
        protected void run(@NotNull Result<Boolean> result) {
            result.setResult(AndroidResourceUtil.createValueResource(getProject(), resourceDir, newStyleName, null, ResourceType.STYLE, "styles.xml", folders, new Processor<ResourceElement>() {

                @Override
                public boolean process(ResourceElement element) {
                    assert element instanceof Style;
                    final Style style = (Style) element;
                    style.getParentStyle().setStringValue(parentStyleName);
                    if (colorPrimaryValue != null) {
                        StyleItem styleItem = style.addItem();
                        styleItem.getName().setStringValue("colorPrimary");
                        styleItem.setStringValue(colorPrimaryValue);
                    }
                    return true;
                }
            }));
        }
    }.execute().getResultObject();
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) Processor(com.intellij.util.Processor) EditedStyleItem(com.android.tools.idea.editors.theme.datamodels.EditedStyleItem) StyleItem(org.jetbrains.android.dom.resources.StyleItem) Style(org.jetbrains.android.dom.resources.Style) ConfiguredThemeEditorStyle(com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result)

Aggregations

Style (org.jetbrains.android.dom.resources.Style)10 DomElement (com.intellij.util.xml.DomElement)5 Result (com.intellij.openapi.application.Result)4 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)4 ResourceElement (org.jetbrains.android.dom.resources.ResourceElement)4 Nullable (org.jetbrains.annotations.Nullable)4 PsiFile (com.intellij.psi.PsiFile)3 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)3 XmlTag (com.intellij.psi.xml.XmlTag)3 ConfiguredThemeEditorStyle (com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle)2 UndoConfirmationPolicy (com.intellij.openapi.command.UndoConfirmationPolicy)2 Project (com.intellij.openapi.project.Project)2 PsiElement (com.intellij.psi.PsiElement)2 Processor (com.intellij.util.Processor)2 AndroidResourceReferenceBase (org.jetbrains.android.dom.converters.AndroidResourceReferenceBase)2 LayoutViewElement (org.jetbrains.android.dom.layout.LayoutViewElement)2 ResourceValue (org.jetbrains.android.dom.resources.ResourceValue)2 StyleItem (org.jetbrains.android.dom.resources.StyleItem)2 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)2 ProjectBasedErrorReporter (org.jetbrains.android.util.ProjectBasedErrorReporter)2