Skip to content

Commit

Permalink
Added options dialog
Browse files Browse the repository at this point in the history
Added an options dialog and a new "Default" setting for the "Run on
build" property, so settings can be set at a global level.
  • Loading branch information
bennor committed Jul 14, 2015
1 parent 0d85d85 commit b7f8ab5
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 33 deletions.
6 changes: 6 additions & 0 deletions AutoT4/AutoT4.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,16 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AutoT4ProjectItemSettings.cs" />
<Compile Include="RunOnBuild.cs" />
<Compile Include="DefaultRunOnBuild.cs" />
<Compile Include="EnumDescriptionConverter.cs" />
<Compile Include="Guids.cs" />
<Compile Include="AutoT4ExtenderProvider.cs" />
<Compile Include="AutoT4Extender.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="Options.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ProjectItemSettings.cs" />
<Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen>
Expand Down
29 changes: 13 additions & 16 deletions AutoT4/AutoT4Package.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using EnvDTE;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using VSLangProj;

namespace BennorMcCarthy.AutoT4
{
[PackageRegistration(UseManagedResourcesOnly = true)]
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
[Guid(GuidList.guidAutoT4PkgString)]
[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
[ProvideOptionPage(typeof(Options), Options.CategoryName, Options.PageName, 1000, 1001, false)]
public sealed class AutoT4Package : Package
{
private DTE _dte;
Expand All @@ -29,6 +21,11 @@ public sealed class AutoT4Package : Package
private AutoT4ExtenderProvider _extenderProvider;
private readonly List<int> _extenderProviderCookies = new List<int>();

private Options Options
{
get { return (Options)GetDialogPage(typeof(Options)); }
}

protected override void Initialize()
{
base.Initialize();
Expand Down Expand Up @@ -62,21 +59,21 @@ private void RegisterExtenderProvider(string catId)
_extenderProviderCookies.Add(_objectExtenders.RegisterExtenderProvider(catId, name, _extenderProvider));
}

private void OnBuildBegin(vsBuildScope Scope, vsBuildAction Action)
private void OnBuildBegin(vsBuildScope scope, vsBuildAction action)
{
RunTemplates(Scope, BuildEvent.BeforeBuild);
RunTemplates(scope, RunOnBuild.BeforeBuild, Options.RunOnBuild == DefaultRunOnBuild.BeforeBuild);
}

private void OnBuildDone(vsBuildScope Scope, vsBuildAction Action)
private void OnBuildDone(vsBuildScope scope, vsBuildAction action)
{
RunTemplates(Scope, BuildEvent.AfterBuild);
RunTemplates(scope, RunOnBuild.AfterBuild, Options.RunOnBuild == DefaultRunOnBuild.AfterBuild);
}

private void RunTemplates(vsBuildScope scope, BuildEvent buildEvent)
private void RunTemplates(vsBuildScope scope, RunOnBuild buildEvent, bool runIfDefault)
{
_dte.GetProjectsWithinBuildScope(scope)
.FindT4ProjectItems()
.ThatShouldRunOn(buildEvent)
.ThatShouldRunOn(buildEvent, runIfDefault)
.ToList()
.ForEach(item => item.RunTemplate());
}
Expand Down
24 changes: 11 additions & 13 deletions AutoT4/AutoT4ProjectItemSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace BennorMcCarthy.AutoT4
[ClassInterface(ClassInterfaceType.None)]
public class AutoT4ProjectItemSettings : ProjectItemSettings
{
private const BuildEvent DefaultRunOnBuildSetting = BuildEvent.BeforeBuild;
private const RunOnBuild DefaultRunOnBuildSetting = RunOnBuild.Default;

public AutoT4ProjectItemSettings(ProjectItem item)
: base(item, "AutoT4") { }
Expand All @@ -19,33 +19,31 @@ public AutoT4ProjectItemSettings(ProjectItem item)
[DisplayName("Run on build")]
[Category("AutoT4")]
[Description("Whether to run this template at build time or not.")]
public BuildEvent RunOnBuild
[TypeConverter(typeof(EnumDescriptionConverter))]
public RunOnBuild RunOnBuild
{
get { return Get(DefaultRunOnBuildSetting, CoerceOldRunOnBuildValue); }
set { Set(value); }
}

/// <summary>
/// Converts the old <see cref="bool"/> <see cref="RunOnBuild"/> property to <see cref="BuildEvent"/>
/// Converts the old <see cref="bool"/> <see cref="RunOnBuild"/> property to <see cref="RunOnBuild"/>
/// </summary>
private BuildEvent CoerceOldRunOnBuildValue(string value)
private RunOnBuild CoerceOldRunOnBuildValue(string value)
{
var newRunOnBuildValue = DefaultRunOnBuildSetting;
bool previousRunOnBuild;
if (bool.TryParse(value, out previousRunOnBuild))
newRunOnBuildValue = previousRunOnBuild ? BuildEvent.BeforeBuild : BuildEvent.DoNotRun;
{
newRunOnBuildValue = previousRunOnBuild
? RunOnBuild.Default
: RunOnBuild.Disabled;
}

//coercion was needed, therefore the new value needs to be assigned so that it gets migrated in the settings
// Coercion was needed, therefore the new value needs to be assigned so that it gets migrated in the settings
RunOnBuild = newRunOnBuildValue;

return newRunOnBuildValue;
}
}

public enum BuildEvent
{
DoNotRun,
BeforeBuild,
AfterBuild
}
}
13 changes: 13 additions & 0 deletions AutoT4/DefaultRunOnBuild.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.ComponentModel;

namespace BennorMcCarthy.AutoT4
{
public enum DefaultRunOnBuild
{
Disabled,
[Description("Before build")]
BeforeBuild,
[Description("After build")]
AfterBuild
}
}
54 changes: 54 additions & 0 deletions AutoT4/EnumDescriptionConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;

namespace BennorMcCarthy.AutoT4
{
public class EnumDescriptionConverter : EnumConverter
{
private readonly Type _enumType;

public EnumDescriptionConverter(Type type)
: base(type)
{
_enumType = type;
}

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string);
}

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType)
{
if (value == null)
return null;

var field = _enumType.GetField(Enum.GetName(_enumType, value));
var attribute = field.GetCustomAttributes(typeof(DescriptionAttribute), true).Cast<DescriptionAttribute>().FirstOrDefault();
return attribute != null
? attribute.Description
: value.ToString();
}

public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var stringValue = value as string;
if (stringValue == null)
return Activator.CreateInstance(_enumType);

var field = _enumType.GetFields()
.FirstOrDefault(f => f.GetCustomAttributes(typeof(DescriptionAttribute), true).Cast<DescriptionAttribute>()
.Any(a => stringValue.Equals(a.Description, StringComparison.OrdinalIgnoreCase)));
return field != null
? field.GetValue(null)
: Enum.Parse(_enumType, stringValue);
}
}
}
10 changes: 6 additions & 4 deletions AutoT4/ExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ public static IEnumerable<Project> GetProjectsWithinBuildScope(this DTE dte, vsB

public static class ProjectItemExtensions
{
public static IEnumerable<ProjectItem> ThatShouldRunOn(this IEnumerable<ProjectItem> projectItems, BuildEvent whenToRun)
public static IEnumerable<ProjectItem> ThatShouldRunOn(this IEnumerable<ProjectItem> projectItems, RunOnBuild whenToRun, bool runIfDefault)
{
return projectItems.Where(projectItem => projectItem.ShouldRunOn(whenToRun));
return projectItems.Where(projectItem => projectItem.ShouldRunOn(whenToRun, runIfDefault));
}

public static bool ShouldRunOn(this ProjectItem projectItem, BuildEvent whenToRun)
public static bool ShouldRunOn(this ProjectItem projectItem, RunOnBuild whenToRun, bool runIfDefault)
{
return (new AutoT4ProjectItemSettings(projectItem)).RunOnBuild == whenToRun;
var setting = new AutoT4ProjectItemSettings(projectItem).RunOnBuild;
return setting == whenToRun ||
(setting == RunOnBuild.Default && runIfDefault);
}

public static void RunTemplate(this ProjectItem template)
Expand Down
24 changes: 24 additions & 0 deletions AutoT4/Options.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.ComponentModel;
using Microsoft.VisualStudio.Shell;

namespace BennorMcCarthy.AutoT4
{
public class Options : DialogPage
{
private DefaultRunOnBuild _buildAction = DefaultRunOnBuild.BeforeBuild;

public const string CategoryName = "AutoT4";
public const string PageName = "General";

[Category("General")]
[DisplayName("Run on build")]
[Description("Run T4 templates when building.")]
[DefaultValue(DefaultRunOnBuild.BeforeBuild)]
[TypeConverter(typeof(EnumDescriptionConverter))]
public DefaultRunOnBuild RunOnBuild
{
get { return _buildAction; }
set { _buildAction = value; }
}
}
}
15 changes: 15 additions & 0 deletions AutoT4/RunOnBuild.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.ComponentModel;

namespace BennorMcCarthy.AutoT4
{
public enum RunOnBuild
{
[Description("Default")]
Default = -1,
Disabled = 0,
[Description("Before build")]
BeforeBuild,
[Description("After build")]
AfterBuild
}
}

0 comments on commit b7f8ab5

Please sign in to comment.