Skip to content
This repository was archived by the owner on Nov 27, 2019. It is now read-only.

Commit e5b17a3

Browse files
committed
Add 'CreateActions' to FileTemplate, and use them to start the report wizard instead of relying on IsDirty.
1 parent 56ef4ff commit e5b17a3

File tree

6 files changed

+114
-72
lines changed

6 files changed

+114
-72
lines changed

src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/EmptyReport.xft

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@
99
language = "SharpDevelopReports"/>
1010

1111
<Description>${res:Templates.SharpReport.NewReport}</Description>
12-
12+
1313
<Files>
1414
<File name="${FullName}" language="SharpDevelopReports"/>
1515
</Files>
1616

17+
<!-- FileTemplate CreateActions run after the files were created, but before they are opened -->
18+
<CreateActions>
19+
<RunCommand path = "/SharpDevelopReports/TemplateCommands/ShowReportWizard" />
20+
</CreateActions>
21+
1722
<AdditionalOptions/>
1823
</Template>
1924

src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.addin

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
class="ICSharpCode.Reporting.Addin.DesignerBinding.ReportDesignerBinding" />
2727
</Path>
2828

29+
<Path name = "/SharpDevelopReports/TemplateCommands">
30+
<Class id="ShowReportWizard"
31+
class="ICSharpCode.Reporting.Addin.ReportWizard.ReportWizardCommand"/>
32+
</Path>
33+
2934
<!-- Tools Menu
3035
<Path name="/SharpDevelop/Workbench/Tools">
3136
<MenuItem id="ReportGeneratorPad"

src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignerBinding/DesignerBinding.cs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,35 +44,10 @@ public double AutoDetectFileContent(FileName fileName, System.IO.Stream fileCont
4444

4545
public IViewContent CreateContentForFile(OpenedFile file)
4646
{
47-
if (file.IsDirty) {
48-
var cmd = new ReportWizardCommand();
49-
cmd.Run();
50-
if (!cmd.Canceled) {
51-
var reportModel = cmd.ReportModel;
52-
var xml = CreateFormSheetFromModel.ToXml(reportModel);
53-
var doc = new XmlDocument();
54-
doc.LoadXml(xml.ToString());
55-
var ar = XmlToArray(doc);
56-
file.SetData(ar);
57-
} else {
58-
LoggingService.Info("ReportWizard canceled");
59-
return null;
60-
}
61-
}
62-
6347
var viewCmd = new CreateDesignerCommand(file);
6448
viewCmd.Run();
6549
LoggingService.Info("DesignerBinding -> Designer started");
6650
return viewCmd.DesignerView;
6751
}
68-
69-
70-
static byte[] XmlToArray(XmlDocument doc)
71-
{
72-
using (var stream = new MemoryStream()) {
73-
doc.Save(stream);
74-
return stream.ToArray();
75-
}
76-
}
7752
}
7853
}

src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/ReportWizard/ReportWizardCommand.cs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,31 @@
77
* To change this template use Tools | Options | Coding | Edit Standard Headers.
88
*/
99
using System;
10+
using System.Linq;
11+
using System.Text;
1012
using ICSharpCode.Core;
1113
using ICSharpCode.Reporting.Interfaces;
14+
using ICSharpCode.SharpDevelop;
15+
using ICSharpCode.SharpDevelop.Templates;
1216
using ICSharpCode.SharpDevelop.Workbench;
17+
using ICSharpCode.Reporting.Addin.Factory;
1318
using ICSharpCode.Reporting.Addin.ReportWizard.Dialog;
1419
using ICSharpCode.Reporting.Addin.ReportWizard.ViewModels;
1520

