diff --git a/plugins/android-designer/src/META-INF/plugin.xml b/plugins/android-designer/src/META-INF/plugin.xml
index 26fb86c102b5..36fb46e22dca 100644
--- a/plugins/android-designer/src/META-INF/plugin.xml
+++ b/plugins/android-designer/src/META-INF/plugin.xml
@@ -20,4 +20,8 @@
serviceImplementation="com.intellij.android.designer.model.ViewsMetaManager"/>
+
+
+
+
diff --git a/plugins/android-designer/src/com/intellij/android/designer/AndroidDesignerRefactoringContextProvider.java b/plugins/android-designer/src/com/intellij/android/designer/AndroidDesignerRefactoringContextProvider.java
new file mode 100644
index 000000000000..13854f92f2d4
--- /dev/null
+++ b/plugins/android-designer/src/com/intellij/android/designer/AndroidDesignerRefactoringContextProvider.java
@@ -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 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;
+ }
+}
diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java
index 4df167a3cd20..ca1275b3c02b 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java
@@ -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();
diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidRefactoringActionWrapper.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidRefactoringActionWrapper.java
new file mode 100644
index 000000000000..5000c9cd7057
--- /dev/null
+++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidRefactoringActionWrapper.java
@@ -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);
+ }
+ }
+}
diff --git a/plugins/android/src/META-INF/plugin.xml b/plugins/android/src/META-INF/plugin.xml
index 287282e4fda2..385a4a5d4128 100644
--- a/plugins/android/src/META-INF/plugin.xml
+++ b/plugins/android/src/META-INF/plugin.xml
@@ -241,5 +241,6 @@
+
diff --git a/plugins/android/src/org/jetbrains/android/refactoring/AndroidExtractStyleAction.java b/plugins/android/src/org/jetbrains/android/refactoring/AndroidExtractStyleAction.java
index 5449ea7d1c30..c2077f28ae85 100644
--- a/plugins/android/src/org/jetbrains/android/refactoring/AndroidExtractStyleAction.java
+++ b/plugins/android/src/org/jetbrains/android/refactoring/AndroidExtractStyleAction.java
@@ -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;
}
diff --git a/plugins/android/src/org/jetbrains/android/refactoring/AndroidRefactoringContextProvider.java b/plugins/android/src/org/jetbrains/android/refactoring/AndroidRefactoringContextProvider.java
new file mode 100644
index 000000000000..e3a625139e53
--- /dev/null
+++ b/plugins/android/src/org/jetbrains/android/refactoring/AndroidRefactoringContextProvider.java
@@ -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 EP_NAME =
+ ExtensionPointName.create("org.jetbrains.android.refactoringContextProvider");
+
+ @Nullable
+ XmlTag getComponentTag(@NotNull DataContext dataContext);
+}