Search in sources :

Example 76 with WriteCommandAction

use of com.intellij.openapi.command.WriteCommandAction in project android by JetBrains.

the class OverrideResourceAction method createValueResource.

private static void createValueResource(@NotNull final Project project, @NotNull final PsiDirectory resDir, @NotNull PsiFile file, @NotNull PsiDirectory resourceSubdir, @NotNull final String resName, @NotNull final String value, @NotNull final ResourceType type, @NotNull final String oldTagText, boolean open) {
    final String filename = file.getName();
    final List<String> dirNames = Collections.singletonList(resourceSubdir.getName());
    final AtomicReference<PsiElement> openAfter = new AtomicReference<PsiElement>();
    final WriteCommandAction<Void> action = new WriteCommandAction<Void>(project, "Override Resource " + resName, file) {

        @Override
        protected void run(@NotNull Result<Void> result) {
            List<ResourceElement> elements = Lists.newArrayListWithExpectedSize(1);
            // AndroidResourceUtil.createValueResource will create a new resource value in the given resource
            // folder (and record the corresponding tags added in the elements list passed into it).
            // However, it only creates a new element and sets the name attribute on it; it does not
            // transfer attributes, child content etc. Therefore, we use this utility method first to
            // create the corresponding tag, and then *afterwards* we will replace the tag with a text copy
            // from the resource tag we are overriding. We do this all under a single write lock such
            // that it becomes a single atomic operation.
            AndroidResourceUtil.createValueResource(project, resDir.getVirtualFile(), resName, type, filename, dirNames, value, elements);
            if (elements.size() == 1) {
                final XmlTag tag = elements.get(0).getXmlTag();
                if (tag != null && tag.isValid()) {
                    try {
                        XmlTag tagFromText = XmlElementFactory.getInstance(tag.getProject()).createTagFromText(oldTagText);
                        PsiElement replaced = tag.replace(tagFromText);
                        openAfter.set(replaced);
                    } catch (IncorrectOperationException e) {
                        // The user tried to override an invalid XML fragment: don't attempt to do a replacement in that case
                        openAfter.set(tag);
                    }
                }
            }
        }
    };
    action.execute();
    PsiElement tag = openAfter.get();
    if (open && tag != null) {
        NavigationUtil.openFileWithPsiElement(tag, true, true);
    }
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) ResourceElement(org.jetbrains.android.dom.resources.ResourceElement) AtomicReference(java.util.concurrent.atomic.AtomicReference) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result) IncorrectOperationException(com.intellij.util.IncorrectOperationException) XmlTag(com.intellij.psi.xml.XmlTag)

Example 77 with WriteCommandAction

use of com.intellij.openapi.command.WriteCommandAction in project android by JetBrains.

the class OverrideResourceAction method forkResourceFile.

