Search in sources :

Example 11 with ResourceItem

use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.

the class ThemeEditorUtils method getModuleThemeQualifiedNamesList.

/**
   * Returns the list of the qualified names of all the user-defined themes available from a given module
   */
@NotNull
public static ImmutableList<String> getModuleThemeQualifiedNamesList(@NotNull Module module) {
    AndroidFacet facet = AndroidFacet.getInstance(module);
    assert facet != null;
    ConfigurationManager manager = facet.getConfigurationManager();
    // We create a new ResourceResolverCache instead of using cache from myConfiguration to optimize memory instead of time/speed,
    // because we are about to create a lot of instances of ResourceResolver here that won't be used outside of this method
    final ResourceResolverCache resolverCache = new ResourceResolverCache(manager);
    final IAndroidTarget target = manager.getTarget();
    final Map<ResourceValue, Boolean> cache = new HashMap<ResourceValue, Boolean>();
    final Set<String> themeNamesSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
    ResourceFolderVisitor visitor = new ResourceFolderVisitor() {

        @Override
        public void visitResourceFolder(@NotNull LocalResourceRepository resources, String moduleName, @NotNull String variantName, boolean isSelected) {
            if (!isSelected) {
                return;
            }
            for (String simpleThemeName : resources.getItemsOfType(ResourceType.STYLE)) {
                String themeStyleResourceUrl = SdkConstants.STYLE_RESOURCE_PREFIX + simpleThemeName;
                List<ResourceItem> themeItems = resources.getResourceItem(ResourceType.STYLE, simpleThemeName);
                assert themeItems != null;
                for (ResourceItem themeItem : themeItems) {
                    ResourceResolver resolver = resolverCache.getResourceResolver(target, themeStyleResourceUrl, themeItem.getConfiguration());
                    ResourceValue themeItemResourceValue = themeItem.getResourceValue(false);
                    assert themeItemResourceValue != null;
                    if (resolver.isTheme(themeItemResourceValue, cache)) {
                        themeNamesSet.add(simpleThemeName);
                        break;
                    }
                }
            }
        }
    };
    acceptResourceResolverVisitor(facet, visitor);
    return ImmutableList.copyOf(themeNamesSet);
}
Also used : IAndroidTarget(com.android.sdklib.IAndroidTarget) NotNull(org.jetbrains.annotations.NotNull) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) ResourceResolverCache(com.android.tools.idea.configurations.ResourceResolverCache) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) ResourceResolver(com.android.ide.common.resources.ResourceResolver) ResourceItem(com.android.ide.common.res2.ResourceItem) ConfigurationManager(com.android.tools.idea.configurations.ConfigurationManager) NotNull(org.jetbrains.annotations.NotNull)

Example 12 with ResourceItem

use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.

the class LintIdeViewTypeDetector method getViewTags.

@Nullable
@Override
protected Collection<String> getViewTags(@NonNull Context context, @NonNull ResourceItem item) {
    AbstractResourceRepository projectResources = context.getClient().getProjectResources(context.getMainProject(), true);
    assert projectResources instanceof LocalResourceRepository : projectResources;
    LocalResourceRepository repository = (LocalResourceRepository) projectResources;
    String viewTag = repository.getViewTag(item);
    if (viewTag != null) {
        return Collections.singleton(viewTag);
    }
    return super.getViewTags(context, item);
}
Also used : AbstractResourceRepository(com.android.ide.common.res2.AbstractResourceRepository) LocalResourceRepository(com.android.tools.idea.res.LocalResourceRepository) Nullable(com.android.annotations.Nullable)

Example 13 with ResourceItem

use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.

the class MigrateDrawableToMipmapFix method apply.

