Beispiel #1
0
 private String getProjectsDir() {
   return WorkbenchPathManager.getUserHome() + File.separator + "MPSProjects";
 }
public class CreateProjectWizard extends DialogWrapper {

  private static final String PROJECTS_DIR =
      WorkbenchPathManager.getUserHome() + File.separator + "MPSProjects";
  private Project myCurrentProject;

  private JPanel myPanel;
  private JBSplitter mySplitter;

  private JPanel myLeftPanel;
  private SearchTextField mySearchField;
  private JBList myList;
  private FilteringListModel<TemplateItem> myFilteringListModel;

  private JPanel myRightPanel;
  private JPanel myProjectPanel;
  private JTextField myProjectName;
  private PathField myProjectPath;
  private JPanel myDescriptionPanel;
  private JTextPane myDescriptionPane;
  private JPanel myTemplateSettingsHolder;
  private HideableDecorator myHideableDecorator;
  private JPanel myTemplateSettings;

  private TemplateItem myCurrentTemplateItem = null;

  private ProjectFormatPanel myProjectFormatPanel = new ProjectFormatPanel();

  public CreateProjectWizard(@Nullable Project project) {
    super(project);
    myCurrentProject = project;
    setTitle("New Project");
    setOKButtonText("&OK");
    setCancelButtonText("Ca&ncel");

    init();
  }

  @Nullable
  @Override
  protected JComponent createCenterPanel() {
    if (myPanel == null) {
      myPanel = new JPanel(new GridLayoutManager(1, 1, JBInsets.NONE, -1, -1));

      initLeftPanel();

      initRightPanel();

      mySplitter = new JBSplitter(false, 0.3f, 0.3f, 0.6f);
      mySplitter.setSplitterProportionKey("select.template.proportion");
      mySplitter.setFirstComponent(myLeftPanel);
      mySplitter.setSecondComponent(myRightPanel);
      myPanel.add(
          mySplitter,
          new GridConstraints(
              0,
              0,
              1,
              1,
              GridConstraints.ANCHOR_CENTER,
              GridConstraints.FILL_BOTH,
              GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
              GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
              null,
              null,
              null));

      myPanel.setPreferredSize(new Dimension(600, 400));
      myList.setSelectedIndex(0);
    }

    return myPanel;
  }

  private void initLeftPanel() {
    myLeftPanel = new JPanel(new GridLayoutManager(2, 1, JBInsets.NONE, -1, -1));

    mySearchField = new SearchTextField(false);
    mySearchField.addDocumentListener(
        new DocumentAdapter() {
          @Override
          protected void textChanged(DocumentEvent e) {
            TemplateItem tmp = myCurrentTemplateItem;
            myFilteringListModel.refilter();
            int idx = myFilteringListModel.getElementIndex(tmp);
            myList.setSelectedIndex(idx < 0 ? 0 : idx);
          }
        });

    new AnAction() {
      @Override
      public void actionPerformed(AnActionEvent e) {
        InputEvent event = e.getInputEvent();
        if (event instanceof KeyEvent) {
          int row = myList.getSelectedIndex();
          int toSelect;
          switch (((KeyEvent) event).getKeyCode()) {
            case KeyEvent.VK_UP:
              toSelect = row == 0 ? myList.getItemsCount() - 1 : row - 1;
              myList.setSelectedIndex(toSelect);
              myList.ensureIndexIsVisible(toSelect);
              break;
            case KeyEvent.VK_DOWN:
              toSelect = row < myList.getItemsCount() - 1 ? row + 1 : 0;
              myList.setSelectedIndex(toSelect);
              myList.ensureIndexIsVisible(toSelect);
              break;
          }
        }
      }
    }.registerCustomShortcutSet(
        new CustomShortcutSet(KeyEvent.VK_UP, KeyEvent.VK_DOWN), mySearchField);

    myLeftPanel.add(
        mySearchField,
        new GridConstraints(
            0,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));

    myList = new JBList();

    List<ProjectTemplatesGroup> templatesGroups =
        new SortedList<ProjectTemplatesGroup>(
            new Comparator<ProjectTemplatesGroup>() {
              @Override
              public int compare(ProjectTemplatesGroup o1, ProjectTemplatesGroup o2) {
                // Put DSL/Development groups on top & Other group to the last place
                if (o1.getName().equals("DSL")) return -1;
                if (o2.getName().equals("DSL")) return 1;
                if (o1.getName().equals("Development")) return -1;
                if (o2.getName().equals("Development")) return 1;
                if (o1.getName().equals("Other")) return 1;
                if (o2.getName().equals("Other")) return -1;
                return o1.getName().compareToIgnoreCase(o2.getName());
              }
            });
    List<TemplateItem> templateItems = new LinkedList<TemplateItem>();

    templatesGroups.addAll(Arrays.asList(ProjectTemplatesGroup.EP_NAME.getExtensions()));

    for (ProjectTemplatesGroup templatesGroup : templatesGroups) {
      for (MPSProjectTemplate template : templatesGroup.getTemplates()) {
        templateItems.add(new TemplateItem(template, templatesGroup));
      }
    }

    CollectionListModel<TemplateItem> model = new CollectionListModel<TemplateItem>(templateItems);
    myFilteringListModel = new FilteringListModel<TemplateItem>(model);
    myFilteringListModel.setFilter(
        new Condition<TemplateItem>() {
          @Override
          public boolean value(TemplateItem templateItem) {
            return templateItem
                .getName()
                .toLowerCase()
                .contains(mySearchField.getText().trim().toLowerCase());
          }
        });
    myList.setModel(myFilteringListModel);

    myList.setCellRenderer(
        new GroupedItemsListRenderer(
            new ListItemDescriptor() {
              @Nullable
              @Override
              public String getTextFor(Object value) {
                return ((TemplateItem) value).getName();
              }

              @Nullable
              @Override
              public String getTooltipFor(Object value) {
                return null;
              }

              @Nullable
              @Override
              public Icon getIconFor(Object value) {
                return ((TemplateItem) value).getIcon();
              }

              @Override
              public boolean hasSeparatorAboveOf(Object value) {
                TemplateItem item = (TemplateItem) value;
                int index = myFilteringListModel.getElementIndex(item);
                return index == 0
                    || !myFilteringListModel
                        .getElementAt(index - 1)
                        .getGroupName()
                        .equals(item.getGroupName());
              }

              @Nullable
              @Override
              public String getCaptionAboveOf(Object value) {
                return ((TemplateItem) value).getGroupName();
              }
            }));

    myList
        .getSelectionModel()
        .addListSelectionListener(
            new ListSelectionListener() {

              @Override
              public void valueChanged(ListSelectionEvent e) {
                myCurrentTemplateItem = (TemplateItem) myList.getSelectedValue();
                updateRightPanel();
              }
            });

    myLeftPanel.add(
        ScrollPaneFactory.createScrollPane(myList),
        new GridConstraints(
            1,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK,
            GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
            null,
            null,
            null));
    myLeftPanel.setPreferredSize(new Dimension(200, 400));
  }

