Search in sources :

Example 6 with LayoutViewElement

use of org.jetbrains.android.dom.layout.LayoutViewElement 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)

Example 7 with LayoutViewElement

use of org.jetbrains.android.dom.layout.LayoutViewElement in project android by JetBrains.

the class AndroidDomUtil method getSpecificConverter.

@Nullable
public static Converter getSpecificConverter(@NotNull XmlName attrName, DomElement context) {
    if (context == null) {
        return null;
    }
    if (!SdkConstants.NS_RESOURCES.equals(attrName.getNamespaceKey())) {
        return null;
    }
    final XmlTag xmlTag = context.getXmlTag();
    if (xmlTag == null) {
        return null;
    }
    final String localName = attrName.getLocalName();
    final String tagName = xmlTag.getName();
    if (context instanceof XmlResourceElement) {
        if ("configure".equals(localName) && "appwidget-provider".equals(tagName)) {
            return ACTIVITY_CONVERTER;
        } else if (VIEW_FRAGMENT.equals(localName)) {
            return FRAGMENT_CLASS_CONVERTER;
        }
    } else if (context instanceof LayoutViewElement || context instanceof MenuItem) {
        if (ATTR_ON_CLICK.equals(localName)) {
            return context instanceof LayoutViewElement ? OnClickConverter.CONVERTER_FOR_LAYOUT : OnClickConverter.CONVERTER_FOR_MENU;
        }
    }
    return null;
}
Also used : LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) XmlResourceElement(org.jetbrains.android.dom.xml.XmlResourceElement) MenuItem(org.jetbrains.android.dom.menu.MenuItem) XmlTag(com.intellij.psi.xml.XmlTag) Nullable(org.jetbrains.annotations.Nullable)

Example 8 with LayoutViewElement

use of org.jetbrains.android.dom.layout.LayoutViewElement in project android by JetBrains.

the class AndroidDomElementDescriptorProvider method getDomElementAndBaseClassQName.

@Nullable
public static Pair<AndroidDomElement, String> getDomElementAndBaseClassQName(@NotNull XmlTag tag) {
    final PsiFile file = tag.getContainingFile();
    if (!(file instanceof XmlFile))
        return null;
    Project project = file.getProject();
    if (project.isDefault())
        return null;
    final DomManager domManager = DomManager.getDomManager(project);
    if (domManager.getFileElement((XmlFile) file, AndroidDomElement.class) == null)
        return null;
    final DomElement domElement = domManager.getDomElement(tag);
    if (!(domElement instanceof AndroidDomElement)) {
        return null;
    }
    String className = null;
    if (domElement instanceof LayoutViewElement) {
        className = AndroidUtils.VIEW_CLASS_NAME;
    } else if (domElement instanceof XmlResourceElement) {
        className = SdkConstants.CLASS_PREFERENCE;
    }
    return Pair.create((AndroidDomElement) domElement, className);
}
Also used : Project(com.intellij.openapi.project.Project) DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) XmlFile(com.intellij.psi.xml.XmlFile) DomManager(com.intellij.util.xml.DomManager) XmlResourceElement(org.jetbrains.android.dom.xml.XmlResourceElement) PsiFile(com.intellij.psi.PsiFile) Nullable(org.jetbrains.annotations.Nullable)

Example 9 with LayoutViewElement

use of org.jetbrains.android.dom.layout.LayoutViewElement in project android by JetBrains.

the class AndroidFindStyleApplicationsProcessor method performRefactoring.

