diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.form
new file mode 100644
index 000000000000..60af5653a56a
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.form
@@ -0,0 +1,55 @@
+
+
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.java
new file mode 100644
index 000000000000..1acf03349249
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2000-2013 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.projectWizard;
+
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.popup.ListItemDescriptor;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.platform.ProjectTemplate;
+import com.intellij.platform.templates.ArchivedProjectTemplate;
+import com.intellij.ui.CollectionListModel;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.popup.list.GroupedItemsListRenderer;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 12/24/13
+ */
+public class ProjectTemplateList extends JPanel {
+
+ private JBList myList;
+ private JPanel myPanel;
+ private JTextPane myDescriptionPane;
+ private ProjectTemplate myFirstArchivedTemplate;
+
+ public ProjectTemplateList() {
+ super(new BorderLayout());
+ add(myPanel, BorderLayout.CENTER);
+
+ myList.setCellRenderer(new GroupedItemsListRenderer(new ListItemDescriptor() {
+ @Nullable
+ @Override
+ public String getTextFor(ProjectTemplate value) {
+ return value.getName();
+ }
+
+ @Nullable
+ @Override
+ public String getTooltipFor(ProjectTemplate value) {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Icon getIconFor(ProjectTemplate value) {
+ return value.getIcon();
+ }
+
+ @Override
+ public boolean hasSeparatorAboveOf(ProjectTemplate value) {
+ return value == myFirstArchivedTemplate;
+ }
+
+ @Nullable
+ @Override
+ public String getCaptionAboveOf(ProjectTemplate value) {
+ return "Project Templates";
+ }
+ }));
+
+
+ myList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ myDescriptionPane.setText("");
+ ProjectTemplate template = getSelectedTemplate();
+ if (template != null) {
+ String description = template.getDescription();
+ if (StringUtil.isNotEmpty(description)) {
+ description = "' + description +
+ "";
+ myDescriptionPane.setText(description);
+ }
+ }
+ }
+ });
+
+ Messages.installHyperlinkSupport(myDescriptionPane);
+ }
+
+ public void setTemplates(List list) {
+ Collections.sort(list, new Comparator() {
+ @Override
+ public int compare(ProjectTemplate o1, ProjectTemplate o2) {
+ return Comparing.compare(o1 instanceof ArchivedProjectTemplate, o2 instanceof ArchivedProjectTemplate);
+ }
+ });
+ myFirstArchivedTemplate = ContainerUtil.find(list, new Condition() {
+ @Override
+ public boolean value(ProjectTemplate template) {
+ return template instanceof ArchivedProjectTemplate;
+ }
+ });
+
+ int index = myList.getSelectedIndex();
+ //noinspection unchecked
+ myList.setModel(new CollectionListModel(list));
+ myList.setSelectedIndex(index == -1 ? 0 : index);
+ }
+
+ public ProjectTemplate getSelectedTemplate() {
+ return (ProjectTemplate)myList.getSelectedValue();
+ }
+
+ public void addListSelectionListener(ListSelectionListener listener) {
+ myList.addListSelectionListener(listener);
+ }
+
+ public boolean setSelectedTemplate(String name) {
+ ListModel model1 = myList.getModel();
+ for (int j = 0; j < model1.getSize(); j++) {
+ if (name.equals(((ProjectTemplate)model1.getElementAt(j)).getName())) {
+ myList.setSelectedIndex(j);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void setPaintBusy(boolean b) {
+ myList.setPaintBusy(b);
+ }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
index b9956d276498..10682f75335f 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.form
@@ -55,43 +55,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
index 9fcbd21b7771..f13e3ea38fb8 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java
@@ -25,11 +25,8 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
-import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.ProjectTemplateEP;
import com.intellij.platform.templates.ArchivedProjectTemplate;
@@ -71,8 +68,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
private JPanel myPanel;
private JPanel myOptionsPanel;
private JBList myProjectTypeList;
- private JTextPane myDescription;
- private JBList myTemplatesList;
+ private ProjectTemplateList myTemplatesList;
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private final FactoryMap myBuilders = new FactoryMap() {
@@ -83,8 +79,8 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
}
};
private final Set myCards = new HashSet();
-
private final MultiMap myTemplatesMap;
+ private boolean myRemoteTemplatesLoaded;
public ProjectTypeStep(WizardContext context, NewProjectWizard wizard, ModulesProvider modulesProvider) {
myContext = context;
@@ -154,23 +150,17 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
}
});
- myTemplatesList.setCellRenderer(new ColoredListCellRenderer() {
- @Override
- protected void customizeCellRenderer(JList list, ProjectTemplate value, int index, boolean selected, boolean hasFocus) {
- append(value.getName()).setIcon(value.getIcon());
- }
- });
- myTemplatesList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ myTemplatesList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
updateSelection();
}
});
+
for (ProjectTemplate category : myTemplatesMap.values()) {
myWizard.getSequence().addStepsForBuilder(myBuilders.get(category), context, modulesProvider);
}
- Messages.installHyperlinkSupport(myDescription);
myProjectTypeList.setSelectedIndex(0);
}
@@ -180,21 +170,39 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
TemplatesGroup group = getSelectedGroup();
if (group == null) return;
Collection templates = myTemplatesMap.get(group);
- String card = DEFAULT_CARD;
+ if (!selectCustomOptions(templates)) {
+ setTemplatesList(group, templates);
+ ((CardLayout)myOptionsPanel.getLayout()).show(myOptionsPanel, DEFAULT_CARD);
+ }
+ updateSelection();
+ }
+
+ private void setTemplatesList(TemplatesGroup group, Collection templates) {
+ ArrayList list = new ArrayList(templates);
+ if (group.getParentGroup() == null) {
+ for (TemplatesGroup templatesGroup : myTemplatesMap.keySet()) {
+ if (group.getName().equals(templatesGroup.getParentGroup())) {
+ list.addAll(myTemplatesMap.get(templatesGroup));
+ }
+ }
+ }
+ myTemplatesList.setTemplates(list);
+ }
+
+ private boolean selectCustomOptions(Collection templates) {
if (templates.size() == 1) {
ModuleBuilder builder = myBuilders.get(templates.iterator().next());
JComponent panel = builder.getCustomOptionsPanel(this);
if (panel != null) {
- card = builder.getBuilderId();
+ String card = builder.getBuilderId();
if (myCards.add(card)) {
myOptionsPanel.add(panel, card);
}
+ ((CardLayout)myOptionsPanel.getLayout()).show(myOptionsPanel, card);
+ return true;
}
}
- myTemplatesList.setModel(new CollectionListModel(templates));
- myTemplatesList.setSelectedIndex(0);
- ((CardLayout)myOptionsPanel.getLayout()).show(myOptionsPanel, card);
- updateSelection();
+ return false;
}
private TemplatesGroup getSelectedGroup() {
@@ -212,7 +220,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
return template;
}
}
- return (ProjectTemplate)myTemplatesList.getSelectedValue();
+ return myTemplatesList.getSelectedTemplate();
}
@Nullable
@@ -236,7 +244,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
@Override
public void updateStep() {
- if (myContext.isCreatingNewProject()) {
+ if (myContext.isCreatingNewProject() && !myRemoteTemplatesLoaded) {
loadRemoteTemplates();
}
}
@@ -256,13 +264,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
for (int i = 0; i < model.getSize(); i++) {
if (group.equals(((TemplatesGroup)model.getElementAt(i)).getName())) {
myProjectTypeList.setSelectedIndex(i);
- ListModel model1 = myTemplatesList.getModel();
- for (int j = 0; j < model1.getSize(); j++) {
- if (name.equals(((ProjectTemplate)model1.getElementAt(j)).getName())) {
- myTemplatesList.setSelectedIndex(j);
- return true;
- }
- }
+ return myTemplatesList.setSelectedTemplate(name);
}
}
return false;
@@ -315,14 +317,13 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
TemplatesGroup group = getSelectedGroup();
if (group == null) return;
Collection templates = myTemplatesMap.get(group);
- int index = myTemplatesList.getSelectedIndex();
- myTemplatesList.setModel(new CollectionListModel(templates));
- myTemplatesList.setSelectedIndex(index);
+ setTemplatesList(group, templates);
}
});
}
finally {
myTemplatesList.setPaintBusy(false);
+ myRemoteTemplatesLoaded = true;
}
}
});
@@ -334,19 +335,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
}
private void updateSelection() {
- ProjectTemplate template = getSelectedTemplate();
- if (template != null) {
- String description = template.getDescription();
- if (StringUtil.isNotEmpty(description)) {
- description = "' + description +
- "";
- myDescription.setText(description);
- }
- }
- else {
- myDescription.setText("");
- }
ModuleBuilder builder = getSelectedBuilder();
if (builder != null) {
myContext.setProjectBuilder(builder);
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypesList.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypesList.java
deleted file mode 100644
index d557a89c3883..000000000000
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypesList.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2000-2013 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.projectWizard;
-
-import com.intellij.ide.util.newProjectWizard.SelectTemplateSettings;
-import com.intellij.ide.util.newProjectWizard.TemplatesGroup;
-import com.intellij.ide.util.projectWizard.ModuleBuilder;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CustomShortcutSet;
-import com.intellij.openapi.module.ModuleType;
-import com.intellij.openapi.ui.popup.ListItemDescriptor;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Pair;
-import com.intellij.platform.ProjectTemplatesFactory;
-import com.intellij.ui.CollectionListModel;
-import com.intellij.ui.ListSpeedSearch;
-import com.intellij.ui.SpeedSearchComparator;
-import com.intellij.ui.components.JBList;
-import com.intellij.ui.popup.list.GroupedItemsListRenderer;
-import com.intellij.util.containers.FactoryMap;
-import com.intellij.util.containers.MultiMap;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.util.*;
-
-/**
- * @author Dmitry Avdeev
- * Date: 11/21/12
- */
-public class ProjectTypesList implements Disposable {
-
- private final JBList myList;
- private final CollectionListModel myModel;
- private Pair myBestMatch;
-
- public ProjectTypesList(JBList list, MultiMap map, FactoryMap builders) {
-
- myList = list;
- myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-
- new ListSpeedSearch(myList) {
- @Override
- protected String getElementText(Object element) {
- return super.getElementText(element);
- }
- }.setComparator(new SpeedSearchComparator(false));
- List items = buildItems(map, builders);
- myModel = new CollectionListModel(items);
-
- 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 = myModel.getElementIndex(item);
- return index == 0 || !myModel.getElementAt(index - 1).getGroupName().equals(item.getGroupName());
- }
-
- @Nullable
- @Override
- public String getCaptionAboveOf(Object value) {
- return ((TemplateItem)value).getGroupName();
- }
- }));
-
- myList.setModel(myModel);
- }
-
- void installKeyAction(JComponent component) {
- 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), component);
- }
-
- void resetSelection() {
- if (myList.getSelectedIndex() != -1) return;
- SelectTemplateSettings settings = SelectTemplateSettings.getInstance();
- if (settings.getLastGroup() == null || !setSelectedType(settings.getLastGroup(), settings.getLastTemplate())) {
- myList.setSelectedIndex(0);
- }
- }
-
- void saveSelection() {
- TemplateItem item = (TemplateItem)myList.getSelectedValue();
- if (item != null) {
- SelectTemplateSettings.getInstance().setLastTemplate(item.getGroupName(), item.getName());
- }
- }
-
- private static List buildItems(final MultiMap map, final FactoryMap builders) {
- List items = new ArrayList();
- List groups = new ArrayList(map.keySet());
-
- final Map moduleTypeMap = new HashMap();
- for (ProjectCategory category : map.values()) {
- ModuleType type = builders.get(category).getModuleType();
- Integer integer = moduleTypeMap.get(type);
- moduleTypeMap.put(type, integer == null ? 0 : integer + 1);
- }
-
- Collections.sort(groups, new Comparator() {
- @Override
- public int compare(TemplatesGroup o1, TemplatesGroup o2) {
- int weight = Comparing.compare(o1.getName().equals(ProjectTemplatesFactory.OTHER_GROUP), o2.getName().equals(ProjectTemplatesFactory.OTHER_GROUP));
- if (weight != 0) return weight;
- int byModuleType = getModuleTypePopularity(o2, map, builders, moduleTypeMap) - getModuleTypePopularity(o1, map, builders, moduleTypeMap);
- if (byModuleType != 0) return byModuleType;
- int i = map.get(o2).size() - map.get(o1).size(); // compare group size
- return i == 0 ? o1.compareTo(o2) : i;
- }
- });
-
- for (TemplatesGroup group : groups) {
- for (ProjectCategory template : map.get(group)) {
- TemplateItem templateItem = new TemplateItem(template, group.getName());
- items.add(templateItem);
- }
- }
- return items;
- }
-
- private static int getModuleTypePopularity(TemplatesGroup group,
- MultiMap map,
- FactoryMap builders,
- Map moduleTypeMap) {
- int moduleTypePopularity = 0;
- for (ProjectCategory category : map.get(group)) {
- ModuleType type = builders.get(category).getModuleType();
- moduleTypePopularity = Math.max(moduleTypePopularity, moduleTypeMap.get(type));
- }
- return moduleTypePopularity;
- }
-
- @Nullable
- public ProjectCategory getSelectedType() {
- Object value = myList.getSelectedValue();
- return value instanceof TemplateItem ? ((TemplateItem)value).myTemplate : null;
- }
-
- public boolean setSelectedType(@Nullable String group, @Nullable String name) {
- for (int i = 0; i < myList.getModel().getSize(); i++) {
- Object o = myList.getModel().getElementAt(i);
- if (o instanceof TemplateItem && ((TemplateItem)o).myGroup.equals(group) && ((TemplateItem)o).getName().equals(name)) {
- myList.setSelectedIndex(i);
- myList.ensureIndexIsVisible(i);
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public void dispose() {
- }
-
- static class TemplateItem {
-
- private final ProjectCategory myTemplate;
- private final String myGroup;
-
- TemplateItem(ProjectCategory template, String group) {
- myTemplate = template;
- myGroup = group;
- }
-
- String getName() {
- return myTemplate.getDisplayName();
- }
-
- public String getGroupName() {
- return myGroup;
- }
-
- Icon getIcon() {
- return myTemplate.createModuleBuilder().getNodeIcon();
- }
-
- @Nullable
- String getDescription() {
- return myTemplate.getDescription();
- }
-
- @Override
- public String toString() {
- return getName() + " " + getGroupName();
- }
- }
-}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java
index e77761706495..ae9dee1448a5 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java
@@ -22,18 +22,18 @@ import javax.swing.*;
/**
* @author kir
*/
-public interface ListItemDescriptor {
+public interface ListItemDescriptor {
@Nullable
- String getTextFor(Object value);
+ String getTextFor(T value);
@Nullable
- String getTooltipFor(Object value);
+ String getTooltipFor(T value);
@Nullable
- Icon getIconFor(Object value);
+ Icon getIconFor(T value);
- boolean hasSeparatorAboveOf(Object value);
+ boolean hasSeparatorAboveOf(T value);
@Nullable
- String getCaptionAboveOf(Object value);
+ String getCaptionAboveOf(T value);
}