/* * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.ide.customize; import com.intellij.ide.plugins.PluginManager; import com.intellij.internal.statistic.ideSettings.IdeInitialConfigButtonUsages; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.openapi.util.Pair; import com.intellij.ui.ColorUtil; import com.intellij.ui.JBCardLayout; import com.intellij.ui.JBColor; import com.intellij.ui.border.CustomLineBorder; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ui.JBUI; import javax.swing.*; import javax.swing.border.CompoundBorder; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Map; public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep implements LinkListener<String> { private static final String MAIN = "main"; private static final String CUSTOMIZE = "customize"; private static final int COLS = 3; private static final TextProvider CUSTOMIZE_TEXT_PROVIDER = new TextProvider() { @Override public String getText() { return "Customize..."; } }; private static final String SWITCH_COMMAND = "Switch"; private static final String CUSTOMIZE_COMMAND = "Customize"; private final JBCardLayout myCardLayout; private final IdSetPanel myCustomizePanel; private final PluginGroups myPluginGroups; public CustomizePluginsStepPanel(PluginGroups pluginGroups) { myPluginGroups = pluginGroups; myCardLayout = new JBCardLayout(); setLayout(myCardLayout); JPanel gridPanel = new JPanel(new GridLayout(0, COLS)); myCustomizePanel = new IdSetPanel(); JBScrollPane scrollPane = createScrollPane(gridPanel); add(scrollPane, MAIN); add(myCustomizePanel, CUSTOMIZE); Map<String, Pair<Icon, List<String>>> groups = pluginGroups.getTree(); for (final Map.Entry<String, Pair<Icon, List<String>>> entry : groups.entrySet()) { final String group = entry.getKey(); if (PluginGroups.CORE.equals(group) || myPluginGroups.getSets(group).isEmpty()) continue; JPanel groupPanel = new JPanel(new GridBagLayout()) { @Override public Color getBackground() { Color color = UIManager.getColor("Panel.background"); return isGroupEnabled(group)? color : ColorUtil.darker(color, 1); } }; gridPanel.setOpaque(true); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.weightx = 1; JLabel titleLabel = new JLabel("<html><body><h2 style=\"text-align:center;\">" + group + "</h2></body></html>", SwingConstants.CENTER) { @Override public boolean isEnabled() { return isGroupEnabled(group); } }; groupPanel.add(new JLabel(entry.getValue().getFirst()), gbc); //gbc.insets.bottom = 5; groupPanel.add(titleLabel, gbc); JLabel descriptionLabel = new JLabel(pluginGroups.getDescription(group), SwingConstants.CENTER) { @Override public Dimension getPreferredSize() { Dimension size = super.getPreferredSize(); size.width = Math.min(size.width, 200); return size; } @Override public boolean isEnabled() { return isGroupEnabled(group); } @Override public Color getForeground() { return ColorUtil.withAlpha(UIManager.getColor("Label.foreground"), .75); } }; groupPanel.add(descriptionLabel, gbc); gbc.weighty = 1; groupPanel.add(Box.createVerticalGlue(), gbc); gbc.weighty = 0; JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, SMALL_GAP, SMALL_GAP / 2)); buttonsPanel.setOpaque(false); if (pluginGroups.getSets(group).size() == 1) { buttonsPanel.add(createLink(SWITCH_COMMAND + ":" + group, getGroupSwitchTextProvider(group))); } else { buttonsPanel.add(createLink(CUSTOMIZE_COMMAND + ":" + group, CUSTOMIZE_TEXT_PROVIDER)); buttonsPanel.add(createLink(SWITCH_COMMAND + ":" + group, getGroupSwitchTextProvider(group))); } groupPanel.add(buttonsPanel, gbc); gridPanel.add(groupPanel); } int cursor = 0; Component[] components = gridPanel.getComponents(); int rowCount = components.length / COLS; if (components.length % COLS == 0) rowCount--; for (Component component : components) { ((JComponent)component).setBorder( new CompoundBorder(new CustomLineBorder(ColorUtil.withAlpha(JBColor.foreground(), .2), 0, 0, cursor / 3 <= rowCount - 1 ? 1 : 0, cursor % COLS != COLS - 1 ? 1 : 0) { @Override protected Color getColor() { return ColorUtil.withAlpha(JBColor.foreground(), .2); } }, BorderFactory.createEmptyBorder(SMALL_GAP, GAP, SMALL_GAP, GAP))); cursor++; } } static JBScrollPane createScrollPane(JPanel gridPanel) { JBScrollPane scrollPane = new JBScrollPane(gridPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setBorder(JBUI.Borders.empty()); // to disallow resetting border on LaF change return scrollPane; } @Override public void linkSelected(LinkLabel linkLabel, String command) { if (command == null || !command.contains(":")) return; int semicolonPosition = command.indexOf(":"); String group = command.substring(semicolonPosition + 1); command = command.substring(0, semicolonPosition); if (SWITCH_COMMAND.equals(command)) { boolean enabled = isGroupEnabled(group); List<IdSet> sets = myPluginGroups.getSets(group); for (IdSet idSet : sets) { String[] ids = idSet.getIds(); for (String id : ids) { myPluginGroups.setPluginEnabledWithDependencies(id, !enabled); } } repaint(); return; } if (CUSTOMIZE_COMMAND.equals(command)) { myCustomizePanel.update(group); myCardLayout.show(this, CUSTOMIZE); setButtonsVisible(false); } } private void setButtonsVisible(boolean visible) { DialogWrapper window = DialogWrapper.findInstance(this); if (window instanceof CustomizeIDEWizardDialog) { ((CustomizeIDEWizardDialog)window).setButtonsVisible(visible); } } private LinkLabel createLink(String command, final TextProvider provider) { return new LinkLabel<String>("", null, this, command) { @Override public String getText() { return provider.getText(); } }; } TextProvider getGroupSwitchTextProvider(final String group) { return new TextProvider() { @Override public String getText() { return (isGroupEnabled(group) ? "Disable" : "Enable") + (myPluginGroups.getSets(group).size() > 1 ? " All" : ""); } }; } private boolean isGroupEnabled(String group) { List<IdSet> sets = myPluginGroups.getSets(group); for (IdSet idSet : sets) { String[] ids = idSet.getIds(); for (String id : ids) { if (myPluginGroups.isPluginEnabled(id)) return true; } } return false; } @Override public String getTitle() { return "Default plugins"; } @Override public String getHTMLHeader() { return "<html><body><h2>Tune " + ApplicationNamesInfo.getInstance().getProductName() + " to your tasks</h2>" + ApplicationNamesInfo.getInstance().getProductName() + " has a lot of tools enabled by default. You can set only ones you need or leave them all." + "</body></html>"; } @Override public boolean beforeOkAction() { try { PluginManager.saveDisabledPlugins(myPluginGroups.getDisabledPluginIds(), false); IdeInitialConfigButtonUsages.setPredefinedDisabledPlugins(new HashSet<>(myPluginGroups.getDisabledPluginIds())); } catch (IOException ignored) { } return true; } private class IdSetPanel extends JPanel implements LinkListener<String> { private JLabel myTitleLabel = new JLabel(); private JPanel myContentPanel = new JPanel(new GridLayout(0, 3, 5, 5)); private JButton mySaveButton = new JButton("Save Changes and Go Back"); private String myGroup; private IdSetPanel() { setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, GAP, true, false)); add(myTitleLabel); add(myContentPanel); JPanel buttonPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets.right = 25; gbc.gridy = 0; buttonPanel.add(mySaveButton, gbc); buttonPanel.add(new LinkLabel<>("Enable All", null, this, "enable"), gbc); buttonPanel.add(new LinkLabel<>("Disable All", null, this, "disable"), gbc); gbc.weightx = 1; buttonPanel.add(Box.createHorizontalGlue(), gbc); add(buttonPanel); mySaveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { myCardLayout.show(CustomizePluginsStepPanel.this, MAIN); setButtonsVisible(true); } }); } @Override public void linkSelected(LinkLabel aSource, String command) { if (myGroup == null) return; boolean enable = "enable".equals(command); List<IdSet> idSets = myPluginGroups.getSets(myGroup); for (IdSet set : idSets) { myPluginGroups.setIdSetEnabled(set, enable); } CustomizePluginsStepPanel.this.repaint(); } void update(String group) { myGroup = group; myTitleLabel.setText("<html><body><h2 style=\"text-align:left;\">" + group + "</h2></body></html>"); myContentPanel.removeAll(); List<IdSet> idSets = myPluginGroups.getSets(group); for (final IdSet set : idSets) { final JCheckBox checkBox = new JCheckBox(set.getTitle(), myPluginGroups.isIdSetAllEnabled(set)); checkBox.setModel(new JToggleButton.ToggleButtonModel() { @Override public boolean isSelected() { return myPluginGroups.isIdSetAllEnabled(set); } }); checkBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { myPluginGroups.setIdSetEnabled(set, !checkBox.isSelected()); CustomizePluginsStepPanel.this.repaint(); } }); myContentPanel.add(checkBox); } } } private interface TextProvider { String getText(); } }