import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.wizard.WizardNavigationState;
import com.intellij.ui.wizard.WizardStep;
-import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
/**
private JButton myEnableAllButton;
private JButton myDisableAllButton;
private final List<IdeaPluginDescriptor> myPlugins = new ArrayList<IdeaPluginDescriptor>();
- private final Set<String> myDisabledPluginIds;
+ private final StartupWizardModel myModel;
private final String myRequirePlugin;
private static final String[] ourSuffixes = new String[] { "integration", "support", "plugin" };
- public SelectPluginsStep(final String title, final Set<String> disabledPluginIds, final String requirePlugin) {
+ public SelectPluginsStep(final String title, final StartupWizardModel model, final String requirePlugin) {
super(title, "Select the plugins to enable. Disabling unused plugins will improve IDE startup speed and performance.\n\nTo change plugin settings later, go to Settings | Plugins.",
null);
- myDisabledPluginIds = disabledPluginIds;
+ myModel = model;
myRequirePlugin = requirePlugin;
myPluginsList.setCellRenderer(new ListCellRenderer() {
private final JCheckBox myCheckbox = new JCheckBox();
final int index,
final boolean isSelected,
final boolean cellHasFocus) {
+ IdeaPluginDescriptor descriptor = (IdeaPluginDescriptor)value;
+ myCheckbox.setEnabled(!myModel.isForceEnable(descriptor));
if (isSelected) {
myCheckbox.setBackground(UIUtil.getListSelectionBackground());
myCheckbox.setForeground(UIUtil.getListSelectionForeground());
myCheckbox.setBackground(UIUtil.getListBackground());
myCheckbox.setForeground(UIUtil.getListForeground());
}
- IdeaPluginDescriptor descriptor = (IdeaPluginDescriptor)value;
myCheckbox.setText(getAbbreviatedName(descriptor) + buildRequires(descriptor));
- myCheckbox.setSelected(!isDisabledPlugin(descriptor));
+ myCheckbox.setSelected(!myModel.isDisabledPlugin(descriptor));
return myCheckbox;
}
});
private String buildRequires(final IdeaPluginDescriptor descriptor) {
StringBuffer requiresBuffer = new StringBuffer();
- for (PluginId id : getNonOptionalDependencies(descriptor)) {
+ for (PluginId id : StartupWizardModel.getNonOptionalDependencies(descriptor)) {
final IdeaPluginDescriptor dependent = findPlugin(id);
if (dependent != null) {
String name = getAbbreviatedName(dependent);
requiresBuffer.append(name);
}
}
+ List<IdeaPluginDescriptor> requiredBy = myModel.getDependentsOnEarlierPages(descriptor, false);
+ if (requiredBy.size() > 0) {
+ if (requiresBuffer.length() > 0) {
+ requiresBuffer.append(", ");
+ }
+ else {
+ requiresBuffer.append(" (");
+ }
+ requiresBuffer.append("required by ");
+ requiresBuffer.append(StringUtil.join(requiredBy, new Function<IdeaPluginDescriptor, String>() {
+ @Override
+ public String fun(IdeaPluginDescriptor ideaPluginDescriptor) {
+ return getAbbreviatedName(ideaPluginDescriptor);
+ }
+ }, ", "));
+ }
if (requiresBuffer.length() > 0) {
requiresBuffer.append(")");
}
return requiresBuffer.toString();
}
- private static List<PluginId> getNonOptionalDependencies(final IdeaPluginDescriptor descriptor) {
- List<PluginId> result = new ArrayList<PluginId>();
- for (PluginId pluginId : descriptor.getDependentPluginIds()) {
- if (pluginId.getIdString().equals("com.intellij")) continue;
- if (!ArrayUtil.contains(pluginId, descriptor.getOptionalDependentPluginIds())) {
- result.add(pluginId);
- }
- }
- return result;
- }
-
private static String getAbbreviatedName(final IdeaPluginDescriptor descriptor) {
final String name = descriptor.getName();
for (String suffix : ourSuffixes) {
return name;
}
- private boolean isDisabledPlugin(final IdeaPluginDescriptor descriptor) {
- return myDisabledPluginIds.contains(descriptor.getPluginId().toString());
- }
-
private void toggleSelection() {
final IdeaPluginDescriptor descriptor = getSelectedPlugin();
- if (descriptor == null) return;
- boolean willDisable = !isDisabledPlugin(descriptor);
+ if (descriptor == null || myModel.isForceEnable(descriptor)) return;
+ boolean willDisable = !myModel.isDisabledPlugin(descriptor);
final Object[] selection = myPluginsList.getSelectedValues();
for (Object o : selection) {
IdeaPluginDescriptor desc = (IdeaPluginDescriptor) o;
if (!willDisable) {
- setPluginEnabledWithDependencies(desc);
+ myModel.setPluginEnabledWithDependencies(desc);
}
else {
- setPluginDisabledWithDependents(desc);
+ myModel.setPluginDisabledWithDependents(desc);
}
}
myPluginsList.repaint();
}
- private void setPluginDisabledWithDependents(final IdeaPluginDescriptor desc) {
- setPluginEnabled(desc, false);
- for (IdeaPluginDescriptor plugin : myPlugins) {
- if (ArrayUtil.contains(desc.getPluginId(), plugin.getDependentPluginIds()) &&
- !ArrayUtil.contains(desc.getPluginId(), plugin.getOptionalDependentPluginIds())) {
- setPluginDisabledWithDependents(plugin);
- }
- }
- }
-
private void setAllPluginsEnabled(boolean value) {
for(IdeaPluginDescriptor descriptor: myPlugins) {
- setPluginEnabled(descriptor, value);
- }
- myPluginsList.repaint();
- }
-
- private void setPluginEnabledWithDependencies(final IdeaPluginDescriptor desc) {
- setPluginEnabled(desc, true);
- for(PluginId id: getNonOptionalDependencies(desc)) {
- final IdeaPluginDescriptor dependent = findPlugin(id);
- if (dependent != null) {
- setPluginEnabledWithDependencies(dependent);
+ if (!value && myModel.isForceEnable(descriptor)) {
+ continue;
}
+ myModel.setPluginEnabled(descriptor, value);
}
+ myPluginsList.repaint();
}
@Nullable
return null;
}
- private void setPluginEnabled(final IdeaPluginDescriptor desc, boolean value) {
- if (value) {
- myDisabledPluginIds.remove(desc.getPluginId().toString());
- }
- else {
- myDisabledPluginIds.add(desc.getPluginId().toString());
- }
- }
-
@Nullable
private IdeaPluginDescriptor getSelectedPlugin() {
final int leadSelectionIndex = myPluginsList.getSelectionModel().getLeadSelectionIndex();
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
+import com.intellij.openapi.extensions.PluginId;
import com.intellij.ui.wizard.WizardModel;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.*;
public class StartupWizardModel extends WizardModel {
private final Set<String> myDisabledPluginIds = new HashSet<String>();
private final Map<String, SelectPluginsStep> myStepMap = new HashMap<String, SelectPluginsStep>();
+ private Map<PluginId, SelectPluginsStep> myPluginToStepMap = new HashMap<PluginId, SelectPluginsStep>();
+ private MultiMap<IdeaPluginDescriptor, IdeaPluginDescriptor> myBackwardDependencies =
+ new MultiMap<IdeaPluginDescriptor, IdeaPluginDescriptor>();
private SelectPluginsStep myOtherStep;
+ private IdeaPluginDescriptor[] myAllPlugins;
public StartupWizardModel(final List<ApplicationInfoEx.PluginChooserPage> pluginChooserPages) {
super(ApplicationNamesInfo.getInstance().getFullProductName() + " Initial Configuration Wizard");
for (ApplicationInfoEx.PluginChooserPage page : pluginChooserPages) {
if (page.getCategory() == null) {
- myOtherStep = new SelectPluginsStep(page.getTitle(), myDisabledPluginIds, null);
+ myOtherStep = new SelectPluginsStep(page.getTitle(), this, null);
}
else {
addSelectPluginsStep(page.getCategory(), page.getTitle(), page.getDependentPlugin());
add(myOtherStep);
}
- final IdeaPluginDescriptor[] pluginDescriptors = PluginManager.loadDescriptors();
- for (IdeaPluginDescriptor pluginDescriptor : pluginDescriptors) {
+ myAllPlugins = PluginManager.loadDescriptors();
+ for (IdeaPluginDescriptor pluginDescriptor : myAllPlugins) {
if (pluginDescriptor.getPluginId().getIdString().equals("com.intellij")) {
// skip 'IDEA CORE' plugin
continue;
}
PluginManager.initClassLoader(getClass().getClassLoader(), (IdeaPluginDescriptorImpl) pluginDescriptor);
SelectPluginsStep step = myStepMap.get(pluginDescriptor.getCategory());
+ if (step == null) {
+ step = myOtherStep;
+ }
if (step != null) {
step.addPlugin(pluginDescriptor);
- }
- else if (myOtherStep != null) {
- myOtherStep.addPlugin(pluginDescriptor);
+ myPluginToStepMap.put(pluginDescriptor.getPluginId(), step);
+ for (PluginId pluginId : pluginDescriptor.getDependentPluginIds()) {
+ if (!ArrayUtil.contains(pluginId, pluginDescriptor.getOptionalDependentPluginIds())) {
+ IdeaPluginDescriptor dependee = findPlugin(pluginId);
+ if (dependee != null) {
+ myBackwardDependencies.putValue(dependee, pluginDescriptor);
+ }
+ }
+ }
}
}
for (SelectPluginsStep step : myStepMap.values()) {
myOtherStep.fillPlugins();
}
+ @Nullable
+ private IdeaPluginDescriptor findPlugin(PluginId pluginId) {
+ for (IdeaPluginDescriptor pluginDescriptor : myAllPlugins) {
+ if (pluginDescriptor.getPluginId().equals(pluginId)) {
+ return pluginDescriptor;
+ }
+ }
+ return null;
+ }
+
+ static List<PluginId> getNonOptionalDependencies(final IdeaPluginDescriptor descriptor) {
+ List<PluginId> result = new ArrayList<PluginId>();
+ for (PluginId pluginId : descriptor.getDependentPluginIds()) {
+ if (pluginId.getIdString().equals("com.intellij")) continue;
+ if (!ArrayUtil.contains(pluginId, descriptor.getOptionalDependentPluginIds())) {
+ result.add(pluginId);
+ }
+ }
+ return result;
+ }
+
private SelectPluginsStep addSelectPluginsStep(final String category, final String title, final String requirePlugin) {
- final SelectPluginsStep step = new SelectPluginsStep(title, myDisabledPluginIds, requirePlugin);
+ final SelectPluginsStep step = new SelectPluginsStep(title, this, requirePlugin);
add(step);
myStepMap.put(category, step);
return step;
public Collection<String> getDisabledPluginIds() {
return myDisabledPluginIds;
}
+
+ public boolean isDisabledPlugin(IdeaPluginDescriptor descriptor) {
+ return myDisabledPluginIds.contains(descriptor.getPluginId().toString());
+ }
+
+ public void setPluginEnabled(final IdeaPluginDescriptor desc, boolean value) {
+ if (value) {
+ myDisabledPluginIds.remove(desc.getPluginId().toString());
+ }
+ else {
+ myDisabledPluginIds.add(desc.getPluginId().toString());
+ }
+ }
+
+ public void setPluginEnabledWithDependencies(final IdeaPluginDescriptor desc) {
+ setPluginEnabled(desc, true);
+ for(PluginId id: getNonOptionalDependencies(desc)) {
+ final IdeaPluginDescriptor dependent = findPlugin(id);
+ if (dependent != null) {
+ setPluginEnabledWithDependencies(dependent);
+ }
+ }
+ }
+
+ public void setPluginDisabledWithDependents(final IdeaPluginDescriptor desc) {
+ setPluginEnabled(desc, false);
+ for (IdeaPluginDescriptor plugin : myAllPlugins) {
+ if (ArrayUtil.contains(desc.getPluginId(), plugin.getDependentPluginIds()) &&
+ !ArrayUtil.contains(desc.getPluginId(), plugin.getOptionalDependentPluginIds())) {
+ setPluginDisabledWithDependents(plugin);
+ }
+ }
+ }
+
+ public boolean isForceEnable(IdeaPluginDescriptor descriptor) {
+ return getDependentsOnEarlierPages(descriptor, true).size() > 0;
+ }
+
+ public List<IdeaPluginDescriptor> getDependentsOnEarlierPages(IdeaPluginDescriptor descriptor, boolean includeSamePage) {
+ List<IdeaPluginDescriptor> dependents = new ArrayList<IdeaPluginDescriptor>();
+ int thisStep = getPluginStepIndex(descriptor);
+ for (IdeaPluginDescriptor dependent : myBackwardDependencies.get(descriptor)) {
+ if (!myDisabledPluginIds.contains(dependent.getPluginId().toString())) {
+ int index = getPluginStepIndex(dependent);
+ if (index < thisStep || (includeSamePage && index == thisStep && getDependentsOnEarlierPages(dependent, true).size() > 0)) {
+ dependents.add(dependent);
+ }
+ }
+ }
+ return dependents;
+ }
+
+ private int getPluginStepIndex(IdeaPluginDescriptor descriptor) {
+ return getStepIndex(myPluginToStepMap.get(descriptor.getPluginId()));
+ }
}