Search in sources :

Example 1 with Conflict

use of com.android.tools.idea.gradle.variant.conflict.Conflict in project android by JetBrains.

the class ProjectProfileSelectionDialog method createProjectStructureTree.

private void createProjectStructureTree() {
    CheckboxTree.CheckboxTreeCellRenderer renderer = new CheckboxTree.CheckboxTreeCellRenderer() {

        @Override
        public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            if (value instanceof DefaultMutableTreeNode) {
                Object data = ((DefaultMutableTreeNode) value).getUserObject();
                ColoredTreeCellRenderer textRenderer = getTextRenderer();
                if (data instanceof ModuleTreeElement) {
                    ModuleTreeElement moduleElement = (ModuleTreeElement) data;
                    textRenderer.append(moduleElement.myModule.getName());
                    if (!moduleElement.myConflicts.isEmpty()) {
                        boolean allResolved = true;
                        for (Conflict conflict : moduleElement.myConflicts) {
                            if (!conflict.isResolved()) {
                                allResolved = false;
                                break;
                            }
                        }
                        SimpleTextAttributes attributes = allResolved ? UNRESOLVED_ATTRIBUTES : SimpleTextAttributes.GRAY_ATTRIBUTES;
                        textRenderer.append(" ");
                        textRenderer.append(myConflicts.size() == 1 ? "[Conflict]" : "[Conflicts]", attributes);
                    }
                    textRenderer.setIcon(AllIcons.Actions.Module);
                } else if (data instanceof String) {
                    textRenderer.append((String) data, SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES);
                    textRenderer.setIcon(AndroidIcons.Variant);
                } else if (data instanceof DependencyTreeElement) {
                    DependencyTreeElement dependency = (DependencyTreeElement) data;
                    textRenderer.append(dependency.myModule.getName());
                    if (!StringUtil.isEmpty(dependency.myVariant)) {
                        textRenderer.append(" (" + dependency.myVariant + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
                    }
                    Icon icon = dependency.myConflict != null ? AllIcons.RunConfigurations.TestFailed : AllIcons.RunConfigurations.TestPassed;
                    textRenderer.setIcon(icon);
                }
            }
        }
    };
    CheckedTreeNode rootNode = new FilterAwareCheckedTreeNode(null);
    ModuleManager moduleManager = ModuleManager.getInstance(myProject);
    Module[] modules = moduleManager.getModules();
    Arrays.sort(modules, ModulesAlphaComparator.INSTANCE);
    Map<String, Module> modulesByGradlePath = Maps.newHashMap();
    for (Module module : modules) {
        String gradlePath = GradleUtil.getGradlePath(module);
        if (StringUtil.isEmpty(gradlePath)) {
            // We always want to include it, therefore we don't give users a chance to uncheck it in the "Project Structure" pane.
            continue;
        }
        modulesByGradlePath.put(gradlePath, module);
        ModuleTreeElement moduleElement = new ModuleTreeElement(module);
        CheckedTreeNode moduleNode = new FilterAwareCheckedTreeNode(moduleElement);
        rootNode.add(moduleNode);
        AndroidModuleModel androidModel = AndroidModuleModel.get(module);
        if (androidModel == null) {
            continue;
        }
        Multimap<String, DependencyTreeElement> dependenciesByVariant = HashMultimap.create();
        for (Variant variant : androidModel.getAndroidProject().getVariants()) {
            for (AndroidLibrary library : getDirectLibraryDependencies(variant, androidModel)) {
                gradlePath = library.getProject();
                if (gradlePath == null) {
                    continue;
                }
                Module dependency = modulesByGradlePath.get(gradlePath);
                if (dependency == null) {
                    dependency = GradleUtil.findModuleByGradlePath(myProject, gradlePath);
                }
                if (dependency == null) {
                    continue;
                }
                Conflict conflict = getConflict(dependency);
                modulesByGradlePath.put(gradlePath, dependency);
                DependencyTreeElement dependencyElement = new DependencyTreeElement(dependency, gradlePath, library.getProjectVariant(), conflict);
                dependenciesByVariant.put(variant.getName(), dependencyElement);
            }
        }
        List<String> variantNames = Lists.newArrayList(dependenciesByVariant.keySet());
        Collections.sort(variantNames);
        List<String> consolidatedVariants = Lists.newArrayList();
        List<String> variantsToSkip = Lists.newArrayList();
        int variantCount = variantNames.size();
        for (int i = 0; i < variantCount; i++) {
            String variant1 = variantNames.get(i);
            if (variantsToSkip.contains(variant1)) {
                continue;
            }
            Collection<DependencyTreeElement> set1 = dependenciesByVariant.get(variant1);
            for (int j = i + 1; j < variantCount; j++) {
                String variant2 = variantNames.get(j);
                Collection<DependencyTreeElement> set2 = dependenciesByVariant.get(variant2);
                if (set1.equals(set2)) {
                    variantsToSkip.add(variant2);
                    if (!consolidatedVariants.contains(variant1)) {
                        consolidatedVariants.add(variant1);
                    }
                    consolidatedVariants.add(variant2);
                }
            }
            String variantName = variant1;
            if (!consolidatedVariants.isEmpty()) {
                variantName = Joiner.on(", ").join(consolidatedVariants);
            }
            DefaultMutableTreeNode variantNode = new DefaultMutableTreeNode(variantName);
            moduleNode.add(variantNode);
            List<DependencyTreeElement> dependencyElements = Lists.newArrayList(set1);
            Collections.sort(dependencyElements);
            for (DependencyTreeElement dependencyElement : dependencyElements) {
                if (dependencyElement.myConflict != null) {
                    moduleElement.addConflict(dependencyElement.myConflict);
                }
                variantNode.add(new DefaultMutableTreeNode(dependencyElement));
            }
            consolidatedVariants.clear();
        }
    }
    myProjectStructureTree = new CheckboxTreeView(renderer, rootNode) {

        @Override
        protected void onNodeStateChanged(@NotNull CheckedTreeNode node) {
            Module module = null;
            Object data = node.getUserObject();
            if (data instanceof ModuleTreeElement) {
                module = ((ModuleTreeElement) data).myModule;
            }
            if (module == null) {
                return;
            }
            boolean updated = false;
            Enumeration variantNodes = myConflictTree.myRoot.children();
            while (variantNodes.hasMoreElements()) {
                Object child = variantNodes.nextElement();
                if (!(child instanceof CheckedTreeNode)) {
                    continue;
                }
                CheckedTreeNode variantNode = (CheckedTreeNode) child;
                Enumeration moduleNodes = variantNode.children();
                while (moduleNodes.hasMoreElements()) {
                    child = moduleNodes.nextElement();
                    if (!(child instanceof CheckedTreeNode)) {
                        continue;
                    }
                    CheckedTreeNode moduleNode = (CheckedTreeNode) child;
                    data = moduleNode.getUserObject();
                    if (!(data instanceof Conflict.AffectedModule)) {
                        continue;
                    }
                    Conflict.AffectedModule affected = (Conflict.AffectedModule) data;
                    boolean checked = node.isChecked();
                    if (module.equals(affected.getTarget()) && moduleNode.isChecked() != checked) {
                        affected.setSelected(checked);
                        moduleNode.setChecked(checked);
                        updated = true;
                    }
                }
            }
            if (updated) {
                repaintAll();
            }
        }
    };
    myProjectStructureTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    myProjectStructureTree.setRootVisible(false);
}
Also used : DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) ModuleManager(com.intellij.openapi.module.ModuleManager) Variant(com.android.builder.model.Variant) Conflict(com.android.tools.idea.gradle.variant.conflict.Conflict) AndroidLibrary(com.android.builder.model.AndroidLibrary) AndroidModuleModel(com.android.tools.idea.gradle.project.model.AndroidModuleModel) Module(com.intellij.openapi.module.Module)