@Override
protected void performRefactoring(@NotNull UsageInfo[] usages) {
    final Set<Pair<String, String>> attrsInStyle = new HashSet<Pair<String, String>>();
    for (AndroidAttributeInfo info : myAttrMap.keySet()) {
        attrsInStyle.add(Pair.create(info.getNamespace(), info.getName()));
    }
    for (UsageInfo usage : usages) {
        final PsiElement element = usage.getElement();
        final DomElement domElement = element instanceof XmlTag ? DomManager.getDomManager(myProject).getDomElement((XmlTag) element) : null;
        if (domElement instanceof LayoutViewElement) {
            final List<XmlAttribute> attributesToDelete = new ArrayList<XmlAttribute>();
            for (XmlAttribute attribute : ((XmlTag) element).getAttributes()) {
                if (attrsInStyle.contains(Pair.create(attribute.getNamespace(), attribute.getLocalName()))) {
                    attributesToDelete.add(attribute);
                }
            }
            ApplicationManager.getApplication().runWriteAction(new Runnable() {

                @Override
                public void run() {
                    for (XmlAttribute attribute : attributesToDelete) {
                        attribute.delete();
                    }
                    ((LayoutViewElement) domElement).getStyle().setStringValue("@style/" + myStyleName);
                }
            });
        }
    }
    final PsiFile file = myStyleTag.getContainingFile();
    if (file != null) {
        UndoUtil.markPsiFileForUndo(file);
    }
    if (myContext != null) {
        UndoUtil.markPsiFileForUndo(myContext);
    }
}
Also used : LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) XmlAttribute(com.intellij.psi.xml.XmlAttribute) DomElement(com.intellij.util.xml.DomElement) PsiFile(com.intellij.psi.PsiFile) UsageInfo(com.intellij.usageView.UsageInfo) PsiElement(com.intellij.psi.PsiElement) HashSet(com.intellij.util.containers.HashSet) Pair(com.intellij.openapi.util.Pair) XmlTag(com.intellij.psi.xml.XmlTag)

Example 10 with LayoutViewElement

use of org.jetbrains.android.dom.layout.LayoutViewElement in project android by JetBrains.

the class AndroidExtractAsIncludeAction method isEnabledForTags.

@Override
protected boolean isEnabledForTags(@NotNull XmlTag[] tags) {
    if (tags.length == 0) {
        return false;
    }
    final DomManager domManager = DomManager.getDomManager(tags[0].getProject());
    boolean containsViewElement = false;
    for (XmlTag tag : tags) {
        final DomElement domElement = domManager.getDomElement(tag);
        if (!isSuitableDomElement(domElement)) {
            return false;
        }
        if (domElement instanceof LayoutViewElement) {
            containsViewElement = true;
        }
    }
    if (!containsViewElement) {
        return false;
    }
    final PsiElement parent = tags[0].getParent();
    if (!(parent instanceof XmlTag) || parent.getContainingFile() == null) {
        return false;
    }
    for (int i = 1; i < tags.length; i++) {
        if (tags[i].getParent() != parent) {
            return false;
        }
    }
    return true;
}
Also used : DomElement(com.intellij.util.xml.DomElement) LayoutViewElement(org.jetbrains.android.dom.layout.LayoutViewElement) DomManager(com.intellij.util.xml.DomManager) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

LayoutViewElement (org.jetbrains.android.dom.layout.LayoutViewElement)12 DomElement (com.intellij.util.xml.DomElement)7 PsiFile (com.intellij.psi.PsiFile)6 XmlTag (com.intellij.psi.xml.XmlTag)5 VirtualFile (com.intellij.openapi.vfs.VirtualFile)4 XmlAttribute (com.intellij.psi.xml.XmlAttribute)4 XmlFile (com.intellij.psi.xml.XmlFile)4 Nullable (org.jetbrains.annotations.Nullable)4 StructureViewModel (com.intellij.ide.structureView.StructureViewModel)3 DomManager (com.intellij.util.xml.DomManager)3 LayoutStructureViewBuilder (org.jetbrains.android.dom.structure.layout.LayoutStructureViewBuilder)3 Project (com.intellij.openapi.project.Project)2 Pair (com.intellij.openapi.util.Pair)2 PsiElement (com.intellij.psi.PsiElement)2 UsageInfo (com.intellij.usageView.UsageInfo)2 HashSet (com.intellij.util.containers.HashSet)2 ResourceValue (org.jetbrains.android.dom.resources.ResourceValue)2 Style (org.jetbrains.android.dom.resources.Style)2 XmlResourceElement (org.jetbrains.android.dom.xml.XmlResourceElement)2 Result (com.intellij.openapi.application.Result)1