@Override
public void apply(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull AndroidQuickfixContexts.Context context) {
    Project project = startElement.getProject();
    AndroidFacet facet = AndroidFacet.getInstance(startElement);
    if (facet == null) {
        return;
    }
    final List<PsiFile> bitmaps = Lists.newArrayList();
    final Set<PsiElement> references = Sets.newHashSet();
    GlobalSearchScope useScope = GlobalSearchScope.projectScope(project);
    ProjectResourceRepository projectResources = facet.getProjectResources(true);
    List<ResourceItem> resourceItems = projectResources.getResourceItem(myUrl.type, myUrl.name);
    if (resourceItems != null) {
        for (ResourceItem item : resourceItems) {
            PsiFile file = LocalResourceRepository.getItemPsiFile(project, item);
            if (file == null) {
                continue;
            }
            bitmaps.add(file);
            Iterable<PsiReference> allReferences = SearchUtils.findAllReferences(file, useScope);
            for (PsiReference next : allReferences) {
                PsiElement element = next.getElement();
                if (element != null) {
                    references.add(element);
                }
            }
        }
    }
    PsiField[] resourceFields = AndroidResourceUtil.findResourceFields(facet, ResourceType.DRAWABLE.getName(), myUrl.name, true);
    if (resourceFields.length == 1) {
        Iterable<PsiReference> allReferences = SearchUtils.findAllReferences(resourceFields[0], useScope);
        for (PsiReference next : allReferences) {
            PsiElement element = next.getElement();
            if (element != null) {
                references.add(element);
            }
        }
    }
    Set<PsiFile> applicableFiles = Sets.newHashSet();
    applicableFiles.addAll(bitmaps);
    for (PsiElement element : references) {
        PsiFile containingFile = element.getContainingFile();
        if (containingFile != null) {
            applicableFiles.add(containingFile);
        }
    }
    WriteCommandAction<Void> action = new WriteCommandAction<Void>(project, "Migrate Drawable to Bitmap", applicableFiles.toArray(new PsiFile[applicableFiles.size()])) {

        @Override
        protected void run(@NotNull Result<Void> result) throws Throwable {
            // Move each drawable bitmap from drawable-my-qualifiers to bitmap-my-qualifiers
            for (PsiFile bitmap : bitmaps) {
                VirtualFile file = bitmap.getVirtualFile();
                if (file == null) {
                    continue;
                }
                VirtualFile parent = file.getParent();
                if (parent == null) {
                    // shouldn't happen for bitmaps found in the resource repository
                    continue;
                }
                if (file.getFileType() == StdFileTypes.XML && parent.getName().startsWith(FD_RES_VALUES)) {
                    // Resource alias rather than an actual drawable XML file: update the type reference instead
                    XmlFile xmlFile = (XmlFile) bitmap;
                    XmlTag root = xmlFile.getRootTag();
                    if (root != null) {
                        for (XmlTag item : root.getSubTags()) {
                            String name = item.getAttributeValue(ATTR_NAME);
                            if (myUrl.name.equals(name)) {
                                if (ResourceType.DRAWABLE.getName().equals(item.getName())) {
                                    item.setName(ResourceType.MIPMAP.getName());
                                } else if (ResourceType.DRAWABLE.getName().equals(item.getAttributeValue(ATTR_TYPE))) {
                                    item.setAttribute(ATTR_TYPE, ResourceType.MIPMAP.getName());
                                }
                            }
                        }
                    }
                    // Don't move the file
                    continue;
                }
                VirtualFile res = parent.getParent();
                if (res == null) {
                    // shouldn't happen for bitmaps found in the resource repository
                    continue;
                }
                FolderConfiguration configuration = FolderConfiguration.getConfigForFolder(parent.getName());
                if (configuration == null) {
                    continue;
                }
                String targetFolderName = configuration.getFolderName(ResourceFolderType.MIPMAP);
                VirtualFile targetFolder = res.findChild(targetFolderName);
                if (targetFolder == null) {
                    targetFolder = res.createChildDirectory(this, targetFolderName);
                }
                file.move(this, targetFolder);
            }
            // Update references
            for (PsiElement reference : references) {
                if (reference instanceof XmlAttributeValue) {
                    // Convert @drawable/foo references to @mipmap/foo
                    XmlAttributeValue value = (XmlAttributeValue) reference;
                    XmlAttribute attribute = (XmlAttribute) value.getParent();
                    attribute.setValue(ResourceUrl.create(ResourceType.MIPMAP, myUrl.name, false, false).toString());
                } else if (reference instanceof PsiReferenceExpression) {
                    // Convert R.drawable.foo references to R.mipmap.foo
                    PsiReferenceExpression inner = (PsiReferenceExpression) reference;
                    PsiExpression qualifier = inner.getQualifierExpression();
                    if (qualifier instanceof PsiReferenceExpression) {
                        PsiReferenceExpression outer = (PsiReferenceExpression) qualifier;
                        if (outer.getReferenceNameElement() instanceof PsiIdentifier) {
                            PsiIdentifier identifier = (PsiIdentifier) outer.getReferenceNameElement();
                            if (ResourceType.DRAWABLE.getName().equals(identifier.getText())) {
                                Project project = reference.getProject();
                                final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
                                PsiIdentifier newIdentifier = elementFactory.createIdentifier(ResourceType.MIPMAP.getName());
                                identifier.replace(newIdentifier);
                            }
                        }
                    }
                }
            }
        }
    };
    action.execute();
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlAttribute(com.intellij.psi.xml.XmlAttribute) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) ProjectResourceRepository(com.android.tools.idea.res.ProjectResourceRepository) XmlFile(com.intellij.psi.xml.XmlFile) FolderConfiguration(com.android.ide.common.resources.configuration.FolderConfiguration) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) Project(com.intellij.openapi.project.Project) ResourceItem(com.android.ide.common.res2.ResourceItem) XmlTag(com.intellij.psi.xml.XmlTag)

Example 14 with ResourceItem

use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.

the class ConfiguredThemeEditorStyle method getConfiguredValues.

