From bf2a8c7dbd50c0c7c5ac9af799d1d2e659c91c07 Mon Sep 17 00:00:00 2001 From: JamesDawson Date: Sun, 26 Sep 2010 01:41:51 +0100 Subject: [PATCH] Initial import of a WinForm-based wizard framework that uses a generated UI to allow the capturing the required values for multiple tokens. --- .../Endjin.Templify.Client.csproj | 4 + .../ViewModel/DeployPackageViewModel.cs | 26 +- .../Packager/Processors/IPackageProcessor.cs | 3 +- .../Packager/Tokeniser/ITemplateTokeniser.cs | 8 +- .../Packager/Processors/PackageProcessor.cs | 20 +- .../Packager/Tokeniser/TemplateTokeniser.cs | 35 +- .../Domain/Packages/Manifest.cs | 5 + .../Packages/PackageConfigurationData.cs | 27 + .../Endjin.Templify.Domain.csproj | 1 + .../Tasks/PackageDeployerTasks.cs | 2 +- .../Command.cs | 33 ++ .../CommandList.cs | 30 ++ .../ConfigHelper.cs | 49 ++ .../Endjin.Templify.WizardFramework.csproj | 91 ++++ .../Forms/BaseWizardForm.cs | 80 +++ .../Forms/BaseWizardForm.resx | 42 ++ .../Forms/FormWizardCommand.cs | 61 +++ .../Forms/InstallParametersForm.cs | 377 ++++++++++++++ .../Forms/InstallParametersForm.resx | 317 ++++++++++++ .../Forms/StartupForm.cs | 292 +++++++++++ .../Forms/StartupForm.resx | 486 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 ++ .../WizardCommand.cs | 32 ++ .../WizardCommand.resx | 42 ++ .../WizardCommandList.cs | 101 ++++ .../WizardState.cs | 24 + Solutions/Endjin.Templify.sln | 14 +- 27 files changed, 2216 insertions(+), 22 deletions(-) create mode 100644 Solutions/Endjin.Templify.Domain/Domain/Packages/PackageConfigurationData.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/Command.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/CommandList.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/ConfigHelper.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/Endjin.Templify.WizardFramework.csproj create mode 100644 Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.resx create mode 100644 Solutions/Endjin.Templify.WizardFramework/Forms/FormWizardCommand.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.resx create mode 100644 Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.resx create mode 100644 Solutions/Endjin.Templify.WizardFramework/Properties/AssemblyInfo.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/WizardCommand.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/WizardCommand.resx create mode 100644 Solutions/Endjin.Templify.WizardFramework/WizardCommandList.cs create mode 100644 Solutions/Endjin.Templify.WizardFramework/WizardState.cs diff --git a/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj b/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj index 7c6f2f5..44e1a08 100644 --- a/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj +++ b/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj @@ -158,6 +158,10 @@ {9E8B79ED-9C17-485B-B1F9-8D33D8BB4BD2} Endjin.Templify.Domain + + {D8F709BA-1E52-48FB-A917-7C3A40445F7F} + Endjin.Templify.WizardFramework + diff --git a/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs b/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs index 903de51..2755ff6 100644 --- a/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs +++ b/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs @@ -19,6 +19,7 @@ namespace Endjin.Templify.Client.ViewModel using Endjin.Templify.Domain.Framework; using Endjin.Templify.Domain.Framework.Threading; using Endjin.Templify.Domain.Infrastructure; + using Endjin.Templify.WizardFramework; #endregion @@ -250,7 +251,11 @@ private void ExecutePackageComplete(RunWorkerCompletedEventArgs e) private void ExecutePackageCore(Package package) { this.packageDeploymentProcessor.Execute(package); - this.packageProcessor.Process(this.CommandOptions.Path, this.Name); + + // TODO: Due to the WizardFramework being a WinForm, the WPF app does not show anything :-( + this.ExecuteWizard(package); + + this.packageProcessor.Process(this.CommandOptions.Path, this.Name, package.Manifest.Configuration); } private void Initialise() @@ -269,5 +274,24 @@ private void RetrievePackages() { this.Packages = new PackageCollection(this.packageRepository.FindAll()); } + + private void ExecuteWizard(Package package) + { + // TODO: Run the wizard to collect the token info + // Instantiate the command list + var cmdList = new CommandList(); + + // Add the WizardCommand objects in order to the list to provide + // the application workflow + cmdList.Add(new PackageConfigurationDataWizardFormCommand(package.Manifest.Configuration)); + + // The wizard simply uses a flow of objects in order until we + // reach the last command, so loop until that condition is + // detected + while (cmdList.CmdPointer > -1 && !cmdList.IsLastCommand()) + { + cmdList.ExecuteNext(); + } + } } } \ No newline at end of file diff --git a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs index 77160fb..29a172c 100644 --- a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs +++ b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs @@ -3,6 +3,7 @@ #region Using Directives using System; + using System.Collections.Generic; using Endjin.Templify.Domain.Domain.Packages; @@ -10,6 +11,6 @@ public interface IPackageProcessor { - void Process(string path, string name); + void Process(string path, string name, List tokens); } } \ No newline at end of file diff --git a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs index c9c10d5..5616323 100644 --- a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs +++ b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs @@ -1,9 +1,13 @@ namespace Endjin.Templify.Domain.Contracts.Packager.Tokeniser { + using System.Collections.Generic; + + using Endjin.Templify.Domain.Domain.Packages; + public interface ITemplateTokeniser { - void TokeniseFileContent(string file, string token); + void TokeniseFileContent(string file, List tokens); - void TokeniseDirectoryAndFilePaths(string file, string token); + void TokeniseDirectoryAndFilePaths(string file, List tokens); } } \ No newline at end of file diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs b/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs index 004f195..9109400 100644 --- a/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs +++ b/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs @@ -43,9 +43,9 @@ public PackageProcessor( this.templateTokeniser = templateTokeniser; } - public void Process(string path, string name) + public void Process(string path, string name, List tokens) { - this.ProcessFiles(path, name); + this.ProcessFiles(path, tokens); this.ProcessDirectories(path); } @@ -67,28 +67,28 @@ private void ProcessDirectories(string path) } } - private void ProcessFiles(string path, string name) + private void ProcessFiles(string path, List tokens) { var files = this.artefactProcessor.RetrieveFiles(path); - - this.ProcessFileContents(files, name); - this.ProcessDirectoryAndFilePaths(files, name); + + this.ProcessFileContents(files, tokens); + this.ProcessDirectoryAndFilePaths(files, tokens); } - private void ProcessDirectoryAndFilePaths(IEnumerable files, string name) + private void ProcessDirectoryAndFilePaths(IEnumerable files, List tokens) { int fileCount = files.Count(); int progress = 0; foreach (var file in files) { - this.templateTokeniser.TokeniseDirectoryAndFilePaths(file, name); + this.templateTokeniser.TokeniseDirectoryAndFilePaths(file, tokens); this.progressNotifier.UpdateProgress(ProgressStage.TokenisePackageStructure, fileCount, progress); progress++; } } - private void ProcessFileContents(IEnumerable files, string name) + private void ProcessFileContents(IEnumerable files, List tokens) { var filteredFiles = this.binaryFileFilter.Filter(files); @@ -97,7 +97,7 @@ private void ProcessFileContents(IEnumerable files, string name) foreach (var file in filteredFiles) { - this.templateTokeniser.TokeniseFileContent(file, name); + this.templateTokeniser.TokeniseFileContent(file, tokens); this.progressNotifier.UpdateProgress(ProgressStage.TokenisePackageContents, fileCount, progress); progress++; } diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs b/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs index efeb937..9a546f0 100644 --- a/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs +++ b/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs @@ -2,11 +2,13 @@ namespace Endjin.Templify.Domain.Domain.Packager.Tokeniser { #region Using Directives + using System.Collections.Generic; using System.ComponentModel.Composition; using System.Text.RegularExpressions; using Endjin.Templify.Domain.Contracts.Packager.Processors; using Endjin.Templify.Domain.Contracts.Packager.Tokeniser; + using Endjin.Templify.Domain.Domain.Packages; using Endjin.Templify.Domain.Infrastructure; #endregion @@ -24,22 +26,43 @@ public TemplateTokeniser(IRenameFileProcessor renameFileProcessor, IFileContentP this.fileContentProcessor = fileContentProcessor; } - public void TokeniseDirectoryAndFilePaths(string file, string token) + private void TokeniseDirectoriesAndFiles(string file, List tokens) { - var tokenisedName = Replace(token, file); + var tokenisedName = Replace(tokens, file); this.renameFileProcessor.Process(file, tokenisedName); } - public void TokeniseFileContent(string file, string token) + private void TokeniseFileContent(string file, List tokens) { var contents = this.fileContentProcessor.ReadContents(file); - contents = Replace(token, contents); + contents = Replace(tokens, contents); this.fileContentProcessor.WriteContents(file, contents); } - private static string Replace(string token, string value) + private static string Replace(List tokens, string value) { - return Regex.Replace(value, Tokens.TokenName, match => token); + string replaced = value; + foreach (var token in tokens) + { + replaced = Regex.Replace(replaced, token.Token, match => token.Value); + } + + // TODO: Probably need a more meaningful return value? + return replaced; + } + + #region ITemplateTokeniser Members + + void ITemplateTokeniser.TokeniseFileContent(string file, List tokens) + { + throw new System.NotImplementedException(); } + + void ITemplateTokeniser.TokeniseDirectoryAndFilePaths(string file, List tokens) + { + throw new System.NotImplementedException(); + } + + #endregion } } \ No newline at end of file diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs b/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs index 2e07f84..795d251 100644 --- a/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs +++ b/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs @@ -16,6 +16,7 @@ public class Manifest : IPackageMetaData public Manifest() { this.Files = new List(); + this.Configuration = new List(); } public string Author { get; set; } @@ -40,5 +41,9 @@ public string Title { get { return this.Name + " - " + this.Version; } } + + [XmlArray] + [XmlArrayItem("Setting")] + public List Configuration { get; set; } } } \ No newline at end of file diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packages/PackageConfigurationData.cs b/Solutions/Endjin.Templify.Domain/Domain/Packages/PackageConfigurationData.cs new file mode 100644 index 0000000..2f44655 --- /dev/null +++ b/Solutions/Endjin.Templify.Domain/Domain/Packages/PackageConfigurationData.cs @@ -0,0 +1,27 @@ +namespace Endjin.Templify.Domain.Domain.Packages +{ + using System.Xml.Serialization; + + public class PackageConfigurationData + { + [XmlAttribute] + public string Token { get; set; } + + [XmlText] + public string Description { get; set; } + + [XmlAttribute] + public PackageConfigurationDataKind Kind { get; set; } + + [XmlIgnore] + public string Value { get; set; } + } + + public enum PackageConfigurationDataKind + { + text = 0, + flag = 1, + choice = 2, + password = 3 + } +} diff --git a/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj b/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj index a2a4b49..4d9eac2 100644 --- a/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj +++ b/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj @@ -99,6 +99,7 @@ + diff --git a/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs b/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs index 4d45fea..b4bfa1d 100644 --- a/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs +++ b/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs @@ -71,7 +71,7 @@ private void RunPackageComplete(RunWorkerCompletedEventArgs e) private void RunDeployPackage(Package package) { this.packageDeploymentProcessor.Execute(package); - this.packageProcessor.Process(this.Path, this.Name); + this.packageProcessor.Process(this.Path, this.Name, package.Manifest.Configuration); } private void OnProgressUpdate(object sender, PackageProgressEventArgs e) diff --git a/Solutions/Endjin.Templify.WizardFramework/Command.cs b/Solutions/Endjin.Templify.WizardFramework/Command.cs new file mode 100644 index 0000000..e1b7e99 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Command.cs @@ -0,0 +1,33 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + using System.Collections.Generic; + + using Endjin.Templify.Domain.Domain.Packages; + + public class PackageConfigurationDataWizardFormCommand : FormWizardCommand + { + private List settings; + + public PackageConfigurationDataWizardFormCommand(List Settings) + { + this.settings = Settings; + } + + /// + /// Sets the form to use as the command form + /// + public override void InitialiseCommand() + { + this.CommandForm = new PackageConfigurationDataWizardForm(this.settings); + } + + /// + /// Implements any cleanup required + /// + public override void CleanupCommand() + { + + } + } +} diff --git a/Solutions/Endjin.Templify.WizardFramework/CommandList.cs b/Solutions/Endjin.Templify.WizardFramework/CommandList.cs new file mode 100644 index 0000000..205da99 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/CommandList.cs @@ -0,0 +1,30 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + + /// + /// Summary description for CommandList. + /// + public class CommandList : WizardCommandList + { + public CommandList() + { + // + // TODO: Add constructor logic here + // + } + + public void ExecuteNext() + { + + // Get the WizardCommand object to execute + WizardCommand formCmd = this[this.CmdPointer]; + + // Execute the WizardCommand object and set the current command + // pointer to that which is returned + this.CmdPointer = formCmd.Execute(this.CmdPointer, this.LastCmdPointer); + + + } + } +} diff --git a/Solutions/Endjin.Templify.WizardFramework/ConfigHelper.cs b/Solutions/Endjin.Templify.WizardFramework/ConfigHelper.cs new file mode 100644 index 0000000..1b42d6b --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/ConfigHelper.cs @@ -0,0 +1,49 @@ +using System; +using System.Configuration; + +namespace Conchango.Fusion.InstallerWizard +{ + /// + /// Summary description for ConfigHelper. + /// + public class ConfigHelper + { + + private static string _wizardTitle = ConfigurationSettings.AppSettings["WizardTitle"]; + private static string _wizardTitleText = ConfigurationSettings.AppSettings["WizardTitleText"]; + private static string _parameterConfigFile = ConfigurationSettings.AppSettings["ParameterConfigFile"]; + private static string _onlineConfigPath = ConfigurationSettings.AppSettings["CfgSrcOnlinePath"]; + private static string _localConfigPath = ConfigurationSettings.AppSettings["CfgSrcLocalPath"]; + + + private ConfigHelper() + { + + } + + public static string GetWizardTitle + { + get { return _wizardTitle; } + } + + public static string GetWizardTitleText + { + get { return _wizardTitleText; } + } + + public static string GetParameterConfigFile + { + get { return _parameterConfigFile; } + } + + public static string GetOnlineConfigPath + { + get { return _onlineConfigPath; } + } + + public static string GetLocalConfigPath + { + get { return _localConfigPath; } + } + } +} diff --git a/Solutions/Endjin.Templify.WizardFramework/Endjin.Templify.WizardFramework.csproj b/Solutions/Endjin.Templify.WizardFramework/Endjin.Templify.WizardFramework.csproj new file mode 100644 index 0000000..8952ef6 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Endjin.Templify.WizardFramework.csproj @@ -0,0 +1,91 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {D8F709BA-1E52-48FB-A917-7C3A40445F7F} + Library + Properties + Endjin.Templify.WizardFramework + Endjin.Templify.WizardFramework + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + Form + + + + Form + + + + + + Form + + + + + + BaseWizardForm.cs + + + StartupForm.cs + + + WizardCommand.cs + + + InstallParametersForm.cs + + + + + {9E8B79ED-9C17-485B-B1F9-8D33D8BB4BD2} + SharpArch.PackageManagement + + + + + \ No newline at end of file diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.cs new file mode 100644 index 0000000..d4ea04a --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.cs @@ -0,0 +1,80 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + using System.Windows.Forms; + + /// + /// Base Form for use with forms that wish to implement the Wizard + /// Command + /// + public class BaseWizardForm : Form { + + #region Constructors + + /// + /// Default constructor + /// + public BaseWizardForm() { + } + + #endregion + + #region Private Variables + + //CommandIndex starts at 0 + private int _commandIndex = 0; + private int _originCommandIndex = 0; + + #endregion + + #region Public Properties + public int CommandIndex { + get { return _commandIndex; } + set { _commandIndex = value; } + } + + public int OriginCommandIndex { + get { return _originCommandIndex; } + set { _originCommandIndex = value; } + } + #endregion + + #region Public Methods + + // Go back to the OriginCommandIndex - who sent the form to the particular index + public void MoveToSender() + { + CommandIndex = OriginCommandIndex; + this.Close(); + + } + + // Move to a specific CommandIndex + public void MoveTo(int index) + { + OriginCommandIndex = CommandIndex; + CommandIndex = index; + this.Close(); + } + // Move to the next CommandIndex in the list + public void MoveNext() { + CommandIndex++; + this.Close(); + } + + // Move to the previous CommandIndex in the list + public void MovePrevious() { + CommandIndex--; + this.Close(); + } + + // + public void MoveExit() { + CommandIndex = -1; + } + + #endregion + + } +} + diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.resx b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.resx new file mode 100644 index 0000000..3f337e0 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/FormWizardCommand.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/FormWizardCommand.cs new file mode 100644 index 0000000..515889b --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Forms/FormWizardCommand.cs @@ -0,0 +1,61 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + + /// + /// Abstract class that defines a wizard command for Windows Forms. Implements + /// the abstract wizard command class. + /// + public abstract class FormWizardCommand : WizardCommand { + + #region Private Variables + + /// + /// The Windows Form used for this command + /// + private BaseWizardForm _commandForm = null; + + #endregion + + #region Properties + + /// + /// he Windows Form used for this command + /// + public BaseWizardForm CommandForm { + get { return _commandForm; } + set { _commandForm = value; } + } + + #endregion + + #region Methods + + /// + /// Executes the WizardCommand object + /// + /// TODO + public override int Execute(int cmdPointer, int lastCmdPointer) { + + // Setup the template - this is implemented within the sub class + InitialiseCommand(); + + // Show the command form + this.CommandForm.CommandIndex = cmdPointer; + this.CommandForm.OriginCommandIndex = lastCmdPointer; + //this.CommandForm.Visible = true; + var res = this.CommandForm.ShowDialog(); + + + // Cleanup the template data - this is implemented within the + // sub class + CleanupCommand(); + + return this.CommandForm.CommandIndex; + + } + + #endregion + + } +} diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.cs new file mode 100644 index 0000000..f5e2158 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.cs @@ -0,0 +1,377 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + using System.Diagnostics; + //using System.DirectoryServices; + //using System.Drawing; + using System.IO; + using System.Text; + using System.Windows.Forms; + + using Endjin.Templify.Domain.Domain.Packages; + + public class PackageConfigurationDataWizardForm : BaseWizardForm + { + private const int MAX_SETTINGS_PER_PAGE = 5; + + private int currentPage = 0; + //private InstallerBootstrapConfigPage[] pages; + //private IisHostHeaderConfigCollection webInfoForComboBox; + + + #region UI cordinates + // These values are used to derive the positions of the + // dynamically generated controls + private int firstLabelX = 8; + private int firstLabelY = 31; + private int labelWidth = 152; + private int labelHeight = 20; + + private int firstControlX = 167; + private int firstControlY = 29; + private int controlWidth = 216; + private int controlHeight = 20; + + #endregion + + + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.Button btnNext; + private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.GroupBox groupParameters; + private System.Windows.Forms.Label lblText; + private System.Windows.Forms.ToolTip toolTip1; + private System.ComponentModel.IContainer components = null; + + public PackageConfigurationDataWizardForm(List settings) + { + // This call is required by the Windows Form Designer. + InitializeComponent(); + + //pages = (InstallerBootstrapConfigPage[])WizardState.Instance.RequiredParameters.ToArray(typeof(InstallerBootstrapConfigPage) ); + this.Settings = settings; + } + + public List Settings { get; set; } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + #region 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(); + System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(PackageConfigurationDataWizardForm)); + this.lblTitle = new System.Windows.Forms.Label(); + this.btnNext = new System.Windows.Forms.Button(); + this.btnBack = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.groupParameters = new System.Windows.Forms.GroupBox(); + this.lblText = new System.Windows.Forms.Label(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.SuspendLayout(); + // + // lblTitle + // + this.lblTitle.BackColor = System.Drawing.SystemColors.Window; + this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.lblTitle.Location = new System.Drawing.Point(24, 5); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(384, 40); + this.lblTitle.TabIndex = 10; + this.lblTitle.Text = "Pre-Installation Parameters"; + this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // btnNext + // + this.btnNext.Location = new System.Drawing.Point(304, 320); + this.btnNext.Name = "btnNext"; + this.btnNext.TabIndex = 1; + this.btnNext.Text = "&Next"; + this.btnNext.Click += new System.EventHandler(this.btnNext_Click); + // + // btnBack + // + this.btnBack.Location = new System.Drawing.Point(216, 320); + this.btnBack.Name = "btnBack"; + this.btnBack.TabIndex = 12; + this.btnBack.Text = "&Back"; + this.btnBack.Click += new System.EventHandler(this.btnBack_Click); + // + // btnCancel + // + this.btnCancel.Location = new System.Drawing.Point(392, 320); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.TabIndex = 14; + this.btnCancel.Text = "&Cancel"; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // groupParameters + // + this.groupParameters.BackColor = System.Drawing.SystemColors.Window; + this.groupParameters.Location = new System.Drawing.Point(32, 112); + this.groupParameters.Name = "groupParameters"; + this.groupParameters.Size = new System.Drawing.Size(416, 184); + this.groupParameters.TabIndex = 0; + this.groupParameters.TabStop = false; + this.groupParameters.Text = ""; + // + // lblText + // + this.lblText.BackColor = System.Drawing.SystemColors.Window; + this.lblText.Location = new System.Drawing.Point(40, 72); + this.lblText.Name = "lblText"; + this.lblText.Size = new System.Drawing.Size(408, 32); + this.lblText.TabIndex = 16; + this.lblText.Text = "Enter the correct settings for the following parameters required by this installa" + + "tion package."; + // + // InstallParametersForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage"))); + this.ClientSize = new System.Drawing.Size(478, 348); + this.Controls.Add(this.lblText); + this.Controls.Add(this.groupParameters); + this.Controls.Add(this.btnNext); + this.Controls.Add(this.btnBack); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.lblTitle); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "InstallParametersForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Load += new System.EventHandler(this.InstallParametersForm_Load); + this.ResumeLayout(false); + + } + #endregion + + private void btnBack_Click(object sender, System.EventArgs e) + { + this.MovePrevious(); + } + + private void btnNext_Click(object sender, System.EventArgs e) + { + // Save the parameter info from the current screen + saveCurrentParameters(); + + currentPage++; + + if (currentPage <= Settings.Count / MAX_SETTINGS_PER_PAGE) + { + // Display theh UI to obtain values for the required parameters + renderParameterPage(currentPage); + } + else + { + // Generate the set of Windows Installer properties that map to the + // parameters that the user has just supplied + //buildMsiPropertyList(); + + // Proceed to next stage in the Wizard + this.MoveNext(); + } + } + + private void btnCancel_Click(object sender, System.EventArgs e) + { + this.MoveExit(); + this.Close(); + } + + private void InstallParametersForm_Load(object sender, System.EventArgs e) + { + // Set some title text based on the config file + this.Text = "*** TO BE REPLACED ***"; + + renderParameterPage(currentPage); + } + + + + + + private void renderParameterPage(int pageNumber) + { + clearControls(); + + //var settingsToRender = from s in this.settings + // select s; + var settingsToRender = this.Settings.Skip((pageNumber - 1) * MAX_SETTINGS_PER_PAGE).Take(MAX_SETTINGS_PER_PAGE).ToList(); + + // set the variables + int numControlsReqd = settingsToRender.Count(); + + // setup the groupbox title + //groupParameters.Text = string.Format("{0} of {1} - {2}", currentPage + 1, pages.Length, this.pages[currentPage].Title); + groupParameters.Text = "Page " + pageNumber; + + #region setup the label controls + for (int i = 1; i <= numControlsReqd; i++) + { + // create a new label + Label lbl = new Label(); + + // position the label + lbl.Left = firstLabelX; + lbl.Top = firstLabelY * i; + lbl.Width = labelWidth; + lbl.Height = labelHeight; + + // setup the control + lbl.Text = settingsToRender[i].Description + ":"; + + // Set the tooltip using the supplied description + toolTip1.SetToolTip(lbl, settingsToRender[i].Description); + + lbl.Visible = true; + + groupParameters.Controls.Add(lbl); + + } + #endregion + + #region setup the input controls + for (int i = 1; i <= numControlsReqd; i++) + { + + if (settingsToRender[i].Kind == PackageConfigurationDataKind.choice) + { + ComboBox inputControl = new ComboBox(); + + // TODO: populate combo box + // inputControl.DataSource = settingsToRender[i].Default.Split('|'); + + // postition the control + inputControl.Left = firstControlX; + inputControl.Top = firstControlY * i; + inputControl.Width = controlWidth; + inputControl.Height = controlHeight; + + inputControl.Visible = true; + + groupParameters.Controls.Add(inputControl); + } + else + { + TextBox inputControl = new TextBox(); + + // Set the tooltip using the supplied description + //inputControl.Text = this.pages[currentPage].Parameters[i - 1].DefaultValue; + toolTip1.SetToolTip(inputControl, settingsToRender[i].Description); + + if (settingsToRender[i].Kind == PackageConfigurationDataKind.password) + { + inputControl.PasswordChar = '*'; + } + + // position the control + inputControl.Left = firstControlX; + inputControl.Top = firstControlY * i; + inputControl.Width = controlWidth; + inputControl.Height = controlHeight; + + inputControl.Visible = true; + + groupParameters.Controls.Add(inputControl); + } + } + #endregion + } + + private void saveCurrentParameters() + { + var settingsToRender = this.Settings.Skip((currentPage - 1) * MAX_SETTINGS_PER_PAGE).Take(MAX_SETTINGS_PER_PAGE).ToList(); + + for (int i = 0; i < settingsToRender.Count(); i++) + { + string paramName = settingsToRender[i].Token; + string paramValue = GetControlValue(i); + + if (paramValue != null) + { + settingsToRender[i].Value = paramValue; + + //if (this.pages[currentPage].Parameters[i].ParamType == InstallerBootstrapConfigPageParameterParamType.path) + //{ + // // Ensure that path parameters have a trailing + // // '\' - as this is required by MSI + // if (!paramValue.EndsWith(@"\")) + // { + // paramValue = string.Concat(paramValue, @"\"); + // } + //} + + // Get the parameter's unique ID, we use this to differentiate between parameters + // of the same name + //string paramId = this.pages[currentPage].Parameters[i].id + "."; + + //if (this.pages[currentPage].Parameters[i].ParamType == InstallerBootstrapConfigPageParameterParamType.website) + //{ + // // If dealing with a web site parameter, the this actually requires three + // // bits of information - which (for the moment?) has to be handled using this hack. + + // // Such parameters must be defined in the parameter WizardState.Instance.Config as 3 comma seperated + // // strings which we split below and return as seperate parameters to the bootstrapper + // string[] splitParameterNames = paramName.Split(",".ToCharArray(), 3); + // WizardState.Instance.ParameterValues.Add(string.Concat(paramId, splitParameterNames[0]), paramValue); + // WizardState.Instance.ParameterValues.Add(string.Concat(paramId, splitParameterNames[1]), webInfoForComboBox[paramValue].Address); + // WizardState.Instance.ParameterValues.Add(string.Concat(paramId, splitParameterNames[2]), webInfoForComboBox[paramValue].Port); + //} + //else + //{ + // otherwise just assign the value to the parameter + //WizardState.Instance.Settings.Add(string.Concat(paramId, paramName), paramValue); + //} + } + } + } + + private void clearControls() + { + // Clear all the existing intput controls + if (groupParameters.HasChildren) + { + //foreach ( Control control in grpParamTitle.Controls ) + //{ + // control.Dispose(); + //} + groupParameters.Controls.Clear(); + } + + } + + private string GetControlValue(int i) + { + // skip the labels + int firstInputControl = (groupParameters.Controls.Count / 2); + + int requiredInputControl = firstInputControl + i; + + return groupParameters.Controls[requiredInputControl].Text; + } + + } +} \ No newline at end of file diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.resx b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.resx new file mode 100644 index 0000000..9c4eff0 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.resx @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + False + + + Private + + + Private + + + Private + + + 17, 17 + + + Private + + + False + + + (Default) + + + False + + + False + + + 8, 8 + + + True + + + InstallParametersForm + + + 80 + + + True + + + Private + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERET + FhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4e + Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAFiAe4DASIAAhEBAxEB/8QA + HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh + MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW + V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG + x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF + BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV + YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE + hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq + 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD7LooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKAE7dKbuHqopc+lcx468W6R4SsYLnV7h4o55vKi2QPKzNtLY2ryeFbmjXYcIObtHc6LzEzz + IB364oaaIA/vUz/vCvGtT+L+m3oSz8PTSve3UscMcl1azRRRb2C72LOMgZB6dxVvxZo/ifw54Mn1PTfG + V5dGRVFx9pO7BdlUtEQfkwTnHzVy4jFeycopXcd+lj1MPlMqih7Sai5u0ez+aIfin43aG+tdL0fV7+wC + 3iR3t/bRo8ajy5CsQdyVDFtmeM4B5rCSTXpUDR/EXXmU9Ck1pg/rXZ6BcTeCNJXSfEegKlgR82pWUZmh + lJ6tMpBdWI6k5XrzXnXxI1/wzpXiK3XwVLLEryLJei0lY2rqeu1FIy3+7ivBzOpXhH2vtLf3e3oej/Zm + Ixj9lgG1yrfRxlbq9NH0Rpj/AISAHI+IXiAn3mtP8a6X4Z6hri/EC30298TX+rWs2m3EpS58g7XR4AGB + j6ffbg1yQ8W2BGQuuEH00y8/+LrpfhbcvqPxHtbqK01RbeHSrtWlurKeFAzy25VQ0hIJ+Vv1rDL6+Ili + YRm3Y+aw/wDaXO/rPwWfbs7fiezUUUV9eIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo + oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo + oAKKKKACiiigBgwCa8p/aEkMdp4bbzDF/wATNhkSbB/x7zf9NE/n/gfVumeM1yfxG8Jx+K7O0gl1G/09 + rWfz45bN1V92xk/i4xh2/H9boz5KkZvo0/uYuRThKDdrxkvvTR5b8NfsF945gttQkhuoHs50Mc0wlVsm + PA2tLIOxxjaev3q7nxB8O5n0yXTfD2sTafZzMrSWUxMsAAYN8meUPHbI9q5O/wDhE1xgSeL/ABBKE+55 + ht22/wC6SwIrc+2eK/BGmC4uNSPiDSonRJftjIlxGrMF+V1Ztx5H3ueetY5tUp18ROrKHuvr8kv0PQyO + lPC4Sjh6NX95G65Xs3zNpq+l9T0+REMJikwy7cMGHWvk/SfDOseIPiXqcOi2yN9k1GWRmdikce2RiAzA + cdAMDtX1mmGA3AHPTIrj/wDhE73Rr641LwneR27XMrTXFldAvBK56sGHzIfpkdeK87MMD9acL7R3XU9T + h/OZZaqyj8U1ZX2uVtL8S2hvItM1xL3Qr88JHeTSKkpHZJBJtf8AOu1s4ghDBy2RjO8t/MmvG/i/8QXs + tBOhaj4aaHVLgY/0hUmtwvTeh/i9sge9dz8FneT4b6KZZGd/JOSzEngkck9auhjIzxDoXu0rmWPymdLB + RxrjyqTta90/NPsdrRRRXonghRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUU + UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUU + UUAFJjPXn6ilooAiMYz/ABf99GuT+Klnc3XgLUIrSGaaYeW4SPcWYLIrEADknANdh2psihkKlcg9jUVI + KpFxfU1oVnRqxqro0/uMfQPEGj63ZedpeoQz7RtdA2HRhxhl6g+xrwi3+MXiTw94u1a01FF1WwjvZVSN + wEljRZCMKQMH8a6L45xLp1zpOr6ZN/Z+otfGB7yB1R2TyJX2kmQAjKg4bA/PB8rhEcd5cXr3iTXM7s8k + 3mxI2Sck4S4Uc189mmLrU6ihHRrr0+4++4byrBVaM6tWPPGa0T3Tv3Nb42eK9G8Yato+o6bLKkUds0cy + yQsHjO/uBz+VevfBHxd4YvLCy8J6NqNxc3NnaNIwls5IdyhgGbJ4zucceleKi6Axi94/6+//ALqrtfgP + KJfihHifzQNJuuku/H72D/ptJ/7L+Nc+WYiTxjnJayO7PcFR/spUVflpXcdfXc+haKKK+sPy4KKKKACi + iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACi + iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAMDxR4V0vxLbwwarFPI + kE3nRbLqSIo+0rkMjA9GYfjWGPhT4T6mLVP/AAcXf/xyu7orGVCnN3lG7OuljsTRjy05tLyZwg+FXhPG + DFqv/g5u/wD45Wl4X8C6B4d1b+09Pt7v7V5DQiSe+mn2oSpKgSO2MlF6eldTRRDD0oO8YodTMMVUi4zq + Np+bCiiitjjCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig + AooooAKKKKACiiigAooooAKKKKACik5o5oAWik596TJ96AHUUnPvRzQAtFFFABRRRQAUUUUAFFFFABRR + RQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRR + RQAUUUUAFFFFABRRRQAUUUUAJ+FH4VwP9o6p/wBBvUv++bf/AOMUf2jqn/Qb1L/vm3/+MVx/Wodjq+q1 + Dvvwo/CuB/tHVP8AoN6l/wB82/8A8Yo/tHVP+g3qX/fNv/8AGKPrUOwfVah334UfhXA/2jqn/Qb1L/vm + 3/8AjFH9o6p/0G9S/wC+bf8A+MUfWodg+q1Dvvwo/CuB/tHVP+g3qX/fNv8A/GKP7R1T/oN6l/3zb/8A + xij61DsH1Wod9+FH4VwP9o6p/wBBvUv++bf/AOMUf2jqn/Qb1L/vm3/+MUfWodg+q1Dvvwo/CuB/tHVP + +g3qX/fNv/8AGKP7R1T/AKDepf8AfNv/APGKPrUOwfVah334UfhXA/2jqn/Qb1L/AL5t/wD4xR/aOqf9 + BvUv++bf/wCMUfWodg+q1Dvvwo/CuB/tHVP+g3qX/fNv/wDGKP7R1T/oN6l/3zb/APxij61DsH1Wod9+ + FH4VwP8AaOqf9BvUv++bf/4xR/aOqf8AQb1L/vm3/wDjFH1qHYPqtQ778KPwrgf7R1T/AKDepf8AfNv/ + APGKP7R1T/oN6l/3zb//ABij61DsH1Wod9+FH4VwP9o6p/0G9S/75t//AIxR/aOqf9BvUv8Avm3/APjF + H1qHYPqtQ778KPwrgf7R1T/oN6l/3zb/APxij+0dU/6Depf982//AMYo+tQ7B9VqHffhR+FcD/aOqf8A + Qb1L/vm3/wDjFH9o6p/0G9S/75t//jFH1qHYPqtQ778KPwrgf7R1T/oN6l/3zb//ABij+0dU/wCg3qX/ + AHzb/wDxij61DsH1Wod9+FH4VwP9o6p/0G9S/wC+bf8A+MUf2jqn/Qb1L/vm3/8AjFH1qHYPqtQ778KP + wrgf7R1T/oN6l/3zb/8Axij+0dU/6Depf982/wD8Yo+tQ7B9VqHffhR+FcD/AGjqn/Qb1L/vm3/+MUf2 + jqn/AEG9S/75t/8A4xR9ah2D6rUO+/Cj8K4H+0dU/wCg3qX/AHzb/wDxij+0dU/6Depf982//wAYo+tQ + 7B9VqHffhR+FcD/aOqf9BvUv++bf/wCMUf2jqn/Qb1L/AL5t/wD4xR9ah2D6rUO+/Cj8K4H+0dU/6Dep + f982/wD8Yo/tHVP+g3qX/fNv/wDGKPrUOwfVah334UfhXA/2jqn/AEG9S/75t/8A4xR/aOqf9BvUv++b + f/4xR9ah2D6rUO+/Cj8K4H+0dU/6Depf982//wAYo/tHVP8AoN6l/wB82/8A8Yo+tQ7B9VqHffhR+FcD + /aOqf9BvUv8Avm3/APjFH9o6p/0G9S/75t//AIxR9ah2D6rUO+/Cj8K4H+0dU/6Depf982//AMYo/tHV + P+g3qX/fNv8A/GKPrUOwfVah334UfhXA/wBo6p/0G9S/75t//jFH9o6p/wBBvUv++bf/AOMUfWodg+q1 + Dvvwo/CuB/tHVP8AoN6l/wB82/8A8Yo/tHVP+g3qX/fNv/8AGKPrUOwfVah334UfhXA/2jqn/Qb1L/vm + 3/8AjFH9o6p/0G9S/wC+bf8A+MUfWodg+q1Dvvwo/CuB/tHVP+g3qX/fNv8A/GKP7R1T/oN6l/3zb/8A + xij61DsH1Wod9+FH4VwP9o6p/wBBvUv++bf/AOMUf2jqn/Qb1L/vm3/+MUfWodg+q1Dvvworgf7R1T/o + N6l/3zb/APxij+0dU/6Depf982//AMYo+tQ7B9VqHfY9qMe1cD/aGqf9BzUvyt//AIzVa6vtfaJRaeIL + 1HDcmSG3bI/BBT+uR7B9Un3EooorgPQCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC + iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC + iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC + iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC + iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC + iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC + iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//2Q== + + + + + AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAzMzMAAAAAAzMzMzAAAAeP/4MzMwAACP///zMzMAA/////+DMzAz////// + MzMDj/////8zMwOP/////4MzAz//////gzMDOP////+DMwMzj////4MzAAMzOIiIMzAAAzMzMzMzMAAA + MzMzMzMAAAADMzMzAAD//wAA/A8AAPgHAADgAwAA4AEAAMAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAA + AADgAQAA4AEAAPADAAD4DwAA + + + \ No newline at end of file diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.cs new file mode 100644 index 0000000..76443a6 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.cs @@ -0,0 +1,292 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + using System.Collections; + using System.ComponentModel; + using System.Drawing; + using System.Windows.Forms; + + public class StartupForm : BaseWizardForm + { + + private System.Windows.Forms.Button btnNext; + private System.Windows.Forms.Button btnBack; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label lblIntro; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.RadioButton radioCfgSrcDefault; + private System.Windows.Forms.RadioButton radioCfgSrcOnline; + private System.Windows.Forms.RadioButton radioCfgSrcCustom; + private System.Windows.Forms.TextBox txtCfgSrcCustomPath; + private System.Windows.Forms.Button btnCfgSrcCustomBrowse; + private System.Windows.Forms.GroupBox groupCfgSrc; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.ComponentModel.IContainer components = null; + + + + public StartupForm() + { + // This call is required by the Windows Form Designer. + InitializeComponent(); + + // TODO: Add any initialization after the InitializeComponent call + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + #region Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(StartupForm)); + this.lblIntro = new System.Windows.Forms.Label(); + this.btnNext = new System.Windows.Forms.Button(); + this.btnBack = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.groupCfgSrc = new System.Windows.Forms.GroupBox(); + this.txtCfgSrcCustomPath = new System.Windows.Forms.TextBox(); + this.btnCfgSrcCustomBrowse = new System.Windows.Forms.Button(); + this.radioCfgSrcDefault = new System.Windows.Forms.RadioButton(); + this.radioCfgSrcOnline = new System.Windows.Forms.RadioButton(); + this.radioCfgSrcCustom = new System.Windows.Forms.RadioButton(); + this.lblTitle = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.groupCfgSrc.SuspendLayout(); + this.SuspendLayout(); + // + // lblIntro + // + this.lblIntro.BackColor = System.Drawing.SystemColors.Window; + this.lblIntro.Location = new System.Drawing.Point(168, 72); + this.lblIntro.Name = "lblIntro"; + this.lblIntro.Size = new System.Drawing.Size(288, 32); + this.lblIntro.TabIndex = 0; + this.lblIntro.Text = "This wizard will guide you through installing the module(s) defined within this i" + + "nstallation package."; + // + // btnNext + // + this.btnNext.Location = new System.Drawing.Point(304, 320); + this.btnNext.Name = "btnNext"; + this.btnNext.TabIndex = 0; + this.btnNext.Text = "&Next"; + this.btnNext.Click += new System.EventHandler(this.btnNext_Click); + // + // btnBack + // + this.btnBack.Enabled = false; + this.btnBack.Location = new System.Drawing.Point(216, 320); + this.btnBack.Name = "btnBack"; + this.btnBack.TabIndex = 1; + this.btnBack.Text = "&Back"; + // + // btnCancel + // + this.btnCancel.Location = new System.Drawing.Point(392, 320); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "&Cancel"; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // groupCfgSrc + // + this.groupCfgSrc.BackColor = System.Drawing.SystemColors.Window; + this.groupCfgSrc.Controls.Add(this.txtCfgSrcCustomPath); + this.groupCfgSrc.Controls.Add(this.btnCfgSrcCustomBrowse); + this.groupCfgSrc.Controls.Add(this.radioCfgSrcDefault); + this.groupCfgSrc.Controls.Add(this.radioCfgSrcOnline); + this.groupCfgSrc.Controls.Add(this.radioCfgSrcCustom); + this.groupCfgSrc.Location = new System.Drawing.Point(168, 168); + this.groupCfgSrc.Name = "groupCfgSrc"; + this.groupCfgSrc.Size = new System.Drawing.Size(296, 120); + this.groupCfgSrc.TabIndex = 1; + this.groupCfgSrc.TabStop = false; + this.groupCfgSrc.Text = "Configuration Management Source"; + // + // txtCfgSrcCustomPath + // + this.txtCfgSrcCustomPath.Enabled = false; + this.txtCfgSrcCustomPath.Location = new System.Drawing.Point(112, 92); + this.txtCfgSrcCustomPath.Name = "txtCfgSrcCustomPath"; + this.txtCfgSrcCustomPath.Size = new System.Drawing.Size(152, 20); + this.txtCfgSrcCustomPath.TabIndex = 3; + this.txtCfgSrcCustomPath.Text = ""; + // + // btnCfgSrcCustomBrowse + // + this.btnCfgSrcCustomBrowse.BackColor = System.Drawing.SystemColors.Control; + this.btnCfgSrcCustomBrowse.Enabled = false; + this.btnCfgSrcCustomBrowse.Location = new System.Drawing.Point(266, 93); + this.btnCfgSrcCustomBrowse.Name = "btnCfgSrcCustomBrowse"; + this.btnCfgSrcCustomBrowse.Size = new System.Drawing.Size(22, 16); + this.btnCfgSrcCustomBrowse.TabIndex = 4; + this.btnCfgSrcCustomBrowse.Text = "..."; + this.btnCfgSrcCustomBrowse.Click += new System.EventHandler(this.btnCfgSrcCustomBrowse_Click); + // + // radioCfgSrcDefault + // + this.radioCfgSrcDefault.Checked = true; + this.radioCfgSrcDefault.Location = new System.Drawing.Point(8, 24); + this.radioCfgSrcDefault.Name = "radioCfgSrcDefault"; + this.radioCfgSrcDefault.Size = new System.Drawing.Size(112, 24); + this.radioCfgSrcDefault.TabIndex = 0; + this.radioCfgSrcDefault.TabStop = true; + this.radioCfgSrcDefault.Text = "Package Defaults"; + // + // radioCfgSrcOnline + // + this.radioCfgSrcOnline.Location = new System.Drawing.Point(8, 56); + this.radioCfgSrcOnline.Name = "radioCfgSrcOnline"; + this.radioCfgSrcOnline.TabIndex = 1; + this.radioCfgSrcOnline.Text = "Online Source"; + // + // radioCfgSrcCustom + // + this.radioCfgSrcCustom.Location = new System.Drawing.Point(8, 89); + this.radioCfgSrcCustom.Name = "radioCfgSrcCustom"; + this.radioCfgSrcCustom.TabIndex = 2; + this.radioCfgSrcCustom.Text = "Custom Source"; + this.radioCfgSrcCustom.CheckedChanged += new System.EventHandler(this.radioCfgSrcCustom_CheckedChanged); + // + // lblTitle + // + this.lblTitle.BackColor = System.Drawing.SystemColors.Window; + this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.lblTitle.Location = new System.Drawing.Point(168, 16); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(288, 40); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "Welcome to the GPP Installation Wizard"; + this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label1 + // + this.label1.BackColor = System.Drawing.SystemColors.Window; + this.label1.Location = new System.Drawing.Point(168, 120); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(288, 32); + this.label1.TabIndex = 0; + this.label1.Text = "First you must select a source of configuration management data to drive the inst" + + "allation."; + // + // StartupForm + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage"))); + this.ClientSize = new System.Drawing.Size(480, 350); + this.Controls.Add(this.groupCfgSrc); + this.Controls.Add(this.btnNext); + this.Controls.Add(this.lblIntro); + this.Controls.Add(this.btnBack); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.lblTitle); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "StartupForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Conchango Fusion Installer Wizard"; + this.Load += new System.EventHandler(this.StartupForm_Load); + this.groupCfgSrc.ResumeLayout(false); + this.ResumeLayout(false); + + } + #endregion + + + private void btnNext_Click(object sender, System.EventArgs e) + { + Utils helper = new Utils(); + + // The configuration file selected as this stage is used in 2 ways: + // 1) Provide a list of environments + // 2) A path to it is passed to all installations via a defined MSI property + + //foreach ( Control rad in groupCfgSrc.Controls ) + for ( int i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + 8, 8 + + + True + + + False + + + True + + + Private + + + Private + + + False + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + False + + + Private + + + Private + + + Private + + + Private + + + 17, 17 + + + False + + + (Default) + + + False + + + False + + + StartupForm + + + 8, 8 + + + True + + + 80 + + + True + + + Private + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwg + JC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy + MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAFiAe4DASIAAhEBAxEB/8QA + HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh + MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW + V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG + x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF + BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV + YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE + hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq + 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iikZgqlmICgZJJ4AoAWisWw8WaLqV29tb3qeapIAf5d/upP + Wsy51G88T6g+naNcPb2EDYur6M4Zj/cQ/wBf8nF14WvF3v2OuOCq8zVRcqWrb0sv627nW0Vyx/4STQDw + f7asR6/LcIP5N/OtTSfEOn6zlLeUrcKPnt5RtkT6g041ot8r0fZ/1qKphJxjzwfNHuv1W6+Zq0UUVqco + UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA + UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVxPjPUJn1OHSZRcJ + pfkrPey2ybn2liAD6LleTXSf8JFof/QZ0/8A8Ck/xrOsb20vvG1xJaXUNwg06NS0MgcA+Y/GR9RXNWca + kVCMt2ejg4TozdWcH7qv2/p9vMkSw8Oa7oqQ28VtcWka4j8vgx/iOQa53wp4caXwzY6lpd/NYX7qxdlO + +OXDEDch47DpXR3/AIUsrmdruykk06+P/Le1O3P+8vRqt+H9KbRdDttPeUStCCC4XAOWJ6fjUex5qic4 + rRPVfK3mjX64qeHapVG7tOz16O9+jT0/yMO88Waj4ftZBrulkuBiK4tWzDK3YHPKk+9ch4R1W51n4iw3 + 10wMkiycAYCjYcAV1nxO/wCRS/7eI/51x3gfRtaW5Gu2NpFLHBlVjlk2GbIIIQ4xx6nA/WuLEOp9ZhTu + 2lZnsYGGHeXVa9lGUrx3026X2v8A1oex0Vg2fi/Sp2aG8l/s66T78F7+6I/E8Grn/CRaH/0GdP8A/ApP + 8a9VVqbV1JHzMsJXi7OD+40qKo2+taVdzrBbanZzTNnbHHOrMcDJwAfSr1WpKWqZjKEoO0lYKKKKZIUU + UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUU + UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAeceT/ANMf/IP/ANqqvPp3mTJPEZ7e + 5QYSaDcjD8oxkVY8n/pj/wCQf/tVHk/9Mf8AyD/9qr5c8qjWqUZ89N2ZbsvFOsaZtj1S1e/tx/y8QRMs + ij/aUgA/hiuzsL+31OxivLSTzIJRlGxjPauAaH5T+57f88v/ALVXS+A/+RL07/df/wBDavUwOIqTnySd + 1Y9qnWWJw8qsopSi0tNE7qXTZPTpZeRe8Q6FD4h0prCaV4gWDq6DJBHSs6DUtS8PxJb6rp6yWUShVu7B + CVVR03R9R+GR7Vp69rlt4e04Xt0krxeYqERgE89+TT9L1vTdag82wuo5l7qDhl+oPIrtkoOp7rtI6abr + LD+/Dmp3fyfWz6P108jnfFXiLwzLoYlmFrqbSDEESt8wPHORynv0PauS8Nb59J3OpkxIQCU3ccd/Lb+d + V/iRbw2/izEMSRh4Fdgi4y2Tz9an8MQMNIBaE/M5IJjzkcf9Mz/OvCxVWU67UraaaHoZphaVHJozi2+Z + p69N9F+vc6HS49niPSj5e398/Pl7f+WMn+wv867+uA0uPZ4j0o+Xt/fPz5e3/ljJ/sL/ADrv69TLv4T9 + f0R8/S/gw9H+bCiiivQKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK + KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDzjyf8A + pj/5B/8AtVHk/wDTH/yD/wDaqPJ/6Y/+Qf8A7VR5P/TH/wAg/wD2qvlzxQMGQR5P/kL/AO1UaRqmr+G4 + EtUtvt+noTtjVGWWME5PJUBupo8n/pj/AOQf/tVHk/8ATH/yD/8AaquFSVOXNF2Z2YXGTw94pJxdrp+X + 4p6vYPG/iLTdb8IstrNidbiPfbyDbInPdT/SuU0DRLtmF/vuLY4/dNGHVj75Cniukn0y3uWVpbQMVOQf + KI/lFU/kY6Qf+Qf/ALVRWqSq1FOW57j4h9jg/q2Ei4tttt2dvJd/mv8AMyLrSL/VdVS61Wb7QI4wgZYn + UuATjPyYrXEAUACDAHAHk/8A2qjyf+mP/kH/AO1UeT/0x/8AIP8A9qqOt2eJjMwr4vlVV6RVklol8kWN + Lj2eI9KPl7f3z8+Xt/5Yyf7C/wA67+uA0uPZ4j0o+Xt/fPz5e3/ljJ/sL/Ou/r2Mu/hP1/RHXS/gw9H+ + bCiiivQKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoo + ooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDj/APhDL7/oK2n/AILV + /wDi6P8AhDL7/oK2n/gtX/4uuworj+oYf+X8X/mP3f5V9y/yOP8A+EMvv+graf8AgtX/AOLo/wCEMvv+ + graf+C1f/i67Cij6hh/5fxf+Ye7/ACr7l/kcf/whl9/0FbT/AMFq/wDxdH/CGX3/AEFbT/wWr/8AF12F + FH1DD/y/i/8AMPd/lX3L/I4//hDL7/oK2n/gtX/4uj/hDL7/AKCtp/4LV/8Ai67Cij6hh/5fxf8AmHu/ + yr7l/kcxp3hS5s9VtbybUYJVgZm2R2QjLEoy/eDH+9munooropUYUlywWg3JtJdvK35BRRRWhIUUUUAF + FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF + FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF + FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF + FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABmioRIP7w/P/AOvTg49R+f8A9egZ + JRTQw9f1p2aBBRRRQAUUUUAVNQ1O00uFJbuRkWR/LXbGzktgnGFBPQH8qz/+Es0f/nrc/wDgFN/8RWd4 + +XfpViu3dm8HG3d/yzk7bW/ka4f7N/07f+S//wBortweCeJjKXNaztt5J9/M48bjoYRxi4N3V97dWuz7 + HpP/AAlmj/8APW5/8Apv/iKP+Es0f/nrc/8AgFN/8RXm32b/AKdv/Jf/AO0UfZv+nb/yX/8AtFdf9kP+ + f8P+Ccf9tU/+fb/8C/8AtT0n/hLNH/563P8A4BTf/EUf8JZo/wDz1uf/AACm/wDiK82+zf8ATt/5L/8A + 2ij7N/07f+S//wBoo/sh/wA/4f8ABD+2qf8Az7f/AIF/9qek/wDCWaP/AM9bn/wCm/8AiKP+Es0f/nrc + /wDgFN/8RXm32b/p2/8AJf8A+0UfZv8Ap2/8l/8A7RR/ZD/n/D/gh/bVP/n2/wDwL/7U9J/4SzR/+etz + /wCAU3/xFWbDXtO1K6NtbSymbYZNrwSR/KCATllHdh+deW/Zv+nb/wAl/wD7RW/4Jj8vxOf3ezNnL/yz + 25+eP/pmn9fwrnxWXuhSdTmva3Tu0u504PMYYmsqXI1dPW99k328j0WiiivPO8KKKKACiiigAooooAKK + KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK + KKACiiigAooooAzxcr/z0H/fwf8AxdSCdf74/wC+x/8AFVgaZ4isNXtluLHUI5oz6TAEfUGbI/GtFbxT + /wAt1/7+j/47TGaQlH94f99D/wCKp4kHqPz/APr1QW6H/PVf+/g/+OVMtwD/AMtB/wB9j/4ugC4GHqPz + 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 + AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUU + AFFFFABRRRQAhFRsD6n8/wD69S0hFAFZ8/3j/wB9H/4qq75/56H/AL+H/wCOVeI9z+f/ANeo2B/vH/vo + /wDxVMZl3EazRPFK4eNhhlaQkEe482vOPEHwb8K6yzS26f2ZOTktasm0/VWlI/LFerMD/fP/AH2f/i6j + YH/nof8Av4f/AI5QB843/wAA9RjJ/s/W7KYdhcFYv5O1Z3/CifFP/P8AaJ/4G/8A2NfTZ3f89W/7+n/4 + 5Rz/AM9W/wC/p/8AjlID51sPgFqEjD+0Ncs4R3FuVk/m6133h74OeFdFdZZ0/tKdTkPdMmAfZVlA/PNe + mgN/z1b/AL+H/wCOU9Qf+eh/7+H/AOOUAVYUWKNY432oowqrKQAPQDzatJn/AJ6H/v4f/jlSKD/fP/fZ + /wDi6lUH+8f++j/8VTAaoOPvH/vo/wDxVTKD6/r/APXoAPr+v/16eBQACloopCCiiigAooooAKKKKACi + iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACi + iigAooooAKKKKACiiigAooooAKKKKACmke9OooAjI9z+f/16YQfU/wDfR/xqekxQMgIP94/99H/4qkwf + 7x/76P8A8VVjH1/Okx9fzpgQ4P8AeP8A30f/AIqnAH1P/fR/xqXH1/OjFIBgB9T+f/16cB7/AK06igQU + UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU + UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRXMfbLz/oIXX5Rf/G6Ptl5/wBBC6/KL/43WPto + 9jb2Mjp6K5j7Zef9BC6/KL/43R9svP8AoIXX5Rf/ABuj20ewexkdPRXMfbLz/oIXX5Rf/G6Ptl5/0ELr + 8ov/AI3R7aPYPYyOnormPtl5/wBBC6/KL/43R9svP+ghdflF/wDG6PbR7B7GR09Fcx9svP8AoIXX5Rf/ + ABuj7Zef9BC6/KL/AON0e2j2D2Mjp6K5j7Zef9BC6/KL/wCN0fbLz/oIXX5Rf/G6PbR7B7GR09Fcx9sv + P+ghdflF/wDG6Ptl5/0ELr8ov/jdHto9g9jI6eiuY+2Xn/QQuvyi/wDjdH2y8/6CF1+UX/xuj20ewexk + dPRXMfbLz/oIXX5Rf/G6Ptl5/wBBC6/KL/43R7aPYPYyOnormPtl5/0ELr8ov/jdH2y8/wCghdflF/8A + G6PbR7B7GR09Fcx9svP+ghdflF/8bo+2Xn/QQuvyi/8AjdHto9g9jI6eiuY+2Xn/AEELr8ov/jdH2y8/ + 6CF1+UX/AMbo9tHsHsZHT0VzH2y8/wCghdflF/8AG6Ptl5/0ELr8ov8A43R7aPYPYyOnormPtl5/0ELr + 8ov/AI3R9svP+ghdflF/8bo9tHsHsZHT0VzH2y8/6CF1+UX/AMbo+2Xn/QQuvyi/+N0e2j2D2Mjp6K5j + 7Zef9BC6/KL/AON0fbLz/oIXX5Rf/G6PbR7B7GR09Fcx9svP+ghdflF/8bo+2Xn/AEELr8ov/jdHto9g + 9jI6eiuY+2Xn/QQuvyi/+N0fbLz/AKCF1+UX/wAbo9tHsHsZHT0VzH2y8/6CF1+UX/xuj7Zef9BC6/KL + /wCN0e2j2D2Mjp6K5j7Zef8AQQuvyi/+N0fbLz/oIXX5Rf8Axuj20ewexkdPRXMfbLz/AKCF1+UX/wAb + o+2Xn/QQuvyi/wDjdHto9g9jI6eiuY+2Xn/QQuvyi/8AjdH2y8/6CF1+UX/xuj20ewexkdPRXMfbLz/o + IXX5Rf8Axuj7Zef9BC6/KL/43R7aPYPYyOnormPtl5/0ELr8ov8A43R9svP+ghdflF/8bo9tHsHsZHT0 + VzH2y8/6CF1+UX/xuj7Zef8AQQuvyi/+N0e2j2D2Mjp6K5j7Zef9BC6/KL/43R9svP8AoIXX5Rf/ABuj + 20ewexkdPRXMfbLz/oIXX5Rf/G6Ptl5/0ELr8ov/AI3R7aPYPYyOnormPtl5/wBBC6/KL/43R9svP+gh + dflF/wDG6PbR7B7GR09Fcx9svP8AoIXX5Rf/ABuj7Zef9BC6/KL/AON0e2j2D2Mjp6K5j7Zef9BC6/KL + /wCN0fbLz/oIXX5Rf/G6PbR7B7GR09Fcx9svP+ghdflF/wDG6imu9TZAINUmRs8l4omGPoFFHt12D2Mu + 42iiiuc6AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK + KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK + KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK + KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK + KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK + KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK + KKACiiigAooooAKKKKAP/9k= + + + + + AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAAAzMzMAAAAAAzMzMzAAAAeP/4MzMwAACP///zMzMAA/////+DMzAz////// + MzMDj/////8zMwOP/////4MzAz//////gzMDOP////+DMwMzj////4MzAAMzOIiIMzAAAzMzMzMzMAAA + MzMzMzMAAAADMzMzAAD//wAA/A8AAPgHAADgAwAA4AEAAMAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAA + AADgAQAA4AEAAPADAAD4DwAA + + + \ No newline at end of file diff --git a/Solutions/Endjin.Templify.WizardFramework/Properties/AssemblyInfo.cs b/Solutions/Endjin.Templify.WizardFramework/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4683eb6 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("Endjin.Templify.WizardFramework")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Endjin.Templify.WizardFramework")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[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("f51fa27b-18a5-4c8a-ad67-e4eeae7b454c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardCommand.cs b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.cs new file mode 100644 index 0000000..52fc5b6 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.cs @@ -0,0 +1,32 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + + /// + /// Abstract class that defines a Wziard Command object. This is used + /// to implement the command pattern. + /// + public abstract class WizardCommand { + + /// + /// Executes the wizard command object. The index of the current + /// command is passed so that the related state can be updated. + /// + /// Index of the current command pointer + /// Index of the next command pointer + public abstract int Execute(int cmdPointer, int lastCmdPointer); + + /// + /// Initialises the command object + /// + public abstract void InitialiseCommand(); + + /// + /// Cleans up the command object + /// + public abstract void CleanupCommand(); + } + + +} + diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardCommand.resx b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.resx new file mode 100644 index 0000000..3f337e0 --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardCommandList.cs b/Solutions/Endjin.Templify.WizardFramework/WizardCommandList.cs new file mode 100644 index 0000000..5bebefd --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/WizardCommandList.cs @@ -0,0 +1,101 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + + /// + /// Base class that defines a WizardCommandList + /// + /// + public abstract class WizardCommandList { + + #region Private Variables + + /// + /// Internal array list that stores the WizardCommand objects + /// + private System.Collections.ArrayList _cmdList = null; + + /// + /// Integer that returns the pointer to the current WizardCommand + /// + private int _cmdPointer = 0; + private int _lastCmdPointer = 0; + + #endregion + + #region Properties + + public int LastCmdPointer { + get { return _lastCmdPointer; } + } + + /// + /// Integer that returns the pointer to the current WizardCommand + /// + public int CmdPointer { + get { return _cmdPointer; } + set { + _lastCmdPointer = _cmdPointer; + _cmdPointer = value; + } + } + + /// + /// Integer that returns the number of WizardCommand objects in the + /// list + /// + public int CmdLength { + get { return _cmdList.Count; } + } + + #endregion + + #region Constructors + + /// + /// Default constructor + /// + public WizardCommandList() { + _cmdList = new System.Collections.ArrayList(); + } + + #endregion + + #region Methods + + /// + /// Adds the WizardCommand object to the internal array list + /// + /// + public void Add(WizardCommand cmd) { + _cmdList.Add(cmd); + } + + /// + /// Determines whether this is the last command in the list + /// + /// Boolean of true if it is the last command in the list, otherwise false + public bool IsLastCommand() { + if (this.CmdPointer == this.CmdLength) { + return true; + } else { + return false; + } + } + + #endregion + + #region Indexers + + /// + /// Indexer that retrieves the WizardComand object at the specified + /// index within the internal array + /// + public WizardCommand this[int index] { + get { return (WizardCommand)_cmdList[index]; } + } + + #endregion + } + +} diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardState.cs b/Solutions/Endjin.Templify.WizardFramework/WizardState.cs new file mode 100644 index 0000000..56b442a --- /dev/null +++ b/Solutions/Endjin.Templify.WizardFramework/WizardState.cs @@ -0,0 +1,24 @@ +namespace Endjin.Templify.WizardFramework +{ + using System; + using System.Collections.Generic; + + using Endjin.Templify.Domain.Domain.Packages; + + /// + /// Summary description for WizardState. + /// + public class WizardState + { + public List Settings { get; set; } + + + // Public instance member + public static WizardState Instance = new WizardState(); + + + private WizardState() + { + } + } +} diff --git a/Solutions/Endjin.Templify.sln b/Solutions/Endjin.Templify.sln index ca23881..5eb0db5 100644 --- a/Solutions/Endjin.Templify.sln +++ b/Solutions/Endjin.Templify.sln @@ -24,6 +24,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{324E1002 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Endjin.Templify.CommandLine", "Endjin.Templify.CommandLine\Endjin.Templify.CommandLine.csproj", "{585FCA37-58D1-4E7C-93BB-30C1FC755437}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Endjin.Templify.WizardFramework", "Endjin.Templify.WizardFramework\Endjin.Templify.WizardFramework.csproj", "{D8F709BA-1E52-48FB-A917-7C3A40445F7F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,7 +38,6 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|Any CPU.ActiveCfg = Debug {56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|Mixed Platforms.ActiveCfg = Debug - {56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|Mixed Platforms.Build.0 = Debug {56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|x86.ActiveCfg = Debug {56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|x86.Build.0 = Debug {56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Release|Any CPU.ActiveCfg = Release @@ -87,6 +88,16 @@ Global {585FCA37-58D1-4E7C-93BB-30C1FC755437}.Release|Mixed Platforms.Build.0 = Release|x86 {585FCA37-58D1-4E7C-93BB-30C1FC755437}.Release|x86.ActiveCfg = Release|x86 {585FCA37-58D1-4E7C-93BB-30C1FC755437}.Release|x86.Build.0 = Release|x86 + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|x86.ActiveCfg = Debug|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Any CPU.Build.0 = Release|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -94,6 +105,7 @@ Global GlobalSection(NestedProjects) = preSolution {56BE3D9C-686D-426A-A49C-BC83FCAB670E} = {6C3DEE68-6633-4899-B980-64339AB62651} {9E8B79ED-9C17-485B-B1F9-8D33D8BB4BD2} = {59A31D18-9067-4B4D-930C-54113BAD4A83} + {D8F709BA-1E52-48FB-A917-7C3A40445F7F} = {59A31D18-9067-4B4D-930C-54113BAD4A83} {AB83608F-1457-4EC7-B9CD-82813A222347} = {4799185A-AFB0-428D-9B2C-29BCDFDF0B3C} {585FCA37-58D1-4E7C-93BB-30C1FC755437} = {4799185A-AFB0-428D-9B2C-29BCDFDF0B3C} {1491A90A-6AC9-4EF4-A959-E0F0439A1D6E} = {AF81571B-C5FB-4073-A8EC-8C912EA07100}