| package org.jetbrains.android.refactoring; |
| |
| import com.intellij.openapi.project.Project; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.util.PsiTreeUtil; |
| import com.intellij.psi.xml.XmlFile; |
| import com.intellij.psi.xml.XmlTag; |
| import com.intellij.refactoring.RefactoringBundle; |
| import com.intellij.util.xml.DomElement; |
| import com.intellij.util.xml.DomFileDescription; |
| import com.intellij.util.xml.DomManager; |
| import org.jetbrains.android.dom.converters.AndroidResourceReferenceBase; |
| import org.jetbrains.android.dom.layout.LayoutDomFileDescription; |
| import org.jetbrains.android.dom.resources.ResourcesDomFileDescription; |
| import org.jetbrains.android.dom.resources.Style; |
| import org.jetbrains.android.util.AndroidBundle; |
| import org.jetbrains.android.util.AndroidUtils; |
| import org.jetbrains.android.util.ProjectBasedErrorReporter; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.TestOnly; |
| |
| /** |
| * @author Eugene.Kudelevsky |
| */ |
| public class AndroidInlineStyleReferenceAction extends AndroidBaseXmlRefactoringAction { |
| public static final String ACTION_ID = "AndroidInlineStyleReferenceAction"; |
| |
| private final AndroidInlineTestConfig myTestConfig; |
| |
| @TestOnly |
| AndroidInlineStyleReferenceAction(AndroidInlineTestConfig testConfig) { |
| myTestConfig = testConfig; |
| } |
| |
| @SuppressWarnings("UnusedDeclaration") |
| public AndroidInlineStyleReferenceAction() { |
| myTestConfig = null; |
| } |
| |
| @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); |
| } |
| |
| @Override |
| protected boolean isEnabledForTags(@NotNull XmlTag[] tags) { |
| return tags.length == 1 && AndroidInlineUtil.getStyleUsageData(tags[0]) != null; |
| } |
| |
| @Override |
| protected boolean isMyFile(PsiFile file) { |
| final DomFileDescription<?> description = DomManager.getDomManager(file.getProject()).getDomFileDescription((XmlFile)file); |
| |
| return description instanceof LayoutDomFileDescription || |
| description instanceof ResourcesDomFileDescription; |
| } |
| } |