  private void initRightPanel() {
    myRightPanel = new JPanel(new GridLayoutManager(4, 1, new JBInsets(5, 5, 5, 0), -1, -1));

    // -----Project panel-----

    myProjectPanel = new JPanel(new GridLayoutManager(2, 2, new JBInsets(0, 0, 5, 0), -1, -1));

    myProjectPanel.add(
        new JLabel("Project name:"),
        new GridConstraints(
            0,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));

    myProjectName = new JTextField(getDefaultProjectName());
    myProjectPanel.add(
        myProjectName,
        new GridConstraints(
            0,
            1,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));

    myProjectPanel.add(
        new JLabel("Project location:"),
        new GridConstraints(
            1,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));

    myProjectPath = new PathField();
    myProjectPath.addPropertyChangeListener(
        "path",
        new PropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent evt) {
            fireProjectPathChanged((String) evt.getNewValue());
          }
        });
    myProjectName.addCaretListener(
        new CaretListener() {
          @Override
          public void caretUpdate(CaretEvent e) {
            updateProjectPath();
          }
        });
    updateProjectPath();
    myProjectPanel.add(
        myProjectPath,
        new GridConstraints(
            1,
            1,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));

    myRightPanel.add(
        myProjectPanel,
        new GridConstraints(
            0,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));

    // -----Description panel-----

    myDescriptionPanel = new JPanel(new GridLayoutManager(1, 1, JBInsets.NONE, -1, -1));
    myDescriptionPanel.setBorder(IdeBorderFactory.createTitledBorder("Description", true));

    myDescriptionPane = new JTextPane();
    Messages.installHyperlinkSupport(myDescriptionPane);

    myDescriptionPanel.add(
        myDescriptionPane,
        new GridConstraints(
            0,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            null,
            null,
            null));

    myRightPanel.add(
        myDescriptionPanel,
        new GridConstraints(
            1,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            null,
            null,
            null));

    myRightPanel.add(
        Box.createVerticalGlue(),
        new GridConstraints(
            2,
            0,
            1,
            1,
            GridConstraints.ANCHOR_NORTHWEST,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            null,
            null,
            null));

    // -----Template settings panel-----

    myTemplateSettingsHolder = new JPanel(new BorderLayout());
    myTemplateSettings = new JPanel(new GridLayoutManager(2, 1, JBInsets.NONE, -1, -1));
    myTemplateSettings.setBorder(
        IdeBorderFactory.createEmptyBorder(0, IdeBorderFactory.TITLED_BORDER_INDENT, 5, 0));
    myHideableDecorator = new HideableDecorator(myTemplateSettingsHolder, "More Settings", false);
    myHideableDecorator.setContentComponent(myTemplateSettings);
    myHideableDecorator.setOn(true);

    myRightPanel.add(
        myTemplateSettingsHolder,
        new GridConstraints(
            3,
            0,
            1,
            1,
            GridConstraints.ANCHOR_SOUTHWEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null));
  }

  private String getDefaultProjectName() {
    int n = 1;
    while (true) {
      String projectName = "Project" + n;
      if (!(new File(PROJECTS_DIR, projectName).exists())) {
        return projectName;
      }
      n = n + 1;
    }
  }

  private void updateProjectPath() {
    if (myProjectPath.getPath() == null
        || myProjectPath.getPath().length() == 0
        || myProjectPath.getPath().startsWith(PROJECTS_DIR)) {
      myProjectPath.setPath(PROJECTS_DIR + File.separator + myProjectName.getText());
    }
  }

  private void fireProjectPathChanged(String newValue) {
    if (myCurrentTemplateItem != null) myCurrentTemplateItem.setNewProjectPath(newValue);
  }

  private void updateRightPanel() {
    setOKActionEnabled(myCurrentTemplateItem != null);

    String description =
        myCurrentTemplateItem != null ? myCurrentTemplateItem.getDescription() : null;
    if (StringUtil.isNotEmpty(description)) {
      StringBuilder sb = new StringBuilder("<html><body><font face=\"Verdana\" ");
      sb.append(SystemInfo.isMac ? "" : "size=\"-1\"").append('>');
      sb.append(description).append("</font></body></html>");
      description = sb.toString();
    }
    myDescriptionPane.setText(description);
    myDescriptionPanel.setVisible(description != null);

    JComponent component =
        myCurrentTemplateItem != null ? myCurrentTemplateItem.getSettings() : null;
    myTemplateSettings.removeAll();
    if (component != null) {
      myTemplateSettings.add(
          component,
          new GridConstraints(
              0,
              0,
              1,
              1,
              GridConstraints.ANCHOR_NORTHWEST,
              GridConstraints.FILL_BOTH,
              GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
              GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
              null,
              null,
              null));
      myTemplateSettings.add(
          myProjectFormatPanel.getPanel(),
          new GridConstraints(
              1,
              0,
              1,
              1,
              GridConstraints.ANCHOR_NORTHWEST,
              GridConstraints.FILL_HORIZONTAL,
              GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
              GridConstraints.SIZEPOLICY_FIXED,
              null,
              null,
              null,
              1));
    }
    if (myCurrentTemplateItem != null)
      myCurrentTemplateItem.setNewProjectPath(myProjectPath.getPath());
    myTemplateSettingsHolder.setVisible(component != null);
  }

  @Nullable
  @Override
  protected String getHelpId() {
    return "MPS_New_Project_Page_1";
  }

  @Nullable
  @Override
  public JComponent getPreferredFocusedComponent() {
    return myList;
  }

  @Override
  protected void doOKAction() {
    super.doOKAction();

    if (myCurrentProject != null) {
      int exitCode =
          Messages.showDialog(
              IdeBundle.message("prompt.open.project.in.new.frame"),
              IdeBundle.message("title.open.project"),
              new String[] {
                IdeBundle.message("button.newframe"), IdeBundle.message("button.existingframe")
              },
              1,
              Messages.getQuestionIcon());
      if (exitCode == 1) {
        ProjectUtil.closeAndDispose(myCurrentProject);
      }
    }

    final ProjectOptions myOptions = new ProjectOptions();
    myOptions.setProjectName(myProjectName.getText());
    myOptions.setProjectPath(myProjectPath.getPath());
    myOptions.setCreateNewLanguage(false);
    myOptions.setCreateNewSolution(false);
    myOptions.setStorageScheme(myProjectFormatPanel.isDefault());

    // invoke later is for plugins to be ready
    ApplicationManager.getApplication()
        .invokeLater(
            new Runnable() {
              @Override
              public void run() {
                try {
                  ProjectFactory factory = new ProjectFactory(myCurrentProject, myOptions);
                  Project project = factory.createProject();
                  myCurrentTemplateItem
                      .getTemplateFiller()
                      .fillProjectWithModules(project.getComponent(MPSProject.class));
                  factory.activate();
                } catch (ProjectNotCreatedException e) {
                  Messages.showErrorDialog(getContentPane(), e.getMessage());
                }
              }
            });
  }

  class TemplateItem {

    private final MPSProjectTemplate myTemplate;
    private final ProjectTemplatesGroup myGroup;

    TemplateItem(MPSProjectTemplate template, ProjectTemplatesGroup group) {
      myTemplate = template;
      myGroup = group;
    }

    String getName() {
      return myTemplate.getName();
    }

    String getGroupName() {
      return myGroup.getName();
    }

    Icon getIcon() {
      return myTemplate.getIcon();
    }

    @Nullable
    String getDescription() {
      return myTemplate.getDescription();
    }

    @Nullable
    JComponent getSettings() {
      return myTemplate.getSettings();
    }

    TemplateFiller getTemplateFiller() {
      return myTemplate.getTemplateFiller();
    }

    void setNewProjectPath(String newValue) {
      myTemplate.setProjectPath(newValue);
    }
  }
}