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