Search in sources :

Example 1 with Style

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

the class ThemeEditorUtils method createNewStyle.

/**
   * Creates a new style
   * @param project the project where the new style is being created
   * @param resourceDir the res/ directory where the new style is being created
   * @param newStyleName the new style name
   * @param parentStyleName the name of the new style parent
   * @param fileName name of the xml file where the style will be added (usually "styles.xml")
   * @param folderNames folder names where the style will be added
   * @return true if the style was created or false otherwise
   */
public static boolean createNewStyle(@NotNull final Project project, @NotNull final VirtualFile resourceDir, @NotNull final String newStyleName, @Nullable final String parentStyleName, @NotNull final String fileName, @NotNull final List<String> folderNames) {
    return new WriteCommandAction<Boolean>(project, "Create new style " + newStyleName) {

        @Override
        protected void run(@NotNull Result<Boolean> result) {
            CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
            result.setResult(AndroidResourceUtil.createValueResource(project, resourceDir, newStyleName, null, ResourceType.STYLE, fileName, folderNames, new Processor<ResourceElement>() {

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

Example 2 with Style

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

the class AndroidInlineStyleReferenceAction method doRefactorForTags.

@Override
protected void doRefactorForTags(@NotNull Project project, @NotNull final XmlTag[] tags) {
    assert tags.length == 1;
    final XmlTag tag = tags[0];
    final PsiFile file = tag.getContainingFile();
    if (file == null) {
        return;
    }
    final StyleUsageData usageData = AndroidInlineUtil.getStyleUsageData(tag);
    if (usageData == null) {
        return;
    }
    final AndroidResourceReferenceBase reference = usageData.getReference();
    final String title = AndroidBundle.message("android.inline.style.title");
    final PsiElement[] styleElements = reference.computeTargetElements();
    if (styleElements.length == 0) {
        AndroidUtils.reportError(project, "Cannot find style by reference '" + reference.getValue() + "'", title);
        return;
    }
    if (styleElements.length > 1) {
        AndroidUtils.reportError(project, RefactoringBundle.getCannotRefactorMessage("Unambiguous style reference."), title);
        return;
    }
    final PsiElement styleElement = styleElements[0];
    final XmlTag styleTag = PsiTreeUtil.getParentOfType(styleElement, XmlTag.class);
    final DomElement domElement = styleTag != null ? DomManager.getDomManager(project).getDomElement(styleTag) : null;
    if (!(domElement instanceof Style)) {
        AndroidUtils.reportError(project, "Cannot find style by reference '" + reference.getValue() + "'", title);
        return;
    }
    final Style style = (Style) domElement;
    String styleName = style.getName().getStringValue();
    if (styleName == null) {
        AndroidUtils.reportError(project, RefactoringBundle.getCannotRefactorMessage("Style name is not specified."), title);
        return;
    }
    AndroidInlineUtil.doInlineStyleDeclaration(project, new AndroidInlineUtil.MyStyleData(styleName, style, styleElement), usageData, new ProjectBasedErrorReporter(project), myTestConfig);
}
Also used : DomElement(com.intellij.util.xml.DomElement) ProjectBasedErrorReporter(org.jetbrains.android.util.ProjectBasedErrorReporter) AndroidResourceReferenceBase(org.jetbrains.android.dom.converters.AndroidResourceReferenceBase) Style(org.jetbrains.android.dom.resources.Style) PsiFile(com.intellij.psi.PsiFile) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag)

Example 3 with Style

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

the class AndroidInlineUtil method getStyleUsageData.

@Nullable
static StyleUsageData getStyleUsageData(@NotNull XmlTag tag) {
    final DomElement domElement = DomManager.getDomManager(tag.getProject()).getDomElement(tag);
    if (domElement instanceof LayoutViewElement) {
        final GenericAttributeValue<ResourceValue> styleAttribute = ((LayoutViewElement) domElement).getStyle();
        final AndroidResourceReferenceBase reference = AndroidDomUtil.getAndroidResourceReference(styleAttribute, true);
        if (reference != null) {
            return new ViewStyleUsageData(tag, styleAttribute, reference);
        }
    } else if (domElement instanceof Style) {
        final AndroidResourceReferenceBase reference = AndroidDomUtil.getAndroidResourceReference(((Style) domElement).getParentStyle(), true);
        if (reference != null) {
            return new ParentStyleUsageData((Style) domElement, reference);
        }
    }
    return null;
}
Also used : DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) AndroidResourceReferenceBase(org.jetbrains.android.dom.converters.AndroidResourceReferenceBase) ResourceValue(org.jetbrains.android.dom.resources.ResourceValue) Style(org.jetbrains.android.dom.resources.Style) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with Style

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

the class AndroidFindStyleApplicationsAction method createFindStyleApplicationsProcessor.

public static AndroidFindStyleApplicationsProcessor createFindStyleApplicationsProcessor(XmlTag tag, MyStyleData styleData, PsiFile context) {
    final ErrorReporter errorReporter = new ProjectBasedErrorReporter(tag.getProject());
    final Style style = styleData.getStyle();
    final Map<AndroidAttributeInfo, String> attrMap = AndroidRefactoringUtil.computeAttributeMap(style, new ProjectBasedErrorReporter(tag.getProject()), AndroidBundle.message("android.find.style.applications.title"));
    if (attrMap == null || attrMap.size() == 0) {
        return null;
    }
    final AndroidFacet facet = styleData.getFacet();
    final StyleRefData parentStyleRef = AndroidRefactoringUtil.getParentStyle(style);
    PsiElement parentStyleAttrName = null;
    if (parentStyleRef != null) {
        parentStyleAttrName = resolveStyleRef(parentStyleRef, facet);
        if (parentStyleAttrName == null) {
            errorReporter.report("Cannot resolve parent style '" + parentStyleRef.getStyleName() + "'", AndroidBundle.message("android.find.style.applications.title"));
            return null;
        }
    }
    return new AndroidFindStyleApplicationsProcessor(styleData.getFacet().getModule(), attrMap, styleData.getName(), tag, styleData.getNameAttrValue(), parentStyleAttrName, context);
}
Also used : ProjectBasedErrorReporter(org.jetbrains.android.util.ProjectBasedErrorReporter) ErrorReporter(org.jetbrains.android.util.ErrorReporter) ProjectBasedErrorReporter(org.jetbrains.android.util.ProjectBasedErrorReporter) Style(org.jetbrains.android.dom.resources.Style) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) PsiElement(com.intellij.psi.PsiElement)

Example 5 with Style

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

the class AndroidExtractStyleAction method doExtractStyle.

@Nullable
public static String doExtractStyle(@NotNull Module module, @NotNull final XmlTag viewTag, final boolean addStyleAttributeToTag, @Nullable MyTestConfig testConfig) {
    final PsiFile file = viewTag.getContainingFile();
    if (file == null) {
        return null;
    }
    final String dialogTitle = AndroidBundle.message("android.extract.style.title");
    final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STYLE);
    assert fileName != null;
    final List<String> dirNames = Collections.singletonList(ResourceFolderType.VALUES.getName());
    final List<XmlAttribute> extractableAttributes = getExtractableAttributes(viewTag);
    final Project project = module.getProject();
    if (extractableAttributes.size() == 0) {
        AndroidUtils.reportError(project, "The tag doesn't contain any attributes that can be extracted", dialogTitle);
        return null;
    }
    final LayoutViewElement viewElement = getLayoutViewElement(viewTag);
    assert viewElement != null;
    final ResourceValue parentStyleValue = viewElement.getStyle().getValue();
    final String parentStyle;
    boolean supportImplicitParent = false;
    if (parentStyleValue != null) {
        parentStyle = parentStyleValue.getResourceName();
        if (ResourceType.STYLE != parentStyleValue.getType() || parentStyle == null || parentStyle.length() == 0) {
            AndroidUtils.reportError(project, "Invalid parent style reference " + parentStyleValue.toString(), dialogTitle);
            return null;
        }
        supportImplicitParent = parentStyleValue.getNamespace() == null;
    } else {
        parentStyle = null;
    }
    final String styleName;
    final List<XmlAttribute> styledAttributes;
    final VirtualFile chosenDirectory;
    final boolean searchStyleApplications;
    if (testConfig == null) {
        final ExtractStyleDialog dialog = new ExtractStyleDialog(module, fileName, supportImplicitParent ? parentStyle : null, dirNames, extractableAttributes);
        dialog.setTitle(dialogTitle);
        if (!dialog.showAndGet()) {
            return null;
        }
        searchStyleApplications = dialog.isToSearchStyleApplications();
        chosenDirectory = dialog.getResourceDirectory();
        if (chosenDirectory == null) {
            AndroidUtils.reportError(project, AndroidBundle.message("check.resource.dir.error", module.getName()));
            return null;
        }
        styledAttributes = dialog.getStyledAttributes();
        styleName = dialog.getStyleName();
    } else {
        testConfig.validate(extractableAttributes);
        chosenDirectory = testConfig.getResourceDirectory();
        styleName = testConfig.getStyleName();
        final Set<String> attrsToExtract = new HashSet<String>(Arrays.asList(testConfig.getAttributesToExtract()));
        styledAttributes = new ArrayList<XmlAttribute>();
        for (XmlAttribute attribute : extractableAttributes) {
            if (attrsToExtract.contains(attribute.getName())) {
                styledAttributes.add(attribute);
            }
        }
        searchStyleApplications = false;
    }
    final boolean[] success = { false };
    final Ref<Style> createdStyleRef = Ref.create();
    final boolean finalSupportImplicitParent = supportImplicitParent;
    new WriteCommandAction(project, "Extract Android Style '" + styleName + "'", file) {

        @Override
        protected void run(@NotNull final Result result) throws Throwable {
            final List<XmlAttribute> attributesToDelete = new ArrayList<XmlAttribute>();
            if (!AndroidResourceUtil.createValueResource(project, chosenDirectory, styleName, null, ResourceType.STYLE, fileName, dirNames, new Processor<ResourceElement>() {

                @Override
                public boolean process(ResourceElement element) {
                    assert element instanceof Style;
                    final Style style = (Style) element;
                    createdStyleRef.set(style);
                    for (XmlAttribute attribute : styledAttributes) {
                        if (SdkConstants.NS_RESOURCES.equals(attribute.getNamespace())) {
                            final StyleItem item = style.addItem();
                            item.getName().setStringValue("android:" + attribute.getLocalName());
                            item.setStringValue(attribute.getValue());
                            attributesToDelete.add(attribute);
                        }
                    }
                    if (parentStyleValue != null && (!finalSupportImplicitParent || !styleName.startsWith(parentStyle + "."))) {
                        final String aPackage = parentStyleValue.getNamespace();
                        style.getParentStyle().setStringValue((aPackage != null ? aPackage + ":" : "") + parentStyle);
                    }
                    return true;
                }
            })) {
                return;
            }
            ApplicationManager.getApplication().runWriteAction(new Runnable() {

                @Override
                public void run() {
                    for (XmlAttribute attribute : attributesToDelete) {
                        attribute.delete();
                    }
                    if (addStyleAttributeToTag) {
                        final LayoutViewElement viewElement = getLayoutViewElement(viewTag);
                        assert viewElement != null;
                        viewElement.getStyle().setStringValue("@style/" + styleName);
                    }
                }
            });
            success[0] = true;
        }

        @Override
        protected UndoConfirmationPolicy getUndoConfirmationPolicy() {
            return UndoConfirmationPolicy.REQUEST_CONFIRMATION;
        }
    }.execute();
    if (!success[0]) {
        return null;
    }
    final Style createdStyle = createdStyleRef.get();
    final XmlTag createdStyleTag = createdStyle != null ? createdStyle.getXmlTag() : null;
    if (createdStyleTag != null) {
        final AndroidFindStyleApplicationsAction.MyStyleData createdStyleData = AndroidFindStyleApplicationsAction.getStyleData(createdStyleTag);
        if (createdStyleData != null && searchStyleApplications) {
            ApplicationManager.getApplication().invokeLater(new Runnable() {

                @Override
                public void run() {
                    AndroidFindStyleApplicationsAction.doRefactoringForTag(createdStyleTag, createdStyleData, file, null);
                }
            });
        }
    }
    return styleName;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) XmlAttribute(com.intellij.psi.xml.XmlAttribute) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) StyleItem(org.jetbrains.android.dom.resources.StyleItem) Result(com.intellij.openapi.application.Result) UndoConfirmationPolicy(com.intellij.openapi.command.UndoConfirmationPolicy) ResourceValue(org.jetbrains.android.dom.resources.ResourceValue) Style(org.jetbrains.android.dom.resources.Style) PsiFile(com.intellij.psi.PsiFile) HashSet(com.intellij.util.containers.HashSet) ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) Project(com.intellij.openapi.project.Project) XmlTag(com.intellij.psi.xml.XmlTag) Nullable(org.jetbrains.annotations.Nullable)

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