1621
namespace ICSharpCode.Reporting.Addin.ReportWizard
1722
{
1823
/// <summary>
19-
/// Description of ReportWizardCommand.
24+
/// This command is invoked by EmptyReport.xfg.
2025
/// </summary>
21-
class ReportWizardCommand: AbstractMenuCommand
26+
class ReportWizardCommand: SimpleCommand
2227
{
2328

24-
public override void Run()
29+
public override void Execute(object parameter)
2530
{
31+
if (parameter == null)
32+
throw new ArgumentNullException("parameter");
33+
FileTemplateResult result = (FileTemplateResult)parameter;
34+
var openedFile = result.NewOpenedFiles.Single();
2635
var wizardViewModel = new ReportWizardContext();
2736
var reportWizard = new ICSharpCode.Reporting.Addin.ReportWizard.Dialog.ReportWizard(wizardViewModel);
2837

@@ -32,14 +41,17 @@ public override void Run()
3241
var rg = new ReportGenerator();
3342

3443
rg.Generate(wizardViewModel);
35-
ReportModel = rg.ReportModel;
36-
} else {
37-
Canceled = true;
44+
string xml = CreateFormSheetFromModel.ToXml(rg.ReportModel).ToString();
45+
openedFile.SetData(Encoding.UTF8.GetBytes(xml));
46+
if (!openedFile.IsUntitled)
47+
openedFile.SaveToDisk();
48+
} else {
49+
LoggingService.Info("ReportWizard canceled");
50+
// HACK: cancel opening the file by clearing the file list
51+
openedFile.CloseIfAllViewsClosed();
52+
result.NewOpenedFiles.Clear();
53+
result.NewFiles.Clear();
3854
}
3955
}
40-
41-
public bool Canceled {get; private set;}
42-
43-
public IReportModel ReportModel {get;private set;}
4456
}
4557
}

src/Main/Base/Project/Templates/FileTemplateResult.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using System.Collections.Generic;
2121
using ICSharpCode.Core;
2222
using ICSharpCode.SharpDevelop.Project;
23+
using ICSharpCode.SharpDevelop.Workbench;
2324

2425
namespace ICSharpCode.SharpDevelop.Templates
2526
{
@@ -49,5 +50,16 @@ public FileTemplateOptions Options {
4950
public IList<FileName> NewFiles {
5051
get { return newFiles; }
5152
}
53+
54+
IList<OpenedFile> newOpenedFiles = new List<OpenedFile>();
55+
56+
/// <summary>
57+
/// Gets the list of newly created files as OpenedFile instances.
58+
/// </summary>
59+
public IList<OpenedFile> NewOpenedFiles {
60+
get {
61+
return newOpenedFiles;
62+
}
63+
}
5264
}
5365
}

src/Main/SharpDevelop/Templates/File/FileTemplateImpl.cs

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ internal class FileTemplateImpl : FileTemplate, ICategory
142142
List<ReferenceProjectItem> requiredAssemblyReferences = new List<ReferenceProjectItem>();
143143

144144
XmlElement fileoptions = null;
145-
Action<FileTemplateResult> actions;
145+
Action<FileTemplateResult> createActions;
146+
Action<FileTemplateResult> openActions;
146147

147148
public string Author {
148149
get {
@@ -292,19 +293,26 @@ public FileTemplateImpl(XmlDocument doc, IReadOnlyFileSystem fileSystem)
292293
}
293294
}
294295

296+
if (doc.DocumentElement["CreateActions"] != null) {
297+
foreach (XmlElement el in doc.DocumentElement["CreateActions"]) {
298+
Action<FileTemplateResult> action = ReadAction(el);
299+
if (action != null)
300+
createActions += action;
301+
}
302+
}
303+
295304
if (doc.DocumentElement["Actions"] != null) {
296305
foreach (XmlElement el in doc.DocumentElement["Actions"]) {
297306
Action<FileTemplateResult> action = ReadAction(el);
298307
if (action != null)
299-
actions += action;
308+
openActions += action;
300309
}
301310
}
302311

303312
fileoptions = doc.DocumentElement["AdditionalOptions"];
304313

