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); } } }