Browse Source

Apply patch from Boris Kozorovitzky:

1. Change order of creating a project from a template:
 - users are asked about overwriting files first before anything gets written to disk
 - write files to disk before calling CreateProject so that the IProjectBinding implementation can use the files that were written by the template
2. Don't read binary files used in file/project templates into memory. Instead, use File.Copy to copy the file directly into the new project.
3. Avoid crash if IProject implementation does not provide IProjectItemListProvider.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6069 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Daniel Grunwald 15 years ago
parent
commit
aeb06aa320
  1. 4
      data/resources/StringResources.resx
  2. 12
      src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs
  3. 2
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/CreateKey.cs
  4. 8
      src/Main/Base/Project/Src/Internal/Templates/File/FileDescriptionTemplate.cs
  5. 177
      src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs

4
data/resources/StringResources.resx

@ -4769,10 +4769,10 @@ Only letters, digits, space, '.' or '_' are allowed.</value> @@ -4769,10 +4769,10 @@ Only letters, digits, space, '.' or '_' are allowed.</value>
<value>Project file ${projectLocation} already exists, do you want to overwrite the existing file ?</value>
</data>
<data name="ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion" xml:space="preserve">
<value>File ${fileName} already exists, do you want to overwrite the existing file ?</value>
<value>The File(s) ${fileNames} already exist, do you want to overwrite the existing file(s)?</value>
</data>
<data name="ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion.InfoName" xml:space="preserve">
<value>File already exists</value>
<value>File(s) already exist</value>
</data>
<data name="ICSharpCode.SharpDevelop.LoadingFile" xml:space="preserve">
<value>Loading ${Filename}...</value>

12
src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs

@ -369,7 +369,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -369,7 +369,7 @@ namespace ICSharpCode.SharpDevelop.Gui
return true;
}
public void SaveFile(FileDescriptionTemplate newfile, string content, byte[] binaryContent)
public void SaveFile(FileDescriptionTemplate newfile, string content, string binaryFileName)
{
string parsedFileName = StringParser.Parse(newfile.Name);
// Parse twice so that tags used in included standard header are parsed
@ -393,13 +393,13 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -393,13 +393,13 @@ namespace ICSharpCode.SharpDevelop.Gui
if (newfile.IsDependentFile && Path.IsPathRooted(parsedFileName)) {
Directory.CreateDirectory(Path.GetDirectoryName(parsedFileName));
if (binaryContent != null)
File.WriteAllBytes(parsedFileName, binaryContent);
if (!String.IsNullOrEmpty(binaryFileName))
File.Copy(binaryFileName, parsedFileName);
else
File.WriteAllText(parsedFileName, parsedContent, ParserService.DefaultFileEncoding);
ParserService.ParseFile(parsedFileName, new StringTextBuffer(parsedContent));
} else {
if (binaryContent != null) {
if (!String.IsNullOrEmpty(binaryFileName)) {
LoggingService.Warn("binary file was skipped");
return;
}
@ -511,8 +511,8 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -511,8 +511,8 @@ namespace ICSharpCode.SharpDevelop.Gui
ScriptRunner scriptRunner = new ScriptRunner();
foreach (FileDescriptionTemplate newfile in item.Template.FileDescriptionTemplates) {
if (newfile.ContentData != null) {
SaveFile(newfile, null, newfile.ContentData);
if (!String.IsNullOrEmpty(newfile.BinaryFileName)) {
SaveFile(newfile, null, newfile.BinaryFileName);
} else {
SaveFile(newfile, scriptRunner.CompileScript(item.Template, newfile), null);
}

2
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/ProjectOptions/CreateKey.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -71,7 +71,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
if (File.Exists(keyPath)) {
string question = "${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion}";
question = StringParser.Parse(question, new string[,] {{"fileName", keyPath}});
question = StringParser.Parse(question, new string[,] {{"fileNames", keyPath}});
if (!MessageService.AskQuestion(question, "${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion.InfoName}")) {
return false;
}

8
src/Main/Base/Project/Src/Internal/Templates/File/FileDescriptionTemplate.cs

@ -23,7 +23,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -23,7 +23,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
// Either content or contentData is set, the other is null
string content;
byte[] contentData;
string binaryFileName;
string itemType;
Dictionary<string, string> metadata = new Dictionary<string, string>();
@ -70,7 +70,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -70,7 +70,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
string fileName = Path.Combine(hintPath, StringParser.Parse(xml.GetAttribute("src")));
try {
if (xml.HasAttribute("binary") && bool.Parse(xml.GetAttribute("binary"))) {
contentData = File.ReadAllBytes(fileName);
binaryFileName = fileName;
} else {
content = File.ReadAllText(fileName);
}
@ -126,9 +126,9 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -126,9 +126,9 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
}
}
public byte[] ContentData {
public string BinaryFileName {
get {
return contentData;
return binaryFileName;
}
}
}

177
src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs

@ -245,7 +245,9 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -245,7 +245,9 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
}
#endregion
#region Create new project from template
//Show prompt, create files from template, create project, execute command, save project
public IProject CreateProject(ProjectCreateInformation projectCreateInformation, string defaultLanguage)
{
// remember old outerProjectBasePath
@ -305,6 +307,83 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -305,6 +307,83 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
StringParserPropertyContainer.FileCreation["StandardNamespace"] = projectCreateInformation.RootNamespace;
if (File.Exists(projectLocation))
{
if (!MessageService.AskQuestion(
StringParser.Parse("${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteProjectQuestion}",
new StringTagPair("projectLocation", projectLocation)),
"${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion.InfoName}"))
{
return null; //The user doesnt want to overwrite the project...
}
}
//Show prompt if any of the files exist
StringBuilder existingFileNames = new StringBuilder();
foreach (FileDescriptionTemplate file in files)
{
string fileName = Path.Combine(projectCreateInformation.ProjectBasePath, StringParser.Parse(file.Name, new string[,] { { "ProjectName", projectCreateInformation.ProjectName } }));
if (File.Exists(fileName))
{
if (existingFileNames.Length > 0)
existingFileNames.Append(", ");
existingFileNames.Append(Path.GetFileName(fileName));
}
}
bool overwriteFiles = true;
if (existingFileNames.Length > 0)
{
if (!MessageService.AskQuestion(
StringParser.Parse("${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion}",
new StringTagPair("fileNames", existingFileNames.ToString())),
"${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion.InfoName}"))
{
overwriteFiles = false;
}
}
#region Copy files to target directory
foreach (FileDescriptionTemplate file in files)
{
string fileName = Path.Combine(projectCreateInformation.ProjectBasePath, StringParser.Parse(file.Name, new string[,] { { "ProjectName", projectCreateInformation.ProjectName } }));
if (File.Exists(fileName) && !overwriteFiles)
{
continue;
}
try
{
if (!Directory.Exists(Path.GetDirectoryName(fileName))) {
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
}
if (!String.IsNullOrEmpty(file.BinaryFileName)) {
// Binary content
File.Copy(file.BinaryFileName,fileName);
} else {
// Textual content
StreamWriter sr = new StreamWriter(File.Create(fileName), ParserService.DefaultFileEncoding);
string fileContent = StringParser.Parse(file.Content, new string[,] { { "ProjectName", projectCreateInformation.ProjectName }, { "FileName", fileName } });
fileContent = StringParser.Parse(fileContent);
if (EditorControlService.GlobalOptions.IndentationString != "\t") {
fileContent = fileContent.Replace("\t", EditorControlService.GlobalOptions.IndentationString);
}
sr.Write(fileContent);
sr.Close();
}
}
catch (Exception ex)
{
MessageService.ShowException(ex, "Exception writing " + fileName);
}
}
#endregion
#region Create Project
IProject project;
try {
project = languageinfo.CreateProject(projectCreateInformation);
@ -312,24 +391,29 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -312,24 +391,29 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
MessageService.ShowError(ex.Message);
return null;
}
#endregion
#region Create Project Items, Imports and Files
// Add Project items
foreach (ProjectItem projectItem in projectItems) {
ProjectItem newProjectItem = new UnknownProjectItem(
project,
StringParser.Parse(projectItem.ItemType.ItemName),
StringParser.Parse(projectItem.Include)
);
foreach (string metadataName in projectItem.MetadataNames) {
string metadataValue = projectItem.GetMetadata(metadataName);
// if the input contains any special MSBuild sequences, don't escape the value
// we want to escape only when the special characters are introduced by the StringParser.Parse replacement
if (metadataValue.Contains("$(") || metadataValue.Contains("%"))
newProjectItem.SetMetadata(StringParser.Parse(metadataName), StringParser.Parse(metadataValue));
else
newProjectItem.SetEvaluatedMetadata(StringParser.Parse(metadataName), StringParser.Parse(metadataValue));
if (project is IProjectItemListProvider)
{
foreach (ProjectItem projectItem in projectItems) {
ProjectItem newProjectItem = new UnknownProjectItem(
project,
StringParser.Parse(projectItem.ItemType.ItemName),
StringParser.Parse(projectItem.Include)
);
foreach (string metadataName in projectItem.MetadataNames) {
string metadataValue = projectItem.GetMetadata(metadataName);
// if the input contains any special MSBuild sequences, don't escape the value
// we want to escape only when the special characters are introduced by the StringParser.Parse replacement
if (metadataValue.Contains("$(") || metadataValue.Contains("%"))
newProjectItem.SetMetadata(StringParser.Parse(metadataName), StringParser.Parse(metadataValue));
else
newProjectItem.SetEvaluatedMetadata(StringParser.Parse(metadataName), StringParser.Parse(metadataValue));
}
((IProjectItemListProvider)project).AddProjectItem(newProjectItem);
}
((IProjectItemListProvider)project).AddProjectItem(newProjectItem);
}
// Add Imports
@ -377,62 +461,27 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -377,62 +461,27 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
}
// Add Files
foreach (FileDescriptionTemplate file in files) {
string fileName = Path.Combine(projectCreateInformation.ProjectBasePath, StringParser.Parse(file.Name, new string[,] { {"ProjectName", projectCreateInformation.ProjectName} }));
FileProjectItem projectFile = new FileProjectItem(project, project.GetDefaultItemType(fileName));
projectFile.Include = FileUtility.GetRelativePath(project.Directory, fileName);
file.SetProjectItemProperties(projectFile);
if (project is IProjectItemListProvider) {
((IProjectItemListProvider)project).AddProjectItem(projectFile);
if (File.Exists(fileName)) {
if (!MessageService.AskQuestion(
StringParser.Parse("${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion}",
new StringTagPair("fileName", fileName)),
"${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion.InfoName}")) {
continue;
}
}
try {
if (!Directory.Exists(Path.GetDirectoryName(fileName))) {
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
}
if (file.ContentData != null) {
// Binary content
File.WriteAllBytes(fileName, file.ContentData);
} else {
// Textual content
StreamWriter sr = new StreamWriter(File.Create(fileName), ParserService.DefaultFileEncoding);
string fileContent = StringParser.Parse(file.Content, new string[,] { {"ProjectName", projectCreateInformation.ProjectName}, {"FileName", fileName}});
fileContent = StringParser.Parse(fileContent);
if (EditorControlService.GlobalOptions.IndentationString != "\t") {
fileContent = fileContent.Replace("\t", EditorControlService.GlobalOptions.IndentationString);
}
sr.Write(fileContent);
sr.Close();
}
} catch (Exception ex) {
MessageService.ShowException(ex, "Exception writing " + fileName);
foreach (FileDescriptionTemplate file in files) {
string fileName = Path.Combine(projectCreateInformation.ProjectBasePath, StringParser.Parse(file.Name, new string[,] { { "ProjectName", projectCreateInformation.ProjectName } }));
FileProjectItem projectFile = new FileProjectItem(project, project.GetDefaultItemType(fileName));
projectFile.Include = FileUtility.GetRelativePath(project.Directory, fileName);
file.SetProjectItemProperties(projectFile);
((IProjectItemListProvider)project).AddProjectItem(projectFile);
}
}
#endregion
RunCreateActions(project);
// Save project
if (File.Exists(projectLocation)) {
if (MessageService.AskQuestion(
StringParser.Parse("${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteProjectQuestion}",
new StringTagPair("projectLocation", projectLocation)),
"${res:ICSharpCode.SharpDevelop.Internal.Templates.ProjectDescriptor.OverwriteQuestion.InfoName}"))
{
project.Save();
}
} else {
project.Save();
}
project.Save();
projectCreateInformation.createdProjects.Add(project);
ProjectService.OnProjectCreated(new ProjectEventArgs(project));

Loading…
Cancel
Save