From 2cec82fdfe260f990e432567d76bd105f814d564 Mon Sep 17 00:00:00 2001 From: Vladekk Date: Mon, 21 Mar 2016 20:31:20 +0200 Subject: [PATCH] Initial commit --- .gitattributes | 63 ++ src/DynamicTemplate/ArgumentDescription.cs | 56 ++ src/DynamicTemplate/Compiler/BodyParser.cs | 175 ++++ .../Compiler/CSharpLanguageProvider.cs | 349 ++++++++ .../Compiler/LanguageProvider.cs | 24 + src/DynamicTemplate/Compiler/Position.cs | 40 + .../Compiler/PositionBuffer.cs | 47 ++ .../Compiler/SourcePositionTransposer.cs | 98 +++ .../Compiler/TemplateCompilationException.cs | 37 + src/DynamicTemplate/DynamicTemplate.csproj | 236 ++++++ src/DynamicTemplate/Icon.png | Bin 0 -> 398 bytes .../Plugin/BooleanParamInput.Designer.cs | 65 ++ .../Plugin/BooleanParamInput.cs | 36 + .../Plugin/BooleanParamInput.resx | 120 +++ .../Plugin/DateTimeParamInput.Designer.cs | 60 ++ .../Plugin/DateTimeParamInput.cs | 28 + .../Plugin/DateTimeParamInput.resx | 120 +++ .../Plugin/DoubleParamInput.Designer.cs | 64 ++ .../Plugin/DoubleParamInput.cs | 50 ++ .../Plugin/DoubleParamInput.resx | 123 +++ .../Plugin/DynamicTemplateContentSource.cs | 64 ++ .../Plugin/IntegerParamInput.Designer.cs | 64 ++ .../Plugin/IntegerParamInput.cs | 50 ++ .../Plugin/IntegerParamInput.resx | 123 +++ .../MultiLineTextboxParamInput.Designer.cs | 61 ++ .../Plugin/MultiLineTextboxParamInput.cs | 30 + .../Plugin/MultiLineTextboxParamInput.resx | 120 +++ .../Plugin/ParamInput.Designer.cs | 64 ++ src/DynamicTemplate/Plugin/ParamInput.cs | 33 + src/DynamicTemplate/Plugin/ParamInput.resx | 120 +++ .../SingleLineTextboxParamInput.Designer.cs | 59 ++ .../Plugin/SingleLineTextboxParamInput.cs | 31 + .../Plugin/SingleLineTextboxParamInput.resx | 120 +++ .../Plugin/TemplateChooserForm.Designer.cs | 196 +++++ .../Plugin/TemplateChooserForm.cs | 236 ++++++ .../Plugin/TemplateChooserForm.resx | 123 +++ .../Plugin/TemplateEditorForm.Designer.cs | 277 +++++++ .../Plugin/TemplateEditorForm.cs | 306 +++++++ .../Plugin/TemplateEditorForm.resx | 132 +++ .../Plugin/TemplateInputForm.Designer.cs | 98 +++ .../Plugin/TemplateInputForm.cs | 77 ++ .../Plugin/TemplateInputForm.resx | 120 +++ .../Plugin/TemplateRenameForm.Designer.cs | 107 +++ .../Plugin/TemplateRenameForm.cs | 78 ++ .../Plugin/TemplateRenameForm.resx | 123 +++ src/DynamicTemplate/Plugin/TooltipHelper.cs | 24 + src/DynamicTemplate/Plugin/WaitCursor.cs | 20 + src/DynamicTemplate/Program.cs | 30 + .../Properties/AssemblyInfo.cs | 33 + .../Properties/Resources.Designer.cs | 63 ++ src/DynamicTemplate/Properties/Resources.resx | 117 +++ .../Properties/Settings.Designer.cs | 26 + .../Properties/Settings.settings | 7 + src/DynamicTemplate/Template.cs | 68 ++ src/DynamicTemplate/packages.config | 4 + .../ConfirmForm.Designer.cs | 201 +++++ src/DynamicTemplateManager/ConfirmForm.cs | 125 +++ src/DynamicTemplateManager/ConfirmForm.resx | 126 +++ .../DynamicTemplateManager.csproj | 119 +++ src/DynamicTemplateManager/Program.cs | 49 ++ .../Properties/AssemblyInfo.cs | 36 + .../Properties/Resources.Designer.cs | 63 ++ .../Properties/Resources.resx | 117 +++ .../Properties/Settings.Designer.cs | 26 + .../Properties/Settings.settings | 7 + src/DynamicTemplateManager/app.config | 3 + .../DynamicTemplateSetup.vdproj | 752 ++++++++++++++++++ src/Template.sln | 32 + 68 files changed, 6651 insertions(+) create mode 100644 .gitattributes create mode 100644 src/DynamicTemplate/ArgumentDescription.cs create mode 100644 src/DynamicTemplate/Compiler/BodyParser.cs create mode 100644 src/DynamicTemplate/Compiler/CSharpLanguageProvider.cs create mode 100644 src/DynamicTemplate/Compiler/LanguageProvider.cs create mode 100644 src/DynamicTemplate/Compiler/Position.cs create mode 100644 src/DynamicTemplate/Compiler/PositionBuffer.cs create mode 100644 src/DynamicTemplate/Compiler/SourcePositionTransposer.cs create mode 100644 src/DynamicTemplate/Compiler/TemplateCompilationException.cs create mode 100644 src/DynamicTemplate/DynamicTemplate.csproj create mode 100644 src/DynamicTemplate/Icon.png create mode 100644 src/DynamicTemplate/Plugin/BooleanParamInput.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/BooleanParamInput.cs create mode 100644 src/DynamicTemplate/Plugin/BooleanParamInput.resx create mode 100644 src/DynamicTemplate/Plugin/DateTimeParamInput.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/DateTimeParamInput.cs create mode 100644 src/DynamicTemplate/Plugin/DateTimeParamInput.resx create mode 100644 src/DynamicTemplate/Plugin/DoubleParamInput.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/DoubleParamInput.cs create mode 100644 src/DynamicTemplate/Plugin/DoubleParamInput.resx create mode 100644 src/DynamicTemplate/Plugin/DynamicTemplateContentSource.cs create mode 100644 src/DynamicTemplate/Plugin/IntegerParamInput.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/IntegerParamInput.cs create mode 100644 src/DynamicTemplate/Plugin/IntegerParamInput.resx create mode 100644 src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.cs create mode 100644 src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.resx create mode 100644 src/DynamicTemplate/Plugin/ParamInput.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/ParamInput.cs create mode 100644 src/DynamicTemplate/Plugin/ParamInput.resx create mode 100644 src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.cs create mode 100644 src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.resx create mode 100644 src/DynamicTemplate/Plugin/TemplateChooserForm.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateChooserForm.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateChooserForm.resx create mode 100644 src/DynamicTemplate/Plugin/TemplateEditorForm.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateEditorForm.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateEditorForm.resx create mode 100644 src/DynamicTemplate/Plugin/TemplateInputForm.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateInputForm.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateInputForm.resx create mode 100644 src/DynamicTemplate/Plugin/TemplateRenameForm.Designer.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateRenameForm.cs create mode 100644 src/DynamicTemplate/Plugin/TemplateRenameForm.resx create mode 100644 src/DynamicTemplate/Plugin/TooltipHelper.cs create mode 100644 src/DynamicTemplate/Plugin/WaitCursor.cs create mode 100644 src/DynamicTemplate/Program.cs create mode 100644 src/DynamicTemplate/Properties/AssemblyInfo.cs create mode 100644 src/DynamicTemplate/Properties/Resources.Designer.cs create mode 100644 src/DynamicTemplate/Properties/Resources.resx create mode 100644 src/DynamicTemplate/Properties/Settings.Designer.cs create mode 100644 src/DynamicTemplate/Properties/Settings.settings create mode 100644 src/DynamicTemplate/Template.cs create mode 100644 src/DynamicTemplate/packages.config create mode 100644 src/DynamicTemplateManager/ConfirmForm.Designer.cs create mode 100644 src/DynamicTemplateManager/ConfirmForm.cs create mode 100644 src/DynamicTemplateManager/ConfirmForm.resx create mode 100644 src/DynamicTemplateManager/DynamicTemplateManager.csproj create mode 100644 src/DynamicTemplateManager/Program.cs create mode 100644 src/DynamicTemplateManager/Properties/AssemblyInfo.cs create mode 100644 src/DynamicTemplateManager/Properties/Resources.Designer.cs create mode 100644 src/DynamicTemplateManager/Properties/Resources.resx create mode 100644 src/DynamicTemplateManager/Properties/Settings.Designer.cs create mode 100644 src/DynamicTemplateManager/Properties/Settings.settings create mode 100644 src/DynamicTemplateManager/app.config create mode 100644 src/DynamicTemplateSetup/DynamicTemplateSetup.vdproj create mode 100644 src/Template.sln diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/src/DynamicTemplate/ArgumentDescription.cs b/src/DynamicTemplate/ArgumentDescription.cs new file mode 100644 index 0000000..04e69a3 --- /dev/null +++ b/src/DynamicTemplate/ArgumentDescription.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml.Serialization; + +namespace DynamicTemplate +{ + public enum ArgumentType + { + TextString, + TextStringExtended, + HtmlString, + HtmlStringExtended, + Integer, + Double, + Boolean, + DateTime + } + + public class ArgumentDescription + { + private ArgumentType _type; + private string _identifier; + private string _label; + + public ArgumentDescription() { } + + public ArgumentDescription(ArgumentType type, string identifier, string label) + { + _type = type; + _identifier = identifier; + _label = label; + } + + [XmlAttribute] + public ArgumentType Type + { + get { return _type; } + set { _type = value; } + } + + [XmlAttribute] + public string Label + { + get { return _label; } + set { _label = value; } + } + + [XmlText] + public string Identifier + { + get { return _identifier; } + set { _identifier = value; } + } + } +} diff --git a/src/DynamicTemplate/Compiler/BodyParser.cs b/src/DynamicTemplate/Compiler/BodyParser.cs new file mode 100644 index 0000000..525f6b7 --- /dev/null +++ b/src/DynamicTemplate/Compiler/BodyParser.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DynamicTemplate.Compiler +{ + class BodyParser + { + public TemplateOperation Parse(string str, ArgumentDescription[] args) + { + LanguageProvider lp = new CSharpLanguageProvider(); + + lp.Start(args); + + IndexToPosition lcf = new IndexToPosition(str); + int pos = 0; + int codeStart; + while (str.Length > pos && 0 <= (codeStart = str.IndexOf("<%", pos))) + { + if (pos < codeStart) + { + lp.Literal(str.Substring(pos, codeStart - pos), lcf.Find(pos)); + } + + pos = codeStart + 2; + + bool isExprMode = false; + if (str.Length > pos && str[pos] == '=') + { + pos++; + isExprMode = true; + } + + int endIndex = str.IndexOf("%>", pos); + if (endIndex == -1) + { + throw new TemplateCompilationException( + "Couldn't find a matching \"%>\"", + lcf.Find(pos) + ); + } + + Position sourcePos = lcf.Find(pos); + string code = str.Substring(pos, endIndex - pos); + if (isExprMode) + lp.Expression(code, sourcePos); + else + lp.Code(code, sourcePos); + + pos = endIndex + 2; + + // skip trailing CRLF? Only if the current code block is + // not in expression mode, and if there's no significant text + // on the same line as the <% or the %>. + if (!isExprMode + && IsLinePrefixOnlyWhitespace(str, codeStart) + && IsLineSuffixOnlyWhitespace(str, pos)) + { + while (pos < str.Length && str[pos] != '\n') + pos++; + if (pos < str.Length) + pos++; + } + } + + if (pos < str.Length) + { + lp.Literal(str.Substring(pos), lcf.Find(pos)); + } + + return lp.End(); + } + + private static bool IsLinePrefixOnlyWhitespace(string str, int index) + { + for (int i = index - 1; i >= 0; i--) + { + if (!char.IsWhiteSpace(str[i])) + return false; + else if (str[i] == '\n') + return true; + } + return true; + } + + private static bool IsLineSuffixOnlyWhitespace(string str, int index) + { + for (int i = index; i < str.Length; i++) + { + if (!char.IsWhiteSpace(str[i])) + return false; + else if (str[i] == '\n') + return true; + } + return true; + } + } + + /// + /// Given an index into a string, returns a line/column position. + /// This implementation is a stateful class that optimizes performance + /// for multiple queries whose index values are further and further along + /// in the string. + /// + class IndexToPosition + { + private readonly string _str; + private int _pos; + private int _line; + private int _col; + + public IndexToPosition(string str) + { + _str = str; + _pos = 0; + _line = 1; + _col = 1; + } + + public Position Find(int index) + { + if (_pos > index) + { + // we've gone backwards; start over + + _pos = 0; + _line = 1; + _col = 1; + } + + for (; _pos < index; _pos++) + { + switch (_str[_pos]) + { + case '\n': + _line++; + _col = 1; + break; + default: + _col++; + break; + } + } + + return new Position(_line, _col); + } + + public static int ReverseFind(string str, int line, int column) + { + int pos = -1; + for (int i = 1; i < line; i++) + { + pos = str.IndexOf('\n', pos + 1); + if (pos == -1) + return -1; + } + pos++; + + for (int i = 1; i < column; i++) + { + pos++; + if (pos >= str.Length) + return -1; + if ('\n' == str[pos]) + return -1; + } + + if (pos >= str.Length) + return -1; + + return pos; + } + } +} diff --git a/src/DynamicTemplate/Compiler/CSharpLanguageProvider.cs b/src/DynamicTemplate/Compiler/CSharpLanguageProvider.cs new file mode 100644 index 0000000..9e9bf9e --- /dev/null +++ b/src/DynamicTemplate/Compiler/CSharpLanguageProvider.cs @@ -0,0 +1,349 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.CSharp; +using System.CodeDom.Compiler; +using System.Reflection; +using System.Globalization; + +namespace DynamicTemplate.Compiler +{ + class CSharpLanguageProvider : LanguageProvider + { + private PositionBuffer _value; + private PositionTransposer _sourcePositionTransposer = new PositionTransposer(); + + public override string Name + { + get { return "C#"; } + } + + public override bool IsValidIdentifier(string identifier, out string errorMessage) + { + if (identifier.Length == 0) + { + errorMessage = "Variable names must be one or more characters long"; + return false; + } + + if (identifier[0] == '@') + { + string subIdentifier = identifier.Substring(1); + if (subIdentifier.Length == 0) + { + errorMessage = "Variable name is too short"; + return false; + } + + if (!IsValidIdentifierInternal(subIdentifier, out errorMessage)) + return false; + } + else + { + if (!IsValidIdentifierInternal(identifier, out errorMessage)) + return false; + } + + switch (identifier) + { + case "abstract": + #region C# keywords + case "as": + case "base": + case "bool": + case "break": + case "byte": + case ": case": + case "catch": + case "char": + case "checked": + case "class": + case "const": + case "continue": + case "decimal": + case "default": + case "delegate": + case "do": + case "double": + case "else": + case "enum": + case "event": + case "explicit": + case "extern": + case "false": + case "finally": + case "fixed": + case "float": + case "for": + case "foreach": + case "goto": + case "if": + case "implicit": + case "in": + case "int": + case "interface": + case "internal": + case "is": + case "lock": + case "long": + case "namespace": + case "new": + case "null": + case "object": + case "operator": + case "out": + case "override": + case "params": + case "private": + case "protected": + case "public": + case "readonly": + case "ref": + case "return": + case "sbyte": + case "sealed": + case "short": + case "sizeof": + case "stackalloc": + case "static": + case "string": + case "struct": + case "switch": + case "this": + case "throw": + case "true": + case "try": + case "typeof": + case "uint": + case "ulong": + case "unchecked": + case "unsafe": + case "ushort": + case "using": + case "virtual": + case "void": + case "volatile": + #endregion + case "while": + errorMessage = "\"" + identifier + "\" is a keyword and cannot be used as a variable name"; + return false; + } + + return true; + } + + private static bool IsValidIdentifierInternal(string identifier, out string errorMessage) + { + if (!char.IsLetter(identifier[0]) && identifier[0] != '_') + { + errorMessage = "Variable names must start with either a letter or the underscore character"; + return false; + } + + for (int i = 1; i < identifier.Length; i++) + { + switch (char.GetUnicodeCategory(identifier[i])) + { + // letter-character + case UnicodeCategory.LowercaseLetter: + case UnicodeCategory.UppercaseLetter: + case UnicodeCategory.TitlecaseLetter: + case UnicodeCategory.ModifierLetter: + case UnicodeCategory.OtherLetter: + case UnicodeCategory.LetterNumber: + // combining-character + case UnicodeCategory.NonSpacingMark: + case UnicodeCategory.SpacingCombiningMark: + // decimal-digit-character + case UnicodeCategory.DecimalDigitNumber: + // connecting-character + case UnicodeCategory.ConnectorPunctuation: + // format-character + case UnicodeCategory.Format: + break; + case UnicodeCategory.SpaceSeparator: + errorMessage = "Variable names must not contain spaces"; + return false; + default: + errorMessage = "Variable name contains illegal character(s)"; + return false; + } + } + + errorMessage = null; + return true; + } + + public override string NormalizeIdentifier(string identifier) + { + return identifier[0] == '@' ? identifier.Substring(1) : identifier; + } + + public override void Start(ArgumentDescription[] args) + { + _value = new PositionBuffer(); + + _value.Append( +@"using System; +using System.Text; +using System.Web; + +//[assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum, Flags = System.Security.Permissions.SecurityPermissionFlag.Execution, Unrestricted = true)] +//[assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestOptional, Flags = System.Security.Permissions.SecurityPermissionFlag.Execution, Unrestricted = true)] + +public class Template +{ + private static string HtmlEncode(string val) + { + return System.Web.HttpUtility.HtmlEncode(val); + } + + private static string HtmlAttributeEncode(string val) + { + return System.Web.HttpUtility.HtmlAttributeEncode(val); + } + + private static string HtmlDecode(string val) + { + return System.Web.HttpUtility.HtmlDecode(val); + } + + private static string UrlEncode(string val) + { + return System.Web.HttpUtility.UrlEncode(val); + } + + private static string UrlPathEncode(string val) + { + return System.Web.HttpUtility.UrlPathEncode(val); + } + + private static string UrlDecode(string val) + { + return System.Web.HttpUtility.UrlDecode(val); + } + + public static string Process(object state, object[] parameters) + { + StringBuilder ___output = new StringBuilder(); + string _selection = state as string; +"); + for (int ___i = 0; ___i < args.Length; ___i++) + { + ArgumentDescription arg = args[___i]; + + string argType; + switch (arg.Type) + { + case ArgumentType.TextString: + case ArgumentType.TextStringExtended: + case ArgumentType.HtmlString: + case ArgumentType.HtmlStringExtended: + argType = "string"; + break; + case ArgumentType.Double: + argType = "double"; + break; + case ArgumentType.Integer: + argType = "int"; + break; + case ArgumentType.Boolean: + argType = "bool"; + break; + case ArgumentType.DateTime: + argType = "System.DateTime"; + break; + default: + throw new ArgumentException("Unexpected argument type: " + arg.Type); + } + + _value.AppendFormat("{0} {1} = ({0})parameters[{2}];", argType, arg.Identifier, ___i); + } + } + + public override void Code(string code, Position startPos) + { + _sourcePositionTransposer.AddMapping( + _value.Position, + startPos); + _value.Append(code); + /* + _sourcePositionTransposer.AddMapping( + new Position(_value.Line, _value.Column), + Position.Unknown); + */ + } + + public override void Expression(string expr, Position startPos) + { + _value.Append("___output.Append("); + + _sourcePositionTransposer.AddMapping( + _value.Position, + startPos); + _value.Append(expr); + /* + _sourcePositionTransposer.AddMapping( + new Position(_value.Line, _value.Column + 1), + Position.Unknown); + */ + + _value.Append(");"); + } + + public override void Literal(string literal, Position startPos) + { + _value.Append("___output.Append(@\""); + foreach (char c in literal) + { + switch (c) + { + case '"': + _value.Append("\"\""); + break; + default: + _value.Append(c.ToString()); + break; + } + } + _value.Append("\");"); + } + + public override TemplateOperation End() + { + _value.Append(@" + return ___output.ToString(); + } +}"); + CompilerParameters p = new CompilerParameters(); + p.IncludeDebugInformation = true; + p.GenerateInMemory = true; + p.ReferencedAssemblies.Add("System.dll"); + p.ReferencedAssemblies.Add("System.Web.dll"); + p.ReferencedAssemblies.Add("System.Windows.Forms.dll"); + CompilerResults results = new CSharpCodeProvider().CompileAssemblyFromSource(p, _value.ToString()); + if (results.NativeCompilerReturnValue != 0) + { + throw TemplateCompilationException.CreateFromCompilerResults(results, _sourcePositionTransposer); + } + Type t = results.CompiledAssembly.GetType("Template"); + MethodInfo m = t.GetMethod("Process", BindingFlags.Static | BindingFlags.Public); + return new TemplateOperation(new InvokeAdapter(m).Invoke); + } + + private class InvokeAdapter + { + private readonly MethodInfo _method; + + public InvokeAdapter(MethodInfo method) + { + _method = method; + } + + public string Invoke(object state, object[] values) + { + return (string)_method.Invoke(null, new object[] { state, values }); + } + } + } +} diff --git a/src/DynamicTemplate/Compiler/LanguageProvider.cs b/src/DynamicTemplate/Compiler/LanguageProvider.cs new file mode 100644 index 0000000..4d5c706 --- /dev/null +++ b/src/DynamicTemplate/Compiler/LanguageProvider.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.CodeDom.Compiler; +using System.Reflection; + +namespace DynamicTemplate.Compiler +{ + public delegate string TemplateOperation(object state, object[] parameters); + + abstract class LanguageProvider + { + public abstract string Name { get; } + + public abstract bool IsValidIdentifier(string identifier, out string errorMessage); + public abstract string NormalizeIdentifier(string identifier); + + public abstract void Start(ArgumentDescription[] argDescs); + public abstract void Code(string code, Position startPos); + public abstract void Expression(string expr, Position startPos); + public abstract void Literal(string literal, Position startPos); + public abstract TemplateOperation End(); + } +} diff --git a/src/DynamicTemplate/Compiler/Position.cs b/src/DynamicTemplate/Compiler/Position.cs new file mode 100644 index 0000000..07b91b6 --- /dev/null +++ b/src/DynamicTemplate/Compiler/Position.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DynamicTemplate.Compiler +{ + public struct Position : IComparable + { + public Position(int line, int column) + { + Line = line; + Column = column; + } + + public readonly int Line; + public readonly int Column; + + public int CompareTo(Position other) + { + if (Line != other.Line) + { + return Line - other.Line; + } + + return Column - other.Column; + } + + public override bool Equals(object obj) + { + return Line == ((Position)obj).Line && Column == ((Position)obj).Column; + } + + public override int GetHashCode() + { + return Line * 513 + Column; + } + + public static readonly Position Unknown = new Position(-1, -1); + } +} diff --git a/src/DynamicTemplate/Compiler/PositionBuffer.cs b/src/DynamicTemplate/Compiler/PositionBuffer.cs new file mode 100644 index 0000000..e964d39 --- /dev/null +++ b/src/DynamicTemplate/Compiler/PositionBuffer.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DynamicTemplate.Compiler +{ + /// + /// A string buffer that can be appended to, and keeps track of what + /// position (line/column) it is currently at. + /// + class PositionBuffer + { + private StringBuilder _buf = new StringBuilder(); + private int _line = 1; + private int _col = 1; + + public void Append(string str) + { + _buf.Append(str); + foreach (char c in str) + { + switch (c) + { + case '\n': + _line++; + _col = 1; + break; + default: + _col++; + break; + } + } + } + + public void AppendFormat(string format, params object[] parameters) + { + Append(string.Format(format, parameters)); + } + + public Position Position { get { return new Position(_line, _col); } } + + public override string ToString() + { + return _buf.ToString(); + } + } +} diff --git a/src/DynamicTemplate/Compiler/SourcePositionTransposer.cs b/src/DynamicTemplate/Compiler/SourcePositionTransposer.cs new file mode 100644 index 0000000..49009db --- /dev/null +++ b/src/DynamicTemplate/Compiler/SourcePositionTransposer.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; + +namespace DynamicTemplate.Compiler +{ + public class PositionTransposer + { + private readonly List _mappings; + private bool dirty = false; + + public PositionTransposer() + { + _mappings = new List(); + } + + public void AddMapping(Position from, Position to) + { + dirty = true; + _mappings.Add(new PositionMapping(from, to)); + } + + public Position TranslatePosition(Position pos) + { + try + { + if (pos.Equals(Position.Unknown)) + return Position.Unknown; + + if (dirty) + { + _mappings.Sort(); + dirty = false; + } + + if (_mappings.Count > 0) + { + int idx = _mappings.BinarySearch(new PositionMapping(pos, Position.Unknown)); + if (idx >= 0) + { + return _mappings[idx].Value; + } + else + { + int closestIndex = (~idx) - 1; + PositionMapping matchedMapping = _mappings[closestIndex]; + if (!matchedMapping.Value.Equals(Position.Unknown)) + { + if (matchedMapping.Key.Line == pos.Line) + { + return new Position( + matchedMapping.Value.Line, + matchedMapping.Value.Column + (pos.Column - matchedMapping.Key.Column)); + } + else + { + return new Position( + matchedMapping.Value.Line + (pos.Line - matchedMapping.Key.Line), + pos.Column); + } + } + } + } + + return Position.Unknown; + } + catch (Exception e) + { + Trace.Fail(e.ToString()); + return Position.Unknown; + } + } + + struct PositionMapping : IComparable, IComparable + { + public PositionMapping(Position key, Position value) + { + Key = key; + Value = value; + } + + public readonly Position Key; + public readonly Position Value; + + public int CompareTo(PositionMapping other) + { + return Key.CompareTo(other.Key); + } + + public int CompareTo(Position other) + { + return Key.CompareTo(other); + } + } + + } +} diff --git a/src/DynamicTemplate/Compiler/TemplateCompilationException.cs b/src/DynamicTemplate/Compiler/TemplateCompilationException.cs new file mode 100644 index 0000000..b93daaa --- /dev/null +++ b/src/DynamicTemplate/Compiler/TemplateCompilationException.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.CodeDom.Compiler; + +namespace DynamicTemplate.Compiler +{ + public class TemplateCompilationException : Exception + { + private readonly string _message; + private readonly Position _position; + + internal static TemplateCompilationException CreateFromCompilerResults(CompilerResults results, PositionTransposer transposer) + { + foreach (CompilerError error in results.Errors) + { + if (!error.IsWarning) + { + string message = error.ErrorNumber + ": " + error.ErrorText; + return new TemplateCompilationException(message, transposer.TranslatePosition(new Position(error.Line, error.Column))); + } + } + throw new ArgumentException(); + } + + internal TemplateCompilationException(string message, Position position) : base(message) + { + _message = message; + _position = position; + } + + public Position Position + { + get { return _position; } + } + } +} diff --git a/src/DynamicTemplate/DynamicTemplate.csproj b/src/DynamicTemplate/DynamicTemplate.csproj new file mode 100644 index 0000000..017b6f8 --- /dev/null +++ b/src/DynamicTemplate/DynamicTemplate.csproj @@ -0,0 +1,236 @@ + + + + Debug + AnyCPU + 9.0.20706 + 2.0 + {5D172116-CDE0-4553-9943-EC6D0736A4F8} + Library + Properties + DynamicTemplate + DynamicTemplate + + + + + 3.5 + + + v4.5.2 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug + DEBUG;TRACE + prompt + 4 + true + false + + + pdbonly + true + bin\Release + TRACE + prompt + 4 + true + false + + + + ..\packages\OpenLiveWriter.SDK.0.5.0-beta\lib\net452\OpenLiveWriter.Api.dll + True + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + UserControl + + + BooleanParamInput.cs + + + UserControl + + + DateTimeParamInput.cs + + + UserControl + + + DoubleParamInput.cs + + + + UserControl + + + IntegerParamInput.cs + + + UserControl + + + MultiLineTextboxParamInput.cs + + + UserControl + + + ParamInput.cs + + + UserControl + + + SingleLineTextboxParamInput.cs + + + Form + + + TemplateChooserForm.cs + + + Form + + + TemplateEditorForm.cs + + + Form + + + TemplateInputForm.cs + + + Form + + + TemplateRenameForm.cs + + + + + + + Designer + BooleanParamInput.cs + + + Designer + DateTimeParamInput.cs + + + Designer + DoubleParamInput.cs + + + Designer + IntegerParamInput.cs + + + Designer + MultiLineTextboxParamInput.cs + + + Designer + ParamInput.cs + + + Designer + SingleLineTextboxParamInput.cs + + + Designer + TemplateChooserForm.cs + + + Designer + TemplateEditorForm.cs + + + Designer + TemplateInputForm.cs + + + Designer + TemplateRenameForm.cs + + + ResXFileCodeGenerator + Designer + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + False + .NET Framework 3.5 SP1 + true + + + + + \ No newline at end of file diff --git a/src/DynamicTemplate/Icon.png b/src/DynamicTemplate/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bcc28f1fe95c68bc1fa3b0c7bebc807247db7db1 GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP(q@_ zHKHUqKdq!Zu_%=xATcwqM9i(EK4|~e(%3^|5?S2pDhCGIPT97 zO0IeHR4kdn$0C2u&PX4|7JbHJ^^DyNv7!to{bjm-qzUWCt+~ + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.chkValue = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // lblName + // + this.lblName.Visible = false; + // + // chkValue + // + this.chkValue.AutoSize = true; + this.chkValue.Location = new System.Drawing.Point(0, 0); + this.chkValue.Name = "chkValue"; + this.chkValue.Size = new System.Drawing.Size(80, 17); + this.chkValue.TabIndex = 1; + this.chkValue.Text = "checkBox1"; + this.chkValue.UseVisualStyleBackColor = true; + // + // BooleanParamInput + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.Controls.Add(this.chkValue); + this.Name = "BooleanParamInput"; + this.Size = new System.Drawing.Size(250, 19); + this.Controls.SetChildIndex(this.chkValue, 0); + this.Controls.SetChildIndex(this.lblName, 0); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkValue; + } +} diff --git a/src/DynamicTemplate/Plugin/BooleanParamInput.cs b/src/DynamicTemplate/Plugin/BooleanParamInput.cs new file mode 100644 index 0000000..d7dd7e0 --- /dev/null +++ b/src/DynamicTemplate/Plugin/BooleanParamInput.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DynamicTemplate.Plugin +{ + public partial class BooleanParamInput : DynamicTemplate.Plugin.ParamInput + { + public BooleanParamInput() + { + InitializeComponent(); + } + + public override string ParamLabel + { + set + { + chkValue.Text = value; + base.ParamLabel = value; + } + } + + public override object Value + { + get + { + return chkValue.Checked; + } + } + } +} + diff --git a/src/DynamicTemplate/Plugin/BooleanParamInput.resx b/src/DynamicTemplate/Plugin/BooleanParamInput.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/DynamicTemplate/Plugin/BooleanParamInput.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/DateTimeParamInput.Designer.cs b/src/DynamicTemplate/Plugin/DateTimeParamInput.Designer.cs new file mode 100644 index 0000000..c5c88b8 --- /dev/null +++ b/src/DynamicTemplate/Plugin/DateTimeParamInput.Designer.cs @@ -0,0 +1,60 @@ +namespace DynamicTemplate.Plugin +{ + partial class DateTimeParamInput + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.dtValue = new System.Windows.Forms.DateTimePicker(); + this.SuspendLayout(); + // + // dtValue + // + this.dtValue.CustomFormat = "M/d/yyyy h:mm:ss tt"; + this.dtValue.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtValue.Location = new System.Drawing.Point(0, 16); + this.dtValue.Name = "dtValue"; + this.dtValue.Size = new System.Drawing.Size(171, 20); + this.dtValue.TabIndex = 1; + // + // DateTimeParamInput + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.Controls.Add(this.dtValue); + this.Name = "DateTimeParamInput"; + this.Size = new System.Drawing.Size(250, 36); + this.Controls.SetChildIndex(this.dtValue, 0); + this.Controls.SetChildIndex(this.lblName, 0); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.DateTimePicker dtValue; + } +} diff --git a/src/DynamicTemplate/Plugin/DateTimeParamInput.cs b/src/DynamicTemplate/Plugin/DateTimeParamInput.cs new file mode 100644 index 0000000..dc557c6 --- /dev/null +++ b/src/DynamicTemplate/Plugin/DateTimeParamInput.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DynamicTemplate.Plugin +{ + public partial class DateTimeParamInput : DynamicTemplate.Plugin.ParamInput + { + public DateTimeParamInput() + { + InitializeComponent(); + dtValue.Value = DateTime.Now; + } + + public override object Value + { + get + { + return dtValue.Value; + } + } + } +} + diff --git a/src/DynamicTemplate/Plugin/DateTimeParamInput.resx b/src/DynamicTemplate/Plugin/DateTimeParamInput.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/DynamicTemplate/Plugin/DateTimeParamInput.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/DoubleParamInput.Designer.cs b/src/DynamicTemplate/Plugin/DoubleParamInput.Designer.cs new file mode 100644 index 0000000..071530b --- /dev/null +++ b/src/DynamicTemplate/Plugin/DoubleParamInput.Designer.cs @@ -0,0 +1,64 @@ +namespace DynamicTemplate.Plugin +{ + partial class DoubleParamInput + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.txtValue = new System.Windows.Forms.TextBox(); + this.errorToolTip = new System.Windows.Forms.ToolTip(this.components); + this.SuspendLayout(); + // + // txtValue + // + this.txtValue.Location = new System.Drawing.Point(0, 16); + this.txtValue.Name = "txtValue"; + this.txtValue.Size = new System.Drawing.Size(250, 20); + this.txtValue.TabIndex = 1; + this.txtValue.Text = "0.0"; + this.txtValue.Validating += new System.ComponentModel.CancelEventHandler(this.txtValue_Validating); + // + // DoubleParamInput + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.Controls.Add(this.txtValue); + this.Name = "DoubleParamInput"; + this.Size = new System.Drawing.Size(250, 40); + this.Controls.SetChildIndex(this.txtValue, 0); + this.Controls.SetChildIndex(this.lblName, 0); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtValue; + private System.Windows.Forms.ToolTip errorToolTip; + + } +} diff --git a/src/DynamicTemplate/Plugin/DoubleParamInput.cs b/src/DynamicTemplate/Plugin/DoubleParamInput.cs new file mode 100644 index 0000000..cf0558d --- /dev/null +++ b/src/DynamicTemplate/Plugin/DoubleParamInput.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DynamicTemplate.Plugin +{ + public partial class DoubleParamInput : DynamicTemplate.Plugin.ParamInput + { + public DoubleParamInput() + { + InitializeComponent(); + } + + public override object Value + { + get + { + return double.Parse(txtValue.Text); + } + } + + private void txtValue_Validating(object sender, CancelEventArgs e) + { + txtValue.Text = txtValue.Text.Trim(); + if (txtValue.Text == "") + { + txtValue.Text = "0.0"; + } + + try + { + double.Parse(txtValue.Text); + } + catch (FormatException) + { + e.Cancel = true; + txtValue.Select(); + txtValue.SelectAll(); + errorToolTip.ToolTipIcon = ToolTipIcon.Warning; + errorToolTip.ToolTipTitle = "Invalid number"; + errorToolTip.Show("Please enter a valid decimal number (e.g. " + (105.34.ToString()) + ")", txtValue, 5000); + } + } + } +} + diff --git a/src/DynamicTemplate/Plugin/DoubleParamInput.resx b/src/DynamicTemplate/Plugin/DoubleParamInput.resx new file mode 100644 index 0000000..b3b935d --- /dev/null +++ b/src/DynamicTemplate/Plugin/DoubleParamInput.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/DynamicTemplateContentSource.cs b/src/DynamicTemplate/Plugin/DynamicTemplateContentSource.cs new file mode 100644 index 0000000..9d8c59a --- /dev/null +++ b/src/DynamicTemplate/Plugin/DynamicTemplateContentSource.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using System.Windows.Forms; +using DynamicTemplate.Compiler; +using DynamicTemplate.Plugin; +using System.Threading; +using OpenLiveWriter.Api; + +namespace DynamicTemplate +{ + [WriterPlugin("233830C2-4EAE-482b-9A2B-8FA70AE6309B", "Dynamic Template", ImagePath="Icon.png", + PublisherUrl="http://www.joecheng.com/code/DynamicTemplate/", + Description="Easily insert oft-used snippets of HTML or text.")] + [InsertableContentSource("Template")] + public class DynamicTemplateContentSource : ContentSource + { + public override DialogResult CreateContent( + IWin32Window dialogOwner, + ref string newContent) + { + string templateName; + Template template; + + using (TemplateChooserForm form = new TemplateChooserForm()) + { + if (form.ShowDialog(dialogOwner) == DialogResult.Cancel) + return DialogResult.Cancel; + templateName = form.SelectedTemplateName; + template = form.SelectedTemplate; + } + + object[] parameters; + if (template.Arguments.Length == 0) + { + parameters = new object[0]; + } + else + { + using (TemplateInputForm form = new TemplateInputForm(templateName, template)) + { + if (form.ShowDialog(dialogOwner) == DialogResult.Cancel) + return DialogResult.Cancel; + parameters = form.ParamValues(); + } + } + + try + { + using (new WaitCursor()) + { + newContent = new BodyParser().Parse(template.Body, template.Arguments)(newContent, parameters); + } + } + catch (TemplateCompilationException tce) + { + throw new ContentCreationException("Template Error", tce.Message); + } + + return DialogResult.OK; + } + } +} diff --git a/src/DynamicTemplate/Plugin/IntegerParamInput.Designer.cs b/src/DynamicTemplate/Plugin/IntegerParamInput.Designer.cs new file mode 100644 index 0000000..16ebf25 --- /dev/null +++ b/src/DynamicTemplate/Plugin/IntegerParamInput.Designer.cs @@ -0,0 +1,64 @@ +namespace DynamicTemplate.Plugin +{ + partial class IntegerParamInput + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.txtValue = new System.Windows.Forms.TextBox(); + this.errorToolTip = new System.Windows.Forms.ToolTip(this.components); + this.SuspendLayout(); + // + // txtValue + // + this.txtValue.Location = new System.Drawing.Point(0, 16); + this.txtValue.Name = "txtValue"; + this.txtValue.Size = new System.Drawing.Size(250, 20); + this.txtValue.TabIndex = 1; + this.txtValue.Text = "0"; + this.txtValue.Validating += new System.ComponentModel.CancelEventHandler(this.txtValue_Validating); + // + // IntegerParamInput + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.Controls.Add(this.txtValue); + this.Name = "IntegerParamInput"; + this.Size = new System.Drawing.Size(250, 36); + this.Controls.SetChildIndex(this.txtValue, 0); + this.Controls.SetChildIndex(this.lblName, 0); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtValue; + private System.Windows.Forms.ToolTip errorToolTip; + + } +} diff --git a/src/DynamicTemplate/Plugin/IntegerParamInput.cs b/src/DynamicTemplate/Plugin/IntegerParamInput.cs new file mode 100644 index 0000000..3902530 --- /dev/null +++ b/src/DynamicTemplate/Plugin/IntegerParamInput.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace DynamicTemplate.Plugin +{ + public partial class IntegerParamInput : DynamicTemplate.Plugin.ParamInput + { + public IntegerParamInput() + { + InitializeComponent(); + } + + public override object Value + { + get + { + return int.Parse(txtValue.Text); + } + } + + private void txtValue_Validating(object sender, CancelEventArgs e) + { + txtValue.Text = txtValue.Text.Trim(); + if (txtValue.Text == "") + { + txtValue.Text = "0"; + } + + try + { + int.Parse(txtValue.Text); + } + catch (FormatException) + { + e.Cancel = true; + txtValue.Select(); + txtValue.SelectAll(); + errorToolTip.ToolTipIcon = ToolTipIcon.Warning; + errorToolTip.ToolTipTitle = "Invalid number"; + errorToolTip.Show("Please enter a positive or negative whole number", txtValue, 5000); + } + } + } +} + diff --git a/src/DynamicTemplate/Plugin/IntegerParamInput.resx b/src/DynamicTemplate/Plugin/IntegerParamInput.resx new file mode 100644 index 0000000..b3b935d --- /dev/null +++ b/src/DynamicTemplate/Plugin/IntegerParamInput.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.Designer.cs b/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.Designer.cs new file mode 100644 index 0000000..ffc9816 --- /dev/null +++ b/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.Designer.cs @@ -0,0 +1,61 @@ +namespace DynamicTemplate.Plugin +{ + partial class MultiLineTextboxParamInput + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtValue = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // txtValue + // + this.txtValue.AcceptsReturn = true; + this.txtValue.Location = new System.Drawing.Point(0, 16); + this.txtValue.Multiline = true; + this.txtValue.Name = "txtValue"; + this.txtValue.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.txtValue.Size = new System.Drawing.Size(250, 74); + this.txtValue.TabIndex = 1; + // + // MultiLineTextboxParamInput + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.txtValue); + this.Name = "MultiLineTextboxParamInput"; + this.Size = new System.Drawing.Size(250, 90); + this.Controls.SetChildIndex(this.txtValue, 0); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtValue; + } +} diff --git a/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.cs b/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.cs new file mode 100644 index 0000000..281b39b --- /dev/null +++ b/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using System.Web; + +namespace DynamicTemplate.Plugin +{ + public partial class MultiLineTextboxParamInput : ParamInput + { + private bool _htmlEscape; + + public MultiLineTextboxParamInput(bool htmlEscape) + { + _htmlEscape = htmlEscape; + InitializeComponent(); + } + + public override object Value + { + get + { + return _htmlEscape ? HttpUtility.HtmlEncode(txtValue.Text) : txtValue.Text; + } + } + } +} diff --git a/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.resx b/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/DynamicTemplate/Plugin/MultiLineTextboxParamInput.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/ParamInput.Designer.cs b/src/DynamicTemplate/Plugin/ParamInput.Designer.cs new file mode 100644 index 0000000..48f8e27 --- /dev/null +++ b/src/DynamicTemplate/Plugin/ParamInput.Designer.cs @@ -0,0 +1,64 @@ +namespace DynamicTemplate.Plugin +{ + partial class ParamInput + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblName = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // lblName + // + this.lblName.AutoSize = true; + this.lblName.Location = new System.Drawing.Point(0, 0); + this.lblName.Name = "lblName"; + this.lblName.Size = new System.Drawing.Size(21, 13); + this.lblName.TabIndex = 0; + this.lblName.Text = "{0}"; + this.lblName.FlatStyle = System.Windows.Forms.FlatStyle.System; + // + // ParamInput + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.AutoSize = true; + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.Controls.Add(this.lblName); + this.Name = "ParamInput"; + this.Size = new System.Drawing.Size(21, 13); + this.Load += new System.EventHandler(this.ParamInput_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + protected System.Windows.Forms.Label lblName; + + } +} diff --git a/src/DynamicTemplate/Plugin/ParamInput.cs b/src/DynamicTemplate/Plugin/ParamInput.cs new file mode 100644 index 0000000..a95eb0c --- /dev/null +++ b/src/DynamicTemplate/Plugin/ParamInput.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace DynamicTemplate.Plugin +{ + public partial class ParamInput : UserControl + { + public ParamInput() + { + InitializeComponent(); + } + + public virtual string ParamLabel + { + set { lblName.Text = value; } + } + + public virtual object Value + { + get { return null; } + } + + private void ParamInput_Load(object sender, EventArgs e) + { + lblName.SendToBack(); + } + } +} diff --git a/src/DynamicTemplate/Plugin/ParamInput.resx b/src/DynamicTemplate/Plugin/ParamInput.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/DynamicTemplate/Plugin/ParamInput.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.Designer.cs b/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.Designer.cs new file mode 100644 index 0000000..6d6f8a3 --- /dev/null +++ b/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.Designer.cs @@ -0,0 +1,59 @@ +namespace DynamicTemplate.Plugin +{ + partial class SingleLineTextboxParamInput + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtValue = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // txtValue + // + this.txtValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtValue.Location = new System.Drawing.Point(0, 16); + this.txtValue.Name = "txtValue"; + this.txtValue.Size = new System.Drawing.Size(250, 20); + this.txtValue.TabIndex = 1; + // + // SingleLineTextboxParamInput + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.Controls.Add(this.txtValue); + this.Name = "SingleLineTextboxParamInput"; + this.Size = new System.Drawing.Size(250, 37); + this.Controls.SetChildIndex(this.txtValue, 0); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtValue; + } +} diff --git a/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.cs b/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.cs new file mode 100644 index 0000000..2964f96 --- /dev/null +++ b/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Web; + +namespace DynamicTemplate.Plugin +{ + public partial class SingleLineTextboxParamInput : DynamicTemplate.Plugin.ParamInput + { + private bool _htmlEscape; + + public SingleLineTextboxParamInput(bool htmlEscape) + { + _htmlEscape = htmlEscape; + InitializeComponent(); + } + + public override object Value + { + get + { + return _htmlEscape ? HttpUtility.HtmlEncode(txtValue.Text) : txtValue.Text; + } + } + } +} + diff --git a/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.resx b/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/DynamicTemplate/Plugin/SingleLineTextboxParamInput.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateChooserForm.Designer.cs b/src/DynamicTemplate/Plugin/TemplateChooserForm.Designer.cs new file mode 100644 index 0000000..b75f1d2 --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateChooserForm.Designer.cs @@ -0,0 +1,196 @@ +namespace DynamicTemplate.Plugin +{ + partial class TemplateChooserForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.lstTemplate = new System.Windows.Forms.ListBox(); + this.btnAdd = new System.Windows.Forms.Button(); + this.btnRemove = new System.Windows.Forms.Button(); + this.btnRename = new System.Windows.Forms.Button(); + this.btnEdit = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.lblTemplate = new System.Windows.Forms.Label(); + this.lnkMore = new System.Windows.Forms.LinkLabel(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.SuspendLayout(); + // + // lstTemplate + // + this.lstTemplate.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lstTemplate.FormattingEnabled = true; + this.lstTemplate.IntegralHeight = false; + this.lstTemplate.Location = new System.Drawing.Point(12, 25); + this.lstTemplate.Name = "lstTemplate"; + this.lstTemplate.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; + this.lstTemplate.Size = new System.Drawing.Size(273, 153); + this.lstTemplate.TabIndex = 1; + this.lstTemplate.SelectedIndexChanged += new System.EventHandler(this.lstTemplate_SelectedIndexChanged); + this.lstTemplate.DoubleClick += new System.EventHandler(this.lstTemplate_DoubleClick); + // + // btnAdd + // + this.btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdd.Location = new System.Drawing.Point(291, 25); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(75, 23); + this.btnAdd.TabIndex = 2; + this.btnAdd.Text = "&New…"; + this.toolTip.SetToolTip(this.btnAdd, "Create a new template"); + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); + // + // btnRemove + // + this.btnRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnRemove.Enabled = false; + this.btnRemove.Location = new System.Drawing.Point(291, 54); + this.btnRemove.Name = "btnRemove"; + this.btnRemove.Size = new System.Drawing.Size(75, 23); + this.btnRemove.TabIndex = 3; + this.btnRemove.Text = "&Delete…"; + this.toolTip.SetToolTip(this.btnRemove, "Delete the selected template(s)"); + this.btnRemove.UseVisualStyleBackColor = true; + this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click); + // + // btnRename + // + this.btnRename.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnRename.Enabled = false; + this.btnRename.Location = new System.Drawing.Point(291, 126); + this.btnRename.Name = "btnRename"; + this.btnRename.Size = new System.Drawing.Size(75, 23); + this.btnRename.TabIndex = 4; + this.btnRename.Text = "&Rename…"; + this.toolTip.SetToolTip(this.btnRename, "Rename the selected template"); + this.btnRename.UseVisualStyleBackColor = true; + this.btnRename.Click += new System.EventHandler(this.btnRename_Click); + // + // btnEdit + // + this.btnEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnEdit.Enabled = false; + this.btnEdit.Location = new System.Drawing.Point(291, 155); + this.btnEdit.Name = "btnEdit"; + this.btnEdit.Size = new System.Drawing.Size(75, 23); + this.btnEdit.TabIndex = 5; + this.btnEdit.Text = "&Edit..."; + this.toolTip.SetToolTip(this.btnEdit, "Edit the selected template"); + this.btnEdit.UseVisualStyleBackColor = true; + this.btnEdit.Click += new System.EventHandler(this.btnEdit_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(276, 208); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(90, 23); + this.btnCancel.TabIndex = 7; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Enabled = false; + this.btnOK.Location = new System.Drawing.Point(180, 208); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(90, 23); + this.btnOK.TabIndex = 6; + this.btnOK.Text = "Continue"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // lblTemplate + // + this.lblTemplate.AutoSize = true; + this.lblTemplate.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.lblTemplate.Location = new System.Drawing.Point(12, 9); + this.lblTemplate.Name = "lblTemplate"; + this.lblTemplate.Size = new System.Drawing.Size(101, 13); + this.lblTemplate.TabIndex = 0; + this.lblTemplate.Text = "Choose a &template:"; + // + // lnkMore + // + this.lnkMore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.lnkMore.Location = new System.Drawing.Point(149, 181); + this.lnkMore.Name = "lnkMore"; + this.lnkMore.Size = new System.Drawing.Size(136, 16); + this.lnkMore.TabIndex = 8; + this.lnkMore.TabStop = true; + this.lnkMore.Text = "Edit Templates"; + this.lnkMore.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.lnkMore.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkMore_LinkClicked); + // + // TemplateChooserForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(378, 243); + this.Controls.Add(this.lnkMore); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnEdit); + this.Controls.Add(this.btnRename); + this.Controls.Add(this.btnRemove); + this.Controls.Add(this.btnAdd); + this.Controls.Add(this.lstTemplate); + this.Controls.Add(this.lblTemplate); + this.DoubleBuffered = true; + this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "TemplateChooserForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Insert Template"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ListBox lstTemplate; + private System.Windows.Forms.Button btnAdd; + private System.Windows.Forms.Button btnRemove; + private System.Windows.Forms.Button btnRename; + private System.Windows.Forms.Button btnEdit; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Label lblTemplate; + private System.Windows.Forms.LinkLabel lnkMore; + private System.Windows.Forms.ToolTip toolTip; + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateChooserForm.cs b/src/DynamicTemplate/Plugin/TemplateChooserForm.cs new file mode 100644 index 0000000..e3b36bd --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateChooserForm.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; +using DynamicTemplate.Compiler; + +namespace DynamicTemplate.Plugin +{ + public partial class TemplateChooserForm : Form + { + private const string TEMPLATE_EXTENSION = ".wlwtemplate"; + + private Template _selectedTemplate; + private string _selectedTemplateName; + private int _restoreWidth; + + public TemplateChooserForm() + { + InitializeComponent(); + } + + public string SelectedTemplateName + { + get { return _selectedTemplateName; } + } + + public Template SelectedTemplate + { + get { return _selectedTemplate; } + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + RefreshList(); + + /* + _restoreWidth = lstTemplate.Width; + lstTemplate.Width = btnAdd.Right - lstTemplate.Left; + */ + + _restoreWidth = Width; + int rightMargin = Width - btnAdd.Right; + Width = lstTemplate.Right + rightMargin; + btnAdd.Visible = false; + btnRemove.Visible = false; + btnEdit.Visible = false; + btnRename.Visible = false; + } + + private void RefreshList() + { + lstTemplate.Items.Clear(); + string templatesPath = TemplateDir; + Directory.CreateDirectory(templatesPath); + string[] files = Directory.GetFiles(templatesPath, "*" + TEMPLATE_EXTENSION, SearchOption.TopDirectoryOnly); + + Array.Sort(files, StringComparer.CurrentCultureIgnoreCase); + + lstTemplate.BeginUpdate(); + try + { + foreach (string file in files) + { + lstTemplate.Items.Add(Path.GetFileNameWithoutExtension(file)); + } + } + finally + { + lstTemplate.EndUpdate(); + } + + ManageButtons(); + } + + private static string TemplateDir + { + get + { + string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + string templatesPath = Path.Combine(appData, "WLWTemplates"); + return templatesPath; + } + } + + private void lstTemplate_SelectedIndexChanged(object sender, EventArgs e) + { + ManageButtons(); + } + + private void ManageButtons() + { + int itemsSelected = lstTemplate.SelectedIndices.Count; + btnOK.Enabled = btnEdit.Enabled = btnRename.Enabled + = itemsSelected == 1; + btnRemove.Enabled = itemsSelected > 0; + } + + private void btnRemove_Click(object sender, EventArgs e) + { + DialogResult result = MessageBox.Show( + this, + "Are you sure you want to delete the selected template(s)?", + "Confirm Delete", + MessageBoxButtons.OKCancel, + MessageBoxIcon.Question, + MessageBoxDefaultButton.Button1); + + try + { + if (result == DialogResult.OK) + { + string templateDir = TemplateDir; + foreach (string file in lstTemplate.SelectedItems) + { + string filePath = NameToPath(file); + if (File.Exists(filePath)) + File.Delete(filePath); + } + } + } + finally + { + RefreshList(); + lstTemplate.SelectedItem = null; + } + } + + private void btnRename_Click(object sender, EventArgs e) + { + using (TemplateRenameForm form = new TemplateRenameForm()) + { + string oldName = (string)lstTemplate.SelectedItem; + form.TemplateName = oldName; + if (form.ShowDialog(this) == DialogResult.OK) + { + string newName = form.TemplateName; + File.Move(NameToPath(oldName), NameToPath(newName)); + RefreshList(); + lstTemplate.SelectedItem = newName; + } + } + } + + private void btnEdit_Click(object sender, EventArgs e) + { + string name = lstTemplate.SelectedItem as string; + using (TemplateEditorForm form = new TemplateEditorForm()) + { + form.Text = string.Format(form.Text, name); + form.LoadFile(NameToPath(name)); + if (form.ShowDialog(this) == DialogResult.OK) + { + form.SaveFile(NameToPath(name)); + } + } + } + + private void btnAdd_Click(object sender, EventArgs e) + { + string name; + using (TemplateRenameForm form = new TemplateRenameForm()) + { + form.Text = "New Template"; + form.NameValidating += new CancelEventHandler(validateAddName); + if (form.ShowDialog(this) != DialogResult.OK) + return; + name = form.TemplateName; + } + + using (TemplateEditorForm form = new TemplateEditorForm()) + { + form.Text = string.Format(form.Text, name); + if (form.ShowDialog(this) == DialogResult.OK) + { + form.SaveFile(NameToPath(name)); + RefreshList(); + lstTemplate.SelectedItem = name; + } + } + } + + void validateAddName(object sender, CancelEventArgs e) + { + if (e.Cancel) + return; + Control ctrl = (Control)sender; + TemplateRenameForm form = (TemplateRenameForm)ctrl.FindForm(); + string name = form.TemplateName; + if (File.Exists(NameToPath(name))) + { + e.Cancel = true; + form.ShowErrorMessage("Name in use", "A template with this name already exists; please choose another name"); + } + } + + private string NameToPath(string name) + { + return Path.Combine(TemplateDir, name + TEMPLATE_EXTENSION); + } + + private void btnOK_Click(object sender, EventArgs e) + { + string name = (string)lstTemplate.SelectedItem; + string filePath = NameToPath(name); + Template template; + using (new WaitCursor()) + { + template = Template.Load(filePath); + } + _selectedTemplateName = name; + _selectedTemplate = template; + DialogResult = DialogResult.OK; + } + + private void lstTemplate_DoubleClick(object sender, EventArgs e) + { + if (btnOK.Enabled) + btnOK_Click(sender, e); + } + + private void lnkMore_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + lnkMore.Visible = false; + Width = _restoreWidth; + btnAdd.Visible = true; + btnRemove.Visible = true; + btnEdit.Visible = true; + btnRename.Visible = true; + } + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateChooserForm.resx b/src/DynamicTemplate/Plugin/TemplateChooserForm.resx new file mode 100644 index 0000000..5deed0a --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateChooserForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateEditorForm.Designer.cs b/src/DynamicTemplate/Plugin/TemplateEditorForm.Designer.cs new file mode 100644 index 0000000..6abb86c --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateEditorForm.Designer.cs @@ -0,0 +1,277 @@ +namespace DynamicTemplate.Plugin +{ + partial class TemplateEditorForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.btnDeleteRow = new System.Windows.Forms.Button(); + this.btnRowDown = new System.Windows.Forms.Button(); + this.btnRowUp = new System.Windows.Forms.Button(); + this.gridArgs = new System.Windows.Forms.DataGridView(); + this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.colType = new System.Windows.Forms.DataGridViewComboBoxColumn(); + this.colLabel = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.label2 = new System.Windows.Forms.Label(); + this.txtBody = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.pnlOrigin = new System.Windows.Forms.Panel(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.gridArgs)).BeginInit(); + this.SuspendLayout(); + // + // splitContainer1 + // + this.splitContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.splitContainer1.Location = new System.Drawing.Point(12, 12); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.btnDeleteRow); + this.splitContainer1.Panel1.Controls.Add(this.btnRowDown); + this.splitContainer1.Panel1.Controls.Add(this.btnRowUp); + this.splitContainer1.Panel1.Controls.Add(this.gridArgs); + this.splitContainer1.Panel1.Controls.Add(this.label2); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.txtBody); + this.splitContainer1.Panel2.Controls.Add(this.label3); + this.splitContainer1.Size = new System.Drawing.Size(522, 393); + this.splitContainer1.SplitterDistance = 149; + this.splitContainer1.TabIndex = 2; + // + // btnDeleteRow + // + this.btnDeleteRow.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnDeleteRow.Font = new System.Drawing.Font("Wingdings 2", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(2))); + this.btnDeleteRow.Location = new System.Drawing.Point(494, 74); + this.btnDeleteRow.Name = "btnDeleteRow"; + this.btnDeleteRow.Size = new System.Drawing.Size(28, 23); + this.btnDeleteRow.TabIndex = 4; + this.btnDeleteRow.Text = "O"; + this.toolTip.SetToolTip(this.btnDeleteRow, "Delete selected row"); + this.btnDeleteRow.UseVisualStyleBackColor = true; + this.btnDeleteRow.Click += new System.EventHandler(this.btnDeleteRow_Click); + // + // btnRowDown + // + this.btnRowDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnRowDown.Font = new System.Drawing.Font("Wingdings", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(2))); + this.btnRowDown.Location = new System.Drawing.Point(494, 45); + this.btnRowDown.Name = "btnRowDown"; + this.btnRowDown.Size = new System.Drawing.Size(28, 23); + this.btnRowDown.TabIndex = 3; + this.btnRowDown.Text = "ê"; + this.btnRowDown.TextAlign = System.Drawing.ContentAlignment.BottomCenter; + this.toolTip.SetToolTip(this.btnRowDown, "Move selected row down"); + this.btnRowDown.UseVisualStyleBackColor = true; + this.btnRowDown.Click += new System.EventHandler(this.btnRowDown_Click); + // + // btnRowUp + // + this.btnRowUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnRowUp.Font = new System.Drawing.Font("Wingdings", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(2))); + this.btnRowUp.Location = new System.Drawing.Point(494, 16); + this.btnRowUp.Name = "btnRowUp"; + this.btnRowUp.Size = new System.Drawing.Size(28, 23); + this.btnRowUp.TabIndex = 2; + this.btnRowUp.Text = "é"; + this.btnRowUp.TextAlign = System.Drawing.ContentAlignment.TopCenter; + this.toolTip.SetToolTip(this.btnRowUp, "Move selected row up"); + this.btnRowUp.UseVisualStyleBackColor = true; + this.btnRowUp.Click += new System.EventHandler(this.btnRowUp_Click); + // + // gridArgs + // + this.gridArgs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.gridArgs.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.gridArgs.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.colName, + this.colType, + this.colLabel}); + this.gridArgs.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter; + this.gridArgs.Location = new System.Drawing.Point(0, 16); + this.gridArgs.Name = "gridArgs"; + this.gridArgs.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.gridArgs.Size = new System.Drawing.Size(488, 130); + this.gridArgs.TabIndex = 1; + this.gridArgs.RowValidating += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.gridArgs_RowValidating); + this.gridArgs.CellValidating += new System.Windows.Forms.DataGridViewCellValidatingEventHandler(this.gridArgs_CellValidating); + this.gridArgs.DefaultValuesNeeded += new System.Windows.Forms.DataGridViewRowEventHandler(this.gridArgs_DefaultValuesNeeded); + // + // colName + // + this.colName.HeaderText = "Variable Name"; + this.colName.Name = "colName"; + this.colName.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; + this.colName.Width = 148; + // + // colType + // + this.colType.HeaderText = "Data Type"; + this.colType.Items.AddRange(new object[] { + "Text", + "Text (Multi-line)", + "HTML", + "HTML (Multi-line)", + "Integer", + "Double", + "Boolean", + "Date/Time"}); + this.colType.Name = "colType"; + this.colType.Resizable = System.Windows.Forms.DataGridViewTriState.True; + this.colType.Width = 149; + // + // colLabel + // + this.colLabel.HeaderText = "Label"; + this.colLabel.Name = "colLabel"; + this.colLabel.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; + this.colLabel.Width = 148; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label2.Location = new System.Drawing.Point(0, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(100, 13); + this.label2.TabIndex = 0; + this.label2.Text = "Template &Variables:"; + // + // txtBody + // + this.txtBody.AcceptsReturn = true; + this.txtBody.AcceptsTab = true; + this.txtBody.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtBody.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtBody.Location = new System.Drawing.Point(0, 22); + this.txtBody.Multiline = true; + this.txtBody.Name = "txtBody"; + this.txtBody.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.txtBody.Size = new System.Drawing.Size(522, 218); + this.txtBody.TabIndex = 1; + this.txtBody.WordWrap = false; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System; + this.label3.Location = new System.Drawing.Point(0, 6); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(81, 13); + this.label3.TabIndex = 0; + this.label3.Text = "Template &Body:"; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point(378, 411); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 3; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(459, 411); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 4; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // pnlOrigin + // + this.pnlOrigin.Location = new System.Drawing.Point(0, 0); + this.pnlOrigin.Name = "pnlOrigin"; + this.pnlOrigin.Size = new System.Drawing.Size(5, 5); + this.pnlOrigin.TabIndex = 5; + // + // TemplateEditorForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(546, 446); + this.Controls.Add(this.pnlOrigin); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.splitContainer1); + this.DoubleBuffered = true; + this.Name = "TemplateEditorForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Edit Template: {0}"; + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel1.PerformLayout(); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.Panel2.PerformLayout(); + this.splitContainer1.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.gridArgs)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.DataGridView gridArgs; + private System.Windows.Forms.TextBox txtBody; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnRowUp; + private System.Windows.Forms.Button btnDeleteRow; + private System.Windows.Forms.Button btnRowDown; + private System.Windows.Forms.DataGridViewTextBoxColumn colName; + private System.Windows.Forms.DataGridViewComboBoxColumn colType; + private System.Windows.Forms.DataGridViewTextBoxColumn colLabel; + private System.Windows.Forms.ToolTip toolTip; + private System.Windows.Forms.Panel pnlOrigin; + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateEditorForm.cs b/src/DynamicTemplate/Plugin/TemplateEditorForm.cs new file mode 100644 index 0000000..81ac9ec --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateEditorForm.cs @@ -0,0 +1,306 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Collections; +using System.Xml.Serialization; +using System.IO; +using DynamicTemplate.Compiler; +using System.CodeDom.Compiler; + +namespace DynamicTemplate.Plugin +{ + public partial class TemplateEditorForm : Form + { + private static Dictionary s_argStrToEnum = new Dictionary(); + private static Dictionary s_argEnumToStr = new Dictionary(); + private LanguageProvider _provider = new CSharpLanguageProvider(); + + public TemplateEditorForm() + { + InitializeComponent(); + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + // Do this late because otherwise exceptions occasionally occur while loading + gridArgs.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + } + + public Template Template + { + get + { + string body = txtBody.Text; + List args = new List(); + foreach (DataGridViewRow row in gridArgs.Rows) + { + if (row.IsNewRow) + continue; + + string identifier = row.Cells[0].Value as string; + string rawType = row.Cells[1].Value as string; + string label = row.Cells[2].Value as string; + ArgumentType type = s_argStrToEnum[rawType]; + args.Add(new ArgumentDescription(type, identifier, label)); + } + + Template template = new Template(); + template.Arguments = args.ToArray(); + template.Body = body; + return template; + } + set + { + txtBody.Text = value.Body; + ArgumentDescription[] args = value.Arguments; + + gridArgs.Rows.Clear(); + if (args.Length > 0) + { + gridArgs.Rows.Add(args.Length); + for (int i = 0; i < args.Length; i++) + { + DataGridViewRow row = gridArgs.Rows[i]; + row.Cells[0].Value = args[i].Identifier; + row.Cells[1].Value = s_argEnumToStr[args[i].Type]; + row.Cells[2].Value = args[i].Label; + } + } + } + } + + public void LoadFile(string filename) + { + Template = Template.Load(filename); + } + + public void SaveFile(string filename) + { + Template.Save(filename); + } + + static TemplateEditorForm() + { + s_argStrToEnum["Text"] = ArgumentType.TextString; + s_argStrToEnum["Text (Multi-line)"] = ArgumentType.TextStringExtended; + s_argStrToEnum["HTML"] = ArgumentType.HtmlString; + s_argStrToEnum["HTML (Multi-line)"] = ArgumentType.HtmlStringExtended; + s_argStrToEnum["Integer"] = ArgumentType.Integer; + s_argStrToEnum["Double"] = ArgumentType.Double; + s_argStrToEnum["Boolean"] = ArgumentType.Boolean; + s_argStrToEnum["Date/Time"] = ArgumentType.DateTime; + + foreach (KeyValuePair pair in s_argStrToEnum) + s_argEnumToStr[pair.Value] = pair.Key; + } + + private void btnDeleteRow_Click(object sender, EventArgs e) + { + if (gridArgs.SelectedRows.Count == 1) + { + DataGridViewRow row = gridArgs.SelectedRows[0]; + if (!row.IsNewRow) + gridArgs.Rows.Remove(row); + } + } + + private void btnRowUp_Click(object sender, EventArgs e) + { + if (gridArgs.SelectedRows.Count == 1) + { + DataGridViewRow row = gridArgs.SelectedRows[0]; + if (!row.IsNewRow) + { + int rowIndex = gridArgs.Rows.IndexOf(row); + if (rowIndex > 0) + { + DataGridViewRow otherRow = gridArgs.Rows[rowIndex - 1]; + gridArgs.Rows.RemoveAt(rowIndex - 1); + gridArgs.Rows.Insert(rowIndex, otherRow); + } + } + } + } + + private void SwapRows(int rowIndex1, int rowIndex2) + { + if (rowIndex1 == rowIndex2) + return; + + if (rowIndex1 > rowIndex2) + { + int tmp = rowIndex2; + rowIndex2 = rowIndex1; + rowIndex1 = tmp; + } + + DataGridViewRow row1 = gridArgs.Rows[rowIndex1]; + DataGridViewRow row2 = gridArgs.Rows[rowIndex2]; + gridArgs.Rows.RemoveAt(rowIndex2); + gridArgs.Rows.RemoveAt(rowIndex1); + gridArgs.Rows.Insert(rowIndex1, row2); + gridArgs.Rows.Insert(rowIndex2, row1); + } + + private void btnRowDown_Click(object sender, EventArgs e) + { + if (gridArgs.SelectedRows.Count == 1) + { + DataGridViewRow row = gridArgs.SelectedRows[0]; + if (!row.IsNewRow) + { + int rowIndex = gridArgs.Rows.IndexOf(row); + if (rowIndex < gridArgs.Rows.Count - 1) + { + DataGridViewRow otherRow = gridArgs.Rows[rowIndex + 1]; + gridArgs.Rows.RemoveAt(rowIndex + 1); + gridArgs.Rows.Insert(rowIndex, otherRow); + } + } + } + } + + private void gridArgs_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e) + { + e.Row.Cells[1].Value = s_argEnumToStr[ArgumentType.TextString]; + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (ValidateArgs() && Compile()) + DialogResult = DialogResult.OK; + } + + private bool Compile() + { + UseWaitCursor = true; + try + { + new BodyParser().Parse(Template.Body, Template.Arguments); + return true; + } + catch (TemplateCompilationException ex) + { + int sourceLine = ex.Position.Line; + int sourceCol = ex.Position.Column; + if (sourceLine >= 0 && sourceCol >= 0) + { + int idx = IndexToPosition.ReverseFind(txtBody.Text, sourceLine, sourceCol); + if (idx >= 0) + { + txtBody.Select(idx, 0); + //tooltipPos = TooltipHelper.GetPointFromIndex(txtBody, idx); + //tooltipPos.Offset(txtBody.Location); + txtBody.Select(); + } + } + string errorTitle = "Compile Error"; + string errorMessage = ex.Message; + ShowError(errorTitle, errorMessage, OffsetToOrigin(txtBody, new Point(0, txtBody.Height))); + return false; + } + finally + { + UseWaitCursor = false; + } + } + + private void ShowError(string errorTitle, string errorMessage, Point p) + { + toolTip.ToolTipTitle = errorTitle; + toolTip.ToolTipIcon = ToolTipIcon.Warning; + toolTip.Show(errorMessage, pnlOrigin, p, 10000); + } + + private bool ValidateArgs() + { + Dictionary usedIdentifiers = new Dictionary(); + + foreach (DataGridViewRow row in gridArgs.Rows) + { + if (row.IsNewRow) + continue; + + DataGridViewCell cell = row.Cells[0]; + if (!ValidateCell(cell, (string)cell.FormattedValue)) + { + if (!cell.Displayed) + { + gridArgs.FirstDisplayedCell = cell; + } + Rectangle rect = gridArgs.GetCellDisplayRectangle(cell.ColumnIndex, cell.RowIndex, true); + ShowError("Error", cell.ErrorText, OffsetToOrigin(gridArgs, new Point(rect.Left, rect.Bottom))); + return false; + } + + string identifier = (string)cell.FormattedValue; + string normalizedIdentifier = _provider.NormalizeIdentifier(identifier); + if (normalizedIdentifier == "_selection") + { + foreach (DataGridViewRow row2 in gridArgs.Rows) + row2.Selected = row2 == row; + ShowError("Error", "_selection is a reserved variable name and cannot be used", OffsetToOrigin(gridArgs, new Point(0, gridArgs.Height))); + return false; + } + if (usedIdentifiers.ContainsKey(normalizedIdentifier)) + { + DataGridViewRow prevRow = usedIdentifiers[normalizedIdentifier]; + foreach (DataGridViewRow row2 in gridArgs.Rows) + { + row2.Selected = (row2 == row || row2 == prevRow); + } + gridArgs.FirstDisplayedScrollingRowIndex = prevRow.Index; + ShowError("Error", "Variable names must be unique", OffsetToOrigin(gridArgs, new Point(0, gridArgs.Height))); + return false; + } + usedIdentifiers.Add(normalizedIdentifier, row); + } + + return true; + } + + private void gridArgs_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) + { + if (e.ColumnIndex == 0) + { + DataGridViewCell cell = gridArgs.Rows[e.RowIndex].Cells[0]; + ValidateCell(cell, (string)e.FormattedValue); + } + } + + private void gridArgs_RowValidating(object sender, DataGridViewCellCancelEventArgs e) + { + DataGridViewCell cell = gridArgs.Rows[e.RowIndex].Cells[0]; + ValidateCell(cell, (string)cell.FormattedValue); + } + + private bool ValidateCell(DataGridViewCell cell, string identifier) + { + if (cell.OwningRow.IsNewRow) + return true; + + string errorMessage; + if (!_provider.IsValidIdentifier(identifier, out errorMessage)) + { + cell.ErrorText = errorMessage; + return false; + } + else + { + cell.ErrorText = ""; + } + return true; + } + + private Point OffsetToOrigin(Control reference, Point p) + { + return pnlOrigin.PointToClient(reference.PointToScreen(p)); + } + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateEditorForm.resx b/src/DynamicTemplate/Plugin/TemplateEditorForm.resx new file mode 100644 index 0000000..0401ce0 --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateEditorForm.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + True + + + True + + + True + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateInputForm.Designer.cs b/src/DynamicTemplate/Plugin/TemplateInputForm.Designer.cs new file mode 100644 index 0000000..2dbfbfb --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateInputForm.Designer.cs @@ -0,0 +1,98 @@ +namespace DynamicTemplate.Plugin +{ + partial class TemplateInputForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.pnlInputs = new System.Windows.Forms.Panel(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // pnlInputs + // + this.pnlInputs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlInputs.AutoScroll = true; + this.pnlInputs.Location = new System.Drawing.Point(12, 12); + this.pnlInputs.Name = "pnlInputs"; + this.pnlInputs.Size = new System.Drawing.Size(282, 387); + this.pnlInputs.TabIndex = 0; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point(138, 413); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.CausesValidation = false; + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(219, 413); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // TemplateInputForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(306, 448); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.pnlInputs); + this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "TemplateInputForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "TemplateInputForm"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel pnlInputs; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateInputForm.cs b/src/DynamicTemplate/Plugin/TemplateInputForm.cs new file mode 100644 index 0000000..7e304b0 --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateInputForm.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using DynamicTemplate.Compiler; + +namespace DynamicTemplate.Plugin +{ + public partial class TemplateInputForm : Form + { + private Template _template; + private const int INTRA_CONTROL_PADDING = 8; + private List _paramInputControls = new List(); + + public TemplateInputForm(string templateName, Template template) + { + _template = template; + InitializeComponent(); + Text = templateName; + + int top = 0; + foreach (ArgumentDescription arg in _template.Arguments) + { + ParamInput paramInputControl; + switch (arg.Type) + { + case ArgumentType.TextString: + case ArgumentType.HtmlString: + paramInputControl = new SingleLineTextboxParamInput(arg.Type == ArgumentType.TextString); + break; + case ArgumentType.TextStringExtended: + case ArgumentType.HtmlStringExtended: + paramInputControl = new MultiLineTextboxParamInput(arg.Type == ArgumentType.TextString); + break; + case ArgumentType.Integer: + paramInputControl = new IntegerParamInput(); + break; + case ArgumentType.Double: + paramInputControl = new DoubleParamInput(); + break; + case ArgumentType.Boolean: + paramInputControl = new BooleanParamInput(); + break; + case ArgumentType.DateTime: + paramInputControl = new DateTimeParamInput(); + break; + default: + continue; + } + paramInputControl.ParamLabel = arg.Label; + paramInputControl.Left = 0; + paramInputControl.Top = top; + top += paramInputControl.Height + INTRA_CONTROL_PADDING; + pnlInputs.Controls.Add(paramInputControl); + _paramInputControls.Add(paramInputControl); + } + + int delta = top - pnlInputs.Height - pnlInputs.AutoScrollMargin.Height * 2 + 10; + if (delta < 0) + Height += delta; + } + + public object[] ParamValues() + { + return _paramInputControls.ConvertAll(pi => pi.Value).ToArray(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (ValidateChildren()) + DialogResult = DialogResult.OK; + } + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateInputForm.resx b/src/DynamicTemplate/Plugin/TemplateInputForm.resx new file mode 100644 index 0000000..19dc0dd --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateInputForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateRenameForm.Designer.cs b/src/DynamicTemplate/Plugin/TemplateRenameForm.Designer.cs new file mode 100644 index 0000000..4d45516 --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateRenameForm.Designer.cs @@ -0,0 +1,107 @@ +namespace DynamicTemplate.Plugin +{ + partial class TemplateRenameForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.lblName = new System.Windows.Forms.Label(); + this.txtName = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.errorToolTip = new System.Windows.Forms.ToolTip(this.components); + this.SuspendLayout(); + // + // lblName + // + this.lblName.AutoSize = true; + this.lblName.Location = new System.Drawing.Point(9, 9); + this.lblName.Name = "lblName"; + this.lblName.Size = new System.Drawing.Size(38, 13); + this.lblName.TabIndex = 0; + this.lblName.Text = "&Name:"; + // + // txtName + // + this.txtName.Location = new System.Drawing.Point(12, 25); + this.txtName.Name = "txtName"; + this.txtName.Size = new System.Drawing.Size(297, 20); + this.txtName.TabIndex = 1; + this.txtName.Validating += new System.ComponentModel.CancelEventHandler(this.txtName_Validating); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(153, 71); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 2; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(234, 71); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // TemplateRenameForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(321, 106); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.txtName); + this.Controls.Add(this.lblName); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "TemplateRenameForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "TemplateRenameForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblName; + private System.Windows.Forms.TextBox txtName; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.ToolTip errorToolTip; + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateRenameForm.cs b/src/DynamicTemplate/Plugin/TemplateRenameForm.cs new file mode 100644 index 0000000..80c6e21 --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateRenameForm.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; + +namespace DynamicTemplate.Plugin +{ + public partial class TemplateRenameForm : Form + { + public TemplateRenameForm() + { + InitializeComponent(); + } + + public event CancelEventHandler NameValidating + { + add + { + txtName.Validating += value; + } + remove + { + txtName.Validating -= value; + } + } + + public string TemplateName + { + get + { + return txtName.Text.Trim(); + } + set { txtName.Text = value; } + } + + private void txtName_Validating(object sender, CancelEventArgs e) + { + txtName.Text = txtName.Text.Trim(); + string name = txtName.Text; + + if (name.Length == 0) + { + e.Cancel = true; + txtName.Select(); + ShowErrorMessage("Missing name", "A name is required"); + return; + } + + char[] badChars = Path.GetInvalidFileNameChars(); + int badIndex; + if ((badIndex = name.IndexOfAny(badChars)) >= 0) + { + e.Cancel = true; + txtName.Select(); + txtName.Select(badIndex, 1); + ShowErrorMessage("Invalid name", "The name contains one or more invalid characters"); + return; + } + } + + public void ShowErrorMessage(string title, string msg) + { + errorToolTip.ToolTipIcon = ToolTipIcon.Warning; + errorToolTip.ToolTipTitle = title; + errorToolTip.Show(msg, txtName, 0, txtName.Height, 5000); + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (ValidateChildren()) + DialogResult = DialogResult.OK; + } + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TemplateRenameForm.resx b/src/DynamicTemplate/Plugin/TemplateRenameForm.resx new file mode 100644 index 0000000..b3b935d --- /dev/null +++ b/src/DynamicTemplate/Plugin/TemplateRenameForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Plugin/TooltipHelper.cs b/src/DynamicTemplate/Plugin/TooltipHelper.cs new file mode 100644 index 0000000..c619bd8 --- /dev/null +++ b/src/DynamicTemplate/Plugin/TooltipHelper.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Drawing; +using System.Windows.Forms; + +namespace DynamicTemplate.Plugin +{ + class TooltipHelper + { + public static Point GetPointFromIndex(TextBox textbox, int index) + { + IntPtr result = SendMessage(textbox.Handle, EM_POSFROMCHAR, new IntPtr(index), IntPtr.Zero); + int res = result.ToInt32(); + return new Point(res & 0xFFFF, (res >> 16) & 0xFFFF); + } + + const uint EM_POSFROMCHAR = 0x426; + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] + private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + } +} diff --git a/src/DynamicTemplate/Plugin/WaitCursor.cs b/src/DynamicTemplate/Plugin/WaitCursor.cs new file mode 100644 index 0000000..54b5307 --- /dev/null +++ b/src/DynamicTemplate/Plugin/WaitCursor.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace DynamicTemplate.Plugin +{ + class WaitCursor : IDisposable + { + public WaitCursor() + { + Cursor.Current = Cursors.WaitCursor; + } + + public void Dispose() + { + Cursor.Current = Cursors.Default; + } + } +} diff --git a/src/DynamicTemplate/Program.cs b/src/DynamicTemplate/Program.cs new file mode 100644 index 0000000..b3f81ee --- /dev/null +++ b/src/DynamicTemplate/Program.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using DynamicTemplate.Plugin; +using System.Xml.Serialization; +using System.Xml; +using System.IO; + +namespace DynamicTemplate +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + //Application.Run(new Form1()); + //Application.Run(new TemplateEditorForm()); + //new TemplateChooserForm().ShowDialog(); + + string newContent = null; + if (DialogResult.OK == new DynamicTemplateContentSource().CreateContent(null, ref newContent)) + MessageBox.Show("BEGIN\r\n" + newContent + "\r\nEND"); + } + } +} \ No newline at end of file diff --git a/src/DynamicTemplate/Properties/AssemblyInfo.cs b/src/DynamicTemplate/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..64b33c1 --- /dev/null +++ b/src/DynamicTemplate/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Dynamic Template")] +[assembly: AssemblyDescription("Dynamic Template Plugin for Windows Live Writer")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Dynamic Template")] +[assembly: AssemblyCopyright("Copyright 2006-2007 Joe Cheng")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("00f7c9cb-9e4e-4f2b-9a0c-ccfde9d098eb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.2.0")] +[assembly: AssemblyFileVersion("1.0.2.0")] diff --git a/src/DynamicTemplate/Properties/Resources.Designer.cs b/src/DynamicTemplate/Properties/Resources.Designer.cs new file mode 100644 index 0000000..447ad85 --- /dev/null +++ b/src/DynamicTemplate/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DynamicTemplate.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DynamicTemplate.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/src/DynamicTemplate/Properties/Resources.resx b/src/DynamicTemplate/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/src/DynamicTemplate/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DynamicTemplate/Properties/Settings.Designer.cs b/src/DynamicTemplate/Properties/Settings.Designer.cs new file mode 100644 index 0000000..47fd128 --- /dev/null +++ b/src/DynamicTemplate/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace DynamicTemplate.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/src/DynamicTemplate/Properties/Settings.settings b/src/DynamicTemplate/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/src/DynamicTemplate/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/DynamicTemplate/Template.cs b/src/DynamicTemplate/Template.cs new file mode 100644 index 0000000..73fae25 --- /dev/null +++ b/src/DynamicTemplate/Template.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml.Serialization; +using System.IO; +using System.Xml; +using System.Text.RegularExpressions; + +namespace DynamicTemplate +{ + public class Template + { + private ArgumentDescription[] _arguments = new ArgumentDescription[0]; + private string _body = string.Empty; + + [XmlArrayItem(ElementName = "Argument")] + public ArgumentDescription[] Arguments + { + get + { + return _arguments; + } + set + { + _arguments = value; + } + } + + public string Body + { + get + { + return _body; + } + set + { + _body = FixupWhiteSpace(value); + } + } + + public static Template Load(string filePath) + { + XmlSerializer ser = new XmlSerializer(typeof(Template)); + using (Stream s = File.OpenRead(filePath)) + { + return (Template)ser.Deserialize(s); + } + } + + public void Save(string filePath) + { + XmlSerializer ser = new XmlSerializer(typeof(Template)); + using (Stream s = File.Create(filePath)) + { + ser.Serialize(s, this); + } + } + + /// + /// HACK: Converts standalone \n to \r\n. For some reason this happens + /// after roundtripping to XML. + /// + private string FixupWhiteSpace(string value) + { + return Regex.Replace(value, @"(? + + + \ No newline at end of file diff --git a/src/DynamicTemplateManager/ConfirmForm.Designer.cs b/src/DynamicTemplateManager/ConfirmForm.Designer.cs new file mode 100644 index 0000000..c5a2ef9 --- /dev/null +++ b/src/DynamicTemplateManager/ConfirmForm.Designer.cs @@ -0,0 +1,201 @@ +namespace DynamicTemplateManager +{ + partial class ConfirmForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.lblText = new System.Windows.Forms.Label(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.txtName = new System.Windows.Forms.TextBox(); + this.delayTimer = new System.Windows.Forms.Timer(this.components); + this.label1 = new System.Windows.Forms.Label(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.label2 = new System.Windows.Forms.Label(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.tableLayoutPanel1.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnOK.Location = new System.Drawing.Point(98, 4); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 0; + this.btnOK.Text = "Install"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(179, 4); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 1; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // lblText + // + this.lblText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lblText.BackColor = System.Drawing.SystemColors.Info; + this.lblText.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblText.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblText.ForeColor = System.Drawing.SystemColors.ControlDarkDark; + this.lblText.Location = new System.Drawing.Point(3, 80); + this.lblText.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0); + this.lblText.Name = "lblText"; + this.lblText.Padding = new System.Windows.Forms.Padding(6); + this.lblText.Size = new System.Drawing.Size(352, 55); + this.lblText.TabIndex = 2; + this.lblText.Text = "WARNING: Templates can easily be used to hack your computer and steal or destroy " + + "your data. Never accept templates from anyone you don\'t fully trust!"; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel1.ColumnCount = 4; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Controls.Add(this.btnOK, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.btnCancel, 2, 0); + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 151); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(3, 16, 3, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 1; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(352, 30); + this.tableLayoutPanel1.TabIndex = 3; + // + // txtName + // + this.txtName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtName.Font = new System.Drawing.Font("Tahoma", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtName.Location = new System.Drawing.Point(3, 19); + this.txtName.Name = "txtName"; + this.txtName.Size = new System.Drawing.Size(352, 30); + this.txtName.TabIndex = 4; + this.txtName.Text = "