support "extract style" in android designer

This commit is contained in:
Eugene Kudelevsky
2012-08-01 17:08:16 +04:00
parent eae391c9c8
commit 651c4552c6
7 changed files with 163 additions and 5 deletions
@@ -20,4 +20,8 @@
serviceImplementation="com.intellij.android.designer.model.ViewsMetaManager"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.android">
<refactoringContextProvider implementation="com.intellij.android.designer.AndroidDesignerRefactoringContextProvider"/>
</extensions>
</idea-plugin>
@@ -0,0 +1,38 @@
package com.intellij.android.designer;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.designSurface.EditableArea;
import com.intellij.designer.model.EmptyXmlTag;
import com.intellij.designer.model.RadComponent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.android.refactoring.AndroidRefactoringContextProvider;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidDesignerRefactoringContextProvider implements AndroidRefactoringContextProvider {
@Override
public XmlTag getComponentTag(@NotNull DataContext dataContext) {
final EditableArea area = EditableArea.DATA_KEY.getData(dataContext);
if (area == null) {
return null;
}
final List<RadComponent> selection = area.getSelection();
if (selection.size() != 1) {
return null;
}
final RadComponent component = selection.get(0);
if (!(component instanceof RadViewComponent)) {
return null;
}
final XmlTag tag = ((RadViewComponent)component).getTag();
return tag != null && !tag.equals(EmptyXmlTag.INSTANCE) ? tag : null;
}
}
@@ -38,9 +38,7 @@ import com.intellij.designer.palette.DefaultPaletteItem;
import com.intellij.designer.palette.PaletteGroup;
import com.intellij.designer.palette.PaletteItem;
import com.intellij.designer.palette.PaletteToolWindowManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.module.Module;
@@ -62,6 +60,7 @@ import com.intellij.util.ThrowableConsumer;
import com.intellij.util.ThrowableRunnable;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.maven.AndroidMavenUtil;
import org.jetbrains.android.refactoring.AndroidExtractStyleAction;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.uipreview.*;
@@ -137,6 +136,8 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
});
myActionPanel.getPopupGroup().addSeparator();
myActionPanel.getPopupGroup().add(buildRefactorActionGroup());
AnAction gotoDeclaration = new AnAction("Go To Declaration") {
@Override
public void update(AnActionEvent e) {
@@ -155,6 +156,15 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
myActionPanel.getPopupGroup().add(gotoDeclaration);
}
@NotNull
private static ActionGroup buildRefactorActionGroup() {
final DefaultActionGroup group = new DefaultActionGroup("_Refactor", true);
final ActionManager manager = ActionManager.getInstance();
final AnAction action = manager.getAction(AndroidExtractStyleAction.ACTION_ID);
group.add(new AndroidRefactoringActionWrapper("_Extract style", action));
return group;
}
private void reparseFile() {
try {
storeState();
@@ -0,0 +1,34 @@
package com.intellij.android.designer.designSurface;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
class AndroidRefactoringActionWrapper extends AnAction {
private final AnAction myWrappee;
public AndroidRefactoringActionWrapper(@NotNull String text, @NotNull AnAction wrappee) {
super(text, null, null);
myWrappee = wrappee;
getTemplatePresentation().setDescription(wrappee.getTemplatePresentation().getDescription());
}
@Override
public void actionPerformed(AnActionEvent e) {
myWrappee.actionPerformed(e);
}
@Override
public void update(AnActionEvent e) {
myWrappee.update(e);
final Presentation p = e.getPresentation();
if (!p.isVisible()) {
p.setEnabled(false);
p.setVisible(true);
}
}
}
+1
View File
@@ -241,5 +241,6 @@
<extensionPoints>
<extensionPoint name="mavenProvider" interface="org.jetbrains.android.maven.AndroidMavenProvider"/>
<extensionPoint name="lightBuildProvider" interface="org.jetbrains.android.compiler.AndroidLightBuildProvider"/>
<extensionPoint name="refactoringContextProvider" interface="org.jetbrains.android.refactoring.AndroidRefactoringContextProvider"/>
</extensionPoints>
</idea-plugin>
@@ -5,7 +5,9 @@ import com.android.resources.ResourceType;
import com.android.sdklib.SdkConstants;
import com.intellij.lang.Language;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.UndoConfirmationPolicy;
@@ -39,6 +41,7 @@ import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -52,6 +55,8 @@ import java.util.Set;
* @author Eugene.Kudelevsky
*/
public class AndroidExtractStyleAction extends BaseRefactoringAction {
@NonNls public static final String ACTION_ID = "AndroidExtractStyleAction";
private static String[] NON_EXTRACTABLE_ATTRIBUTES =
new String[]{AndroidDomUtil.ATTR_ID, AndroidDomUtil.ATTR_TEXT, AndroidDomUtil.ATTR_HINT, AndroidDomUtil.ATTR_SRC,
AndroidDomUtil.ATTR_ON_CLICK};
@@ -109,7 +114,45 @@ public class AndroidExtractStyleAction extends BaseRefactoringAction {
@Override
protected RefactoringActionHandler getHandler(DataContext dataContext) {
return new MyHandler(myTestConfig);
final XmlTag componentTag = getComponentTag(dataContext);
return new MyHandler(myTestConfig, componentTag);
}
@Override
public void update(AnActionEvent e) {
final DataContext context = e.getDataContext();
final DataContext patchedContext = new DataContext() {
@Override
public Object getData(@NonNls String dataId) {
final Object data = context.getData(dataId);
if (data != null) {
return data;
}
if (LangDataKeys.PSI_ELEMENT.is(dataId)) {
return getComponentTag(context);
}
return null;
}
};
super.update(new AnActionEvent(e.getInputEvent(), patchedContext, e.getPlace(), e.getPresentation(),
e.getActionManager(), e.getModifiers()));
}
@Nullable
private static XmlTag getComponentTag(DataContext dataContext) {
if (dataContext == null) {
return null;
}
for (AndroidRefactoringContextProvider provider : AndroidRefactoringContextProvider.EP_NAME.getExtensions()) {
final XmlTag componentTag = provider.getComponentTag(dataContext);
if (componentTag != null) {
return componentTag;
}
}
return null;
}
@Override
@@ -293,13 +336,19 @@ public class AndroidExtractStyleAction extends BaseRefactoringAction {
private static class MyHandler implements RefactoringActionHandler {
private final MyTestConfig myTestConfig;
private final XmlTag myTag;
private MyHandler(@Nullable MyTestConfig testConfig) {
private MyHandler(@Nullable MyTestConfig testConfig, @Nullable XmlTag tag) {
myTestConfig = testConfig;
myTag = tag;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
if (myTag != null) {
doExtractStyle(myTag, myTestConfig);
return;
}
final PsiElement element = getElementAtCaret(editor, file);
if (element == null) {
return;
@@ -313,6 +362,10 @@ public class AndroidExtractStyleAction extends BaseRefactoringAction {
@Override
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
if (myTag != null) {
doExtractStyle(myTag, myTestConfig);
return;
}
if (elements.length != 1) {
return;
}
@@ -0,0 +1,18 @@
package org.jetbrains.android.refactoring;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
public interface AndroidRefactoringContextProvider {
ExtensionPointName<AndroidRefactoringContextProvider> EP_NAME =
ExtensionPointName.create("org.jetbrains.android.refactoringContextProvider");
@Nullable
XmlTag getComponentTag(@NotNull DataContext dataContext);
}