Example 2 with Conflict

use of com.android.tools.idea.gradle.variant.conflict.Conflict in project android by JetBrains.

the class PostSyncProjectSetup method findAndShowVariantConflicts.

private void findAndShowVariantConflicts() {
    ConflictSet conflicts = findConflicts(myProject);
    List<Conflict> structureConflicts = conflicts.getStructureConflicts();
    if (!structureConflicts.isEmpty() && SystemProperties.getBooleanProperty("enable.project.profiles", false)) {
        ProjectProfileSelectionDialog dialog = new ProjectProfileSelectionDialog(myProject, structureConflicts);
        dialog.show();
    }
    List<Conflict> selectionConflicts = conflicts.getSelectionConflicts();
    if (!selectionConflicts.isEmpty()) {
        boolean atLeastOneSolved = solveSelectionConflicts(selectionConflicts);
        if (atLeastOneSolved) {
            conflicts = findConflicts(myProject);
        }
    }
    conflicts.showSelectionConflicts();
}
Also used : Conflict(com.android.tools.idea.gradle.variant.conflict.Conflict) ConflictSet(com.android.tools.idea.gradle.variant.conflict.ConflictSet) ProjectProfileSelectionDialog(com.android.tools.idea.gradle.variant.profiles.ProjectProfileSelectionDialog)

