use of com.android.resources.ResourceType in project android by JetBrains.
the class ResourcesCompletionProvider method getCompletions.
@NotNull
@Override
public List<String> getCompletions(@NotNull EditedStyleItem value) {
ConfiguredThemeEditorStyle selectedStyle = value.getSourceStyle();
AttributeDefinition attrDefinition = ResolutionUtils.getAttributeDefinition(selectedStyle.getConfiguration(), value.getSelectedValue());
if (attrDefinition == null) {
return Collections.emptyList();
}
Set<ResourceType> acceptedTypes = EnumSet.noneOf(ResourceType.class);
if (ThemeEditorUtils.acceptsFormat(attrDefinition, AttributeFormat.Color)) {
acceptedTypes.add(ResourceType.COLOR);
}
if (ThemeEditorUtils.acceptsFormat(attrDefinition, AttributeFormat.Dimension)) {
acceptedTypes.add(ResourceType.DIMEN);
}
if (ThemeEditorUtils.acceptsFormat(attrDefinition, AttributeFormat.String)) {
acceptedTypes.add(ResourceType.STRING);
}
if (ThemeEditorUtils.acceptsFormat(attrDefinition, AttributeFormat.Reference)) {
acceptedTypes.addAll(ImmutableList.of(ResourceType.LAYOUT, ResourceType.COLOR, ResourceType.DRAWABLE, ResourceType.MIPMAP, ResourceType.STYLE, ResourceType.ATTR, ResourceType.STRING, ResourceType.DIMEN, ResourceType.TRANSITION));
}
ArrayList<String> resourceNamesList = new ArrayList<String>(myAllResources.size());
for (ResourceValue resource : myAllResources) {
if (!acceptedTypes.contains(resource.getResourceType())) {
continue;
}
final String name = String.format("%1$s%2$s%3$s/%4$s", ResourceType.ATTR == resource.getResourceType() ? SdkConstants.PREFIX_THEME_REF : SdkConstants.PREFIX_RESOURCE_REF, resource.isFramework() ? SdkConstants.ANDROID_NS_NAME_PREFIX : "", resource.getResourceType().getName(), resource.getName());
resourceNamesList.add(name);
}
return resourceNamesList;
}
use of com.android.resources.ResourceType in project android by JetBrains.
the class AndroidResourceRenameResourceProcessor method findExistingNameConflicts.
@Override
public void findExistingNameConflicts(final PsiElement originalElement, String newName, final MultiMap<PsiElement, String> conflicts) {
ResourceType type = getResourceType(originalElement);
if (type == null) {
return;
}
PsiElement element = LazyValueResourceElementWrapper.computeLazyElement(originalElement);
if (element == null) {
return;
}
AndroidFacet facet = AndroidFacet.getInstance(element);
if (facet == null) {
return;
}
// First check to see if the new name is conflicting with an existing resource
if (element instanceof PsiFile) {
// The name of a file resource is the name of the file without the extension.
// So when dealing with a file, we must first remove the extension in the name
// before checking if it is already used.
newName = AndroidCommonUtils.getResourceName(type.getName(), newName);
}
AppResourceRepository appResources = AppResourceRepository.getAppResources(facet, true);
if (appResources.hasResourceItem(type, newName)) {
boolean foundElements = false;
PsiField[] resourceFields = AndroidResourceUtil.findResourceFields(facet, type.getName(), newName, true);
String message = String.format("Resource @%1$s/%2$s already exists", type, newName);
if (resourceFields.length > 0) {
// Use find usages to find the actual declaration location such that they can be shown in the conflicts view
AndroidFindUsagesHandlerFactory factory = new AndroidFindUsagesHandlerFactory();
if (factory.canFindUsages(originalElement)) {
FindUsagesHandler handler = factory.createFindUsagesHandler(resourceFields[0], false);
if (handler != null) {
PsiElement[] elements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements());
for (PsiElement e : elements) {
if (e instanceof LightElement) {
// AndroidLightField does not work in the conflicts view; UsageInfo throws NPE
continue;
}
conflicts.putValue(e, message);
foundElements = true;
}
}
}
}
if (!foundElements) {
conflicts.putValue(originalElement, message);
}
}
// Next see if the renamed resource is also defined externally, in which case we should ask the
// user if they really want to continue. Despite the name of this method ("findExistingNameConflicts")
// and the dialog used to show the message (ConflictsDialog), this isn't conflict specific; the
// dialog title simply says "Problems Detected" and the label for the text view is "The following
// problems were found". We need to use this because it's the only facility in the rename processor
// which lets us ask the user whether to continue and to have the answer either bail out of the operation
// or to resume.
// See if this is a locally defined resource (you can't rename fields from libraries such as appcompat)
// e.g. ?attr/listPreferredItemHeightSmall
String name = getResourceName(originalElement);
if (name != null) {
Project project = facet.getModule().getProject();
List<ResourceItem> all = appResources.getResourceItem(type, name);
if (all == null) {
all = Collections.emptyList();
}
List<ResourceItem> local = ProjectResourceRepository.getProjectResources(facet, true).getResourceItem(type, name);
if (local == null) {
local = Collections.emptyList();
}
HtmlBuilder builder = null;
if (local.size() == 0 && all.size() > 0) {
builder = new HtmlBuilder(new StringBuilder(300));
builder.add("Resource is also only defined in external libraries and cannot be renamed.");
} else if (local.size() < all.size()) {
// This item is also defined in one of the libraries, not just locally: we can't rename it. Should we
// display some sort of warning?
builder = new HtmlBuilder(new StringBuilder(300));
builder.add("The resource ").beginBold().add(PREFIX_RESOURCE_REF).add(type.getName()).add("/").add(name).endBold();
builder.add(" is defined outside of the project (in one of the libraries) and cannot ");
builder.add("be updated. This can change the behavior of the application.").newline().newline();
builder.add("Are you sure you want to do this?");
}
if (builder != null) {
appendUnhandledReferences(project, facet, all, local, builder);
conflicts.putValue(originalElement, builder.getHtml());
}
}
}
use of com.android.resources.ResourceType in project android by JetBrains.
the class ProjectResourceRepositoryTest method testInvalidateIds.
// Ensure that we invalidate the id cache when the file is rescanned but ids don't change
// (this was broken)
public void testInvalidateIds() {
// Like testOverlayUpdates1, but rather than testing changes to layout resources (file-based resource)
// perform document edits in value-documents
VirtualFile layoutFile = myFixture.copyFileToProject(LAYOUT, "res/layout/layout1.xml");
VirtualFile res1 = myFixture.copyFileToProject(VALUES, "res/values/values.xml").getParent().getParent();
VirtualFile res2 = myFixture.copyFileToProject(VALUES_OVERLAY1, "res2/values/values.xml").getParent().getParent();
VirtualFile res3 = myFixture.copyFileToProject(VALUES_OVERLAY2, "res3/values/nameDoesNotMatter.xml").getParent().getParent();
myFixture.copyFileToProject(VALUES_OVERLAY2_NO, "res3/values-no/values.xml");
assertNotSame(res1, res2);
assertNotSame(res1, res3);
assertNotSame(res2, res3);
// Just need an empty repository to make it a real module -set-; otherwise with a single
// module we just get a module repository, not a module set repository
LocalResourceRepository other = new LocalResourceRepository("unit test") {
@NonNull
@Override
protected Map<ResourceType, ListMultimap<String, ResourceItem>> getMap() {
return Collections.emptyMap();
}
@Nullable
@Override
protected ListMultimap<String, ResourceItem> getMap(ResourceType type, boolean create) {
return ArrayListMultimap.create();
}
@NotNull
@Override
protected Set<VirtualFile> computeResourceDirs() {
return ImmutableSet.of();
}
};
ModuleResourceRepository module = ModuleResourceRepository.createForTest(myFacet, Arrays.asList(res1, res2, res3));
final ProjectResourceRepository resources = ProjectResourceRepository.createForTest(myFacet, Arrays.asList(module, other));
PsiFile layoutPsiFile = PsiManager.getInstance(getProject()).findFile(layoutFile);
assertNotNull(layoutPsiFile);
assertTrue(resources.hasResourceItem(ResourceType.ID, "btn_title_refresh"));
final ResourceItem item = getFirstItem(resources, ResourceType.ID, "btn_title_refresh");
final long generation = resources.getModificationCount();
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
final Document document = documentManager.getDocument(layoutPsiFile);
assertNotNull(document);
WriteCommandAction.runWriteCommandAction(null, () -> {
String string = "<ImageView style=\"@style/TitleBarSeparator\" />";
int offset = document.getText().indexOf(string);
document.deleteString(offset, offset + string.length());
documentManager.commitDocument(document);
});
assertTrue(resources.isScanPending(layoutPsiFile));
ApplicationManager.getApplication().invokeLater(() -> {
assertTrue(generation < resources.getModificationCount());
// Should still be defined:
assertTrue(resources.hasResourceItem(ResourceType.ID, "btn_title_refresh"));
ResourceItem newItem = getFirstItem(resources, ResourceType.ID, "btn_title_refresh");
assertNotNull(newItem.getSource());
// However, should be a different item
assertNotSame(item, newItem);
});
UIUtil.dispatchAllInvocationEvents();
}
use of com.android.resources.ResourceType in project android by JetBrains.
the class ModuleResourceRepositoryTest method testHasResourcesOfType.
public void testHasResourcesOfType() {
// Test hasResourcesOfType merging (which may be optimized to be lighter-weight than map merging).
VirtualFile res1 = myFixture.copyFileToProject(LAYOUT, "res/layout/layout.xml").getParent().getParent();
VirtualFile res2 = myFixture.copyFileToProject(VALUES_OVERLAY1, "res2/values/values.xml").getParent().getParent();
assertNotSame(res1, res2);
ModuleResourceRepository resources = ModuleResourceRepository.createForTest(myFacet, Arrays.asList(res1, res2));
EnumSet<ResourceType> typesWithoutRes3 = EnumSet.of(ResourceType.ARRAY, ResourceType.ID, ResourceType.LAYOUT, ResourceType.STRING, ResourceType.STYLE);
assertHasExactResourceTypes(resources, typesWithoutRes3);
// Now update the repo with additional files, to test that merging picks up the new types.
VirtualFile values3 = myFixture.copyFileToProject(VALUES, "res3/values/many_more_values.xml");
VirtualFile res3 = values3.getParent().getParent();
assertNotSame(res1, res3);
assertNotSame(res2, res3);
resources.updateRoots(Arrays.asList(res1, res2, res3));
EnumSet<ResourceType> allTypes = EnumSet.copyOf(typesWithoutRes3);
allTypes.addAll(Arrays.asList(ResourceType.ATTR, ResourceType.INTEGER, ResourceType.DECLARE_STYLEABLE, ResourceType.PLURALS));
assertHasExactResourceTypes(resources, allTypes);
// Now delete the values file and check again.
final PsiFile psiValues3 = PsiManager.getInstance(getProject()).findFile(values3);
assertNotNull(psiValues3);
WriteCommandAction.runWriteCommandAction(null, new Runnable() {
@Override
public void run() {
psiValues3.delete();
}
});
assertHasExactResourceTypes(resources, typesWithoutRes3);
}
use of com.android.resources.ResourceType in project android_frameworks_base by crdroidandroid.
the class CustomBar method getColor.
private static int getColor(RenderResources renderResources, String attr) {
// From ?attr/foo to @color/bar. This is most likely an ItemResourceValue.
ResourceValue resource = renderResources.findItemInTheme(attr, true);
// Form @color/bar to the #AARRGGBB
resource = renderResources.resolveResValue(resource);
if (resource != null) {
ResourceType type = resource.getResourceType();
if (type == null || type == ResourceType.COLOR) {
// file, rather than referencing a color resource value.
try {
return ResourceHelper.getColor(resource.getValue());
} catch (NumberFormatException e) {
// Conversion failed.
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, "Theme attribute @android:" + attr + " does not reference a color, instead is '" + resource.getValue() + "'.", resource);
}
}
}
return 0;
}
Aggregations