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());
98 if (CustomizeDesktopEntryStep.isAvailable()) {
99 mySteps.add(new CustomizeDesktopEntryStep("/UbuntuDesktopEntry.png"));
102 PluginGroups pluginGroups = new PluginGroups();
103 mySteps.add(new CustomizePluginsStepPanel(pluginGroups));
105 mySteps.add(new CustomizeFeaturedPluginsStepPanel(pluginGroups));
107 catch (CustomizeFeaturedPluginsStepPanel.OfflineException e) {
108 //skip featured step if we're offline
113 protected JComponent createCenterPanel() {
114 JPanel result = new JPanel(new BorderLayout(5, 5));
115 myContentPanel = new JPanel(myCardLayout);
116 for (AbstractCustomizeWizardStep step : mySteps) {
117 myContentPanel.add(step, step.getTitle());
119 JPanel topPanel = new JPanel(new BorderLayout(5, 5));
120 topPanel.add(myNavigationLabel, BorderLayout.NORTH);
121 topPanel.add(myHeaderLabel, BorderLayout.CENTER);
122 result.add(topPanel, BorderLayout.NORTH);
123 result.add(myContentPanel, BorderLayout.CENTER);
124 result.add(myFooterLabel, BorderLayout.SOUTH);
125 result.setPreferredSize(new Dimension(700, 600));
126 result.setBorder(AbstractCustomizeWizardStep.createSmallEmptyBorder());
131 protected JComponent createSouthPanel() {
132 final JPanel buttonPanel = new JPanel(new GridBagLayout());
133 GridBagConstraints gbc = new GridBagConstraints();
134 gbc.insets.right = 5;
135 gbc.fill = GridBagConstraints.BOTH;
138 if (!PlatformUtils.isCLion()) {
139 buttonPanel.add(mySkipButton, gbc);
142 buttonPanel.add(myBackButton, gbc);
145 buttonPanel.add(Box.createHorizontalGlue(), gbc);
148 buttonPanel.add(myNextButton, gbc);
149 buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
150 myButtonWrapper.add(buttonPanel, BUTTONS);
151 myButtonWrapper.add(new JLabel(), NOBUTTONS);
152 myButtonWrapperLayout.show(myButtonWrapper, BUTTONS);
153 return myButtonWrapper;
156 void setButtonsVisible(boolean visible) {
157 myButtonWrapperLayout.show(myButtonWrapper, visible ? BUTTONS : NOBUTTONS);
161 public void actionPerformed(ActionEvent e) {
162 if (e.getSource() == mySkipButton) {
166 if (e.getSource() == myBackButton) {
168 initCurrentStep(false);
171 if (e.getSource() == myNextButton) {
172 if (myIndex >= mySteps.size() - 1) {
177 initCurrentStep(true);
183 protected ActionListener createCancelAction() {
184 return null;//Prevent closing by <Esc>
188 public void doCancelAction() {
193 protected void doOKAction() {
194 for (AbstractCustomizeWizardStep step : mySteps) {
195 if (!step.beforeOkAction()) {
196 int index = mySteps.indexOf(step);
197 if (myIndex != index) {
199 initCurrentStep(true);
207 private void initCurrentStep(boolean forward) {
208 final AbstractCustomizeWizardStep myCurrentStep = mySteps.get(myIndex);
209 myCurrentStep.beforeShown(forward);
210 myCardLayout.swipe(myContentPanel, myCurrentStep.getTitle(), JBCardLayout.SwipeDirection.AUTO, new Runnable() {
213 Component component = myCurrentStep.getDefaultFocusedComponent();
214 if (component != null) {
215 component.requestFocus();
220 myBackButton.setVisible(myIndex > 0);
222 myBackButton.setText("Back to " + mySteps.get(myIndex - 1).getTitle());
224 mySkipButton.setText("Skip " + (myIndex > 0 ? "Remaining" : "All") + " and Set Defaults");
226 myNextButton.setText(myIndex < mySteps.size() - 1
227 ? "Next: " + mySteps.get(myIndex + 1).getTitle()
228 : "Start using " + ApplicationNamesInfo.getInstance().getFullProductName());
229 myHeaderLabel.setText(myCurrentStep.getHTMLHeader());
230 myFooterLabel.setText(myCurrentStep.getHTMLFooter());
231 StringBuilder navHTML = new StringBuilder("<html><body>");
232 for (int i = 0; i < mySteps.size(); i++) {
233 if (i > 0) navHTML.append(" → ");
234 if (i == myIndex) navHTML.append("<b>");
235 navHTML.append(mySteps.get(i).getTitle());
236 if (i == myIndex) navHTML.append("</b>");
238 myNavigationLabel.setText(navHTML.toString());