//
//
//
//
// $Revision$
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.XmlForms;
using ICSharpCode.SharpDevelop.Internal.Templates;
namespace ICSharpCode.SharpDevelop.Project.Dialogs
{
///
/// This class displays a new project dialog and sets up and creates a a new project,
/// the project types are described in an XML options file
///
public class NewProjectDialog : BaseSharpDevelopForm
{
protected Container components = new System.ComponentModel.Container();
protected List alltemplates = new List();
protected List categories = new List();
// icon resource name => image index
protected Dictionary icons = new Dictionary();
protected bool createNewSolution;
public NewProjectDialog(bool createNewSolution)
{
StandardHeader.SetHeaders();
this.createNewSolution = createNewSolution;
InitializeComponents();
InitializeTemplates();
InitializeView();
((TreeView)ControlDictionary["categoryTreeView"]).Select();
((TextBox)ControlDictionary["locationTextBox"]).Text = PropertyService.Get("ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.DefaultPath", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "SharpDevelop Projects"));
StartPosition = FormStartPosition.CenterParent;
Icon = null;
}
protected virtual void InitializeView()
{
ImageList smalllist = new ImageList();
ImageList imglist = new ImageList();
smalllist.ColorDepth = ColorDepth.Depth32Bit;
imglist.ColorDepth = ColorDepth.Depth32Bit;
imglist.ImageSize = new Size(32, 32);
smalllist.ImageSize = new Size(16, 16);
smalllist.Images.Add(ResourceService.GetBitmap("Icons.32x32.EmptyProjectIcon"));
imglist.Images.Add(ResourceService.GetBitmap("Icons.32x32.EmptyProjectIcon"));
// load the icons and set their index from the image list in the hashtable
int i = 0;
Dictionary tmp = new Dictionary(icons);
foreach (KeyValuePair entry in icons) {
Bitmap bitmap = IconService.GetBitmap(entry.Key);
if (bitmap != null) {
smalllist.Images.Add(bitmap);
imglist.Images.Add(bitmap);
tmp[entry.Key] = ++i;
} else {
LoggingService.Warn("NewProjectDialog: can't load bitmap " + entry.Key.ToString() + " using default");
}
}
// set the correct imageindex for all templates
icons = tmp;
foreach (TemplateItem item in alltemplates) {
if (item.Template.Icon == null) {
item.ImageIndex = 0;
} else {
item.ImageIndex = icons[item.Template.Icon];
}
}
((ListView)ControlDictionary["templateListView"]).LargeImageList = imglist;
((ListView)ControlDictionary["templateListView"]).SmallImageList = smalllist;
InsertCategories(null, categories);
((TreeView)ControlDictionary["categoryTreeView"]).TreeViewNodeSorter = new TemplateCategoryComparer();
((TreeView)ControlDictionary["categoryTreeView"]).Sort();
SelectLastSelectedCategoryNode(((TreeView)ControlDictionary["categoryTreeView"]).Nodes, PropertyService.Get("Dialogs.NewProjectDialog.LastSelectedCategory", "C#"));
}
void InsertCategories(TreeNode node, IEnumerable catarray)
{
foreach (Category cat in catarray) {
if (node == null) {
((TreeView)ControlDictionary["categoryTreeView"]).Nodes.Add(cat);
} else {
node.Nodes.Add(cat);
}
InsertCategories(cat, cat.Categories);
}
}
protected Category GetCategory(string categoryname, string subcategoryname)
{
foreach (Category category in categories) {
if (category.Text == categoryname) {
if (subcategoryname == null) {
return category;
} else {
return GetSubcategory(category, subcategoryname);
}
}
}
Category newcategory = new Category(categoryname, TemplateCategorySortOrderFile.GetProjectCategorySortOrder(categoryname));
categories.Add(newcategory);
if (subcategoryname != null) {
return GetSubcategory(newcategory, subcategoryname);
}
return newcategory;
}
Category GetSubcategory(Category parentCategory, string name)
{
foreach (Category subcategory in parentCategory.Categories) {
if (subcategory.Text == name)
return subcategory;
}
Category newsubcategory = new Category(name, TemplateCategorySortOrderFile.GetProjectCategorySortOrder(parentCategory.Name, name));
parentCategory.Categories.Add(newsubcategory);
return newsubcategory;
}
protected virtual void InitializeTemplates()
{
foreach (ProjectTemplate template in ProjectTemplate.ProjectTemplates) {
if (template.ProjectDescriptor == null && createNewSolution == false) {
// Do not show solution template when added a new project to existing solution
continue;
}
TemplateItem titem = new TemplateItem(template);
if (titem.Template.Icon != null) {
icons[titem.Template.Icon] = 0; // "create template icon"
}
if (template.NewProjectDialogVisible == true) {
Category cat = GetCategory(StringParser.Parse(titem.Template.Category), StringParser.Parse(titem.Template.Subcategory));
cat.Templates.Add(titem);
if (cat.Templates.Count == 1)
titem.Selected = true;
}
alltemplates.Add(titem);
}
}
protected void CategoryChange(object sender, TreeViewEventArgs e)
{
((ListView)ControlDictionary["templateListView"]).Items.Clear();
if (((TreeView)ControlDictionary["categoryTreeView"]).SelectedNode != null) {
foreach (TemplateItem item in ((Category)((TreeView)ControlDictionary["categoryTreeView"]).SelectedNode).Templates) {
((ListView)ControlDictionary["templateListView"]).Items.Add(item);
}
}
this.SelectedIndexChange(sender, e);
}
void OnBeforeExpand(object sender, TreeViewCancelEventArgs e)
{
e.Node.ImageIndex = 1;
}
void OnBeforeCollapse(object sender, TreeViewCancelEventArgs e)
{
e.Node.ImageIndex = 0;
}
void CheckedChange(object sender, EventArgs e)
{
((TextBox)ControlDictionary["solutionNameTextBox"]).ReadOnly = !((CheckBox)ControlDictionary["createSeparateDirCheckBox"]).Checked;
if (((TextBox)ControlDictionary["solutionNameTextBox"]).ReadOnly) { // unchecked created own directory for solution
NameTextChanged(null, null); // set the value of the ((TextBox)ControlDictionary["solutionNameTextBox"]) to ((TextBox)ControlDictionary["nameTextBox"])
}
}
void NameTextChanged(object sender, EventArgs e)
{
if (!((CheckBox)ControlDictionary["createSeparateDirCheckBox"]).Checked) {
((TextBox)ControlDictionary["solutionNameTextBox"]).Text = ((TextBox)ControlDictionary["nameTextBox"]).Text.Trim();
}
}
string ProjectSolution {
get {
string name = String.Empty;
if (((CheckBox)ControlDictionary["createSeparateDirCheckBox"]).Checked) {
name += Path.DirectorySeparatorChar + ((TextBox)ControlDictionary["solutionNameTextBox"]).Text.Trim();
}
return ProjectLocation + name;
}
}
string ProjectLocation {
get {
string location = ((TextBox)ControlDictionary["locationTextBox"]).Text.TrimEnd('\\', '/', Path.DirectorySeparatorChar);
string name = ((TextBox)ControlDictionary["nameTextBox"]).Text.Trim();
return location.Trim() + (((CheckBox)ControlDictionary["autoCreateSubDirCheckBox"]).Checked ? Path.DirectorySeparatorChar + name : String.Empty);
}
}
void PathChanged(object sender, EventArgs e)
{
string solutionPath = ProjectSolution;
try {
if (solutionPath.Length > 3 && Path.IsPathRooted(solutionPath)) {
solutionPath = solutionPath.Substring(3);
bool didCut = false;
const int maxLength = 62;
while (solutionPath.Length > maxLength && solutionPath.Length > 1) {
int idx = solutionPath.IndexOf(Path.DirectorySeparatorChar, 1);
if (idx < 0) {
break;
}
solutionPath = solutionPath.Substring(idx);
didCut = true;
}
solutionPath = ProjectSolution.Substring(0, 3) + (didCut ? "..." : "") + solutionPath;
if (solutionPath.Length > maxLength + 6) {
solutionPath = solutionPath.Substring(0, maxLength + 3) + "...";
}
}
} catch (ArgumentException) {
ControlDictionary["createInLabel"].Text = ResourceService.GetString("ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.IllegalProjectNameError").Replace("\n", " ").Replace("\r", "");
return;
}
ControlDictionary["createInLabel"].Text = ResourceService.GetString("Dialog.NewProject.ProjectAtDescription")+ " " + solutionPath;
}
void IconSizeChange(object sender, EventArgs e)
{
((ListView)ControlDictionary["templateListView"]).View = ((RadioButton)ControlDictionary["smallIconsRadioButton"]).Checked ? View.List : View.LargeIcon;
}
public string NewProjectLocation;
public string NewCombineLocation;
void OpenEvent(object sender, EventArgs e)
{
if (((TreeView)ControlDictionary["categoryTreeView"]).SelectedNode != null) {
PropertyService.Set("Dialogs.NewProjectDialog.LastSelectedCategory", ((TreeView)ControlDictionary["categoryTreeView"]).SelectedNode.Text);
PropertyService.Set("Dialogs.NewProjectDialog.LargeImages", ((RadioButton)ControlDictionary["largeIconsRadioButton"]).Checked);
}
string solution = ((TextBox)ControlDictionary["solutionNameTextBox"]).Text.Trim();
string name = ((TextBox)ControlDictionary["nameTextBox"]).Text.Trim();
string location = ((TextBox)ControlDictionary["locationTextBox"]).Text.Trim();
if (!FileUtility.IsValidFileName(solution)
|| solution.IndexOf(Path.DirectorySeparatorChar) >= 0
|| solution.IndexOf(Path.AltDirectorySeparatorChar) >= 0
|| !FileUtility.IsValidFileName(name)
|| name.IndexOf(Path.AltDirectorySeparatorChar) >= 0
|| name.IndexOf(Path.DirectorySeparatorChar) >= 0
|| !FileUtility.IsValidFileName(location))
{
MessageService.ShowError("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.IllegalProjectNameError}");
return;
}
if (!char.IsLetter(name[0]) && name[0] != '_') {
MessageService.ShowError("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.ProjectNameMustStartWithLetter}");
return;
}
if (name.EndsWith(".")) {
MessageService.ShowError("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.ProjectNameMustNotEndWithDot}");
return;
}
PropertyService.Set("ICSharpCode.SharpDevelop.Gui.NewProjectDialog.AutoCreateProjectSubdir", ((CheckBox)ControlDictionary["autoCreateSubDirCheckBox"]).Checked);
if (((ListView)ControlDictionary["templateListView"]).SelectedItems.Count == 1 && ((TextBox)ControlDictionary["locationTextBox"]).Text.Length > 0 && ((TextBox)ControlDictionary["solutionNameTextBox"]).Text.Length > 0) {
TemplateItem item = (TemplateItem)((ListView)ControlDictionary["templateListView"]).SelectedItems[0];
try {
System.IO.Directory.CreateDirectory(ProjectSolution);
} catch (Exception) {
MessageService.ShowError("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.CantCreateDirectoryError}");
return;
}
ProjectCreateInformation cinfo = new ProjectCreateInformation();
if (!createNewSolution) {
cinfo.Solution = ProjectService.OpenSolution;
}
cinfo.SolutionPath = ProjectLocation;
cinfo.ProjectBasePath = ProjectSolution;
cinfo.ProjectName = name;
NewCombineLocation = item.Template.CreateProject(cinfo);
if (NewCombineLocation == null || NewCombineLocation.Length == 0) {
return;
}
if (createNewSolution) {
ProjectService.LoadSolutionOrProject(NewCombineLocation);
item.Template.RunOpenActions(cinfo);
}
NewProjectLocation = cinfo.CreatedProjects.Count > 0 ? cinfo.CreatedProjects[0] : "";
DialogResult = DialogResult.OK;
}
}
void BrowseDirectories(object sender, EventArgs e)
{
FolderDialog fd = new FolderDialog();
if (fd.DisplayDialog("${res:Dialog.NewProject.SelectDirectoryForProject}") == DialogResult.OK) {
((TextBox)ControlDictionary["locationTextBox"]).Text = fd.Path;
}
// End
}
// list view event handlers
void SelectedIndexChange(object sender, EventArgs e)
{
if (((ListView)ControlDictionary["templateListView"]).SelectedItems.Count == 1) {
ControlDictionary["descriptionLabel"].Text = StringParser.Parse(((TemplateItem)((ListView)ControlDictionary["templateListView"]).SelectedItems[0]).Template.Description);
ControlDictionary["openButton"].Enabled = true;
} else {
ControlDictionary["descriptionLabel"].Text = String.Empty;
ControlDictionary["openButton"].Enabled = false;
}
}
TreeNode SelectLastSelectedCategoryNode(TreeNodeCollection nodes, string name)
{
foreach (TreeNode node in nodes) {
if (node.Name == name) {
((TreeView)ControlDictionary["categoryTreeView"]).SelectedNode = node;
node.ExpandAll();
return node;
}
TreeNode selectedNode = SelectLastSelectedCategoryNode(node.Nodes, name);
if (selectedNode != null) {
return selectedNode;
}
}
return null;
}
protected void InitializeComponents()
{
SetupFromXmlStream(this.GetType().Assembly.GetManifestResourceStream("Resources.NewProjectDialog.xfrm"));
ImageList imglist = new ImageList();
imglist.ColorDepth = ColorDepth.Depth32Bit;
imglist.Images.Add(IconService.GetBitmap("Icons.16x16.OpenFolderBitmap"));
imglist.Images.Add(IconService.GetBitmap("Icons.16x16.ClosedFolderBitmap"));
((TreeView)ControlDictionary["categoryTreeView"]).ImageList = imglist;
((ListView)ControlDictionary["templateListView"]).DoubleClick += new EventHandler(OpenEvent);
((ListView)ControlDictionary["templateListView"]).SelectedIndexChanged += new EventHandler(SelectedIndexChange);
((TreeView)ControlDictionary["categoryTreeView"]).AfterSelect += new TreeViewEventHandler(CategoryChange);
((TreeView)ControlDictionary["categoryTreeView"]).BeforeSelect += new TreeViewCancelEventHandler(OnBeforeExpand);
((TreeView)ControlDictionary["categoryTreeView"]).BeforeExpand += new TreeViewCancelEventHandler(OnBeforeExpand);
((TreeView)ControlDictionary["categoryTreeView"]).BeforeCollapse += new TreeViewCancelEventHandler(OnBeforeCollapse);
((TextBox)ControlDictionary["solutionNameTextBox"]).TextChanged += new EventHandler(PathChanged);
((TextBox)ControlDictionary["nameTextBox"]).TextChanged += new EventHandler(NameTextChanged);
((TextBox)ControlDictionary["nameTextBox"]).TextChanged += new EventHandler(PathChanged);
((TextBox)ControlDictionary["locationTextBox"]).TextChanged += new EventHandler(PathChanged);
((RadioButton)ControlDictionary["largeIconsRadioButton"]).Checked = PropertyService.Get("Dialogs.NewProjectDialog.LargeImages", true);
((RadioButton)ControlDictionary["largeIconsRadioButton"]).CheckedChanged += new EventHandler(IconSizeChange);
((RadioButton)ControlDictionary["largeIconsRadioButton"]).FlatStyle = FlatStyle.Standard;
((RadioButton)ControlDictionary["largeIconsRadioButton"]).Image = IconService.GetBitmap("Icons.16x16.LargeIconsIcon");
((RadioButton)ControlDictionary["smallIconsRadioButton"]).Checked = !PropertyService.Get("Dialogs.NewProjectDialog.LargeImages", true);
((RadioButton)ControlDictionary["smallIconsRadioButton"]).CheckedChanged += new EventHandler(IconSizeChange);
((RadioButton)ControlDictionary["smallIconsRadioButton"]).FlatStyle = FlatStyle.Standard;
((RadioButton)ControlDictionary["smallIconsRadioButton"]).Image = IconService.GetBitmap("Icons.16x16.SmallIconsIcon");
ControlDictionary["openButton"] .Click += new EventHandler(OpenEvent);
ControlDictionary["browseButton"].Click += new EventHandler(BrowseDirectories);
((CheckBox)ControlDictionary["createSeparateDirCheckBox"]).CheckedChanged += new EventHandler(CheckedChange);
((CheckBox)ControlDictionary["createSeparateDirCheckBox"]).CheckedChanged += new EventHandler(PathChanged);
((CheckBox)ControlDictionary["autoCreateSubDirCheckBox"]).CheckedChanged += new EventHandler(PathChanged);
ToolTip tooltip = new ToolTip();
tooltip.SetToolTip(ControlDictionary["largeIconsRadioButton"], StringParser.Parse("${res:Global.LargeIconToolTip}"));
tooltip.SetToolTip(ControlDictionary["smallIconsRadioButton"], StringParser.Parse("${res:Global.SmallIconToolTip}"));
tooltip.Active = true;
Owner = (Form)WorkbenchSingleton.Workbench;
StartPosition = FormStartPosition.CenterParent;
Icon = null;
CheckedChange(this, EventArgs.Empty);
IconSizeChange(this, EventArgs.Empty);
}
///
/// Represents a category
///
public class Category : TreeNode, ICategory
{
List categories = new List();
List templates = new List();
int sortOrder = TemplateCategorySortOrderFile.UndefinedSortOrder;
public Category(string name) : this(name, TemplateCategorySortOrderFile.UndefinedSortOrder)
{
}
public Category(string name, int sortOrder) : base(StringParser.Parse(name))
{
this.Name = StringParser.Parse(name);
ImageIndex = 1;
this.sortOrder = sortOrder;
}
public int SortOrder {
get {
return sortOrder;
}
set {
sortOrder = value;
}
}
public List Categories {
get {
return categories;
}
}
public List Templates {
get {
return templates;
}
}
}
///
/// Holds a new file template
///
public class TemplateItem : ListViewItem
{
ProjectTemplate template;
public TemplateItem(ProjectTemplate template) : base(StringParser.Parse(template.Name))
{
this.template = template;
ImageIndex = 0;
}
public ProjectTemplate Template {
get {
return template;
}
}
}
}
}