private static void forkResourceFile(@NotNull Project project, @NotNull final ResourceFolderType folderType, @NotNull final VirtualFile file, @Nullable final XmlFile xmlFile, @Nullable String myNewFolder, @Nullable Configuration configuration, boolean open) {
    final FolderConfiguration folderConfig;
    if (myNewFolder == null) {
        // Open a file chooser to select the configuration to be created
        VirtualFile parentFolder = file.getParent();
        assert parentFolder != null;
        VirtualFile res = parentFolder.getParent();
        folderConfig = selectFolderConfig(project, res, folderType);
    } else {
        folderConfig = FolderConfiguration.getConfigForFolder(myNewFolder);
    }
    if (folderConfig == null) {
        return;
    }
    final Computable<Pair<String, VirtualFile>> computable = new Computable<Pair<String, VirtualFile>>() {

        @Override
        public Pair<String, VirtualFile> compute() {
            String folderName = folderConfig.getFolderName(folderType);
            try {
                VirtualFile parentFolder = file.getParent();
                assert parentFolder != null;
                VirtualFile res = parentFolder.getParent();
                VirtualFile newParentFolder = res.findChild(folderName);
                if (newParentFolder == null) {
                    newParentFolder = res.createChildDirectory(this, folderName);
                    if (newParentFolder == null) {
                        String message = String.format("Could not create folder %1$s in %2$s", folderName, res.getPath());
                        return Pair.of(message, null);
                    }
                }
                final VirtualFile existing = newParentFolder.findChild(file.getName());
                if (existing != null && existing.exists()) {
                    String message = String.format("File 'res/%1$s/%2$s' already exists!", folderName, file.getName());
                    return Pair.of(message, null);
                }
                // Attempt to get the document from the PSI file rather than the file on disk: get edited contents too
                String text;
                if (xmlFile != null) {
                    text = xmlFile.getText();
                } else {
                    text = StreamUtil.readText(file.getInputStream(), "UTF-8");
                }
                VirtualFile newFile = newParentFolder.createChildData(this, file.getName());
                VfsUtil.saveText(newFile, text);
                return Pair.of(null, newFile);
            } catch (IOException e2) {
                String message = String.format("Failed to create File 'res/%1$s/%2$s' : %3$s", folderName, file.getName(), e2.getMessage());
                return Pair.of(message, null);
            }
        }
    };
    WriteCommandAction<Pair<String, VirtualFile>> action = new WriteCommandAction<Pair<String, VirtualFile>>(project, "Add Resource") {

        @Override
        protected void run(@NotNull Result<Pair<String, VirtualFile>> result) throws Throwable {
            result.setResult(computable.compute());
        }
    };
    Pair<String, VirtualFile> result = action.execute().getResultObject();
    String error = result.getFirst();
    VirtualFile newFile = result.getSecond();
    if (error != null) {
        Messages.showErrorDialog(project, error, "Create Resource");
    } else {
        // First create a compatible configuration based on the current configuration
        if (configuration != null) {
            ConfigurationManager configurationManager = configuration.getConfigurationManager();
            configurationManager.createSimilar(newFile, file);
        }
        if (open) {
            OpenFileDescriptor descriptor = new OpenFileDescriptor(project, newFile, -1);
            FileEditorManager.getInstance(project).openEditor(descriptor, true);
        }
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) FolderConfiguration(com.android.ide.common.resources.configuration.FolderConfiguration) IOException(java.io.IOException) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result) OpenFileDescriptor(com.intellij.openapi.fileEditor.OpenFileDescriptor) ConfigurationManager(com.android.tools.idea.configurations.ConfigurationManager) Computable(com.intellij.openapi.util.Computable) Pair(com.android.utils.Pair)

Example 78 with WriteCommandAction

use of com.intellij.openapi.command.WriteCommandAction in project android by JetBrains.

the class InferSupportAnnotationsAction method checkModules.