305314
// load the files
306-
XmlElement files = doc.DocumentElement["Files"];
307-
XmlNodeList nodes = files.ChildNodes;
315+
XmlNodeList nodes = doc.DocumentElement["Files"].ChildNodes;
308316
foreach (XmlNode filenode in nodes) {
309317
if (filenode is XmlElement) {
310318
this.files.Add(new FileDescriptionTemplate((XmlElement)filenode, fileSystem));
@@ -336,13 +344,13 @@ static Action<FileTemplateResult> ReadAction(XmlElement el)
336344

337345
public override void RunActions(FileTemplateResult result)
338346
{
339-
if (actions != null)
340-
actions(result);
347+
if (openActions != null)
348+
openActions(result);
341349
}
342350

343351
public override string SuggestFileName(DirectoryName basePath)
344352
{
345-
if (defaultName.IndexOf("${Number}") >= 0) {
353+
if (defaultName.IndexOf("${Number}", StringComparison.Ordinal) >= 0) {
346354
try {
347355
int curNumber = 1;
348356

@@ -377,7 +385,7 @@ public override object CreateCustomizationObject()
377385
LocalizedTypeDescriptor localizedTypeDescriptor = new LocalizedTypeDescriptor();
378386
foreach (TemplateProperty property in Properties) {
379387
LocalizedProperty localizedProperty;
380-
if (property.Type.StartsWith("Types:")) {
388+
if (property.Type.StartsWith("Types:", StringComparison.Ordinal)) {
381389
localizedProperty = new LocalizedProperty(property.Name, "System.Enum", property.Category, property.Description);
382390
TemplateType type = null;
383391
foreach (TemplateType templateType in CustomTypes) {
@@ -448,33 +456,53 @@ public override FileTemplateResult Create(FileTemplateOptions options)
448456
return null;
449457
}
450458
}
451-
ScriptRunner scriptRunner = new ScriptRunner();
452-
foreach (FileDescriptionTemplate newFile in FileDescriptionTemplates) {
453-
FileOperationResult opresult = FileUtility.ObservedSave(
454-
() => {
455-
string resultFile;
456-
if (!String.IsNullOrEmpty(newFile.BinaryFileName)) {
457-
resultFile = SaveFile(newFile, null, newFile.BinaryFileName, options);
458-
} else {
459-
resultFile = SaveFile(newFile, scriptRunner.CompileScript(this, newFile), null, options);
460-
}
461-
if (resultFile != null) {
462-
result.NewFiles.Add(FileName.Create(resultFile));
463-
}
464-
}, FileName.Create(StringParser.Parse(newFile.Name))
465-
);
466-
if (opresult != FileOperationResult.OK)
467-
return null;
459+
try {
460+
var filesToOpen = new List<FileName>();
461+
ScriptRunner scriptRunner = new ScriptRunner();
462+
foreach (FileDescriptionTemplate newFile in FileDescriptionTemplates) {
463+
FileOperationResult opresult = FileUtility.ObservedSave(
464+
() => {
465+
OpenedFile resultFile;
466+
bool shouldOpen;
467+
if (!String.IsNullOrEmpty(newFile.BinaryFileName)) {
468+
resultFile = SaveFile(newFile, null, newFile.BinaryFileName, options, out shouldOpen);
469+
} else {
470+
resultFile = SaveFile(newFile, scriptRunner.CompileScript(this, newFile), null, options, out shouldOpen);
471+
}
472+
if (resultFile != null) {
473+
result.NewOpenedFiles.Add(resultFile);
474+
result.NewFiles.Add(resultFile.FileName);
475+
if (shouldOpen)
476+
filesToOpen.Add(resultFile.FileName);
477+
}
478+
}, FileName.Create(StringParser.Parse(newFile.Name))
479+
);
480+
if (opresult != FileOperationResult.OK)
481+
return null;
482+
}
483+
484+
// Run creation actions
485+
if (createActions != null)
486+
createActions(result);
487+
488+
foreach (var filename in filesToOpen.Intersect(result.NewFiles))
489+
SD.FileService.OpenFile(filename);
490+
} finally {
491+
// Now that the view contents
492+
foreach (var file in result.NewOpenedFiles) {
493+
file.CloseIfAllViewsClosed();
494+
}
495+
result.NewOpenedFiles.RemoveAll(f => f.RegisteredViewContents.Count == 0);
496+
}
497+
// raise FileCreated event for the new files.
498+
foreach (var fileName in result.NewFiles) {
499+
FileService.FireFileCreated(fileName, false);
468500
}
469501

470502
if (project != null) {
471503
project.Save();
472504
}
473505

474-
// raise FileCreated event for the new files.
475-
foreach (var fileName in result.NewFiles) {
476-
FileService.FireFileCreated(fileName, false);
477-
}
478506
return result;
479507
}
480508

@@ -486,8 +514,12 @@ bool IsFilenameAvailable(string fileName)
486514
return true;
487515
}
488516

489-
string SaveFile(FileDescriptionTemplate newFile, string content, string binaryFileName, FileTemplateOptions options)
517+
/// <summary>
518+
/// Creates an OpenedFile for the new file, fills it with the file content, and saves it to disk.
519+
/// </summary>
520+
OpenedFile SaveFile(FileDescriptionTemplate newFile, string content, string binaryFileName, FileTemplateOptions options, out bool shouldOpen)
490521
{
522+
shouldOpen = false;
491523
string unresolvedFileName = StringParser.Parse(newFile.Name);
492524
// Parse twice so that tags used in included standard header are parsed
493525
string parsedContent = StringParser.Parse(StringParser.Parse(content));
@@ -502,8 +534,8 @@ string SaveFile(FileDescriptionTemplate newFile, string content, string binaryFi
502534
// when newFile.Name is "${Path}/${FileName}", there might be a useless '/' in front of the file name
503535
// if the file is created when no project is opened. So we remove single '/' or '\', but not double
504536
// '\\' (project is saved on network share).
505-
if (unresolvedFileName.StartsWith("/") && !unresolvedFileName.StartsWith("//")
506-
|| unresolvedFileName.StartsWith("\\") && !unresolvedFileName.StartsWith("\\\\"))
537+
if (unresolvedFileName.StartsWith("/", StringComparison.Ordinal) && !unresolvedFileName.StartsWith("//", StringComparison.Ordinal)
538+
|| unresolvedFileName.StartsWith("\\", StringComparison.Ordinal) && !unresolvedFileName.StartsWith("\\\\", StringComparison.Ordinal))
507539
{
508540
unresolvedFileName = unresolvedFileName.Substring(1);
509541
}
@@ -519,6 +551,7 @@ string SaveFile(FileDescriptionTemplate newFile, string content, string binaryFi
519551
File.WriteAllText(fileName, parsedContent, SD.FileService.DefaultFileEncoding);
520552
if (project != null)
521553
AddTemplateFileToProject(project, newFile, fileName);
554+
return SD.FileService.GetOrCreateOpenedFile(fileName);
522555
} else {
523556
if (!String.IsNullOrEmpty(binaryFileName)) {
524557
LoggingService.Warn("binary file was skipped");
@@ -539,15 +572,15 @@ string SaveFile(FileDescriptionTemplate newFile, string content, string binaryFi
539572
} else {
540573
file = SD.FileService.CreateUntitledOpenedFile(Path.GetFileName(fileName), data);
541574
}
542-
543-
SD.FileService.OpenFile(file.FileName);
575+
shouldOpen = true;
576+
OpenedFile retVal = file;
577+
file = null; // don't close file when there was no exception and we're returning it
578+
return retVal;
544579
} finally {
545580
if (file != null)
546581
file.CloseIfAllViewsClosed();
547582
}
548583
}
549-
550-
return fileName;
551584
}
552585

553586
static void AddTemplateFileToProject(IProject project, FileDescriptionTemplate newFile, FileName fileName)

0 commit comments

Comments
 (0)