Search in sources :

Example 51 with ResourceType

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;
}
Also used : ResourceValue(com.android.ide.common.rendering.api.ResourceValue) AttributeDefinition(org.jetbrains.android.dom.attrs.AttributeDefinition) ResourceType(com.android.resources.ResourceType) ConfiguredThemeEditorStyle(com.android.tools.idea.editors.theme.datamodels.ConfiguredThemeEditorStyle) NotNull(org.jetbrains.annotations.NotNull)

Example 52 with ResourceType

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());
        }
    }
}
Also used : FindUsagesHandler(com.intellij.find.findUsages.FindUsagesHandler) HtmlBuilder(com.android.utils.HtmlBuilder) ResourceType(com.android.resources.ResourceType) AppResourceRepository(com.android.tools.idea.res.AppResourceRepository) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) LightElement(com.intellij.psi.impl.light.LightElement) Project(com.intellij.openapi.project.Project) ResourceItem(com.android.ide.common.res2.ResourceItem)

Example 53 with ResourceType

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();
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) ResourceType(com.android.resources.ResourceType) Document(com.intellij.openapi.editor.Document) PsiFile(com.intellij.psi.PsiFile) ArrayListMultimap(com.google.common.collect.ArrayListMultimap) ListMultimap(com.google.common.collect.ListMultimap) ResourceItem(com.android.ide.common.res2.ResourceItem) PsiDocumentManager(com.intellij.psi.PsiDocumentManager)

Example 54 with ResourceType

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);
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) ResourceType(com.android.resources.ResourceType) PsiFile(com.intellij.psi.PsiFile)

Example 55 with ResourceType

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;
}
Also used : StyleResourceValue(com.android.ide.common.rendering.api.StyleResourceValue) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) ResourceType(com.android.resources.ResourceType)

Aggregations

ResourceType (com.android.resources.ResourceType)137 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)31 NotNull (org.jetbrains.annotations.NotNull)16 Field (java.lang.reflect.Field)13 StyleResourceValue (com.android.ide.common.rendering.api.StyleResourceValue)12 BridgeContext (com.android.layoutlib.bridge.android.BridgeContext)11 VirtualFile (com.intellij.openapi.vfs.VirtualFile)10 Map (java.util.Map)10 Nullable (org.jetbrains.annotations.Nullable)10 Nullable (com.android.annotations.Nullable)8 ResourceFolderType (com.android.resources.ResourceFolderType)8 File (java.io.File)8 EnumMap (java.util.EnumMap)7 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)7 Context (android.content.Context)6 View (android.view.View)6 AbsListView (android.widget.AbsListView)6 AdapterView (android.widget.AdapterView)6 ExpandableListView (android.widget.ExpandableListView)6 FrameLayout (android.widget.FrameLayout)6