// For Android we need to check SDK version and possibly update the gradle project file
protected boolean checkModules(@NotNull Project project, @NotNull AnalysisScope scope, @NotNull Map<Module, PsiFile> modules) {
    Set<Module> modulesWithoutAnnotations = new HashSet<>();
    Set<Module> modulesWithLowVersion = new HashSet<>();
    for (Module module : modules.keySet()) {
        AndroidModuleInfo info = AndroidModuleInfo.get(module);
        if (info != null && info.getBuildSdkVersion() != null && info.getBuildSdkVersion().getFeatureLevel() < MIN_SDK_WITH_NULLABLE) {
            modulesWithLowVersion.add(module);
        }
        GradleBuildModel buildModel = GradleBuildModel.get(module);
        if (buildModel == null) {
            Logger.getInstance(InferSupportAnnotationsAction.class).warn("Unable to find Gradle build model for module " + module.getModuleFilePath());
            continue;
        }
        boolean dependencyFound = false;
        DependenciesModel dependenciesModel = buildModel.dependencies();
        if (dependenciesModel != null) {
            for (ArtifactDependencyModel dependency : dependenciesModel.artifacts(COMPILE)) {
                String notation = dependency.compactNotation().value();
                if (notation.startsWith(SdkConstants.APPCOMPAT_LIB_ARTIFACT) || notation.startsWith(SdkConstants.SUPPORT_LIB_ARTIFACT) || notation.startsWith(SdkConstants.ANNOTATIONS_LIB_ARTIFACT)) {
                    dependencyFound = true;
                    break;
                }
            }
        }
        if (!dependencyFound) {
            modulesWithoutAnnotations.add(module);
        }
    }
    if (!modulesWithLowVersion.isEmpty()) {
        Messages.showErrorDialog(project, String.format("Infer Support Annotations requires the project sdk level be set to %1$d or greater.", MIN_SDK_WITH_NULLABLE), "Infer Support Annotations");
        return false;
    }
    if (modulesWithoutAnnotations.isEmpty()) {
        return true;
    }
    String moduleNames = StringUtil.join(modulesWithoutAnnotations, Module::getName, ", ");
    int count = modulesWithoutAnnotations.size();
    String message = String.format("The %1$s %2$s %3$sn't refer to the existing '%4$s' library with Android nullity annotations. \n\n" + "Would you like to add the %5$s now?", pluralize("module", count), moduleNames, count > 1 ? "do" : "does", SupportLibrary.SUPPORT_ANNOTATIONS.getArtifactId(), pluralize("dependency", count));
    if (Messages.showOkCancelDialog(project, message, "Infer Nullity Annotations", Messages.getErrorIcon()) == Messages.OK) {
        LocalHistoryAction action = LocalHistory.getInstance().startAction(ADD_DEPENDENCY);
        try {
            new WriteCommandAction(project, ADD_DEPENDENCY) {

                @Override
                protected void run(@NotNull Result result) throws Throwable {
                    RepositoryUrlManager manager = RepositoryUrlManager.get();
                    String annotationsLibraryCoordinate = manager.getLibraryStringCoordinate(SupportLibrary.SUPPORT_ANNOTATIONS, true);
                    for (Module module : modulesWithoutAnnotations) {
                        addDependency(module, annotationsLibraryCoordinate);
                    }
                    GradleSyncInvoker.Request request = new GradleSyncInvoker.Request().setGenerateSourcesOnSuccess(false);
                    GradleSyncInvoker.getInstance().requestProjectSync(project, request, new GradleSyncListener.Adapter() {

                        @Override
                        public void syncSucceeded(@NotNull Project project) {
                            restartAnalysis(project, scope);
                        }
                    });
                }
            }.execute();
        } finally {
            action.finish();
        }
    }
    return false;
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) RepositoryUrlManager(com.android.tools.idea.templates.RepositoryUrlManager) ArtifactDependencyModel(com.android.tools.idea.gradle.dsl.model.dependencies.ArtifactDependencyModel) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result) AndroidModuleInfo(com.android.tools.idea.model.AndroidModuleInfo) Project(com.intellij.openapi.project.Project) GradleBuildModel(com.android.tools.idea.gradle.dsl.model.GradleBuildModel) LocalHistoryAction(com.intellij.history.LocalHistoryAction) DependenciesModel(com.android.tools.idea.gradle.dsl.model.dependencies.DependenciesModel) Module(com.intellij.openapi.module.Module)

Example 79 with WriteCommandAction

use of com.intellij.openapi.command.WriteCommandAction in project android by JetBrains.

the class HtmlLinkManager method handleNewClassUrl.

