2 * Copyright 2000-2014 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.ide.customize;
18 import com.intellij.ide.startup.StartupActionScriptManager;
19 import com.intellij.idea.Main;
20 import com.intellij.openapi.application.ApplicationNamesInfo;
21 import com.intellij.openapi.ui.DialogWrapper;
22 import com.intellij.openapi.util.SystemInfo;
23 import com.intellij.ui.JBCardLayout;
24 import com.intellij.util.PlatformUtils;
25 import org.jetbrains.annotations.Nullable;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.util.ArrayList;
32 import java.util.List;
34 public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionListener {
35 private static final String BUTTONS = "BUTTONS";
36 private static final String NOBUTTONS = "NOBUTTONS";
37 private final JButton mySkipButton = new JButton("Skip All and Set Defaults");
38 private final JButton myBackButton = new JButton("Back");
39 private final JButton myNextButton = new JButton("Next");
41 private final JBCardLayout myCardLayout = new JBCardLayout();
42 protected final List<AbstractCustomizeWizardStep> mySteps = new ArrayList<AbstractCustomizeWizardStep>();
43 private int myIndex = 0;
44 private final JLabel myNavigationLabel = new JLabel();
45 private final JLabel myHeaderLabel = new JLabel();
46 private final JLabel myFooterLabel = new JLabel();
47 private final CardLayout myButtonWrapperLayout = new CardLayout();
48 private final JPanel myButtonWrapper = new JPanel(myButtonWrapperLayout);
49 private JPanel myContentPanel;
51 public CustomizeIDEWizardDialog() {
52 super(null, true, true);
53 setTitle("Customize " + ApplicationNamesInfo.getInstance().getProductName());
54 getPeer().setAppIcons();
56 mySkipButton.addActionListener(this);
57 myBackButton.addActionListener(this);
58 myNextButton.addActionListener(this);
59 myNavigationLabel.setEnabled(false);
60 myFooterLabel.setEnabled(false);
62 initCurrentStep(true);
64 System.setProperty(StartupActionScriptManager.STARTUP_WIZARD_MODE, "true");
67 public static void showCustomSteps(String stepsProviderName) {
68 final CustomizeIDEWizardStepsProvider provider;
71 Class<CustomizeIDEWizardStepsProvider> providerClass = (Class<CustomizeIDEWizardStepsProvider>)Class.forName(stepsProviderName);
72 provider = providerClass.newInstance();
75 Main.showMessage("Start Failed", e);
79 new CustomizeIDEWizardDialog() {
81 protected void initSteps() {
82 provider.initSteps(this, mySteps);
88 protected void dispose() {
89 System.clearProperty(StartupActionScriptManager.STARTUP_WIZARD_MODE);
93 protected void initSteps() {
94 mySteps.add(new CustomizeUIThemeStepPanel());
95 if (SystemInfo.isMac) {
96 mySteps.add(new CustomizeKeyboardSchemeStepPanel());
99 PluginGroups pluginGroups = new PluginGroups();
100 mySteps.add(new CustomizePluginsStepPanel(pluginGroups));
102 mySteps.add(new CustomizeFeaturedPluginsStepPanel(pluginGroups));
104 catch (CustomizeFeaturedPluginsStepPanel.OfflineException e) {
105 //skip featured step if we're offline
110 protected JComponent createCenterPanel() {
111 JPanel result = new JPanel(new BorderLayout(5, 5));
112 myContentPanel = new JPanel(myCardLayout);
113 for (AbstractCustomizeWizardStep step : mySteps) {
114 myContentPanel.add(step, step.getTitle());
116 JPanel topPanel = new JPanel(new BorderLayout(5, 5));
117 topPanel.add(myNavigationLabel, BorderLayout.NORTH);
118 topPanel.add(myHeaderLabel, BorderLayout.CENTER);
119 result.add(topPanel, BorderLayout.NORTH);
120 result.add(myContentPanel, BorderLayout.CENTER);
121 result.add(myFooterLabel, BorderLayout.SOUTH);
122 result.setPreferredSize(new Dimension(700, 600));
123 result.setBorder(AbstractCustomizeWizardStep.createSmallEmptyBorder());
128 protected JComponent createSouthPanel() {
129 final JPanel buttonPanel = new JPanel(new GridBagLayout());
130 GridBagConstraints gbc = new GridBagConstraints();
131 gbc.insets.right = 5;
132 gbc.fill = GridBagConstraints.BOTH;
135 if (!PlatformUtils.isCLion()) {
136 buttonPanel.add(mySkipButton, gbc);
139 buttonPanel.add(myBackButton, gbc);
142 buttonPanel.add(Box.createHorizontalGlue(), gbc);
145 buttonPanel.add(myNextButton, gbc);
146 buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
147 myButtonWrapper.add(buttonPanel, BUTTONS);
148 myButtonWrapper.add(new JLabel(), NOBUTTONS);
149 myButtonWrapperLayout.show(myButtonWrapper, BUTTONS);
150 return myButtonWrapper;
153 void setButtonsVisible(boolean visible) {
154 myButtonWrapperLayout.show(myButtonWrapper, visible ? BUTTONS : NOBUTTONS);
158 public void actionPerformed(ActionEvent e) {
159 if (e.getSource() == mySkipButton) {
163 if (e.getSource() == myBackButton) {
165 initCurrentStep(false);
168 if (e.getSource() == myNextButton) {
169 if (myIndex >= mySteps.size() - 1) {
174 initCurrentStep(true);
180 protected ActionListener createCancelAction() {
181 return null;//Prevent closing by <Esc>
185 public void doCancelAction() {
190 protected void doOKAction() {
191 for (AbstractCustomizeWizardStep step : mySteps) {
192 if (!step.beforeOkAction()) {
193 int index = mySteps.indexOf(step);
194 if (myIndex != index) {
196 initCurrentStep(true);
204 private void initCurrentStep(boolean forward) {
205 final AbstractCustomizeWizardStep myCurrentStep = mySteps.get(myIndex);
206 myCurrentStep.beforeShown(forward);
207 myCardLayout.swipe(myContentPanel, myCurrentStep.getTitle(), JBCardLayout.SwipeDirection.AUTO, new Runnable() {
210 Component component = myCurrentStep.getDefaultFocusedComponent();
211 if (component != null) {
212 component.requestFocus();
217 myBackButton.setVisible(myIndex > 0);
219 myBackButton.setText("Back to " + mySteps.get(myIndex - 1).getTitle());
221 mySkipButton.setText("Skip " + (myIndex > 0 ? "Remaining" : "All") + " and Set Defaults");
223 myNextButton.setText(myIndex < mySteps.size() - 1
224 ? "Next: " + mySteps.get(myIndex + 1).getTitle()
225 : "Start using " + ApplicationNamesInfo.getInstance().getFullProductName());
226 myHeaderLabel.setText(myCurrentStep.getHTMLHeader());
227 myFooterLabel.setText(myCurrentStep.getHTMLFooter());
228 StringBuilder navHTML = new StringBuilder("<html><body>");
229 for (int i = 0; i < mySteps.size(); i++) {
230 if (i > 0) navHTML.append(" → ");
231 if (i == myIndex) navHTML.append("<b>");
232 navHTML.append(mySteps.get(i).getTitle());
233 if (i == myIndex) navHTML.append("</b>");
235 myNavigationLabel.setText(navHTML.toString());