mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
refactoring, create android resources from java usages
This commit is contained in:
@@ -412,4 +412,5 @@ deployment.target.settings.min.sdk.info.message=Only compatible AVDs are shown.
|
||||
android.compilation.warning.circular.app.dependency=Generated fields in {0}.R class in module ''{1}'' won''t be final, because of circular dependency on module ''{2}''
|
||||
cannot.find.zip.align=The zipalign tool was not found in the SDK.\n\nPlease update to the latest SDK and re-export your application\nor run zipalign manually.\n\nAligning applications allows Android to use application resources\nmore efficiently.
|
||||
file.name.not.specified.error=File name is not specified
|
||||
root.element.not.specified.error=Root element is not specified
|
||||
root.element.not.specified.error=Root element is not specified
|
||||
directory.not.specified.error=Directory is not specified
|
||||
@@ -219,6 +219,8 @@
|
||||
<usageTargetProvider implementation="org.jetbrains.android.AndroidUsagesTargetProvider"/>
|
||||
<renameHandler implementation="org.jetbrains.android.AndroidRenameHandler" order="first"/>
|
||||
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.android.inspections.AndroidQuickFixProvider"/>
|
||||
|
||||
<packaging.elementType implementation="org.jetbrains.android.compiler.artifact.AndroidFinalPackageElementType"/>
|
||||
<packaging.sourceItemProvider implementation="org.jetbrains.android.compiler.artifact.AndroidSourceItemsProvider"/>
|
||||
<packaging.artifactPropertiesProvider implementation="org.jetbrains.android.compiler.artifact.AndroidArtifactPropertiesProvider"/>
|
||||
|
||||
@@ -19,7 +19,11 @@ import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiIdentifier;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import com.intellij.psi.meta.PsiMetaOwner;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
@@ -27,7 +31,6 @@ import org.jetbrains.android.dom.wrappers.FileResourceElementWrapper;
|
||||
import org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.android.util.AndroidUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -51,47 +54,22 @@ public class AndroidGotoDeclarationHandler implements GotoDeclarationHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String resFieldName = refExp.getReferenceName();
|
||||
if (resFieldName == null || resFieldName.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiExpression qExp = refExp.getQualifierExpression();
|
||||
if (!(qExp instanceof PsiReferenceExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiReferenceExpression resClassReference = (PsiReferenceExpression)qExp;
|
||||
|
||||
final String resClassName = resClassReference.getReferenceName();
|
||||
if (resClassName == null || resClassName.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
qExp = resClassReference.getQualifierExpression();
|
||||
if (!(qExp instanceof PsiReferenceExpression)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiElement resolvedElement = ((PsiReferenceExpression)qExp).resolve();
|
||||
if (!(resolvedElement instanceof PsiClass) ||
|
||||
!AndroidUtils.R_CLASS_NAME.equals(((PsiClass)resolvedElement).getName())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiFile containingFile = resolvedElement.getContainingFile();
|
||||
if (containingFile == null || !AndroidResourceUtil.isRJavaFile(facet, containingFile)) {
|
||||
final Pair<String, String> pair = AndroidResourceUtil.getReferredResourceField(facet, refExp);
|
||||
if (pair == null) {
|
||||
return null;
|
||||
}
|
||||
final String resClassName = pair.getFirst();
|
||||
final String resFieldName = pair.getSecond();
|
||||
|
||||
final List<PsiElement> resourceList = facet.getLocalResourceManager().findResourcesByFieldName(resClassName, resFieldName);
|
||||
final PsiElement[] resources = resourceList.toArray(new PsiElement[resourceList.size()]);
|
||||
final PsiElement[] wrappedResources = new PsiElement[resources.length];
|
||||
|
||||
|
||||
for (int i = 0; i < resources.length; i++) {
|
||||
final PsiElement resource = resources[i];
|
||||
|
||||
if (resource instanceof XmlAttributeValue &&
|
||||
resource instanceof PsiMetaOwner &&
|
||||
|
||||
if (resource instanceof XmlAttributeValue &&
|
||||
resource instanceof PsiMetaOwner &&
|
||||
resource instanceof NavigationItem) {
|
||||
wrappedResources[i] = new ValueResourceElementWrapper((XmlAttributeValue)resource);
|
||||
}
|
||||
|
||||
+3
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.android.actions;
|
||||
|
||||
import com.android.resources.ResourceFolderType;
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.facet.ProjectFacetManager;
|
||||
@@ -57,7 +58,7 @@ public class AndroidCreateLayoutFileAction extends CreateTypedResourceFileAction
|
||||
private String myLastRootComponentName;
|
||||
|
||||
public AndroidCreateLayoutFileAction() {
|
||||
super("Layout", "layout", "LinearLayout", false, false);
|
||||
super("Layout", ResourceFolderType.LAYOUT, false, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -75,7 +76,7 @@ public class AndroidCreateLayoutFileAction extends CreateTypedResourceFileAction
|
||||
@Override
|
||||
protected PsiElement[] create(String newName, PsiDirectory directory) throws Exception {
|
||||
assert myLastRootComponentName != null;
|
||||
return doCreate(newName, directory, myLastRootComponentName, false);
|
||||
return doCreateAndNavigate(newName, directory, myLastRootComponentName, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -73,15 +73,19 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
private final Map<String, CreateTypedResourceFileAction> myResType2ActionMap = new HashMap<String, CreateTypedResourceFileAction>();
|
||||
private final DeviceConfiguratorPanel myDeviceConfiguratorPanel;
|
||||
private final AndroidFacet myFacet;
|
||||
private final ResourceType myPredefinedResourceType;
|
||||
|
||||
public CreateResourceDialog(@NotNull AndroidFacet facet,
|
||||
Collection<CreateTypedResourceFileAction> actions,
|
||||
@Nullable ResourceType predefinedResourceType,
|
||||
@Nullable String predefinedFileName,
|
||||
boolean chooseFileName,
|
||||
@NotNull Module module,
|
||||
boolean chooseModule) {
|
||||
super(facet.getModule().getProject());
|
||||
myFacet = facet;
|
||||
myPredefinedResourceType = predefinedResourceType;
|
||||
|
||||
myResTypeLabel.setLabelFor(myResourceTypeCombo);
|
||||
myResourceTypeCombo.registerUpDownHint(myFileNameField);
|
||||
myUpDownHint.setIcon(PlatformIcons.UP_DOWN_ARROWS);
|
||||
@@ -137,7 +141,7 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
myDeviceConfiguratorPanel.applyEditors();
|
||||
updateRootElementCombo();
|
||||
updateRootElementTextField();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -153,8 +157,10 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
if (predefinedFileName != null) {
|
||||
myFileNameField.setVisible(false);
|
||||
myFileNameLabel.setVisible(false);
|
||||
if (!chooseFileName) {
|
||||
myFileNameField.setVisible(false);
|
||||
myFileNameLabel.setVisible(false);
|
||||
}
|
||||
myFileNameField.setText(predefinedFileName);
|
||||
}
|
||||
|
||||
@@ -183,11 +189,13 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
myDeviceConfiguratorPanel.updateAll();
|
||||
myDeviceConfiguratorWrapper.add(myDeviceConfiguratorPanel, BorderLayout.CENTER);
|
||||
setOKActionEnabled(myDirectoryNameTextField.getText().length() > 0);
|
||||
updateRootElementCombo();
|
||||
updateRootElementTextField();
|
||||
init();
|
||||
|
||||
setTitle(AndroidBundle.message("new.resource.dialog.title"));
|
||||
}
|
||||
|
||||
private void updateRootElementCombo() {
|
||||
private void updateRootElementTextField() {
|
||||
final CreateTypedResourceFileAction action = getSelectedAction();
|
||||
|
||||
if (action != null) {
|
||||
@@ -195,12 +203,19 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
myRootElementField = new TextFieldWithAutoCompletion<String>(
|
||||
myFacet.getModule().getProject(), new TextFieldWithAutoCompletion.StringsCompletionProvider(allowedTagNames, null), true);
|
||||
myRootElementField.setEnabled(allowedTagNames.size() > 1);
|
||||
myRootElementField.setText(!action.isChooseTagName() ? action.getDefaultRootTag() : "");
|
||||
myRootElementField.setText(!action.isChooseTagName() && myPredefinedResourceType != ResourceType.LAYOUT
|
||||
? action.getDefaultRootTag()
|
||||
: "");
|
||||
myRootElementFieldWrapper.removeAll();
|
||||
myRootElementFieldWrapper.add(myRootElementField, BorderLayout.CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFileName() {
|
||||
return myFileNameField.getText().trim();
|
||||
}
|
||||
|
||||
private static boolean containsElement(@NotNull ListModel model, @NotNull Object objectToFind) {
|
||||
for (int i = 0, n = model.getSize(); i < n; i++) {
|
||||
if (objectToFind.equals(model.getElementAt(i))) {
|
||||
@@ -232,7 +247,10 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
final String subdirName = getSubdirName();
|
||||
assert subdirName.length() > 0;
|
||||
if (subdirName.length() == 0) {
|
||||
Messages.showErrorDialog(myPanel, AndroidBundle.message("directory.not.specified.error"), CommonBundle.getErrorTitle());
|
||||
return;
|
||||
}
|
||||
myValidator = createValidator(subdirName);
|
||||
if (myValidator == null || myValidator.checkInput(fileName) && myValidator.canClose(fileName)) {
|
||||
super.doOKAction();
|
||||
@@ -266,7 +284,7 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
if (myFileNameField.isVisible()) {
|
||||
if (myFileNameField.getText().length() == 0) {
|
||||
return myFileNameField;
|
||||
}
|
||||
else if (myResourceTypeCombo.isVisible()) {
|
||||
@@ -275,7 +293,10 @@ public class CreateResourceDialog extends DialogWrapper {
|
||||
else if (myModuleCombo.isVisible()) {
|
||||
return myModuleCombo;
|
||||
}
|
||||
return myDeviceConfiguratorPanel.getAvailableQualifiersList();
|
||||
else if (myRootElementFieldWrapper.isVisible()) {
|
||||
return myRootElementField;
|
||||
}
|
||||
return myDirectoryNameTextField;
|
||||
}
|
||||
|
||||
public CreateTypedResourceFileAction getSelectedAction() {
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.InputValidator;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -90,39 +91,48 @@ public class CreateResourceFileAction extends CreateElementActionBase {
|
||||
});
|
||||
}
|
||||
|
||||
// must be invoked in a write action
|
||||
public static PsiElement[] createResourceFile(final Project project,
|
||||
@NotNull AndroidFacet facet,
|
||||
@NotNull
|
||||
public static PsiElement[] createFileResource(@NotNull AndroidFacet facet,
|
||||
@NotNull final ResourceType resType,
|
||||
@NotNull String resName,
|
||||
boolean chooseDirectory) {
|
||||
boolean chooseResName) {
|
||||
final CreateResourceFileAction action = getInstance();
|
||||
String subdirName = resType.getName();
|
||||
VirtualFile resourceDir = facet.getLocalResourceManager().getResourceDir();
|
||||
|
||||
if (chooseDirectory) {
|
||||
final MyDialog dialog = new MyDialog(facet, action.mySubactions.values(), resType, resName, action, facet.getModule(), true);
|
||||
dialog.setTitle(AndroidBundle.message("new.resource.dialog.title"));
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) {
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
subdirName = dialog.getSubdirName();
|
||||
final AndroidFacet selectedFacet = AndroidFacet.getInstance(dialog.getSelectedModule());
|
||||
LOG.assertTrue(selectedFacet != null);
|
||||
resourceDir = selectedFacet.getLocalResourceManager().getResourceDir();
|
||||
final MyDialog dialog =
|
||||
new MyDialog(facet, action.mySubactions.values(), resType, resName, chooseResName, action, facet.getModule(), true);
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) {
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
if (resourceDir != null) {
|
||||
final PsiDirectory psiResDir = PsiManager.getInstance(project).findDirectory(resourceDir);
|
||||
if (psiResDir != null) {
|
||||
CreateElementActionBase.MyInputValidator validator = action.createValidator(project, psiResDir, subdirName);
|
||||
if (validator.checkInput(resName) && validator.canClose(resName)) {
|
||||
return validator.getCreatedElements();
|
||||
}
|
||||
}
|
||||
if (chooseResName) {
|
||||
resName = dialog.getFileName();
|
||||
}
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
final String subdirName = dialog.getSubdirName();
|
||||
final AndroidFacet selectedFacet = AndroidFacet.getInstance(dialog.getSelectedModule());
|
||||
LOG.assertTrue(selectedFacet != null);
|
||||
|
||||
final VirtualFile resourceDir = selectedFacet.getLocalResourceManager().getResourceDir();
|
||||
final Project project = facet.getModule().getProject();
|
||||
final PsiDirectory psiResDir = resourceDir != null ? PsiManager.getInstance(project).findDirectory(resourceDir) : null;
|
||||
|
||||
if (psiResDir == null) {
|
||||
Messages.showErrorDialog(project, "Cannot find resource directory for module " + selectedFacet.getModule().getName(),
|
||||
CommonBundle.getErrorTitle());
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
final String finalResName = resName;
|
||||
|
||||
final PsiElement[] elements = ApplicationManager.getApplication().runWriteAction(new Computable<PsiElement[]>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement[] compute() {
|
||||
MyInputValidator validator = action.createValidator(project, psiResDir, subdirName);
|
||||
return validator.checkInput(finalResName) && validator.canClose(finalResName)
|
||||
? validator.getCreatedElements()
|
||||
: null;
|
||||
}
|
||||
});
|
||||
return elements != null ? elements : PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -131,13 +141,13 @@ public class CreateResourceFileAction extends CreateElementActionBase {
|
||||
final AndroidFacet facet = AndroidFacet.getInstance(directory);
|
||||
LOG.assertTrue(facet != null);
|
||||
|
||||
MyDialog dialog = new MyDialog(facet, mySubactions.values(), null, null, CreateResourceFileAction.this, facet.getModule(), false) {
|
||||
final MyDialog dialog =
|
||||
new MyDialog(facet, mySubactions.values(), null, null, true, CreateResourceFileAction.this, facet.getModule(), false) {
|
||||
@Override
|
||||
protected InputValidator createValidator(@NotNull String subdirName) {
|
||||
return CreateResourceFileAction.this.createValidator(project, directory, subdirName);
|
||||
}
|
||||
};
|
||||
dialog.setTitle(AndroidBundle.message("new.resource.dialog.title"));
|
||||
dialog.show();
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
}
|
||||
@@ -159,8 +169,11 @@ public class CreateResourceFileAction extends CreateElementActionBase {
|
||||
@Override
|
||||
protected PsiElement[] create(String newName, PsiDirectory directory) throws Exception {
|
||||
CreateTypedResourceFileAction action = getActionByDir(directory);
|
||||
if (action == null) {
|
||||
throw new IllegalArgumentException("Incorrect directory");
|
||||
}
|
||||
if (myRootElement != null && myRootElement.length() > 0) {
|
||||
return action.doCreate(newName, directory, myRootElement, false);
|
||||
return action.doCreateAndNavigate(newName, directory, myRootElement, false);
|
||||
}
|
||||
return action.create(newName, directory);
|
||||
}
|
||||
@@ -204,10 +217,11 @@ public class CreateResourceFileAction extends CreateElementActionBase {
|
||||
Collection<CreateTypedResourceFileAction> actions,
|
||||
@Nullable ResourceType predefinedResourceType,
|
||||
@Nullable String predefinedFileName,
|
||||
boolean chooseFileName,
|
||||
@NotNull CreateResourceFileAction action,
|
||||
@NotNull Module module,
|
||||
boolean chooseModule) {
|
||||
super(facet, actions, predefinedResourceType, predefinedFileName, module, chooseModule);
|
||||
super(facet, actions, predefinedResourceType, predefinedFileName, chooseFileName, module, chooseModule);
|
||||
myAction = action;
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.android.actions;
|
||||
|
||||
import com.android.resources.ResourceFolderType;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import org.jetbrains.android.dom.animation.AndroidAnimationUtils;
|
||||
import org.jetbrains.android.dom.animator.AndroidAnimatorUtil;
|
||||
@@ -40,7 +41,7 @@ public class CreateResourceFileActionGroup extends DefaultActionGroup {
|
||||
CreateResourceFileAction a = new CreateResourceFileAction();
|
||||
a.add(new AndroidCreateLayoutFileAction());
|
||||
|
||||
a.add(new CreateTypedResourceFileAction("XML", "xml", "PreferenceScreen", false, true) {
|
||||
a.add(new CreateTypedResourceFileAction("XML", ResourceFolderType.XML, false, true) {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getAllowedTagNames(@NotNull AndroidFacet facet) {
|
||||
@@ -48,7 +49,7 @@ public class CreateResourceFileActionGroup extends DefaultActionGroup {
|
||||
}
|
||||
});
|
||||
|
||||
a.add(new CreateTypedResourceFileAction("Drawable", "drawable", "selector", false, true) {
|
||||
a.add(new CreateTypedResourceFileAction("Drawable", ResourceFolderType.DRAWABLE, false, true) {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getAllowedTagNames(@NotNull AndroidFacet facet) {
|
||||
@@ -56,11 +57,11 @@ public class CreateResourceFileActionGroup extends DefaultActionGroup {
|
||||
}
|
||||
});
|
||||
|
||||
a.add(new CreateTypedResourceFileAction("Color", "color", "selector", false, false));
|
||||
a.add(new CreateTypedResourceFileAction("Values", "values", "resources", true, false));
|
||||
a.add(new CreateTypedResourceFileAction("Menu", "menu", "menu", false, false));
|
||||
a.add(new CreateTypedResourceFileAction("Color", ResourceFolderType.COLOR, false, false));
|
||||
a.add(new CreateTypedResourceFileAction("Values", ResourceFolderType.VALUES, true, false));
|
||||
a.add(new CreateTypedResourceFileAction("Menu", ResourceFolderType.MENU, false, false));
|
||||
|
||||
a.add(new CreateTypedResourceFileAction("Animation", "anim", "set", false, true) {
|
||||
a.add(new CreateTypedResourceFileAction("Animation", ResourceFolderType.ANIM, false, true) {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getAllowedTagNames(@NotNull AndroidFacet facet) {
|
||||
@@ -68,7 +69,7 @@ public class CreateResourceFileActionGroup extends DefaultActionGroup {
|
||||
}
|
||||
});
|
||||
|
||||
a.add(new CreateTypedResourceFileAction("Animator", "animator", "set", false, true) {
|
||||
a.add(new CreateTypedResourceFileAction("Animator", ResourceFolderType.ANIMATOR, false, true) {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getAllowedTagNames(@NotNull AndroidFacet facet) {
|
||||
|
||||
+36
-36
@@ -16,11 +16,9 @@
|
||||
|
||||
package org.jetbrains.android.actions;
|
||||
|
||||
import com.android.resources.ResourceFolderType;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.actions.CreateElementActionBase;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateUtil;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -38,7 +36,6 @@ import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.PsiNavigateUtil;
|
||||
import com.intellij.xml.refactoring.XmlTagInplaceRenamer;
|
||||
import org.jetbrains.android.AndroidFileTemplateProvider;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.util.AndroidBundle;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
@@ -48,36 +45,33 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class CreateTypedResourceFileAction extends CreateElementActionBase {
|
||||
static final String ROOT_TAG_PROPERTY = "ROOT_TAG";
|
||||
|
||||
private final String myResourceType;
|
||||
private final ResourceFolderType myResourceType;
|
||||
private final String myResourcePresentableName;
|
||||
protected final String myDefaultRootTag;
|
||||
private final boolean myValuesResourceFile;
|
||||
private final boolean myChooseTagName;
|
||||
|
||||
public CreateTypedResourceFileAction(@NotNull String resourcePresentableName,
|
||||
@NotNull String resourceType,
|
||||
@NotNull String defaultRootTag,
|
||||
@NotNull ResourceFolderType resourceFolderType,
|
||||
boolean valuesResourceFile,
|
||||
boolean chooseTagName) {
|
||||
super(AndroidBundle.message("new.typed.resource.action.title", resourcePresentableName),
|
||||
AndroidBundle.message("new.typed.resource.action.description", resourcePresentableName), StdFileTypes.XML.getIcon());
|
||||
myResourceType = resourceType;
|
||||
myResourceType = resourceFolderType;
|
||||
myResourcePresentableName = resourcePresentableName;
|
||||
myDefaultRootTag = defaultRootTag;
|
||||
myDefaultRootTag = getDefaultRootTabByResourceType(resourceFolderType);
|
||||
myValuesResourceFile = valuesResourceFile;
|
||||
myChooseTagName = chooseTagName;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myResourceType;
|
||||
return myResourceType.getName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -93,20 +87,12 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PsiElement[] create(String newName, PsiDirectory directory) throws Exception {
|
||||
return doCreate(newName, directory, myDefaultRootTag, myChooseTagName);
|
||||
return doCreateAndNavigate(newName, directory, myDefaultRootTag, myChooseTagName);
|
||||
}
|
||||
|
||||
PsiElement[] doCreate(String newName, PsiDirectory directory, String rootTagName, boolean chooseTagName) throws Exception {
|
||||
FileTemplateManager manager = FileTemplateManager.getInstance();
|
||||
String templateName = getTemplateName();
|
||||
FileTemplate template = manager.getJ2eeTemplate(templateName);
|
||||
Properties properties = new Properties();
|
||||
if (!myValuesResourceFile) {
|
||||
properties.setProperty(ROOT_TAG_PROPERTY, rootTagName);
|
||||
}
|
||||
PsiElement createdElement = FileTemplateUtil.createFromTemplate(template, newName, properties, directory);
|
||||
assert createdElement instanceof XmlFile;
|
||||
final XmlFile file = (XmlFile)createdElement;
|
||||
PsiElement[] doCreateAndNavigate(String newName, PsiDirectory directory, String rootTagName, boolean chooseTagName) throws Exception {
|
||||
final XmlFile file = AndroidResourceUtil
|
||||
.createFileResource(newName, directory, rootTagName, myResourceType.getName(), myValuesResourceFile);
|
||||
doNavigate(file);
|
||||
|
||||
if (chooseTagName) {
|
||||
@@ -124,26 +110,16 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PsiElement[]{createdElement};
|
||||
return new PsiElement[]{file};
|
||||
}
|
||||
|
||||
protected void doNavigate(XmlFile file) {
|
||||
PsiNavigateUtil.navigate(file);
|
||||
}
|
||||
|
||||
private String getTemplateName() {
|
||||
if (myValuesResourceFile) {
|
||||
return AndroidFileTemplateProvider.VALUE_RESOURCE_FILE_TEMPLATE;
|
||||
}
|
||||
if ("layout".equals(myResourceType)) {
|
||||
return AndroidFileTemplateProvider.LAYOUT_RESOURCE_FILE_TEMPLATE;
|
||||
}
|
||||
return AndroidFileTemplateProvider.RESOURCE_FILE_TEMPLATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAvailable(DataContext context) {
|
||||
return super.isAvailable(context) && doIsAvailable(context, myResourceType);
|
||||
return super.isAvailable(context) && doIsAvailable(context, myResourceType.getName());
|
||||
}
|
||||
|
||||
public boolean isChooseTagName() {
|
||||
@@ -202,4 +178,28 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase {
|
||||
public String toString() {
|
||||
return myResourcePresentableName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getDefaultRootTabByResourceType(@NotNull ResourceFolderType resourceType) {
|
||||
switch (resourceType) {
|
||||
case XML:
|
||||
return "PreferenceScreen";
|
||||
case DRAWABLE:
|
||||
return "selector";
|
||||
case COLOR:
|
||||
return "selector";
|
||||
case VALUES:
|
||||
return "resources";
|
||||
case MENU:
|
||||
return "menu";
|
||||
case ANIM:
|
||||
return "set";
|
||||
case ANIMATOR:
|
||||
return "set";
|
||||
case LAYOUT:
|
||||
return "LinearLayout";
|
||||
default:
|
||||
}
|
||||
throw new IllegalArgumentException("Incorrect resource folder type");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,13 +83,16 @@ public class CreateXmlResourceDialog extends DialogWrapper {
|
||||
public CreateXmlResourceDialog(@NotNull Module module,
|
||||
@NotNull ResourceType resourceType,
|
||||
@Nullable String predefinedName,
|
||||
@Nullable String predefinedValue) {
|
||||
@Nullable String predefinedValue,
|
||||
boolean chooseName) {
|
||||
super(module.getProject());
|
||||
myResourceType = resourceType;
|
||||
|
||||
if (predefinedName != null && predefinedName.length() > 0) {
|
||||
myNameLabel.setVisible(false);
|
||||
myNameField.setVisible(false);
|
||||
if (!chooseName) {
|
||||
myNameLabel.setVisible(false);
|
||||
myNameField.setVisible(false);
|
||||
}
|
||||
myNameField.setText(predefinedName);
|
||||
}
|
||||
|
||||
@@ -390,7 +393,7 @@ public class CreateXmlResourceDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myNameField.isVisible() ? myNameField : myValueField;
|
||||
return myNameField.getText().length() == 0 ? myNameField : myValueField;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-181
@@ -15,38 +15,26 @@
|
||||
*/
|
||||
package org.jetbrains.android.dom.converters;
|
||||
|
||||
import com.android.AndroidConstants;
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.*;
|
||||
import org.jetbrains.android.actions.CreateXmlResourceDialog;
|
||||
import org.jetbrains.android.dom.AdditionalConverter;
|
||||
import org.jetbrains.android.dom.AndroidResourceType;
|
||||
import org.jetbrains.android.dom.resources.Item;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.resources.ResourceValue;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.inspections.CreateFileResourceQuickFix;
|
||||
import org.jetbrains.android.inspections.CreateValueResourceQuickFix;
|
||||
import org.jetbrains.android.resourceManagers.LocalResourceManager;
|
||||
import org.jetbrains.android.resourceManagers.ResourceManager;
|
||||
import org.jetbrains.android.util.AndroidBundle;
|
||||
import org.jetbrains.android.util.AndroidCommonUtils;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -61,11 +49,6 @@ import static org.jetbrains.android.util.AndroidUtils.SYSTEM_RESOURCE_PACKAGE;
|
||||
* @author yole
|
||||
*/
|
||||
public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue> implements CustomReferenceConverter<ResourceValue> {
|
||||
private static final Set<ResourceType> XML_FILE_RESOURCE_TYPES = EnumSet.of(ResourceType.ANIM, ResourceType.ANIMATOR,
|
||||
ResourceType.INTERPOLATOR, ResourceType.LAYOUT,
|
||||
ResourceType.MENU, ResourceType.XML, ResourceType.COLOR,
|
||||
ResourceType.DRAWABLE);
|
||||
|
||||
private final List<String> myResourceTypes;
|
||||
private ResolvingConverter<String> myAdditionalConverter;
|
||||
private boolean myAdditionalConverterSoft = false;
|
||||
@@ -313,10 +296,10 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
final List<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
|
||||
|
||||
if (AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(resType)) {
|
||||
fixes.add(new MyCreateValueResourceQuickFix(facet, resType, resourceName, context.getFile()));
|
||||
fixes.add(new CreateValueResourceQuickFix(facet, resType, resourceName, context.getFile(), false));
|
||||
}
|
||||
if (XML_FILE_RESOURCE_TYPES.contains(resType)) {
|
||||
fixes.add(new MyCreateFileResourceQuickFix(facet, resType, resourceName, context.getFile()));
|
||||
if (AndroidResourceUtil.XML_FILE_RESOURCE_TYPES.contains(resType)) {
|
||||
fixes.add(new CreateFileResourceQuickFix(facet, resType, resourceName, context.getFile(), false));
|
||||
}
|
||||
return fixes.toArray(new LocalQuickFix[fixes.size()]);
|
||||
}
|
||||
@@ -350,163 +333,4 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
}
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public static class MyCreateValueResourceQuickFix implements LocalQuickFix, IntentionAction {
|
||||
private final AndroidFacet myFacet;
|
||||
private final ResourceType myResourceType;
|
||||
private final String myResourceName;
|
||||
private final PsiFile myFile;
|
||||
|
||||
public MyCreateValueResourceQuickFix(@NotNull AndroidFacet facet,
|
||||
@NotNull ResourceType resourceType,
|
||||
@NotNull String resourceName,
|
||||
@NotNull PsiFile file) {
|
||||
myFacet = facet;
|
||||
myResourceType = resourceType;
|
||||
myResourceName = resourceName;
|
||||
myFile = file;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return AndroidBundle.message("create.value.resource.quickfix.name", myResourceName,
|
||||
AndroidResourceUtil.getDefaultResourceFileName(myResourceType.getName()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return AndroidBundle.message("create.value.resource.intention.name", myResourceType, myResourceName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return AndroidBundle.message("quick.fixes.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
final String fileName = AndroidResourceUtil.getDefaultResourceFileName(myResourceType.getName());
|
||||
assert fileName != null;
|
||||
|
||||
if (!AndroidResourceUtil.createValueResource(myFacet.getModule(), myResourceName, myResourceType,
|
||||
fileName, Collections.singletonList(AndroidConstants.FD_RES_VALUES), "a")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
final CreateXmlResourceDialog dialog = new CreateXmlResourceDialog(myFacet.getModule(), myResourceType, myResourceName, null);
|
||||
dialog.setTitle("New " + StringUtil.capitalize(myResourceType.getDisplayName()) + " Value Resource");
|
||||
dialog.show();
|
||||
|
||||
if (!dialog.isOK()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Module moduleToPlaceResource = dialog.getModule();
|
||||
if (moduleToPlaceResource == null) {
|
||||
return;
|
||||
}
|
||||
if (!AndroidResourceUtil.createValueResource(moduleToPlaceResource, dialog.getResourceName(), myResourceType,
|
||||
dialog.getFileName(), dialog.getDirNames(), dialog.getValue())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
UndoUtil.markPsiFileForUndo(file);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
// simplified resource creating for batch mode
|
||||
LocalResourceManager manager = myFacet.getLocalResourceManager();
|
||||
|
||||
String initialValue = !myResourceType.equals(ResourceType.ID) ? "value" : null;
|
||||
ResourceElement resElement = manager.addValueResource(myResourceType.getName(), myResourceName, initialValue);
|
||||
if (resElement != null) {
|
||||
if (!(resElement instanceof Item)) {
|
||||
// then it is ID
|
||||
List<ResourceElement> list = manager.findValueResources(myResourceType.getName(), myResourceName);
|
||||
if (list.size() == 1) {
|
||||
ResourceElement element = list.get(0);
|
||||
XmlTag tag = element.getXmlTag();
|
||||
tag.getValue().setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
UndoUtil.markPsiFileForUndo(myFile);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyCreateFileResourceQuickFix implements LocalQuickFix, IntentionAction {
|
||||
private final AndroidFacet myFacet;
|
||||
private final ResourceType myResourceType;
|
||||
private final String myResourceName;
|
||||
private final PsiFile myFile;
|
||||
|
||||
public MyCreateFileResourceQuickFix(@NotNull AndroidFacet facet,
|
||||
@NotNull ResourceType resourceType,
|
||||
@NotNull String resourceName,
|
||||
@NotNull PsiFile file) {
|
||||
myFacet = facet;
|
||||
myResourceType = resourceType;
|
||||
myResourceName = resourceName;
|
||||
myFile = file;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return AndroidBundle.message("create.file.resource.quickfix.name", myResourceName,
|
||||
'\'' + myResourceType.getName() + "' directory");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return AndroidBundle.message("create.file.resource.intention.name", myResourceType, myResourceName + ".xml");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return AndroidBundle.message("quick.fixes.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
// simplified resource creating for batch mode
|
||||
myFacet.getLocalResourceManager().addResourceFileAndNavigate(myResourceName, myResourceType, true);
|
||||
UndoUtil.markPsiFileForUndo(myFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
// simplified resource creating for batch mode
|
||||
myFacet.getLocalResourceManager().addResourceFileAndNavigate(myResourceName, myResourceType, false);
|
||||
UndoUtil.markPsiFileForUndo(myFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.jetbrains.android.inspections;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
|
||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import org.jetbrains.android.dom.manifest.Manifest;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class AndroidQuickFixProvider extends UnresolvedReferenceQuickFixProvider<PsiReferenceExpression> {
|
||||
@Override
|
||||
public void registerFixes(PsiReferenceExpression exp, QuickFixActionRegistrar registrar) {
|
||||
final Module contextModule = ModuleUtil.findModuleForPsiElement(exp);
|
||||
if (contextModule == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final AndroidFacet facet = AndroidFacet.getInstance(contextModule);
|
||||
if (facet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Manifest manifest = facet.getManifest();
|
||||
if (manifest == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String aPackage = manifest.getPackage().getValue();
|
||||
if (aPackage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiFile contextFile = exp.getContainingFile();
|
||||
if (contextFile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Pair<String, String> pair = AndroidResourceUtil.getReferredResourceField(facet, exp);
|
||||
if (pair == null) {
|
||||
return;
|
||||
}
|
||||
final String resClassName = pair.getFirst();
|
||||
final String resFieldName = pair.getSecond();
|
||||
|
||||
final ResourceType resourceType = ResourceType.getEnum(resClassName);
|
||||
if (resourceType == ResourceType.STYLEABLE || resourceType == ResourceType.ATTR) {
|
||||
// todo: support
|
||||
return;
|
||||
}
|
||||
|
||||
if (AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(resourceType)) {
|
||||
registrar
|
||||
.register(new CreateValueResourceQuickFix(facet, resourceType, resFieldName, contextFile, true));
|
||||
}
|
||||
if (AndroidResourceUtil.XML_FILE_RESOURCE_TYPES.contains(resourceType)) {
|
||||
registrar.register(new CreateFileResourceQuickFix(facet, resourceType, resFieldName, contextFile, true));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Class<PsiReferenceExpression> getReferenceClass() {
|
||||
return PsiReferenceExpression.class;
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package org.jetbrains.android.inspections;
|
||||
|
||||
import com.android.resources.ResourceFolderType;
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.android.actions.CreateResourceFileAction;
|
||||
import org.jetbrains.android.actions.CreateTypedResourceFileAction;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.util.AndroidBundle;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class CreateFileResourceQuickFix implements LocalQuickFix, IntentionAction, HighPriorityAction {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.inspections.CreateFileResourceQuickFix");
|
||||
|
||||
private final AndroidFacet myFacet;
|
||||
private final ResourceType myResourceType;
|
||||
private final String myResourceName;
|
||||
private final PsiFile myFile;
|
||||
private final boolean myChooseResName;
|
||||
|
||||
public CreateFileResourceQuickFix(@NotNull AndroidFacet facet,
|
||||
@NotNull ResourceType resourceType,
|
||||
@NotNull String resourceName,
|
||||
@NotNull PsiFile file,
|
||||
boolean chooseResName) {
|
||||
myFacet = facet;
|
||||
myResourceType = resourceType;
|
||||
myResourceName = resourceName;
|
||||
myFile = file;
|
||||
myChooseResName = chooseResName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return AndroidBundle.message("create.file.resource.quickfix.name", myResourceName,
|
||||
'\'' + myResourceType.getName() + "' directory");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return AndroidBundle.message("create.file.resource.intention.name", myResourceType, myResourceName + ".xml");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return AndroidBundle.message("quick.fixes.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
final PsiElement[] createdElements =
|
||||
CreateResourceFileAction.createFileResource(myFacet, myResourceType, myResourceName + ".xml", myChooseResName);
|
||||
if (createdElements.length > 0) {
|
||||
UndoUtil.markPsiFileForUndo(myFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final VirtualFile resourceDir = myFacet.getLocalResourceManager().getResourceDir();
|
||||
if (resourceDir == null) {
|
||||
return;
|
||||
}
|
||||
final PsiDirectory psiResDir = PsiManager.getInstance(project).findDirectory(resourceDir);
|
||||
if (psiResDir == null) {
|
||||
return;
|
||||
}
|
||||
final String resDirName = myResourceType.getName();
|
||||
PsiDirectory resSubdir = psiResDir.findSubdirectory(resDirName);
|
||||
|
||||
if (resSubdir == null) {
|
||||
resSubdir = ApplicationManager.getApplication().runWriteAction(new Computable<PsiDirectory>() {
|
||||
public PsiDirectory compute() {
|
||||
return psiResDir.createSubdirectory(resDirName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
AndroidResourceUtil.createFileResource(myResourceName, resSubdir, CreateTypedResourceFileAction.getDefaultRootTabByResourceType(
|
||||
ResourceFolderType.getFolderType(resDirName)), resDirName, false);
|
||||
UndoUtil.markPsiFileForUndo(myFile);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package org.jetbrains.android.inspections;
|
||||
|
||||
import com.android.AndroidConstants;
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.android.actions.CreateXmlResourceDialog;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.util.AndroidBundle;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class CreateValueResourceQuickFix implements LocalQuickFix, IntentionAction, HighPriorityAction {
|
||||
private final AndroidFacet myFacet;
|
||||
private final ResourceType myResourceType;
|
||||
private final String myResourceName;
|
||||
private final PsiFile myFile;
|
||||
private final boolean myChooseName;
|
||||
|
||||
public CreateValueResourceQuickFix(@NotNull AndroidFacet facet,
|
||||
@NotNull ResourceType resourceType,
|
||||
@NotNull String resourceName,
|
||||
@NotNull PsiFile file,
|
||||
boolean chooseName) {
|
||||
myFacet = facet;
|
||||
myResourceType = resourceType;
|
||||
myResourceName = resourceName;
|
||||
myFile = file;
|
||||
myChooseName = chooseName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return AndroidBundle.message("create.value.resource.quickfix.name", myResourceName,
|
||||
AndroidResourceUtil.getDefaultResourceFileName(myResourceType.getName()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return AndroidBundle.message("create.value.resource.intention.name", myResourceType, myResourceName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return AndroidBundle.message("quick.fixes.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
doInvoke();
|
||||
}
|
||||
|
||||
protected boolean doInvoke() {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
final String fileName = AndroidResourceUtil.getDefaultResourceFileName(myResourceType.getName());
|
||||
assert fileName != null;
|
||||
|
||||
if (!AndroidResourceUtil.createValueResource(myFacet.getModule(), myResourceName, myResourceType, fileName,
|
||||
Collections.singletonList(AndroidConstants.FD_RES_VALUES), "a")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
final CreateXmlResourceDialog dialog = new CreateXmlResourceDialog(myFacet.getModule(), myResourceType, myResourceName, null,
|
||||
myChooseName);
|
||||
dialog.setTitle("New " + StringUtil.capitalize(myResourceType.getDisplayName()) + " Value Resource");
|
||||
dialog.show();
|
||||
|
||||
if (!dialog.isOK()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Module moduleToPlaceResource = dialog.getModule();
|
||||
if (moduleToPlaceResource == null) {
|
||||
return false;
|
||||
}
|
||||
final String fileName = dialog.getFileName();
|
||||
final List<String> dirNames = dialog.getDirNames();
|
||||
final String resValue = dialog.getValue();
|
||||
final String resName = dialog.getResourceName();
|
||||
if (!AndroidResourceUtil.createValueResource(moduleToPlaceResource, resName, myResourceType, fileName, dirNames, resValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
PsiDocumentManager.getInstance(myFile.getProject()).commitAllDocuments();
|
||||
UndoUtil.markPsiFileForUndo(myFile);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
// todo: implement local fix
|
||||
}
|
||||
}
|
||||
+2
-35
@@ -35,10 +35,8 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
@@ -180,7 +178,7 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction impl
|
||||
}
|
||||
|
||||
if (resName == null) {
|
||||
final CreateXmlResourceDialog dialog = new CreateXmlResourceDialog(facet.getModule(), ResourceType.STRING, null, value);
|
||||
final CreateXmlResourceDialog dialog = new CreateXmlResourceDialog(facet.getModule(), ResourceType.STRING, null, value, false);
|
||||
dialog.setTitle("Extract String Resource");
|
||||
dialog.show();
|
||||
|
||||
@@ -244,7 +242,7 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction impl
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
createStubResourceField(module, aPackage, resType, rJavaFieldName);
|
||||
AndroidResourceUtil.createStubResourceField(module, aPackage, resType, rJavaFieldName);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -292,37 +290,6 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction impl
|
||||
});
|
||||
}
|
||||
|
||||
private static void createStubResourceField(final Module module,
|
||||
final String aPackage,
|
||||
final String resType,
|
||||
final String fieldName) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Project project = module.getProject();
|
||||
final PsiClass[] classes =
|
||||
JavaPsiFacade.getInstance(project).findClasses(aPackage + ".R", GlobalSearchScope.moduleScope(module));
|
||||
if (classes.length == 1) {
|
||||
final PsiClass aClass = classes[0];
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
|
||||
PsiClass resTypeClass = aClass.findInnerClassByName(resType, false);
|
||||
|
||||
if (resTypeClass == null) {
|
||||
resTypeClass = (PsiClass)aClass.add(factory.createClass(resType));
|
||||
}
|
||||
else if (resTypeClass.findFieldByName(fieldName, false) != null) {
|
||||
return;
|
||||
}
|
||||
final PsiField psiField = (PsiField)resTypeClass.add(factory.createField(fieldName, PsiType.INT));
|
||||
PsiUtil.setModifierProperty(psiField, PsiModifier.PUBLIC, true);
|
||||
PsiUtil.setModifierProperty(psiField, PsiModifier.STATIC, true);
|
||||
PsiUtil.setModifierProperty(psiField, PsiModifier.FINAL, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPackage(@NotNull AndroidFacet facet) {
|
||||
Manifest manifest = facet.getManifest();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.android.newProject;
|
||||
|
||||
import com.android.AndroidConstants;
|
||||
import com.android.resources.ResourceType;
|
||||
import com.android.sdklib.IAndroidTarget;
|
||||
import com.android.sdklib.SdkConstants;
|
||||
import com.intellij.CommonBundle;
|
||||
@@ -78,6 +79,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
@@ -425,7 +427,10 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
|
||||
final String normalizedAppName = AndroidResourceUtil.normalizeXmlResourceValue(myApplicationName.replace("\\", "\\\\"));
|
||||
|
||||
if (appNameResElement == null) {
|
||||
manager.addValueResource("string", appNameResource, normalizedAppName);
|
||||
final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STRING.getName());
|
||||
assert fileName != null;
|
||||
AndroidResourceUtil.createValueResource(facet.getModule(), appNameResource, ResourceType.STRING, fileName, Collections
|
||||
.singletonList(AndroidConstants.FD_RES_VALUES), normalizedAppName);
|
||||
}
|
||||
else {
|
||||
appNameResElement.setStringValue(normalizedAppName);
|
||||
|
||||
@@ -22,10 +22,8 @@ import com.intellij.CommonBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -33,13 +31,11 @@ import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import org.jetbrains.android.AndroidFileTemplateProvider;
|
||||
import org.jetbrains.android.AndroidValueResourcesIndex;
|
||||
import org.jetbrains.android.actions.CreateResourceFileAction;
|
||||
import org.jetbrains.android.dom.attrs.AttributeDefinitions;
|
||||
import org.jetbrains.android.dom.resources.Attr;
|
||||
import org.jetbrains.android.dom.resources.DeclareStyleable;
|
||||
@@ -57,8 +53,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.android.util.AndroidUtils.loadDomElement;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
@@ -263,50 +257,6 @@ public class LocalResourceManager extends ResourceManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
// must be invoked in a write action
|
||||
@Nullable
|
||||
public VirtualFile addResourceFileAndNavigate(@NotNull final String fileOrResourceName,
|
||||
@NotNull ResourceType resType,
|
||||
boolean chooseDirectory) {
|
||||
Project project = myModule.getProject();
|
||||
PsiElement[] createdElements =
|
||||
CreateResourceFileAction.createResourceFile(project, myFacet, resType, fileOrResourceName, chooseDirectory);
|
||||
if (createdElements.length == 0) return null;
|
||||
assert createdElements.length == 1;
|
||||
PsiElement element = createdElements[0];
|
||||
assert element instanceof PsiFile;
|
||||
return ((PsiFile)element).getVirtualFile();
|
||||
}
|
||||
|
||||
// must be invoked in a write action
|
||||
@Nullable
|
||||
public ResourceElement addValueResource(@NotNull final String type, @NotNull final String name, @Nullable final String value) {
|
||||
String resourceFileName = AndroidResourceUtil.getDefaultResourceFileName(type);
|
||||
if (resourceFileName == null) {
|
||||
throw new IllegalArgumentException("Incorrect resource type");
|
||||
}
|
||||
VirtualFile resFile = findOrCreateResourceFile(resourceFileName);
|
||||
if (resFile == null ||
|
||||
!ReadonlyStatusHandler.ensureFilesWritable(myModule.getProject(), resFile)) {
|
||||
return null;
|
||||
}
|
||||
final Resources resources = loadDomElement(myModule, resFile, Resources.class);
|
||||
if (resources == null) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
throw new IncorrectOperationException("invalid strings.xml");
|
||||
}
|
||||
Messages.showErrorDialog(myModule.getProject(), AndroidBundle.message("not.resource.file.error", resourceFileName),
|
||||
CommonBundle.getErrorTitle());
|
||||
return null;
|
||||
}
|
||||
ResourceElement element = AndroidResourceUtil.addValueResource(type, resources);
|
||||
element.getName().setValue(name);
|
||||
if (value != null) {
|
||||
element.setStringValue(value);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VirtualFile findOrCreateChildDir(@NotNull final VirtualFile dir, @NotNull final String name) {
|
||||
try {
|
||||
|
||||
@@ -21,6 +21,9 @@ import com.android.resources.ResourceType;
|
||||
import com.android.sdklib.SdkConstants;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.actions.CreateElementActionBase;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -30,13 +33,17 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModulePackageIndex;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -68,6 +75,11 @@ public class AndroidResourceUtil {
|
||||
ResourceType.ID, ResourceType.BOOL, ResourceType.INTEGER);
|
||||
|
||||
public static final Set<ResourceType> REFERRABLE_RESOURCE_TYPES = EnumSet.noneOf(ResourceType.class);
|
||||
public static final Set<ResourceType> XML_FILE_RESOURCE_TYPES = EnumSet.of(ResourceType.ANIM, ResourceType.ANIMATOR,
|
||||
ResourceType.INTERPOLATOR, ResourceType.LAYOUT,
|
||||
ResourceType.MENU, ResourceType.XML, ResourceType.COLOR,
|
||||
ResourceType.DRAWABLE);
|
||||
static final String ROOT_TAG_PROPERTY = "ROOT_TAG";
|
||||
|
||||
private AndroidResourceUtil() {
|
||||
}
|
||||
@@ -606,11 +618,11 @@ public class AndroidResourceUtil {
|
||||
}
|
||||
|
||||
private static boolean addValueResource(@NotNull AndroidFacet facet,
|
||||
@NotNull String resourceName,
|
||||
@NotNull ResourceType resourceType,
|
||||
@NotNull final String resourceName,
|
||||
@NotNull final ResourceType resourceType,
|
||||
@NotNull String fileName,
|
||||
@NotNull List<String> dirNames,
|
||||
@NotNull String value) throws Exception {
|
||||
@NotNull final String value) throws Exception {
|
||||
if (dirNames.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -638,14 +650,19 @@ public class AndroidResourceUtil {
|
||||
resourcesElements[i] = resources;
|
||||
}
|
||||
|
||||
for (Resources resources : resourcesElements) {
|
||||
final ResourceElement element = addValueResource(resourceType.getName(), resources);
|
||||
element.getName().setValue(resourceName);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Resources resources : resourcesElements) {
|
||||
final ResourceElement element = addValueResource(resourceType.getName(), resources);
|
||||
element.getName().setValue(resourceName);
|
||||
|
||||
if (value.length() > 0) {
|
||||
element.setStringValue(value);
|
||||
if (value.length() > 0) {
|
||||
element.setStringValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -691,4 +708,99 @@ public class AndroidResourceUtil {
|
||||
Messages.showErrorDialog(project, message, CommonBundle.getErrorTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Pair<String, String> getReferredResourceField(@NotNull AndroidFacet facet, @NotNull PsiReferenceExpression exp) {
|
||||
final String resFieldName = exp.getReferenceName();
|
||||
if (resFieldName == null || resFieldName.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiExpression qExp = exp.getQualifierExpression();
|
||||
if (!(qExp instanceof PsiReferenceExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiReferenceExpression resClassReference = (PsiReferenceExpression)qExp;
|
||||
|
||||
final String resClassName = resClassReference.getReferenceName();
|
||||
if (resClassName == null || resClassName.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
qExp = resClassReference.getQualifierExpression();
|
||||
if (!(qExp instanceof PsiReferenceExpression)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiElement resolvedElement = ((PsiReferenceExpression)qExp).resolve();
|
||||
if (!(resolvedElement instanceof PsiClass) ||
|
||||
!AndroidUtils.R_CLASS_NAME.equals(((PsiClass)resolvedElement).getName())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiFile containingFile = resolvedElement.getContainingFile();
|
||||
if (containingFile == null || !isRJavaFile(facet, containingFile)) {
|
||||
return null;
|
||||
}
|
||||
return new Pair<String, String>(resClassName, resFieldName);
|
||||
}
|
||||
|
||||
public static void createStubResourceField(@NotNull final Module module,
|
||||
@NotNull final String aPackage,
|
||||
@NotNull final String resClassName,
|
||||
@NotNull final String resFieldName) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Project project = module.getProject();
|
||||
final PsiClass[] classes =
|
||||
JavaPsiFacade.getInstance(project).findClasses(aPackage + ".R", GlobalSearchScope.moduleScope(module));
|
||||
if (classes.length == 1) {
|
||||
final PsiClass aClass = classes[0];
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
|
||||
PsiClass resTypeClass = aClass.findInnerClassByName(resClassName, false);
|
||||
|
||||
if (resTypeClass == null) {
|
||||
resTypeClass = (PsiClass)aClass.add(factory.createClass(resClassName));
|
||||
}
|
||||
else if (resTypeClass.findFieldByName(resFieldName, false) != null) {
|
||||
return;
|
||||
}
|
||||
final PsiField psiField = (PsiField)resTypeClass.add(factory.createField(resFieldName, PsiType.INT));
|
||||
PsiUtil.setModifierProperty(psiField, PsiModifier.PUBLIC, true);
|
||||
PsiUtil.setModifierProperty(psiField, PsiModifier.STATIC, true);
|
||||
PsiUtil.setModifierProperty(psiField, PsiModifier.FINAL, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static XmlFile createFileResource(@NotNull String fileName,
|
||||
@NotNull PsiDirectory resSubdir,
|
||||
@NotNull String rootTagName,
|
||||
@NotNull String resourceType,
|
||||
boolean valuesResourceFile) throws Exception {
|
||||
FileTemplateManager manager = FileTemplateManager.getInstance();
|
||||
String templateName = getTemplateName(resourceType, valuesResourceFile);
|
||||
FileTemplate template = manager.getJ2eeTemplate(templateName);
|
||||
Properties properties = new Properties();
|
||||
if (!valuesResourceFile) {
|
||||
properties.setProperty(ROOT_TAG_PROPERTY, rootTagName);
|
||||
}
|
||||
PsiElement createdElement = FileTemplateUtil.createFromTemplate(template, fileName, properties, resSubdir);
|
||||
assert createdElement instanceof XmlFile;
|
||||
return (XmlFile)createdElement;
|
||||
}
|
||||
|
||||
private static String getTemplateName(String resourceType, boolean valuesResourceFile) {
|
||||
if (valuesResourceFile) {
|
||||
return AndroidFileTemplateProvider.VALUE_RESOURCE_FILE_TEMPLATE;
|
||||
}
|
||||
if ("layout".equals(resourceType)) {
|
||||
return AndroidFileTemplateProvider.LAYOUT_RESOURCE_FILE_TEMPLATE;
|
||||
}
|
||||
return AndroidFileTemplateProvider.RESOURCE_FILE_TEMPLATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@ import com.android.sdklib.SdkConstants;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.actions.CleanupInspectionIntention;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.android.dom.converters.ResourceReferenceConverter;
|
||||
import org.jetbrains.android.inspections.CreateValueResourceQuickFix;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -351,7 +350,7 @@ public class AndroidLayoutDomTest extends AndroidDomTest {
|
||||
if (ranges != null) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : ranges) {
|
||||
final IntentionAction action = pair.getFirst().getAction();
|
||||
if (action instanceof ResourceReferenceConverter.MyCreateValueResourceQuickFix) {
|
||||
if (action instanceof CreateValueResourceQuickFix) {
|
||||
actions.add(action);
|
||||
}
|
||||
}
|
||||
@@ -368,44 +367,6 @@ public class AndroidLayoutDomTest extends AndroidDomTest {
|
||||
myFixture.checkResultByFile("res/values/drawables.xml", testFolder + '/' + getTestName(true) + "_drawable_after.xml", true);
|
||||
}
|
||||
|
||||
public void testCreateResourceFromUsageCleanUp() throws Throwable {
|
||||
final VirtualFile virtualFile = copyFileToProject(getTestName(true) + ".xml");
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile);
|
||||
final List<HighlightInfo> infos = myFixture.doHighlighting();
|
||||
|
||||
final List<IntentionAction> actions = new ArrayList<IntentionAction>();
|
||||
|
||||
for (HighlightInfo info : infos) {
|
||||
final List<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>> ranges = info.quickFixActionRanges;
|
||||
|
||||
if (ranges != null) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : ranges) {
|
||||
final HighlightInfo.IntentionActionDescriptor descriptor = pair.getFirst();
|
||||
if (descriptor.getAction() instanceof ResourceReferenceConverter.MyCreateValueResourceQuickFix) {
|
||||
final List<IntentionAction> options = descriptor.getOptions(myFixture.getFile(), myFixture.getEditor());
|
||||
|
||||
if (options != null) {
|
||||
for (IntentionAction option : options) {
|
||||
if (option instanceof CleanupInspectionIntention) {
|
||||
actions.add(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assertEquals(1, actions.size());
|
||||
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
actions.get(0).invoke(getProject(), myFixture.getEditor(), myFixture.getFile());
|
||||
}
|
||||
}.execute();
|
||||
myFixture.checkResultByFile("res/values/drawables.xml", testFolder + '/' + getTestName(true) + "_drawable_after.xml", true);
|
||||
}
|
||||
|
||||
public void testXsdFile1() throws Throwable {
|
||||
final VirtualFile virtualFile = copyFileToProject("XsdFile.xsd", "res/raw/XsdFile.xsd");
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile);
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import org.jetbrains.android.dom.converters.ResourceReferenceConverter;
|
||||
import org.jetbrains.android.inspections.CreateValueResourceQuickFix;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -199,7 +199,7 @@ public class AndroidValueResourcesTest extends AndroidDomTest {
|
||||
if (ranges != null) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : ranges) {
|
||||
final IntentionAction action = pair.getFirst().getAction();
|
||||
if (action instanceof ResourceReferenceConverter.MyCreateValueResourceQuickFix) {
|
||||
if (action instanceof CreateValueResourceQuickFix) {
|
||||
actions.add(action);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user