Example 3 with Conflict

use of com.android.tools.idea.gradle.variant.conflict.Conflict in project android by JetBrains.

the class ProjectProfileSelectionDialog method filterProjectStructure.

private void filterProjectStructure(@NotNull List<ConflictTableRow> rows) {
    List<Module> selectedConflictSources = Lists.newArrayList();
    for (ConflictTableRow row : rows) {
        if (row.myFilter) {
            selectedConflictSources.add(row.myConflict.getSource());
        }
    }
    Enumeration moduleNodes = myProjectStructureTree.myRoot.children();
    while (moduleNodes.hasMoreElements()) {
        boolean show = false;
        Object child = moduleNodes.nextElement();
        if (!(child instanceof FilterAwareCheckedTreeNode)) {
            continue;
        }
        FilterAwareCheckedTreeNode moduleNode = (FilterAwareCheckedTreeNode) child;
        Object data = moduleNode.getUserObject();
        if (!(data instanceof ModuleTreeElement)) {
            continue;
        }
        ModuleTreeElement moduleElement = (ModuleTreeElement) data;
        if (selectedConflictSources.isEmpty()) {
            show = true;
        } else {
            // We show the modules that depend on any of the selected conflict sources.
            for (Conflict conflict : moduleElement.myConflicts) {
                if (selectedConflictSources.contains(conflict.getSource())) {
                    show = true;
                    break;
                }
            }
            // We show the conflict sources as well.
            if (!show && selectedConflictSources.contains(moduleElement.myModule)) {
                show = true;
            }
        }
        moduleNode.myVisible = show;
    }
    myProjectStructureTree.reload();
    myProjectStructureTree.expandAll();
}
Also used : Conflict(com.android.tools.idea.gradle.variant.conflict.Conflict) Module(com.intellij.openapi.module.Module)

Example 4 with Conflict

use of com.android.tools.idea.gradle.variant.conflict.Conflict in project android by JetBrains.

the class ProjectProfileSelectionDialog method showConflictDetail.

private void showConflictDetail() {
    myConflictTree.myRoot.removeAllChildren();
    int selectedIndex = myConflictsTable.getSelectedRow();
    ConflictsTableModel tableModel = (ConflictsTableModel) myConflictsTable.getModel();
    ConflictTableRow row = tableModel.myRows.get(selectedIndex);
    Conflict conflict = row.myConflict;
    myConflictDetails.setText("Conflict Detail: " + conflict.getSource().getName());
    List<String> variants = Lists.newArrayList(conflict.getVariants());
    Collections.sort(variants);
    for (String variant : variants) {
        CheckedTreeNode variantNode = new CheckedTreeNode(variant);
        myConflictTree.myRoot.add(variantNode);
        for (Conflict.AffectedModule module : conflict.getModulesExpectingVariant(variant)) {
            CheckedTreeNode moduleNode = new CheckedTreeNode(module);
            variantNode.add(moduleNode);
        }
    }
    myConflictTree.reload();
    myConflictTree.expandAll();
}
Also used : Conflict(com.android.tools.idea.gradle.variant.conflict.Conflict)

Aggregations

Conflict (com.android.tools.idea.gradle.variant.conflict.Conflict)4 Module (com.intellij.openapi.module.Module)2 AndroidLibrary (com.android.builder.model.AndroidLibrary)1 Variant (com.android.builder.model.Variant)1 AndroidModuleModel (com.android.tools.idea.gradle.project.model.AndroidModuleModel)1 ConflictSet (com.android.tools.idea.gradle.variant.conflict.ConflictSet)1 ProjectProfileSelectionDialog (com.android.tools.idea.gradle.variant.profiles.ProjectProfileSelectionDialog)1 ModuleManager (com.intellij.openapi.module.ModuleManager)1 DefaultMutableTreeNode (javax.swing.tree.DefaultMutableTreeNode)1