IDEA-251172 Missing checkboxes in settings
[idea/community.git] / java / idea-ui / src / com / intellij / ide / util / newProjectWizard / AddModuleWizard.java
1 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.ide.util.newProjectWizard;
3
4 import com.intellij.ide.JavaUiBundle;
5 import com.intellij.ide.util.newProjectWizard.modes.ImportMode;
6 import com.intellij.ide.util.newProjectWizard.modes.WizardMode;
7 import com.intellij.ide.util.projectWizard.ModuleWizardStep;
8 import com.intellij.ide.util.projectWizard.ProjectBuilder;
9 import com.intellij.ide.util.projectWizard.WizardContext;
10 import com.intellij.ide.wizard.Step;
11 import com.intellij.openapi.project.Project;
12 import com.intellij.openapi.projectRoots.ProjectJdkTable;
13 import com.intellij.openapi.projectRoots.Sdk;
14 import com.intellij.openapi.projectRoots.SdkTypeId;
15 import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
16 import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
17 import com.intellij.openapi.util.NlsContexts;
18 import com.intellij.projectImport.ProjectImportBuilder;
19 import com.intellij.projectImport.ProjectImportProvider;
20 import com.intellij.util.containers.ContainerUtil;
21 import org.jetbrains.annotations.NotNull;
22 import org.jetbrains.annotations.Nullable;
23 import org.jetbrains.annotations.TestOnly;
24
25 import java.awt.*;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.function.Function;
30
31 import static java.util.stream.Collectors.*;
32
33 public class AddModuleWizard extends AbstractProjectWizard {
34   private final List<ProjectImportProvider> myImportProviders;
35   private final ModulesProvider myModulesProvider;
36   private WizardMode myWizardMode;
37
38   /**
39    * @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing project.
40    */
41   public AddModuleWizard(@Nullable Project project, String filePath, ProjectImportProvider... importProviders) {
42     super(getImportWizardTitle(project, importProviders), project, filePath);
43     myImportProviders = Arrays.asList(importProviders);
44     myModulesProvider = DefaultModulesProvider.createForProject(project);
45     initModuleWizard(project, filePath);
46   }
47
48   /**
49    * @param project if null, the wizard will start creating new project, otherwise will add a new module to the existing project.
50    */
51   public AddModuleWizard(Project project, Component dialogParent, String filePath, ProjectImportProvider... importProviders) {
52     super(getImportWizardTitle(project, importProviders), project, dialogParent);
53     myImportProviders = Arrays.asList(importProviders);
54     myModulesProvider = DefaultModulesProvider.createForProject(project);
55     initModuleWizard(project, filePath);
56   }
57
58   private static @NlsContexts.DialogTitle String getImportWizardTitle(Project project, ProjectImportProvider... providers) {
59     int isProject = project == null ? 0 : 1;
60     if (providers.length != 1) {
61       return JavaUiBundle.message("module.wizard.dialog.title", isProject, 0, null);
62     }
63     return JavaUiBundle.message("module.wizard.dialog.title", isProject, 1, providers[0].getName());
64   }
65
66   private void initModuleWizard(@Nullable final Project project, @Nullable final String defaultPath) {
67     myWizardContext.addContextListener(new WizardContext.Listener() {
68       @Override
69       public void buttonsUpdateRequested() {
70         updateButtons();
71       }
72
73       @Override
74       public void nextStepRequested() {
75         doNextAction();
76       }
77     });
78
79     myWizardMode = new ImportMode(myImportProviders);
80     StepSequence sequence = myWizardMode.getSteps(myWizardContext, DefaultModulesProvider.createForProject(project));
81     appendSteps(sequence);
82     for (ProjectImportProvider provider : myImportProviders) {
83       provider.getBuilder().setFileToImport(defaultPath);
84     }
85     if (myImportProviders.size() == 1) {
86       final ProjectImportBuilder builder = myImportProviders.get(0).getBuilder();
87       myWizardContext.setProjectBuilder(builder);
88       builder.setUpdate(getWizardContext().getProject() != null);
89     }
90     init();
91   }
92
93   private void appendSteps(@Nullable final StepSequence sequence) {
94     if (sequence != null) {
95       for (ModuleWizardStep step : sequence.getAllSteps()) {
96         addStep(step);
97       }
98     }
99   }
100
101   @Override
102   public StepSequence getSequence() {
103     return myWizardMode.getSteps(myWizardContext, myModulesProvider);
104   }
105
106   @Nullable
107   public static Sdk getMostRecentSuitableSdk(final WizardContext context) {
108     if (context.getProject() == null) {
109       List<Sdk> sdks = Arrays.asList(ProjectJdkTable.getInstance().getAllJdks());
110
111       ProjectBuilder builder = context.getProjectBuilder();
112       if (builder != null) {
113         sdks = ContainerUtil.filter(sdks, sdk -> builder.isSuitableSdkType(sdk.getSdkType()));
114       }
115
116       Map<SdkTypeId, List<Sdk>> sdksByType = sdks.stream().collect(groupingBy(Sdk::getSdkType, mapping(Function.identity(), toList())));
117       Map.Entry<SdkTypeId, List<Sdk>> pair = ContainerUtil.getFirstItem(sdksByType.entrySet());
118       if (pair != null) {
119         return pair.getValue().stream().max(pair.getKey().versionComparator()).orElse(null);
120       }
121     }
122
123     return null;
124   }
125
126   @NotNull
127   public WizardContext getWizardContext() {
128     return myWizardContext;
129   }
130
131   @Override
132   protected String getDimensionServiceKey() {
133     return "NewModule_or_Project.wizard";
134   }
135
136   /**
137    * Allows to ask current wizard to move to the desired step.
138    *
139    * @param filter  closure that allows to indicate target step - is called with each of registered steps and is expected
140    *                to return {@code true} for the step to go to
141    * @return        {@code true} if current wizard is navigated to the target step; {@code false} otherwise
142    */
143   public boolean navigateToStep(@NotNull com.intellij.util.Function<? super Step, Boolean> filter) {
144     for (int i = 0, myStepsSize = mySteps.size(); i < myStepsSize; i++) {
145       ModuleWizardStep step = mySteps.get(i);
146       if (filter.fun(step) != Boolean.TRUE) {
147         continue;
148       }
149
150       // Update current step.
151       myCurrentStep = i;
152       updateStep();
153       return true;
154     }
155     return false;
156   }
157
158   @TestOnly
159   public void commit() {
160     commitStepData(getCurrentStepObject());
161   }
162 }