private static void handleNewClassUrl(@NotNull String url, @NotNull Module module) {
    assert url.startsWith(URL_CREATE_CLASS) : url;
    String s = url.substring(URL_CREATE_CLASS.length());
    final Project project = module.getProject();
    String title = "Create Custom View";
    final String className;
    final String packageName;
    int index = s.lastIndexOf('.');
    if (index == -1) {
        className = s;
        packageName = MergedManifest.get(module).getPackage();
        if (packageName == null) {
            return;
        }
    } else {
        packageName = s.substring(0, index);
        className = s.substring(index + 1);
    }
    CreateClassDialog dialog = new CreateClassDialog(project, title, className, packageName, CreateClassKind.CLASS, true, module) {

        @Override
        protected boolean reportBaseInSourceSelectionInTest() {
            return true;
        }
    };
    dialog.show();
    if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
        final PsiDirectory targetDirectory = dialog.getTargetDirectory();
        if (targetDirectory != null) {
            PsiClass newClass = new WriteCommandAction<PsiClass>(project, "Create Class") {

                @Override
                protected void run(@NotNull Result<PsiClass> result) throws Throwable {
                    PsiClass targetClass = JavaDirectoryService.getInstance().createClass(targetDirectory, className);
                    PsiManager manager = PsiManager.getInstance(project);
                    final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
                    final PsiElementFactory factory = facade.getElementFactory();
                    // Extend android.view.View
                    PsiJavaCodeReferenceElement superclassReference = factory.createReferenceElementByFQClassName(CLASS_VIEW, targetClass.getResolveScope());
                    PsiReferenceList extendsList = targetClass.getExtendsList();
                    if (extendsList != null) {
                        extendsList.add(superclassReference);
                    }
                    // Add constructor
                    GlobalSearchScope scope = GlobalSearchScope.allScope(project);
                    PsiJavaFile javaFile = (PsiJavaFile) targetClass.getContainingFile();
                    PsiImportList importList = javaFile.getImportList();
                    if (importList != null) {
                        PsiClass contextClass = JavaPsiFacade.getInstance(project).findClass(CLASS_CONTEXT, scope);
                        if (contextClass != null) {
                            importList.add(factory.createImportStatement(contextClass));
                        }
                        PsiClass attributeSetClass = JavaPsiFacade.getInstance(project).findClass(CLASS_ATTRIBUTE_SET, scope);
                        if (attributeSetClass != null) {
                            importList.add(factory.createImportStatement(attributeSetClass));
                        }
                    }
                    PsiMethod constructor = factory.createMethodFromText("public " + className + "(Context context, AttributeSet attrs, int defStyle) {\n" + "  super(context, attrs, defStyle);\n" + "}\n", targetClass);
                    targetClass.add(constructor);
                    // Format class
                    CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject());
                    PsiFile containingFile = targetClass.getContainingFile();
                    if (containingFile != null) {
                        codeStyleManager.reformat(javaFile);
                    }
                    result.setResult(targetClass);
                }
            }.execute().getResultObject();
            if (newClass != null) {
                PsiFile file = newClass.getContainingFile();
                if (file != null) {
                    openEditor(project, file, newClass.getTextOffset());
                }
            }
        }
    }
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) CodeStyleManager(com.intellij.psi.codeStyle.CodeStyleManager) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result) Project(com.intellij.openapi.project.Project) CreateClassDialog(com.intellij.codeInsight.intention.impl.CreateClassDialog) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope)

Example 80 with WriteCommandAction

use of com.intellij.openapi.command.WriteCommandAction in project android by JetBrains.

the class HtmlLinkManager method assignLayout.

private static void assignLayout(@NotNull final Project project, @NotNull final XmlFile file, @NotNull final String activityName, @NotNull final String layout) {
    WriteCommandAction<Void> action = new WriteCommandAction<Void>(project, "Assign Preview Layout", file) {

        @Override
        protected void run(@NotNull Result<Void> result) throws Throwable {
            AndroidResourceUtil.ensureNamespaceImported(file, TOOLS_URI, null);
            Collection<XmlTag> xmlTags = PsiTreeUtil.findChildrenOfType(file, XmlTag.class);
            for (XmlTag tag : xmlTags) {
                if (tag.getName().equals(VIEW_FRAGMENT)) {
                    String name = tag.getAttributeValue(ATTR_CLASS);
                    if (name == null || name.isEmpty()) {
                        name = tag.getAttributeValue(ATTR_NAME, ANDROID_URI);
                    }
                    if (activityName.equals(name)) {
                        tag.setAttribute(ATTR_LAYOUT, TOOLS_URI, layout);
                    }
                }
            }
        }
    };
    action.execute();
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)176 Result (com.intellij.openapi.application.Result)175 NotNull (org.jetbrains.annotations.NotNull)62 Project (com.intellij.openapi.project.Project)45 VirtualFile (com.intellij.openapi.vfs.VirtualFile)29 XmlFile (com.intellij.psi.xml.XmlFile)28 XmlTag (com.intellij.psi.xml.XmlTag)23 Document (com.intellij.openapi.editor.Document)22 PsiFile (com.intellij.psi.PsiFile)16 Module (com.intellij.openapi.module.Module)14 Nullable (org.jetbrains.annotations.Nullable)12 NlModel (com.android.tools.idea.uibuilder.model.NlModel)11 AttributesTransaction (com.android.tools.idea.uibuilder.model.AttributesTransaction)10 Editor (com.intellij.openapi.editor.Editor)10 TextRange (com.intellij.openapi.util.TextRange)8 XmlAttribute (com.intellij.psi.xml.XmlAttribute)8 File (java.io.File)8 IOException (java.io.IOException)8 ArrayList (java.util.ArrayList)8 GradleBuildModel (com.android.tools.idea.gradle.dsl.model.GradleBuildModel)7