/**
   * Returns all the style attributes and its values. For each attribute, multiple {@link ConfiguredElement} can be returned
   * representing the multiple values in different configurations for each item.
   * TODO: needs to be deleted, as we don't use this method except tests
   */
@NotNull
public ImmutableCollection<ConfiguredElement<ItemResourceValue>> getConfiguredValues() {
    // Get a list of all the items indexed by the item name. Each item contains a list of the
    // possible values in this theme in different configurations.
    //
    // If item1 has multiple values in different configurations, there will be an
    // item1 = {folderConfiguration1 -> value1, folderConfiguration2 -> value2}
    final ImmutableList.Builder<ConfiguredElement<ItemResourceValue>> itemResourceValues = ImmutableList.builder();
    if (isFramework()) {
        assert myConfiguration.getFrameworkResources() != null;
        com.android.ide.common.resources.ResourceItem styleItem = myConfiguration.getFrameworkResources().getResourceItem(ResourceType.STYLE, myStyleResourceValue.getName());
        // Go over all the files containing the resource.
        for (ResourceFile file : styleItem.getSourceFileList()) {
            ResourceValue styleResourceValue = file.getValue(ResourceType.STYLE, styleItem.getName());
            FolderConfiguration folderConfiguration = file.getConfiguration();
            if (styleResourceValue instanceof StyleResourceValue) {
                for (final ItemResourceValue value : ((StyleResourceValue) styleResourceValue).getValues()) {
                    itemResourceValues.add(ConfiguredElement.create(folderConfiguration, value));
                }
            }
        }
    } else {
        for (ResourceItem styleDefinition : getStyleResourceItems()) {
            ResourceValue styleResourceValue = styleDefinition.getResourceValue(isFramework());
            FolderConfiguration folderConfiguration = styleDefinition.getConfiguration();
            if (styleResourceValue instanceof StyleResourceValue) {
                for (final ItemResourceValue value : ((StyleResourceValue) styleResourceValue).getValues()) {
                    // We use the qualified name since apps and libraries can use the same attribute name twice with and without "android:"
                    itemResourceValues.add(ConfiguredElement.create(folderConfiguration, value));
                }
            }
        }
    }
    return itemResourceValues.build();
}
Also used : FolderConfiguration(com.android.ide.common.resources.configuration.FolderConfiguration) ResourceFile(com.android.ide.common.resources.ResourceFile) StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue) ResourceItem(com.android.ide.common.res2.ResourceItem) NotNull(org.jetbrains.annotations.NotNull)

Example 15 with ResourceItem

use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.

the class ConfiguredThemeEditorStyle method getParentNames.

/**
   * Returns the names of all the parents of this style. Parents might differ depending on the folder configuration, this returns all the
   * variants for this style.
   */
public Collection<ConfiguredElement<String>> getParentNames() {
    if (isFramework()) {
        // Framework themes do not have multiple parents so we just get the only one.
        ConfiguredThemeEditorStyle parent = getParent();
        if (parent != null) {
            return ImmutableList.of(ConfiguredElement.create(new FolderConfiguration(), parent.getQualifiedName()));
        }
        // The theme has no parent (probably the main "Theme" style)
        return Collections.emptyList();
    }
    ImmutableList.Builder<ConfiguredElement<String>> parents = ImmutableList.builder();
    for (final ResourceItem styleItem : getStyleResourceItems()) {
        StyleResourceValue style = (StyleResourceValue) styleItem.getResourceValue(false);
        assert style != null;
        String parentName = ResolutionUtils.getParentQualifiedName(style);
        if (parentName != null) {
            parents.add(ConfiguredElement.create(styleItem.getConfiguration(), parentName));
        }
    }
    return parents.build();
}
Also used : StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue) FolderConfiguration(com.android.ide.common.resources.configuration.FolderConfiguration) ResourceItem(com.android.ide.common.res2.ResourceItem)

Aggregations

ResourceItem (com.android.ide.common.res2.ResourceItem)83 VirtualFile (com.intellij.openapi.vfs.VirtualFile)44 PsiFile (com.intellij.psi.PsiFile)35 Document (com.intellij.openapi.editor.Document)26 PsiDocumentManager (com.intellij.psi.PsiDocumentManager)26 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)11 FolderConfiguration (com.android.ide.common.resources.configuration.FolderConfiguration)11 XmlTag (com.intellij.psi.xml.XmlTag)11 NotNull (org.jetbrains.annotations.NotNull)11 IOException (java.io.IOException)10 AbstractResourceRepository (com.android.ide.common.res2.AbstractResourceRepository)8 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)8 StyleResourceValue (com.android.ide.common.rendering.api.StyleResourceValue)7 ResourceFile (com.android.ide.common.res2.ResourceFile)7 ResourceType (com.android.resources.ResourceType)7 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)7 Nullable (org.jetbrains.annotations.Nullable)7 LocalResourceRepository (com.android.tools.idea.res.LocalResourceRepository)6 Project (com.intellij.openapi.project.Project)6 File (java.io.File)6