#At file:///D:/Work/MySQL/installer/ based on revid:iggy@mysql.com-20110317155158-t79o9hyfs6e2afuz
371 Mike Lischke 2011-03-18
- ManifestUpdater: improved file matching to account for different architectures.
- Setup: added 64 bit msi files for server and connectors.
- Setup: set default package to 5.5 64 bit. This will automatically adjusted for 32 bit platforms.
- Setup: added 64 bit product catalogs and products.
- FeatureBox: reworked drawing.
- FeatureBox: added central product retrieval function based on architecture, active catalog, all/installed inclusion.
- FeatureTree: reworked drawing.
- FeatureBox + FeatureTree: show architecture in titles if Any is currently selected. (In debug mode the architecture is always displayed).
- Features: added support for architecture choice.
- Changed logic for ActiveCatalog: the catalog is now persistently stored, is usually always assigned except if all/installed items are selected in the custom setup and is set to the default catalog if the user switchs to any preset setup.
- RemoveComplete: improved directory removal. Care is taken to remove any read-only setting bevor deletion.
- Moved handling for the default catalog from Program.cs to the ProductManager.
- Added support for OS architecture detection.
- Some minor refactorings and additional log output.
added:
WexInstaller/Controls/FeatureTreeView.resx
modified:
ManifestUpdater/Program.cs
Setup/IncludeMSIs.wxs
Setup/Setup_Net.wixproj
Setup/manifest-base.xml
StandardPlugins/Server/ServerConfigPanel2.cs
WexInstaller.Core/InstallerConfiguration.cs
WexInstaller.Core/Package.cs
WexInstaller.Core/Product.cs
WexInstaller.Core/ProductCatalog.cs
WexInstaller.Core/ProductFeature.cs
WexInstaller.Core/ProductManager.cs
WexInstaller.Core/WexInstaller.Core.csproj
WexInstaller.Core/Win32.cs
WexInstaller/Controls/FeatureBox.cs
WexInstaller/Controls/FeatureTreeView.cs
WexInstaller/InstallWizard/Features.Designer.cs
WexInstaller/InstallWizard/Features.cs
WexInstaller/InstallWizard/Features.resx
WexInstaller/InstallWizard/InstallType.cs
WexInstaller/Program.cs
WexInstaller/RemovePanels/RemoveComplete.cs
WexInstaller/WexInstaller.csproj
installer-vs2010.sln
=== modified file 'ManifestUpdater/Program.cs'
=== modified file 'ManifestUpdater/Program.cs'
--- a/ManifestUpdater/Program.cs 2011-03-02 15:58:16 +0000
+++ b/ManifestUpdater/Program.cs 2011-03-18 10:29:04 +0000
@@ -1,214 +1,234 @@
using System;
using System.Collections.Generic;
-using System.Text;
+using System.IO;
+using Microsoft.Tools.WindowsInstallerXml.Msi;
+using System.Text.RegularExpressions;
+
using Mono.Options;
+
using WexInstaller.Core;
-using System.IO;
-using Microsoft.Tools.WindowsInstallerXml.Msi;
namespace ManifestUpdater
{
- class Program
- {
- static string inFile = null;
- static string outFile = null;
- static string cacheDir = null;
- static bool wait = true;
-
- static void Main(string[] args)
- {
-
- // Parse our command line args
- OptionSet p = new OptionSet()
- .Add("input=|in=", input => inFile=input)
- .Add("output=|out=", output => outFile=output)
- .Add("cachedir=|cache=", dir => cacheDir=dir)
- .Add("wait=", dowait => wait = (dowait == "y" || dowait == "Y"));
- p.Parse(args);
-
- // load the manifest
- ProductManifest manifest = ProductManifest.Load(inFile);
-
- foreach (ProductCategory category in manifest.ProductCategories)
- {
- foreach (Product product in category.Products)
- {
- if (product.Packages.Count != 1) continue;
- Package package = product.Packages[0];
- UpdateProductAndPackage(product, package);
- }
- }
-
- // now save the manifest
- manifest.Save(outFile);
- if (wait)
- {
- Console.WriteLine();
- Console.WriteLine("Manifest generation done. Press Enter.");
- Console.ReadLine();
- }
- }
-
- static void UpdateProductAndPackage(Product product, Package package)
- {
- // first find the latest MSI in our cache
- string msiFile = FindLatestVersion(package.FileName);
- if (String.IsNullOrEmpty(msiFile)) return;
-
- UpdateProductInfo(product, msiFile);
- UpdatePackageInfo(package, msiFile);
- }
-
- static string FindLatestVersion(string fileName)
- {
- int index = fileName.IndexOf('.');
- index = fileName.IndexOf('.', index + 1);
- string baseName = fileName.Substring(0, index);
-
- Version newestVersion = new Version(0, 0);
- string newestFile = null;
-
- string[] files = Directory.GetFiles(cacheDir, baseName + "*.msi");
- foreach (string file in files)
- {
- Version v = new Version(GetProperty(file, "ProductVersion"));
- if (v <= newestVersion) continue;
- newestVersion = v;
- newestFile = file;
- }
- return newestFile;
- }
-
- static void UpdateProductInfo(Product product, string msiFile)
- {
- product.UpgradeId = GetProperty(msiFile, "UpgradeCode");
- if (String.IsNullOrEmpty(product.UpgradeId))
- Console.WriteLine(String.Format("Warning: {0} doesn't have an upgrade code",
- Path.GetFileName(msiFile)));
- }
-
- static void UpdatePackageInfo(Package package, string msiFile)
- {
- package.FileName = Path.GetFileName(msiFile);
- package.ThisVersion = GetProperty(msiFile, "ProductVersion");
- package.Id = GetProperty(msiFile, "ProductCode");
- package.Features.Clear();
- SetFeatures(msiFile, package);
- }
-
- static void SetFeatures(string msiFile, Package package)
- {
- Database msiDb = new Database(msiFile, OpenDatabase.ReadOnly);
- GetFeatures(msiDb, package);
- msiDb.Close();
- }
-
- static void GetFeatures(Database msiDb, object parent)
- {
- List<ProductFeature> features = new List<ProductFeature>();
-
- if (parent is Package)
- (parent as Package).Features = features;
- else
- (parent as ProductFeature).Features = features;
- string parentName = parent is Package ? null : (parent as ProductFeature).Name;
-
- using (View featureView = msiDb.OpenExecuteView("SELECT * FROM Feature ORDER BY Display"))
- {
- Record record;
- while (null != (record = featureView.Fetch()))
- {
- int featureLevel = record.GetInteger(6);
- if (featureLevel == 0) continue; // level 0 features will not be installed anyway
-
- string featureParent = record.GetString(2);
- if (featureParent != parentName) continue;
-
- ProductFeature feature = new ProductFeature();
- feature.Name = record.GetString(1);
- feature.Title = record.GetString(3);
- feature.Description = record.GetString(4);
- feature.Display = record.GetInteger(5);
- feature.HasComponents = FeatureHasComponents(msiDb, feature.Name);
- feature.SizeEstimate = GetSizeEstimate(msiDb, feature.Name);
- features.Add(feature);
- }
- }
-
- // now recurse
- if (features != null && features.Count > 0)
- foreach (ProductFeature feature in features)
- GetFeatures(msiDb, feature);
- }
-
- static long GetSizeEstimate(Database msiDb, string featureName)
- {
- List<string> components = GetComponentsForFeature(msiDb, featureName);
-
- long size = 0;
- foreach (string component in components)
- size += GetSizeOfComponent(msiDb, component);
-
- return size;
- }
-
- static List<string> GetComponentsForFeature(Database msiDb, string feature)
- {
- List<string> components = new List<string>();
-
- using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
- {
- Record record;
- while (null != (record = view.Fetch()))
- {
- if (String.Compare(feature, record.GetString(1), true) == 0)
- components.Add(record.GetString(2));
- }
- }
- return components;
- }
-
- static long GetSizeOfComponent(Database msiDb, string component)
- {
- long size = 0;
-
- using (View view = msiDb.OpenExecuteView("SELECT * FROM File"))
- {
- Record record;
- while (null != (record = view.Fetch()))
- {
- if (String.Compare(component, record.GetString(2), true) == 0)
- size += (long)record.GetInteger(4);
- }
- }
- return size;
- }
-
- static bool FeatureHasComponents(Database msiDb, string featureName)
- {
- using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
- {
- Record record;
- while (null != (record = view.Fetch()))
- {
- if (String.Compare(featureName, record.GetString(1), true) == 0)
- return true;
- }
- }
- return false;
- }
-
- static string GetProperty(string msiFile, string property)
- {
- using (Database d = new Database(msiFile, OpenDatabase.ReadOnly))
- {
- string sql = String.Format("SELECT * FROM `Property` WHERE `Property`.`Property` = '{0}'", property);
- View view = d.OpenView(sql);
- view.Execute();
- Record record = view.Fetch();
- if (record == null) return String.Empty;
- return record.GetString(2);
- }
- }
- }
+ class Program
+ {
+ static string inFile = null;
+ static string outFile = null;
+ static string cacheDir = null;
+ static bool wait = true;
+
+ static void Main(string[] args)
+ {
+ // Parse our command line args
+ OptionSet p = new OptionSet()
+ .Add("input=|in=", input => inFile=input)
+ .Add("output=|out=", output => outFile=output)
+ .Add("cachedir=|cache=", dir => cacheDir=dir)
+ .Add("wait=", dowait => wait = (dowait == "y" || dowait == "Y"));
+ p.Parse(args);
+
+ // load the manifest
+ ProductManifest manifest = ProductManifest.Load(inFile);
+
+ foreach (ProductCategory category in manifest.ProductCategories)
+ {
+ foreach (Product product in category.Products)
+ {
+ if (product.Packages.Count != 1) continue;
+ Package package = product.Packages[0];
+ UpdateProductAndPackage(product, package);
+ }
+ }
+
+ // now save the manifest
+ manifest.Save(outFile);
+ if (wait)
+ {
+ Console.WriteLine();
+ Console.WriteLine("Manifest generation done. Press Enter.");
+ Console.ReadLine();
+ }
+ }
+
+ static void UpdateProductAndPackage(Product product, Package package)
+ {
+ // first find the latest MSI in our cache
+ string msiFile = FindLatestVersion(package.FileName);
+ if (String.IsNullOrEmpty(msiFile))
+ return;
+
+ UpdateProductInfo(product, msiFile);
+ UpdatePackageInfo(package, msiFile);
+ }
+
+ /// <summary>
+ /// Given a complete file name the function looks for similar file names, which only differ
+ /// in certain parts (mainly the embedded version number) to find the newest of these files.
+ /// </summary>
+ /// <param name="fileName">The path and file name used as patter to look for more files.</param>
+ /// <returns>The found file with the latest version or null if none could be found.</returns>
+ static string FindLatestVersion(string fileName)
+ {
+ // Names adhere to the pattern mysql-([a-zA-Z\+]+-)*[0-9]\.[0-9]\.[0-9][0-9]-win(32|x64)\.msi
+ // e.g. mysql-5.5.9-win32.msi, or mysql-connector-odbc-5.1.8-winx64.msi.
+ // Extract the architecture and extension part, which forms the end of our search pattern.
+ Regex filePattern = new Regex(@"(?<baseName>mysql-([a-zA-Z\+]+-)*\d\.\d\.)(\d)+(?<ending>-win(32|x64)\.msi)$");
+ Match match = filePattern.Match(fileName);
+ string newestFile = null;
+ if (match.Success)
+ {
+ string ending = match.Groups["ending"].Value;
+ string baseName = match.Groups["baseName"].Value;
+
+ Version newestVersion = new Version(0, 0);
+
+ string[] files = Directory.GetFiles(cacheDir, baseName + "*" + ending);
+ foreach (string file in files)
+ {
+ Version v = new Version(GetProperty(file, "ProductVersion"));
+ if (v <= newestVersion) continue;
+ newestVersion = v;
+ newestFile = file;
+ }
+ }
+ return newestFile;
+ }
+
+ static void UpdateProductInfo(Product product, string msiFile)
+ {
+ product.UpgradeId = GetProperty(msiFile, "UpgradeCode");
+ if (String.IsNullOrEmpty(product.UpgradeId))
+ Console.WriteLine(String.Format("Warning: {0} doesn't have an upgrade code",
+ Path.GetFileName(msiFile)));
+ }
+
+ static void UpdatePackageInfo(Package package, string msiFile)
+ {
+ package.FileName = Path.GetFileName(msiFile);
+ package.ThisVersion = GetProperty(msiFile, "ProductVersion");
+ package.Id = GetProperty(msiFile, "ProductCode");
+ package.Features.Clear();
+ SetFeatures(msiFile, package);
+ }
+
+ static void SetFeatures(string msiFile, Package package)
+ {
+ Database msiDb = new Database(msiFile, OpenDatabase.ReadOnly);
+ GetFeatures(msiDb, package);
+ msiDb.Close();
+ }
+
+ static void GetFeatures(Database msiDb, object parent)
+ {
+ List<ProductFeature> features = new List<ProductFeature>();
+
+ if (parent is Package)
+ (parent as Package).Features = features;
+ else
+ (parent as ProductFeature).Features = features;
+ string parentName = parent is Package ? null : (parent as ProductFeature).Name;
+
+ using (View featureView = msiDb.OpenExecuteView("SELECT * FROM Feature ORDER BY Display"))
+ {
+ Record record;
+ while (null != (record = featureView.Fetch()))
+ {
+ int featureLevel = record.GetInteger(6);
+ if (featureLevel == 0)
+ continue; // level 0 features will not be installed anyway
+
+ string featureParent = record.GetString(2);
+ if (featureParent != parentName)
+ continue;
+
+ ProductFeature feature = new ProductFeature();
+ feature.Name = record.GetString(1);
+ feature.Title = record.GetString(3);
+ feature.Description = record.GetString(4);
+ feature.Display = record.GetInteger(5);
+ feature.HasComponents = FeatureHasComponents(msiDb, feature.Name);
+ feature.SizeEstimate = GetSizeEstimate(msiDb, feature.Name);
+ features.Add(feature);
+ }
+ }
+
+ // now recurse
+ if (features != null && features.Count > 0)
+ foreach (ProductFeature feature in features)
+ GetFeatures(msiDb, feature);
+ }
+
+ static long GetSizeEstimate(Database msiDb, string featureName)
+ {
+ List<string> components = GetComponentsForFeature(msiDb, featureName);
+
+ long size = 0;
+ foreach (string component in components)
+ size += GetSizeOfComponent(msiDb, component);
+
+ return size;
+ }
+
+ static List<string> GetComponentsForFeature(Database msiDb, string feature)
+ {
+ List<string> components = new List<string>();
+
+ using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
+ {
+ Record record;
+ while (null != (record = view.Fetch()))
+ {
+ if (String.Compare(feature, record.GetString(1), true) == 0)
+ components.Add(record.GetString(2));
+ }
+ }
+ return components;
+ }
+
+ static long GetSizeOfComponent(Database msiDb, string component)
+ {
+ long size = 0;
+
+ using (View view = msiDb.OpenExecuteView("SELECT * FROM File"))
+ {
+ Record record;
+ while (null != (record = view.Fetch()))
+ {
+ if (String.Compare(component, record.GetString(2), true) == 0)
+ size += (long)record.GetInteger(4);
+ }
+ }
+ return size;
+ }
+
+ static bool FeatureHasComponents(Database msiDb, string featureName)
+ {
+ using (View view = msiDb.OpenExecuteView("SELECT * FROM FeatureComponents"))
+ {
+ Record record;
+ while (null != (record = view.Fetch()))
+ {
+ if (String.Compare(featureName, record.GetString(1), true) == 0)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static string GetProperty(string msiFile, string property)
+ {
+ using (Database d = new Database(msiFile, OpenDatabase.ReadOnly))
+ {
+ string sql = String.Format("SELECT * FROM `Property` WHERE `Property`.`Property` = '{0}'",
+ property);
+ View view = d.OpenView(sql);
+ view.Execute();
+ Record record = view.Fetch();
+ if (record == null)
+ return String.Empty;
+
+ return record.GetString(2);
+ }
+ }
+ }
}
=== modified file 'Setup/IncludeMSIs.wxs'
--- a/Setup/IncludeMSIs.wxs 2011-03-14 15:50:43 +0000
+++ b/Setup/IncludeMSIs.wxs 2011-03-18 10:29:04 +0000
@@ -5,10 +5,14 @@
<Directory Id="ProductCache" Name="Product Cache">
<Component Id="Products" Guid="88D9D419-FCCB-4B4B-881E-FAE4D29C81B9" Permanent="yes">
<!--File Id="server51" Name="mysql-5.1.55-win32.msi" Source="ProductCache\mysql-5.1.56-win32.msi"/ -->
- <File Id="server55" Name="mysql-5.5.9-win32.msi" Source="ProductCache\mysql-5.5.9-win32.msi"/>
- <File Id="connector_cpp_10" Name="mysql-connector-c++-1.1.0-win32.msi" Source="ProductCache\mysql-connector-c++-1.1.0-win32.msi"/>
- <File Id="connector_c_60" Name="mysql-connector-c-6.0.2-win32.msi" Source="ProductCache\mysql-connector-c-6.0.2-win32.msi"/>
- <File Id="connector_odbc_51" Name="mysql-connector-odbc-5.1.8-win32.msi" Source="ProductCache\mysql-connector-odbc-5.1.8-win32.msi"/>
+ <File Id="server55_x86" Name="mysql-5.5.9-win32.msi" Source="ProductCache\mysql-5.5.9-win32.msi"/>
+ <File Id="server55_x64" Name="mysql-5.5.9-winx64.msi" Source="ProductCache\mysql-5.5.9-winx64.msi"/>
+ <File Id="connector_cpp_10_x86" Name="mysql-connector-c++-1.1.0-win32.msi" Source="ProductCache\mysql-connector-c++-1.1.0-win32.msi"/>
+ <File Id="connector_cpp_10_x64" Name="mysql-connector-c++-1.1.0-winx64.msi" Source="ProductCache\mysql-connector-c++-1.1.0-winx64.msi"/>
+ <File Id="connector_c_60_x86" Name="mysql-connector-c-6.0.2-win32.msi" Source="ProductCache\mysql-connector-c-6.0.2-win32.msi"/>
+ <File Id="connector_c_60_x64" Name="mysql-connector-c-6.0.2-winx64.msi" Source="ProductCache\mysql-connector-c-6.0.2-winx64.msi"/>
+ <File Id="connector_odbc_51_x86" Name="mysql-connector-odbc-5.1.8-win32.msi" Source="ProductCache\mysql-connector-odbc-5.1.8-win32.msi"/>
+ <File Id="connector_odbc_51_x64" Name="mysql-connector-odbc-5.1.8-winx64.msi" Source="ProductCache\mysql-connector-odbc-5.1.8-winx64.msi"/>
<!--<File Id="examples_51" Name="mysql-examples-5.1.0.msi" Source="ProductCache\mysql-examples-5.1.0.msi"/> -->
<File Id="examples_55" Name="mysql-examples-5.5.0.msi" Source="ProductCache\mysql-examples-5.5.0.msi"/>
<File Id="universal_installer_document_bundle_10" Name="mysql-universal-installer-document-bundle-1.0.0.0.msi" Source="ProductCache\mysql-universal-installer-document-bundle-1.0.0.0.msi"/>
=== modified file 'Setup/Setup_Net.wixproj'
--- a/Setup/Setup_Net.wixproj 2011-03-02 22:27:21 +0000
+++ b/Setup/Setup_Net.wixproj 2011-03-18 10:29:04 +0000
@@ -6,7 +6,7 @@
<ProductVersion>3.5</ProductVersion>
<ProjectGuid>{fbc6c598-ec89-49e6-8fe4-4140141761cc}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
- <OutputName>mysql-universal-installer-1.0.6.0-b-net</OutputName>
+ <OutputName>mysql-universal-installer-1.0.9</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
@@ -16,7 +16,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
- <DefineConstants>ProductVersion=1.0.6.0;ProductName=MySQL Universal Installer;CatalogName=mysql-5.5-gpl</DefineConstants>
+ <DefineConstants>ProductVersion=1.0.9.0;ProductName=MySQL Universal Installer;CatalogName=mysql-5.5-winx64-gpl</DefineConstants>
<SuppressPdbOutput>True</SuppressPdbOutput>
<VerboseOutput>True</VerboseOutput>
</PropertyGroup>
=== modified file 'Setup/manifest-base.xml'
--- a/Setup/manifest-base.xml 2011-03-17 15:06:16 +0000
+++ b/Setup/manifest-base.xml 2011-03-18 10:29:04 +0000
@@ -4,58 +4,107 @@
<UpdateVersion></UpdateVersion>
<UpdateHash></UpdateHash>
<ProductCatalogs>
- <ProductCatalog id="mysql-5.5-gpl" name="MySQL 5.5" description="MySQL 5.5 Community Edition" commercial="false">
- <SetupTypes>
- <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
- <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
- <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
- <SetupType flag="64" name="Full" description="Installs all products from this catalog" />
- <SetupType flag="128" name="Custom" description="The user can select which products to install" />
- </SetupTypes>
- <CatalogProducts>
- <CatalogProduct productId="mysql-server-5.5-gpl" setupTypeFlags="3" />
- <CatalogProduct productId="workbench" setupTypeFlags="5" />
- <CatalogProduct productId="connector-odbc" setupTypeFlags="5" />
- <CatalogProduct productId="connector-c" setupTypeFlags="5" />
- <CatalogProduct productId="connector-cpp" setupTypeFlags="5" />
- <CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
- </CatalogProducts>
- </ProductCatalog>
- <ProductCatalog id="mysql-5.1-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
- <SetupTypes>
- <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
- <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
- <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
- <SetupType flag="64" name="Full" description="Installs all products from this catalog" />
- <SetupType flag="128" name="Custom" description="The user can select which products to install" />
- </SetupTypes>
- <CatalogProducts>
- <CatalogProduct productId="mysql-server-5.1-gpl" setupTypeFlags="3" />
- <CatalogProduct productId="workbench" setupTypeFlags="5" />
- <CatalogProduct productId="connector-odbc" setupTypeFlags="5" />
- <CatalogProduct productId="connector-c" setupTypeFlags="5" />
- <CatalogProduct productId="connector-cpp" setupTypeFlags="5" />
- <CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
+ <ProductCatalog id="mysql-5.5-win32-gpl" name="MySQL 5.5" description="MySQL 5.5 Community Edition" commercial="false">
+ <SetupTypes>
+ <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+ <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+ <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
+ <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+ <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+ </SetupTypes>
+ <CatalogProducts>
+ <CatalogProduct productId="mysql-server-5.5-win32-gpl" setupTypeFlags="3" />
+ <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-odbc-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-c-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-cpp-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-documentation-5.5" setupTypeFlags="5"/>
+ </CatalogProducts>
+ </ProductCatalog>
+ <ProductCatalog id="mysql-5.5-winx64-gpl" name="MySQL 5.5" description="MySQL 5.5 Community Edition" commercial="false">
+ <SetupTypes>
+ <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+ <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+ <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products, i.e. MySQL Workbench, connectors + samples and examples." />
+ <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+ <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+ </SetupTypes>
+ <CatalogProducts>
+ <CatalogProduct productId="mysql-server-5.5-winx64-gpl" setupTypeFlags="3" />
+ <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-odbc-winx64" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-c-winx64" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-cpp-winx64" setupTypeFlags="5" />
+ <CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-documentation-5.5" setupTypeFlags="5"/>
+ </CatalogProducts>
+ </ProductCatalog>
+ <ProductCatalog id="mysql-5.1-win32-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
+ <SetupTypes>
+ <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+ <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+ <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products." />
+ <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+ <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+ </SetupTypes>
+ <CatalogProducts>
+ <CatalogProduct productId="mysql-server-5.1-win32-gpl" setupTypeFlags="3" />
+ <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-odbc-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-c-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-cpp-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-documentation-5.1" setupTypeFlags="5"/>
+ </CatalogProducts>
+ </ProductCatalog>
+ <ProductCatalog id="mysql-5.1-winx64-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
+ <SetupTypes>
+ <SetupType flag="1" name="Developer Default" description="Installs all products needed for MySQL development, including server, MySQL Workbench, connectors + samples and examples." />
+ <SetupType flag="2" name="Server only" description="Installs only the MySQL Server product. Use this type for servers that do not need developer resources" />
+ <SetupType flag="4" name="Client only" description="Installs only the MySQL Client products." />
+ <SetupType flag="64" name="Full" description="Installs all products from this catalog." />
+ <SetupType flag="128" name="Custom" description="The user can select which products to install." />
+ </SetupTypes>
+ <CatalogProducts>
+ <CatalogProduct productId="mysql-server-5.1-winx64-gpl" setupTypeFlags="3" />
+ <CatalogProduct productId="workbench-win32" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-odbc-winx64" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-c-winx64" setupTypeFlags="5" />
+ <CatalogProduct productId="connector-cpp-winx64" setupTypeFlags="5" />
+ <CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-documentation-5.1" setupTypeFlags="5"/>
</CatalogProducts>
</ProductCatalog>
</ProductCatalogs>
+
<ProductCategories>
<ProductCategory name="Server" title="MySql Servers" description="MySQL Database Servers">
- <Product name="mysql-server-5.5-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.5">
- <Packages>
- <Package type="MSI" arch="X86" filename="mysql-5.5.8-win32.msi" id="" thisVersion="">
- </Package>
- </Packages>
- </Product>
- <Product name="mysql-server-5.1-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.1">
+ <Product name="mysql-server-5.5-win32-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.5">
+ <Packages>
+ <Package type="MSI" arch="X86" filename="mysql-5.5.8-win32.msi" id="" thisVersion="" />
+ </Packages>
+ </Product>
+ <Product name="mysql-server-5.5-winx64-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.5">
+ <Packages>
+ <Package type="MSI" arch="X64" filename="mysql-5.5.8-winx64.msi" id="" thisVersion="" />
+ </Packages>
+ </Product>
+ <Product name="mysql-server-5.1-win32-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.1">
<Packages>
<Package type="MSI" arch="X86" filename="mysql-5.1.54-win32.msi" id="" thisVersion="">
</Package>
</Packages>
</Product>
+ <Product name="mysql-server-5.1-winx64-gpl" title="MySQL Server" description="The core MySQL database server" upgradeId="" urlBaseDir="mysql-5.1">
+ <Packages>
+ <Package type="MSI" arch="X64" filename="mysql-5.1.54-winx64.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
</ProductCategory>
<ProductCategory name="Application" title="Applications" description="Applications that work with MySQL">
- <Product name="workbench" title="MySQL Workbench" description="The MySQL GUI Developer tool" upgradeId="" urlBaseDir="MySQLGUITools">
+ <Product name="workbench-win32" title="MySQL Workbench" description="The MySQL GUI Developer tool" upgradeId="" urlBaseDir="MySQLGUITools">
<Packages>
<Package type="MSI" arch="X86" filename="mysql-workbench-gpl-5.2.31a-win32.msi" id="" thisVersion="">
</Package>
@@ -63,41 +112,65 @@
</Product>
</ProductCategory>
<ProductCategory name="Connector" title="MySQL Connectors" description="Database drivers for programming languages">
- <Product name="connector-odbc" title="Connector/ODBC" description="MySQL Connector for ODBC" upgradeId="" urlBaseDir="mysql-connector-odbc-5.1">
- <Packages>
- <Package type="MSI" arch="X86" filename="mysql-connector-odbc-5.1.6-win32.msi" id="" thisVersion="">
- </Package>
- </Packages>
- </Product>
- <Product name="connector-cpp" title="Connector/C++" description="MySQL Connector for C++" upgradeId="" urlBaseDir="">
- <Packages>
- <Package type="MSI" arch="X86" filename="mysql-connector-c++-1.0.5-win32.msi" id="" thisVersion="">
- </Package>
- </Packages>
- </Product>
- <Product name="connector-C" title="Connector/C" description="MySQL Connector for C" upgradeId="" urlBaseDir="">
+ <Product name="connector-odbc-win32" title="Connector/ODBC" description="MySQL Connector for ODBC" upgradeId="" urlBaseDir="mysql-connector-odbc-5.1">
+ <Packages>
+ <Package type="MSI" arch="X86" filename="mysql-connector-odbc-5.1.8-win32.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="connector-odbc-winx64" title="Connector/ODBC" description="MySQL Connector for ODBC" upgradeId="" urlBaseDir="mysql-connector-odbc-5.1">
+ <Packages>
+ <Package type="MSI" arch="X64" filename="mysql-connector-odbc-5.1.8-winx64.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="connector-cpp-win32" title="Connector/C++" description="MySQL Connector for C++" upgradeId="" urlBaseDir="">
+ <Packages>
+ <Package type="MSI" arch="X86" filename="mysql-connector-c++-1.1.0-win32.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="connector-cpp-winx64" title="Connector/C++" description="MySQL Connector for C++" upgradeId="" urlBaseDir="">
+ <Packages>
+ <Package type="MSI" arch="X64" filename="mysql-connector-c++-1.1.0-winx64.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="connector-c-win32" title="Connector/C" description="MySQL Connector for C" upgradeId="" urlBaseDir="">
<Packages>
<Package type="MSI" arch="X86" filename="mysql-connector-c-6.0.2-win32.msi" id="" thisVersion="">
</Package>
</Packages>
</Product>
+ <Product name="connector-c-winx64" title="Connector/C" description="MySQL Connector for C" upgradeId="" urlBaseDir="">
+ <Packages>
+ <Package type="MSI" arch="X64" filename="mysql-connector-c-6.0.2-winx64.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
</ProductCategory>
<ProductCategory name="Documentation" title="Documentation" description="">
- <Product name="Universal-Docs" title="MySQL Documentation" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
- <Packages>
- <Package type="MSI" arch="X86" filename="mysql-universal-installer-document-bundle-1.0.0.0.msi" id="" thisVersion="">
- </Package>
- </Packages>
- </Product>
- <Product name="examples-5.1" title="Samples and Examples" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
- <Packages>
- <Package type="MSI" arch="X86" filename="mysql-examples-5.1.0.msi" id="" thisVersion="">
- </Package>
- </Packages>
- </Product>
- <Product name="examples-5.5" title="Samples and Examples" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
- <Packages>
- <Package type="MSI" arch="X86" filename="mysql-examples-5.5.0.msi" id="" thisVersion="">
+ <Product name="mysql-documentation-5.5" title="MySQL Documentation 5.5" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+ <Packages>
+ <Package type="MSI" arch="Any" filename="mysql-documentation-5.5.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="mysql-documentation-5.1" title="MySQL Documentation 5.1" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+ <Packages>
+ <Package type="MSI" arch="Any" filename="mysql-documentation-5.1.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="examples-5.5" title="Samples and Examples 5.5" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+ <Packages>
+ <Package type="MSI" arch="Any" filename="mysql-examples-5.5.0.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="examples-5.1" title="Samples and Examples 5.1" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+ <Packages>
+ <Package type="MSI" arch="Any" filename="mysql-examples-5.1.0.msi" id="" thisVersion="">
</Package>
</Packages>
</Product>
=== modified file 'StandardPlugins/Server/ServerConfigPanel2.cs'
--- a/StandardPlugins/Server/ServerConfigPanel2.cs 2011-03-07 12:55:25 +0000
+++ b/StandardPlugins/Server/ServerConfigPanel2.cs 2011-03-18 10:29:04 +0000
@@ -65,9 +65,11 @@
if (Controller.Template != null && Controller.Template.Reconfiguring)
{
enableTCPIP.Checked = Controller.Template.EnableNetworking;
+ enableTCPIP_CheckedChanged(null, null);
if (enableTCPIP.Checked)
portNumber.Text = Controller.Template.Port;
+ // TODO: check if the service actually exists (if not enable service name edit).
if (!String.IsNullOrEmpty(Controller.ServiceName))
{
serviceName.Text = Controller.ServiceName;
@@ -105,9 +107,12 @@
public override bool NextOk()
{
- if (portErrorSign.Visible) return false;
- if (rootPwdErrorSign.Visible) return false;
- if (serviceErrorSign.Visible) return false;
+ if (portErrorSign.Visible)
+ return false;
+ if (rootPwdErrorSign.Visible)
+ return false;
+ if (serviceErrorSign.Visible)
+ return false;
return true;
}
=== modified file 'WexInstaller.Core/InstallerConfiguration.cs'
--- a/WexInstaller.Core/InstallerConfiguration.cs 2011-03-10 15:47:49 +0000
+++ b/WexInstaller.Core/InstallerConfiguration.cs 2011-03-18 10:29:04 +0000
@@ -1,208 +1,207 @@
using System;
using System.Collections.Generic;
-using System.Text;
-using System.Xml.Serialization;
+using System.Diagnostics;
+using System.Drawing;
using System.IO;
-using System.Reflection;
-using System.Drawing;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
using System.Net;
+using System.Xml.Serialization;
+
using MySQL.Utilities.SysUtils;
namespace WexInstaller.Core
{
- public sealed class InstallerConfiguration
- {
- private static InstallerConfigurationData Instance = new InstallerConfigurationData();
- private static WebClient Wc = new WebClient();
-
- // Indicates if this configuration was loaded from file or is just a default config.
- private static bool isDefault = true;
-
- #region Properties
-
- public static bool DisplayLicenseAgreement
- {
- get { return Instance.LicenseAgreement > 0; }
- set { if (value) Instance.LicenseAgreement = 1; else Instance.LicenseAgreement = 0; }
- }
-
- public static Point Location
- {
- get { return Instance.Location; }
- set { Instance.Location = value; }
- }
-
- public static string ProposedInstallationPath { get; set; }
-
- public static string HomeDir { get; set; }
-
- public static bool NewInstall
- {
- get { return true; }
- }
-
- public static List<UpdateURL> UpdateURLs
- {
- get { return Instance.UpdateURLs; }
- set { Instance.UpdateURLs = value; }
- }
-
- public static int UpdateTimeoutMilliseconds
- {
- get { return Instance.UpdateTimeoutMilliseconds; }
- set { Instance.UpdateTimeoutMilliseconds = value; }
- }
-
- public static int UpdateCheckFrequency
- {
- get { return Instance.UpdateCheckFrequency; }
- set { Instance.UpdateCheckFrequency = value; }
- }
-
- public static string ProductCachePath
- {
- get { return Instance.ProductCachePath; }
- set { Instance.ProductCachePath = value; }
- }
-
- public static string InstallationRoot
- {
- get { return Instance.InstallationRoot; }
- set { Instance.InstallationRoot = value; }
- }
-
- public static string ProductCode
- {
- get { return Instance.ProductCode; }
- set { Instance.ProductCode = value; }
- }
-
- private static string ConfigFile
- {
- get { return String.Format("{0}\\config.xml", HomeDir); }
- }
-
- public static string ProductsManifest
- {
- get { return String.Format("{0}\\products.xml", HomeDir); }
- }
-
- public static string TempProductsManifest
- {
- get { return String.Format("{0}\\products.xml.temp", HomeDir); }
- }
-
- public static string TemplateName
- {
- get { return String.Format("{0}\\my-template.ini", HomeDir); }
- }
-
- public static string TempManifest
- {
- get { return String.Format("{0}\\new_products.xml", HomeDir);}
- }
-
- public static bool IsDefault
- {
- get { return isDefault; }
- }
-
- #endregion
-
- public static void Save()
- {
- XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
- TextWriter w = new StreamWriter(ConfigFile);
- s.Serialize(w, Instance);
- w.Close();
- }
-
- public static void Load()
- {
- if (HomeDir == null || HomeDir == String.Empty)
- HomeDir = String.Format("{0}\\MySQL\\MySQL Universal Installer",
- Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
-
- if (!Directory.Exists(HomeDir))
- Directory.CreateDirectory(HomeDir);
-
- if (File.Exists(ConfigFile))
- {
- XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
- TextReader r = new StreamReader(ConfigFile);
- Instance = (InstallerConfigurationData)s.Deserialize(r);
- isDefault = false;
- }
- else
- {
- Instance.LicenseAgreement = 1;
- Instance.UpdateCheckFrequency = 7;
- // XXX: is this a constant GUID or rather dynamically created?
- Instance.ProductCode = "{303BA173-69F6-4DC3-B11B-96B104C45BF9}";
- }
-
- // Consider incomplete/corrupt/non-existing config file.
- // Set useful defaults for important values.
- if (Instance.UpdateURLs.Count == 0)
- {
- UpdateURL url = new UpdateURL("http://wb.mysql.com/installer/products.xml");
- Instance.UpdateURLs.Add(url);
- }
-
- Instance.UpdateTimeoutMilliseconds = 10000;
-
- // Product cache and installation root defaults and sanity checks.
- if (Instance.ProductCachePath == null || Instance.ProductCachePath == String.Empty)
- Instance.ProductCachePath = Path.Combine(HomeDir, @"Product Cache\");
- if (!Instance.ProductCachePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
- Instance.ProductCachePath += Path.DirectorySeparatorChar;
- if (!Directory.Exists(Instance.ProductCachePath))
- Directory.CreateDirectory(Instance.ProductCachePath);
-
- if (Instance.InstallationRoot == null || Instance.InstallationRoot == String.Empty)
- Instance.InstallationRoot = Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
- @"MySQL\MySQL Universal Installer\");
- if (!Instance.InstallationRoot.EndsWith(Path.DirectorySeparatorChar.ToString()))
- Instance.InstallationRoot += Path.DirectorySeparatorChar;
- }
-
- public static bool IsWow64()
- {
- bool isWow64 = false;
-
- Win32.IsWow64Process(Process.GetCurrentProcess().Handle, out isWow64);
-
- return isWow64;
- }
- }
-
- [XmlRoot("Configuration")]
- public class InstallerConfigurationData
- {
- public List<UpdateURL> UpdateURLs { get; set; }
- public int UpdateTimeoutMilliseconds { get; set; }
- public int UpdateCheckFrequency { get; set; }
- public string ProductCachePath { get; set; }
- public string InstallationRoot { get; set; }
- public int LicenseAgreement { get; set; }
- public Point Location { get; set; }
- public string ProductCode { get; set; }
- }
-
- public class UpdateURL
- {
- public UpdateURL()
- {
- URL = "";
- }
-
- public UpdateURL(string url)
- {
- URL = url;
- }
- public string URL { get; set; }
- }
+ public sealed class InstallerConfiguration
+ {
+ private static InstallerConfigurationData instance = new InstallerConfigurationData();
+ private static WebClient webClient = new WebClient();
+
+ // Indicates if this configuration was loaded from file or is just a default config.
+ private static bool isDefault = true;
+
+ #region Properties
+
+ public static bool DisplayLicenseAgreement
+ {
+ get { return instance.LicenseAgreement > 0; }
+ set { if (value) instance.LicenseAgreement = 1; else instance.LicenseAgreement = 0; }
+ }
+
+ public static Point Location
+ {
+ get { return instance.Location; }
+ set { instance.Location = value; }
+ }
+
+ public static string ProposedInstallationPath { get; set; }
+
+ public static string HomeDir { get; set; }
+
+ public static bool NewInstall
+ {
+ get { return true; }
+ }
+
+ public static List<UpdateURL> UpdateURLs
+ {
+ get { return instance.UpdateURLs; }
+ set { instance.UpdateURLs = value; }
+ }
+
+ public static int UpdateTimeoutMilliseconds
+ {
+ get { return instance.UpdateTimeoutMilliseconds; }
+ set { instance.UpdateTimeoutMilliseconds = value; }
+ }
+
+ public static int UpdateCheckFrequency
+ {
+ get { return instance.UpdateCheckFrequency; }
+ set { instance.UpdateCheckFrequency = value; }
+ }
+
+ public static string ProductCachePath
+ {
+ get { return instance.ProductCachePath; }
+ set { instance.ProductCachePath = value; }
+ }
+
+ public static string InstallationRoot
+ {
+ get { return instance.InstallationRoot; }
+ set { instance.InstallationRoot = value; }
+ }
+
+ public static string ProductCode
+ {
+ get { return instance.ProductCode; }
+ set { instance.ProductCode = value; }
+ }
+
+ private static string ConfigFile
+ {
+ get { return String.Format("{0}\\config.xml", HomeDir); }
+ }
+
+ public static string ProductsManifest
+ {
+ get { return String.Format("{0}\\products.xml", HomeDir); }
+ }
+
+ public static string TempProductsManifest
+ {
+ get { return String.Format("{0}\\products.xml.temp", HomeDir); }
+ }
+
+ public static string TemplateName
+ {
+ get { return String.Format("{0}\\my-template.ini", HomeDir); }
+ }
+
+ public static string TempManifest
+ {
+ get { return String.Format("{0}\\new_products.xml", HomeDir);}
+ }
+
+ public static bool IsDefault
+ {
+ get { return isDefault; }
+ }
+
+ public static string ActiveCatalog
+ {
+ get { return instance.ActiveCatalog; }
+ set { instance.ActiveCatalog = value; }
+ }
+ #endregion
+
+ public static void Save()
+ {
+ XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
+ TextWriter w = new StreamWriter(ConfigFile);
+ s.Serialize(w, instance);
+ w.Close();
+ }
+
+ public static void Load()
+ {
+ Logger.LogInformation("Loading configuration.");
+
+ if (HomeDir == null || HomeDir == String.Empty)
+ HomeDir = String.Format("{0}\\MySQL\\MySQL Universal Installer",
+ Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
+
+ if (!Directory.Exists(HomeDir))
+ Directory.CreateDirectory(HomeDir);
+
+ if (File.Exists(ConfigFile))
+ {
+ Logger.LogInformation("Configuration file found.");
+ XmlSerializer s = new XmlSerializer(typeof(InstallerConfigurationData));
+ TextReader r = new StreamReader(ConfigFile);
+ instance = (InstallerConfigurationData)s.Deserialize(r);
+ isDefault = false;
+ }
+ else
+ {
+ instance.LicenseAgreement = 1;
+ instance.UpdateCheckFrequency = 7;
+ // XXX: is this a constant GUID or rather dynamically created?
+ instance.ProductCode = "{303BA173-69F6-4DC3-B11B-96B104C45BF9}";
+ }
+
+ // Consider incomplete/corrupt/non-existing config file.
+ // Set useful defaults for important values.
+ if (instance.UpdateURLs.Count == 0)
+ {
+ UpdateURL url = new UpdateURL("http://wb.mysql.com/installer/products.xml");
+ instance.UpdateURLs.Add(url);
+ }
+
+ Logger.LogInformation("Configuration sanity checks and default values.");
+ instance.UpdateTimeoutMilliseconds = 10000;
+
+ // Product cache and installation root defaults and sanity checks.
+ if (string.IsNullOrEmpty(instance.ProductCachePath))
+ instance.ProductCachePath = Path.Combine(HomeDir, @"Product Cache\");
+ if (!instance.ProductCachePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
+ instance.ProductCachePath += Path.DirectorySeparatorChar;
+ if (!Directory.Exists(instance.ProductCachePath))
+ Directory.CreateDirectory(instance.ProductCachePath);
+
+ if (string.IsNullOrEmpty(instance.InstallationRoot))
+ instance.InstallationRoot = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
+ @"MySQL\MySQL Universal Installer\");
+ if (!instance.InstallationRoot.EndsWith(Path.DirectorySeparatorChar.ToString()))
+ instance.InstallationRoot += Path.DirectorySeparatorChar;
+ }
+ }
+
+ [XmlRoot("Configuration")]
+ public class InstallerConfigurationData
+ {
+ public List<UpdateURL> UpdateURLs { get; set; }
+ public int UpdateTimeoutMilliseconds { get; set; }
+ public int UpdateCheckFrequency { get; set; }
+ public string ProductCachePath { get; set; }
+ public string InstallationRoot { get; set; }
+ public int LicenseAgreement { get; set; }
+ public Point Location { get; set; }
+ public string ProductCode { get; set; }
+ public string ActiveCatalog { get; set; }
+ }
+
+ public class UpdateURL
+ {
+ public UpdateURL()
+ {
+ URL = "";
+ }
+
+ public UpdateURL(string url)
+ {
+ URL = url;
+ }
+ public string URL { get; set; }
+ }
}
=== modified file 'WexInstaller.Core/Package.cs'
--- a/WexInstaller.Core/Package.cs 2011-02-08 21:28:42 +0000
+++ b/WexInstaller.Core/Package.cs 2011-03-18 10:29:04 +0000
@@ -1,16 +1,16 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using Microsoft.Win32;
-using System.Diagnostics;
namespace WexInstaller.Core
{
public class Package
{
- private string PackageCode;
+ private string packageCode;
private FileVersionInfo msiVersion;
[XmlAttribute("type")]
@@ -25,8 +25,8 @@
[XmlAttribute("id")]
public string Id
{
- get { return PackageCode; }
- set { PackageCode = value; UpdateOptionalParameters(); }
+ get { return packageCode; }
+ set { packageCode = value; UpdateOptionalParameters(); }
}
[XmlAttribute("thisVersion")]
=== modified file 'WexInstaller.Core/Product.cs'
--- a/WexInstaller.Core/Product.cs 2011-03-17 15:51:58 +0000
+++ b/WexInstaller.Core/Product.cs 2011-03-18 10:29:04 +0000
@@ -59,9 +59,39 @@
public List<Package> Packages { get; set; }
+ public PackageArchitecture Architecture
+ {
+ get { return GetPackage().Architecture; }
+ }
+
public string TitleWithVersion
{
- get { return String.Format("{0} {1}", Title, GetPackage().ThisVersion); }
+ get
+ {
+#if DEBUG
+ return TitleWithVersionAndArchitecture;
+#else
+ return String.Format("{0} {1}", Title, GetPackage().ThisVersion);
+#endif
+ }
+ }
+
+ public string TitleWithVersionAndArchitecture
+ {
+ get
+ {
+ string architecture = "";
+ switch (GetPackage().Architecture)
+ {
+ case PackageArchitecture.X86:
+ architecture = " (32-Bit)";
+ break;
+ case PackageArchitecture.X64:
+ architecture = " (64-Bit)";
+ break;
+ }
+ return String.Format("{0} {1}{2}", Title, GetPackage().ThisVersion, architecture);
+ }
}
public ProductConfigurationController Controller
=== modified file 'WexInstaller.Core/ProductCatalog.cs'
--- a/WexInstaller.Core/ProductCatalog.cs 2011-02-08 21:28:42 +0000
+++ b/WexInstaller.Core/ProductCatalog.cs 2011-03-18 10:29:04 +0000
@@ -1,69 +1,135 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Collections.Generic;
using System.Xml.Serialization;
-using System.Runtime.Serialization;
namespace WexInstaller.Core
{
- public class ProductCatalog
- {
- [XmlAttribute("id")]
- public string Id;
- [XmlAttribute("name")]
- public string Name;
- [XmlAttribute("description")]
- public string Description;
- [XmlAttribute("commercial")]
- public bool Commercial;
- [XmlAttribute("default")]
- public bool Default;
- [XmlArray("SetupTypes")]
- public List<SetupType> SetupTypes;
- [XmlArray("CatalogProducts")]
- public List<CatalogProduct> Products;
- }
-
- public class CatalogProduct
- {
- [XmlIgnore]
- public Product ReferencedProduct;
-
- [XmlAttribute("productId")]
- public string ProductId;
-
- [XmlAttribute("setupTypeFlags")]
- public int SetupTypeFlag;
- }
-
- public enum SetupTypeFlag : int
- {
- Full=64,
- Custom=128
- }
-
- public class SetupType
- {
- [XmlAttribute("flag")]
- public int Flag;
- [XmlAttribute("name")]
- public string Name;
- [XmlAttribute("description")]
- public string Description;
-
- public bool IsFull
- {
- get { return Flag == (int)SetupTypeFlag.Full; }
- }
-
- public bool IsCustom
- {
- get { return Flag == (int)SetupTypeFlag.Custom; }
- }
-
- public bool Includes(CatalogProduct product)
- {
- return IsFull || ((product.SetupTypeFlag & Flag) != 0);
- }
- }
+ /// <summary>
+ /// Represents the architecture type of the contained products.
+ /// </summary>
+ public enum CatalogArchitecture
+ {
+ Unknown,
+ X86,
+ X64,
+ Any,
+ Mixed
+ }
+
+ public class ProductCatalog
+ {
+ [XmlAttribute("id")]
+ public string Id;
+ [XmlAttribute("name")]
+ public string Name;
+ [XmlAttribute("description")]
+ public string Description;
+ [XmlAttribute("commercial")]
+ public bool Commercial;
+ [XmlAttribute("default")]
+ public bool Default;
+ [XmlArray("SetupTypes")]
+ public List<SetupType> SetupTypes;
+ [XmlArray("CatalogProducts")]
+ public List<CatalogProduct> Products;
+
+ private CatalogArchitecture architecture = CatalogArchitecture.Unknown;
+ [XmlIgnore]
+ public CatalogArchitecture Architecture
+ {
+ get
+ {
+ if (architecture == CatalogArchitecture.Unknown && Products.Count > 0)
+ {
+ foreach (CatalogProduct product in Products)
+ {
+ CatalogArchitecture currentArchitecture = CatalogArchitecture.Unknown;
+ switch (product.ReferencedProduct.Architecture)
+ {
+ case PackageArchitecture.X86:
+ currentArchitecture = CatalogArchitecture.X86;
+ break;
+ case PackageArchitecture.X64:
+ currentArchitecture = CatalogArchitecture.X64;
+ break;
+ case PackageArchitecture.Any:
+ currentArchitecture = CatalogArchitecture.Any;
+ break;
+ }
+
+ if (architecture == CatalogArchitecture.Unknown)
+ architecture = currentArchitecture;
+ else
+ if (architecture != currentArchitecture)
+ {
+ architecture = CatalogArchitecture.Mixed;
+ break;
+ }
+ }
+ }
+
+ return architecture;
+ }
+ }
+
+ /// <summary>
+ /// Determines if any of the contained products requires a 64 bit architecture.
+ /// This does not include those with "Any" set. This does not *require* a 64 bit arch.
+ /// </summary>
+ public bool Requires64BitArchitecture
+ {
+ get
+ {
+ if (architecture == CatalogArchitecture.X64)
+ return true;
+ foreach (CatalogProduct product in Products)
+ if (product.ReferencedProduct.Architecture == PackageArchitecture.X64)
+ return true;
+
+ return false;
+ }
+ }
+ }
+
+ public class CatalogProduct
+ {
+ [XmlIgnore]
+ public Product ReferencedProduct;
+
+ [XmlAttribute("productId")]
+ public string ProductId;
+
+ [XmlAttribute("setupTypeFlags")]
+ public int SetupTypeFlag;
+ }
+
+ public enum SetupTypeFlag : int
+ {
+ Full=64,
+ Custom=128
+ }
+
+ public class SetupType
+ {
+ [XmlAttribute("flag")]
+ public int Flag;
+ [XmlAttribute("name")]
+ public string Name;
+ [XmlAttribute("description")]
+ public string Description;
+
+ public bool IsFull
+ {
+ get { return Flag == (int)SetupTypeFlag.Full; }
+ }
+
+ public bool IsCustom
+ {
+ get { return Flag == (int)SetupTypeFlag.Custom; }
+ }
+
+ public bool Includes(CatalogProduct product)
+ {
+ return IsFull || ((product.SetupTypeFlag & Flag) != 0);
+ }
+ }
}
=== modified file 'WexInstaller.Core/ProductFeature.cs'
--- a/WexInstaller.Core/ProductFeature.cs 2011-03-03 15:21:07 +0000
+++ b/WexInstaller.Core/ProductFeature.cs 2011-03-18 10:29:04 +0000
@@ -26,11 +26,11 @@
[XmlIgnore]
public Image LargeIcon
{
- get
- {
- EnsureIconsAreLoaded();
- return largeIcon;
- }
+ get
+ {
+ EnsureIconsAreLoaded();
+ return largeIcon;
+ }
}
[XmlIgnore]
@@ -106,76 +106,77 @@
[XmlIgnore]
public bool ProposedInstalled
{
- get { return proposedInstalled; }
- set { SetProposedInstalled(value); }
+ get { return proposedInstalled; }
+ set { SetProposedInstalled(value); }
}
[XmlIgnore]
public int FeatureCount
{
- get
+ get
+ {
+ int count = 0;
+ foreach (ProductFeature f in Features)
{
- int count = 0;
- foreach (ProductFeature f in Features)
- {
- count++;
- count += f.FeatureCount;
- }
- return count;
+ count++;
+ count += f.FeatureCount;
}
+ return count;
+ }
}
public ProductFeature()
{
- Features = new List<ProductFeature>();
+ Features = new List<ProductFeature>();
}
protected virtual void SetProposedInstalled(bool shouldInstall)
{
- if (shouldInstall == proposedInstalled) return;
- proposedInstalled = shouldInstall;
- foreach (ProductFeature f in Features)
- {
- f.ProposedInstalled = shouldInstall;
- }
+ if (shouldInstall == proposedInstalled)
+ return;
+ proposedInstalled = shouldInstall;
+ foreach (ProductFeature f in Features)
+ f.ProposedInstalled = shouldInstall;
}
public bool HasChanges()
{
- bool hasChanges;
- hasChanges = Installed != ProposedInstalled;
- foreach (ProductFeature feature in Features)
- hasChanges |= feature.HasChanges();
- return hasChanges;
+ bool hasChanges;
+ hasChanges = Installed != ProposedInstalled;
+ foreach (ProductFeature feature in Features)
+ hasChanges |= feature.HasChanges();
+ return hasChanges;
}
internal void ProcessFeatures(List<ProductFeature> toAdd, List<ProductFeature> toRemove)
{
- foreach (ProductFeature f in Features)
+ foreach (ProductFeature f in Features)
+ {
+ if (f.Installed != f.ProposedInstalled)
{
- if (f.Installed != f.ProposedInstalled)
- {
- if (!f.Installed) toAdd.Add(f);
- else toRemove.Add(f);
- }
- f.ProcessFeatures(toAdd, toRemove);
+ if (!f.Installed)
+ toAdd.Add(f);
+ else
+ toRemove.Add(f);
}
+ f.ProcessFeatures(toAdd, toRemove);
+ }
}
public virtual long GetInstallationSizeEstimate()
{
- long sizeEst = 0;
- foreach (ProductFeature f in Features)
- sizeEst += f.SizeEstimate;
- sizeEst += SizeEstimate;
- return sizeEst;
+ long sizeEst = 0;
+ foreach (ProductFeature f in Features)
+ sizeEst += f.SizeEstimate;
+ sizeEst += SizeEstimate;
+ return sizeEst;
}
public override void SetParent(ProductElement parent)
{
- base.SetParent(parent);
- foreach (ProductFeature f in Features)
- f.SetParent(this);
+ base.SetParent(parent);
+ foreach (ProductFeature f in Features)
+ f.SetParent(this);
}
}
}
=== modified file 'WexInstaller.Core/ProductManager.cs'
--- a/WexInstaller.Core/ProductManager.cs 2011-03-10 03:08:26 +0000
+++ b/WexInstaller.Core/ProductManager.cs 2011-03-18 10:29:04 +0000
@@ -6,6 +6,8 @@
using System.Threading;
using System.Xml.Serialization;
+using MySQL.Utilities.SysUtils;
+
namespace WexInstaller.Core
{
public delegate void DownloadManifestProgressHandler(object sender, DownloadProgressChangedEventArgs de);
@@ -30,8 +32,21 @@
private static bool CatalogProductsUpgrade { get; set; }
public static bool ProductsInstalled { get; private set; }
public static bool ProductsUpgrade { get; private set; }
- public static ProductCatalog ActiveCatalog { get; set; }
- public static string DefaultCatalog { get; set; }
+ public static ProductCatalog DefaultCatalog { get; set; }
+
+ private static ProductCatalog activeCatalog = null;
+ public static ProductCatalog ActiveCatalog
+ {
+ get { return activeCatalog; }
+ set
+ {
+ activeCatalog = value;
+ if (value != null)
+ InstallerConfiguration.ActiveCatalog = value.Id;
+ else
+ InstallerConfiguration.ActiveCatalog = null;
+ }
+ }
private static ProductManifest ObjectifyManifest(string fileName)
{
@@ -93,22 +108,65 @@
throw new InvalidOperationException();
}
- // Default to first catalog and then see if we have a catalog file
- // that gives us a different default
- string defaultCatalog = GetDefaultCatalogIfAny();
- ActiveCatalog = null;
- if (defaultCatalog != null)
- {
- foreach (ProductCatalog cat in manifest.ProductCatalogs)
- if (cat.Id == defaultCatalog)
- {
- ActiveCatalog = cat;
- break;
- }
- }
+ // Set a good active catalog. Use either what was active last, is given on the command line
+ // or pick a good default. Consider OS architecture when determining an own default.
+ string givenCatalogId = null;
+ string[] args = Environment.GetCommandLineArgs();
+ if (args.Length > 1)
+ {
+ Logger.LogInformation(string.Format("Using default catalog from command line {0}.", args[1]));
+ givenCatalogId = args[1]; // This should be the default catalog name (not id).
+ }
+
+ // If no default catalog is given then use the one stored in the settings.
+ if (givenCatalogId == null)
+ givenCatalogId = InstallerConfiguration.ActiveCatalog;
+
+ DefaultCatalog = null;
+ if (givenCatalogId != null)
+ {
+ foreach (ProductCatalog catalog in manifest.ProductCatalogs)
+ if (catalog.Id == givenCatalogId)
+ {
+ DefaultCatalog = catalog;
+ break;
+ }
+ }
+
+ // Sanity check: see if the default is for a 64 bit OS but we are only on 32 bit.
+ bool is64Bit = Win32.Is64BitOS();
+ if (DefaultCatalog != null && DefaultCatalog.Requires64BitArchitecture && !is64Bit)
+ {
+ Logger.LogInformation("Invalid default catalog architecture given. Switching to 32 bit.");
+
+ // Change the default catalog to the 32 bit version.
+ foreach (ProductCatalog catalog in manifest.ProductCatalogs)
+ if (catalog.Name == DefaultCatalog.Name && !catalog.Requires64BitArchitecture)
+ {
+ DefaultCatalog = catalog;
+ break;
+ }
+ }
+
+ if (DefaultCatalog == null)
+ {
+ // If there was no catalog given (or none found/stored) use the first catalog from the manifest
+ // which corresponds to our current OS architecture.
+ foreach (ProductCatalog catalog in manifest.ProductCatalogs)
+ if (catalog.Requires64BitArchitecture == is64Bit)
+ {
+ DefaultCatalog = catalog;
+ break;
+ }
+ }
+
+ // The default catalog is also the initial active catalog. If there was a stored catalog
+ // then it is already used for the default catalog (if no other was given on the command line).
+ ActiveCatalog = DefaultCatalog;
+
if (ActiveCatalog != null)
{
- // setup the Installed and IsUpgrade global variables based
+ // Setup the Installed and IsUpgrade global variables based
// on what from the active catalog is installed.
foreach (CatalogProduct cp in ActiveCatalog.Products)
{
@@ -116,6 +174,8 @@
CatalogProductsUpgrade |= cp.ReferencedProduct.IsUpgrade;
}
}
+ else
+ Logger.LogError("Could not set a default catalog.");
}
public static bool IsNewSetup()
@@ -138,18 +198,6 @@
}
}
- private static string GetDefaultCatalogIfAny()
- {
- // if ActiveCatalog != null, then this isn't the the first
- // time we have run so we always use default in that case
- if (ActiveCatalog != null)
- return null;
- string[] args = Environment.GetCommandLineArgs();
- if (args.Length < 2)
- return null;
- return args[1]; // this should be the default catalog name
- }
-
private static void LoadManifestWithCheckForTemp()
{
// first we need to see if there is any temp manifest file to check
=== modified file 'WexInstaller.Core/WexInstaller.Core.csproj'
--- a/WexInstaller.Core/WexInstaller.Core.csproj 2011-03-03 15:21:07 +0000
+++ b/WexInstaller.Core/WexInstaller.Core.csproj 2011-03-18 10:29:04 +0000
@@ -37,6 +37,7 @@
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
+ <Reference Include="System.Management" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
=== modified file 'WexInstaller.Core/Win32.cs'
--- a/WexInstaller.Core/Win32.cs 2011-03-10 15:47:49 +0000
+++ b/WexInstaller.Core/Win32.cs 2011-03-18 10:29:04 +0000
@@ -5,6 +5,7 @@
using System.Diagnostics;
using Microsoft.Win32.SafeHandles;
using System.Drawing;
+using System.Management;
namespace MySQL.Utilities.SysUtils
{
@@ -3092,6 +3093,27 @@
}
}
+ /// <summary>
+ /// Determines if we are currently running on a 64 Bit OS.
+ /// </summary>
+ public static bool Is64BitOS()
+ {
+ ManagementObjectSearcher searcher =
+ new ManagementObjectSearcher("root\\CIMV2", "select * from Win32_OperatingSystem");
+ foreach (ManagementObject wmi in searcher.Get())
+ {
+ // There is only one object in the returned result set (as we are on one OS only)
+ // though the principles of working with WMI dictate the handling we need here.
+ var architecture = wmi.GetPropertyValue("OSArchitecture");
+ if (architecture == null)
+ return false; // Not available before Vista/Win 2008,
+
+ return "64-bit".Equals(architecture);
+ }
+
+ return false;
+ }
+
#endregion
#region Console handling
=== modified file 'WexInstaller/Controls/FeatureBox.cs'
--- a/WexInstaller/Controls/FeatureBox.cs 2011-03-03 15:21:07 +0000
+++ b/WexInstaller/Controls/FeatureBox.cs 2011-03-18 10:29:04 +0000
@@ -1,178 +1,290 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Drawing;
-using System.Text;
using System.Windows.Forms;
+using System.Windows.Forms.VisualStyles;
+
using WexInstaller.Core;
-using System.Windows.Forms.VisualStyles;
namespace WexInstaller.Controls
{
- public partial class FeatureBox : UserControl
- {
- private const int HEADER_HEIGHT = 44;
-
- private ProductElement selectedObject;
- private Font largeFont;
- private Font smallFont;
- private Size CBGlyphSize;
-
- public FeatureBox()
- {
- InitializeComponent();
- largeFont = new Font(Font, FontStyle.Bold);
- smallFont = new Font(Font.FontFamily, (float)(Font.SizeInPoints * .85));
- }
-
- internal FeatureTreeView FeatureTree { get; set; }
-
- public ProductElement SelectedObject
- {
- get { return selectedObject; }
- set
- {
- selectedObject = value;
- UpdateFeatureList();
- Invalidate(ClientRectangle);
- }
- }
-
- private void UpdateFeatureList()
- {
- featureList.Nodes.Clear();
- if (SelectedObject == null) return;
-
- if (SelectedObject is Product)
- PopulateProduct();
- else
- PopulateProductCategory();
- }
-
- private void PopulateProduct()
- {
- Product p = SelectedObject as Product;
- List<ProductFeature> productFeatures = p.GetProductFeatures();
-
- foreach (ProductFeature feature in productFeatures)
- {
- if (feature.Display != "0")
- {
- if (feature.HasComponents != null && feature.HasComponents.Length > 0)
- {
- TreeNode node = featureList.Nodes.Add(feature.Title);
- node.Tag = feature;
- }
-
- foreach (ProductFeature childFeature in feature.Features)
- {
- if (childFeature.Display != "0")
- {
- if (childFeature.HasComponents.Length > 0)
- {
- TreeNode node = featureList.Nodes.Add(childFeature.Title);
- node.Tag = childFeature;
- }
- }
- }
- }
- }
- }
-
- private void PopulateProductCategory()
- {
- ProductCategory pc = SelectedObject as ProductCategory;
- if (pc != null)
- {
- foreach (Product p in pc.Products)
- {
- TreeNode node = featureList.Nodes.Add(p.TitleWithVersion);
- node.Tag = p;
- }
- }
- }
-
- protected override void OnPaint(PaintEventArgs e)
- {
- base.OnPaint(e);
-
- if (e.ClipRectangle.Top < HEADER_HEIGHT)
- PaintHeader(e.Graphics);
- }
-
- private void PaintHeader(Graphics g)
- {
- Brush grayBrush = new SolidBrush(Color.LightGray);
- Brush whiteBrush = new SolidBrush(Color.White);
- Brush blackBrush = new SolidBrush(Color.Black);
-
- g.FillRectangle(grayBrush, 0, 0, Width, HEADER_HEIGHT);
-
- if (SelectedObject == null) return;
+ public partial class FeatureBox : UserControl
+ {
+ #region Members and constants
+
+ private const int HEADER_HEIGHT = 44;
+
+ private ProductElement selectedObject;
+ private Font largeFont;
+ private Font smallFont;
+ private Size CBGlyphSize;
+
+ #endregion
+
+ #region Construction and setup
+
+ public FeatureBox()
+ {
+ InitializeComponent();
+ largeFont = new Font(Font, FontStyle.Bold);
+ smallFont = new Font(Font.FontFamily, (float)(Font.SizeInPoints * .85));
+ }
+
+ #endregion
+
+ #region Properties
+
+ internal FeatureTreeView FeatureTree { get; set; }
+
+ public ProductElement SelectedObject
+ {
+ get { return selectedObject; }
+ set
+ {
+ selectedObject = value;
+ UpdateFeatureList();
+ Invalidate(ClientRectangle);
+ }
+ }
+
+ public ProductCatalog Catalog { get; set; }
+
+ // These two are mutually exclusive, so an enum seems a good alternative.
+ // Having two bools makes handling a lot simpler, however.
+ public bool ListAllItems { get; set; }
+ public bool ListInstalledItems { get; set; }
+
+ #endregion
+
+ #region Application logic
+
+ private void UpdateFeatureList()
+ {
+ featureList.Nodes.Clear();
+ if (SelectedObject == null)
+ return;
+
+ if (SelectedObject is Product)
+ PopulateProduct();
+ else
+ PopulateProductCategory();
+ }
+
+ private void PopulateProduct()
+ {
+ Product p = SelectedObject as Product;
+ List<ProductFeature> productFeatures = p.GetProductFeatures();
+
+ foreach (ProductFeature feature in productFeatures)
+ {
+ if (feature.Display != "0")
+ {
+ if (feature.HasComponents != null && feature.HasComponents.Length > 0)
+ {
+ TreeNode node = featureList.Nodes.Add(feature.Title);
+ node.Tag = feature;
+ }
+
+ foreach (ProductFeature childFeature in feature.Features)
+ {
+ if (childFeature.Display != "0")
+ {
+ if (childFeature.HasComponents.Length > 0)
+ {
+ TreeNode node = featureList.Nodes.Add(childFeature.Title);
+ node.Tag = childFeature;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void PopulateProductCategory()
+ {
+ ProductCategory category = SelectedObject as ProductCategory;
+ if (category == null)
+ return;
+
+ bool showArchitecture = (FeatureTree.Architecture == CatalogArchitecture.Any);
+ List<Product> products = GetProducts(category);
+ foreach (Product product in products)
+ {
+ TreeNode node = featureList.Nodes.Add(
+ showArchitecture ? product.TitleWithVersionAndArchitecture : product.TitleWithVersion);
+ node.Tag = product;
+ }
+ }
+
+ /// <summary>
+ /// Returns a list of products which match the current criteria.
+ /// </summary>
+ /// <param name="category">Return only products which are part of this category.</param>
+ /// <returns>A list of products as specified by the parameters.</returns>
+ public List<Product> GetProducts(ProductCategory category)
+ {
+ List<Product> result = new List<Product>();
+
+ bool anyArchitecture = (FeatureTree.Architecture == CatalogArchitecture.Any);
+ PackageArchitecture packageArchitecture;
+ switch (FeatureTree.Architecture)
+ {
+ case CatalogArchitecture.X86:
+ packageArchitecture = PackageArchitecture.X86;
+ break;
+ case CatalogArchitecture.X64:
+ packageArchitecture = PackageArchitecture.X64;
+ break;
+ default:
+ packageArchitecture = PackageArchitecture.Any;
+ break;
+ }
+ if (ListAllItems || ListInstalledItems)
+ {
+ // List of products independent on a specific catalog. Just filter by architecture.
+ Dictionary<string, Product> products = new Dictionary<string, Product>();
+ foreach (Product p in category.Products)
+ {
+ bool architectureDoesNotMatter = anyArchitecture || p.Architecture == PackageArchitecture.Any;
+ if (architectureDoesNotMatter || p.Architecture == packageArchitecture)
+ {
+ if ((ListAllItems || p.Installed) && !products.ContainsKey(p.Name))
+ products[p.Name] = p;
+ }
+ }
+
+ result.AddRange(products.Values);
+ }
+ else
+ {
+ // Add products based on the products list in the given catalog.
+ // This catalog serves as base for the product list and might not represent the user's
+ // architecture choice. Additionally we need to consider several catalogs if Any is given
+ // as architecture.
+ List<ProductCatalog> catalogList = new List<ProductCatalog>();
+ bool needs64Bit = (packageArchitecture == PackageArchitecture.X64);
+ foreach (ProductCatalog candidate in ProductManager.Catalogs)
+ {
+ // Compare name first. Only catalogs with the same name participate here.
+ if (candidate.Name.Equals(Catalog.Name, StringComparison.InvariantCultureIgnoreCase))
+ {
+ if (anyArchitecture || candidate.Requires64BitArchitecture == needs64Bit)
+ catalogList.Add(candidate);
+ }
+ }
+
+ // No iterate over all categories and their products and see if any of the products matches
+ // any of the products in the reference catalog(s).
+ Dictionary<string, Product> products = new Dictionary<string, Product>();
+ foreach (Product p in category.Products)
+ {
+ foreach (ProductCatalog currentCatalog in catalogList)
+ foreach (CatalogProduct cp in currentCatalog.Products)
+ if (cp.ProductId.Equals(p.Name, StringComparison.InvariantCultureIgnoreCase) &&
+ !products.ContainsKey(p.Name))
+ products[p.Name] = p;
+ }
+ result.AddRange(products.Values);
+ }
+
+ return result;
+ }
+
+ #endregion
+
+ #region Drawing
+
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ base.OnPaint(e);
+
+ if (e.ClipRectangle.Top < HEADER_HEIGHT)
+ PaintHeader(e.Graphics);
+ }
+
+ private void PaintHeader(Graphics g)
+ {
+ Brush whiteBrush = new SolidBrush(Color.White);
+ Brush blackBrush = new SolidBrush(Color.Black);
+
+ using (Brush grayBrush = new SolidBrush(Color.LightGray))
+ g.FillRectangle(grayBrush, 0, 0, Width, HEADER_HEIGHT);
+
+ if (SelectedObject == null)
+ return;
- if (SelectedObject.LargeIcon != null)
- g.DrawImage(SelectedObject.LargeIcon, 6, 6);
-
- Point textPt = new Point(50, 10);
- g.DrawString(SelectedObject.Title, largeFont, whiteBrush, textPt);
- textPt.Offset(-1, -1);
- g.DrawString(SelectedObject.Title, largeFont, blackBrush, textPt);
-
- textPt = new Point(50, 24);
- g.DrawString(SelectedObject.Description, smallFont, blackBrush, textPt);
- }
-
- private void featureList_AfterCheck(object sender, TreeViewEventArgs e)
- {
- Product p = e.Node.Tag as Product;
- if (p != null)
- {
- if (p.Installed) return;
- p.ProposedInstalled = !p.ProposedInstalled;
-
- List<ProductFeature> productFeatures = p.GetProductFeatures();
- foreach (ProductFeature pf in productFeatures)
- pf.ProposedInstalled = p.ProposedInstalled;
- }
- else
- {
- ProductFeature pf = e.Node.Tag as ProductFeature;
- pf.ProposedInstalled = !pf.ProposedInstalled;
- }
- featureList.Refresh();
- if (FeatureTree != null)
- FeatureTree.Refresh();
- }
-
- private void featureList_DrawNode(object sender, DrawTreeNodeEventArgs e)
- {
- if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0) return;
-
- CheckBoxState state = CheckBoxState.UncheckedNormal;
- Product p = (e.Node.Tag as Product);
- if (p != null)
- {
- state = p.Installed ? CheckBoxState.CheckedDisabled :
- p.ProposedInstalled ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
- }
- else
- {
- ProductFeature pf = (e.Node.Tag as ProductFeature);
- if (pf.ProposedInstalled) state = CheckBoxState.CheckedNormal;
- }
-
- if (CBGlyphSize.IsEmpty)
- CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
- Point location = new Point(e.Bounds.Left + CBGlyphSize.Width / 2,
- e.Bounds.Top + ((featureList.ItemHeight - CBGlyphSize.Height) / 2));
- CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
-
- using (Brush blackBrush = new SolidBrush(Color.Black))
- {
- e.Graphics.DrawString(e.Node.Text, featureList.Font, blackBrush,
- e.Bounds.X + (CBGlyphSize.Width*2),
- e.Bounds.Y + ((featureList.ItemHeight - featureList.Font.Height) / 2));
- }
- }
- }
+ if (SelectedObject.LargeIcon != null)
+ g.DrawImage(SelectedObject.LargeIcon, 6, 6);
+
+ Point textPt = new Point(50, 10);
+ g.DrawString(SelectedObject.Title, largeFont, whiteBrush, textPt);
+ textPt.Offset(-1, -1);
+ g.DrawString(SelectedObject.Title, largeFont, blackBrush, textPt);
+
+ textPt = new Point(50, 24);
+ g.DrawString(SelectedObject.Description, smallFont, blackBrush, textPt);
+ }
+
+ #endregion
+
+ #region Event handling
+
+ private void featureList_AfterCheck(object sender, TreeViewEventArgs e)
+ {
+ Product p = e.Node.Tag as Product;
+ if (p != null)
+ {
+ if (p.Installed) return;
+ p.ProposedInstalled = !p.ProposedInstalled;
+
+ List<ProductFeature> productFeatures = p.GetProductFeatures();
+ foreach (ProductFeature pf in productFeatures)
+ pf.ProposedInstalled = p.ProposedInstalled;
+ }
+ else
+ {
+ ProductFeature pf = e.Node.Tag as ProductFeature;
+ pf.ProposedInstalled = !pf.ProposedInstalled;
+ }
+ featureList.Refresh();
+ if (FeatureTree != null)
+ FeatureTree.Refresh();
+ }
+
+ private void featureList_DrawNode(object sender, DrawTreeNodeEventArgs e)
+ {
+ if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0)
+ return;
+
+ CheckBoxState state = CheckBoxState.UncheckedNormal;
+ Product p = (e.Node.Tag as Product);
+ if (p != null)
+ {
+ state = p.Installed ? CheckBoxState.CheckedDisabled :
+ p.ProposedInstalled ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
+ }
+ else
+ {
+ ProductFeature pf = (e.Node.Tag as ProductFeature);
+ if (pf.ProposedInstalled)
+ state = CheckBoxState.CheckedNormal;
+ }
+
+ if (CBGlyphSize.IsEmpty)
+ CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
+ Point location = new Point(e.Bounds.Left + CBGlyphSize.Width / 2,
+ e.Bounds.Top + ((featureList.ItemHeight - CBGlyphSize.Height) / 2));
+ CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
+
+ using (Brush blackBrush = new SolidBrush(Color.Black))
+ {
+ e.Graphics.DrawString(e.Node.Text, featureList.Font, blackBrush,
+ e.Bounds.X + (CBGlyphSize.Width * 2),
+ e.Bounds.Y + ((featureList.ItemHeight - featureList.Font.Height) / 2));
+ }
+ }
+
+ #endregion
+
+ }
}
=== modified file 'WexInstaller/Controls/FeatureTreeView.cs'
--- a/WexInstaller/Controls/FeatureTreeView.cs 2011-03-03 15:21:07 +0000
+++ b/WexInstaller/Controls/FeatureTreeView.cs 2011-03-18 10:29:04 +0000
@@ -1,319 +1,329 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Collections.Generic;
+using System.Drawing;
using System.Windows.Forms;
-using System.Drawing;
using System.Windows.Forms.VisualStyles;
-using System.Drawing.Imaging;
+
+using WexInstaller.Core;
using WexInstaller.Properties;
-using WexInstaller.Core;
-using System.Diagnostics;
namespace WexInstaller.Controls
{
- class FeatureTreeView : TreeView
- {
- private SolidBrush grayBrush { get; set; }
- private SolidBrush blackBrush { get; set; }
- private SolidBrush lightGrayBrush { get; set; }
- private Font titleFont { get; set; }
- private Size CBGlyphSize { get; set; }
- private Size PlusMinusSize { get; set; }
- private int CurrentWidth { get; set; }
-
- public FeatureTreeView()
- : base()
- {
- grayBrush = new SolidBrush(Color.WhiteSmoke);
- blackBrush = new SolidBrush(Color.Black);
- lightGrayBrush = new SolidBrush(Color.Gray);
- titleFont = new Font("Tahoma", 8.25F, FontStyle.Bold);
-
- DrawMode = TreeViewDrawMode.OwnerDrawAll;
- SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
- UpdateStyles();
- }
-
- public TreeNode AddCategory(ProductCategory category)
- {
- TreeNode node = Nodes.Add(category.Title);
- node.ToolTipText = category.Description;
- node.Tag = category;
- return node;
- }
-
- public void AddProduct(Product product, TreeNode parentNode)
- {
- TreeNode node = new TreeNode(product.TitleWithVersion);
- node.ToolTipText = product.Description;
- node.Tag = product;
- if (parentNode == null)
- Nodes.Add(node);
- else
- parentNode.Nodes.Add(node);
- }
-
- protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
- {
- int offset = GetOffset(e.Node);
- Rectangle cbRect = new Rectangle();
- cbRect.Location = new Point(offset+10, e.Node.Bounds.Top + ((ItemHeight - CBGlyphSize.Height) / 2));
- cbRect.Size = CBGlyphSize;
-
- Rectangle plusMinusRect = new Rectangle();
- plusMinusRect.Location = new Point(CurrentWidth - 25,
- e.Node.Bounds.Top + ((ItemHeight - PlusMinusSize.Height) / 2));
- plusMinusRect.Size = PlusMinusSize;
-
- if (cbRect.Contains(e.Location))
- {
- ClickNode(e.Node);
- Refresh();
- }
- else if (plusMinusRect.Contains(e.Location))
- {
- if (e.Node.IsExpanded)
- e.Node.Collapse();
- else
- e.Node.Expand();
- }
- base.OnNodeMouseClick(e);
- }
-
- private void ClickNode(TreeNode node)
- {
- ProductCategory pc = node.Tag as ProductCategory;
- if (pc != null)
- ClickCategoryNode(pc);
- else
- ClickProductNode(node.Tag as Product);
- }
-
- private void ClickCategoryNode(ProductCategory cat)
- {
- foreach (Product p in cat.Products)
- {
- if (!p.Installed)
- p.ProposedInstalled = !p.ProposedInstalled;
-
- List<ProductFeature> productFeatures = p.GetProductFeatures();
- foreach (ProductFeature pf in productFeatures)
- pf.ProposedInstalled = p.ProposedInstalled;
- }
- }
-
- private void ClickProductNode(Product p)
- {
- if (!p.Installed)
- p.ProposedInstalled = !p.ProposedInstalled;
-
- List<ProductFeature> productFeatures = p.GetProductFeatures();
- foreach (ProductFeature pf in productFeatures)
- pf.ProposedInstalled = p.ProposedInstalled;
- }
-
- protected override void OnDrawNode(DrawTreeNodeEventArgs e)
- {
- if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0) return;
-
- CurrentWidth = e.Bounds.Width;
- DrawBackground(e);
-
- Rectangle r = e.Bounds;
- r.Offset(GetOffset(e.Node), 0);
-
- DrawCheckbox(e, r);
- if ((e.Node.Tag as ProductCategory) != null && ((e.Node.Tag as ProductCategory).Products.Count > 0))
- {
- DrawPlusMinus(e, r);
- }
- DrawState(e, r);
- DrawText(e, r);
- }
-
- protected override void OnAfterExpand(TreeViewEventArgs e)
- {
- base.OnAfterExpand(e);
- Invalidate();
- Update();
- }
-
- protected override void OnAfterCollapse(TreeViewEventArgs e)
- {
- base.OnAfterCollapse(e);
- Invalidate();
- Update();
- }
-
- private CheckBoxState GetNodeCheckboxState(TreeNode node)
- {
- Product product = node.Tag as Product;
- if (product !=null)
- return GetStateForProduct(product);
-
- List<ProductFeature> featureList = new List<ProductFeature>();
- ProductCategory pc = node.Tag as ProductCategory;
- foreach (Product p in pc.Products)
- {
- List<ProductFeature> productFeatures = p.GetProductFeatures();
-
- foreach (ProductFeature pf in productFeatures)
- {
- featureList.Add(pf);
- }
- }
- return GetStateFromFeatureList(featureList);
- }
-
- private CheckBoxState GetStateForProduct(Product p)
- {
- List<ProductFeature> productFeatures = p.GetProductFeatures();
- CheckBoxState state = GetStateFromFeatureList(productFeatures);
- if (state == CheckBoxState.CheckedNormal || state == CheckBoxState.MixedNormal)
- {
- if (!p.ProposedInstalled)
- p.ProposedInstalled = true;
- }
- if (p.Installed)
- state = (CheckBoxState)((int)state + 3);
- return state;
- }
-
- private CheckBoxState GetStateFromFeatureList(List<ProductFeature> featureList)
- {
- bool allInstalled = true;
- bool anyInstalled = false;
- foreach (ProductFeature f in featureList)
- {
- allInstalled &= f.ProposedInstalled;
- anyInstalled |= f.ProposedInstalled;
- }
- if (allInstalled) return CheckBoxState.CheckedNormal;
- if (anyInstalled) return CheckBoxState.MixedNormal;
- return CheckBoxState.UncheckedNormal;
- }
-
- private int GetOffset(TreeNode node)
- {
- return node.Level * 15;
- }
-
- private Image GetNodeIcon(TreeNode node)
- {
- while (node != null)
- {
- ProductCategory pc = node.Tag as ProductCategory;
- if (pc != null)
- return pc.SmallIcon;
- Product p = node.Tag as Product;
- if (p.SmallIcon != null)
- return p.SmallIcon;
- node = node.Parent;
- }
- return null;
- }
-
- private void DrawCheckbox(DrawTreeNodeEventArgs e, Rectangle r)
- {
- CheckBoxState state = GetNodeCheckboxState(e.Node);
-
- if (CBGlyphSize.IsEmpty)
- CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
- int offset = (ItemHeight - CBGlyphSize.Height) / 2;
- Point location = new Point(r.Left+10, r.Top + offset);
-
- CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
- }
-
- private void DrawPlusMinus(DrawTreeNodeEventArgs e, Rectangle r)
- {
- Image displayImage = (e.Node.IsExpanded) ? Resources.minus_sign : Resources.plus_sign;
- if (PlusMinusSize.IsEmpty)
- PlusMinusSize = displayImage.Size;
- int top = r.Top + ((ItemHeight - displayImage.Height) / 2);
- int left = r.Left + r.Width - 25;
-
- e.Graphics.DrawImageUnscaled(displayImage, left, top);
- }
-
- private void DrawText(DrawTreeNodeEventArgs e, Rectangle r)
- {
- e.Graphics.DrawString(e.Node.Text, titleFont, blackBrush,
- r.Left + 62,
- r.Top + ((ItemHeight - titleFont.Height) / 2));
- }
-
- private void DrawState(DrawTreeNodeEventArgs e, Rectangle r)
- {
- int top = r.Top;
- int left = r.Left;
-
- Image icon = GetNodeIcon(e.Node);
- if (icon != null)
- e.Graphics.DrawImage(icon, left + 32, top + 6);
-
- //ProductCategory pc = e.Node.Tag as ProductCategory;
- //int index = -1;
- // if (pc == null)
- //{
- // ProductFeature f = e.Node.Tag as ProductFeature;
+ class FeatureTreeView : TreeView
+ {
+ private SolidBrush grayBrush { get; set; }
+ private Size CBGlyphSize { get; set; }
+ private Size PlusMinusSize { get; set; }
+ private int CurrentWidth { get; set; }
+
+ public CatalogArchitecture Architecture { get; set; }
+
+ public FeatureTreeView()
+ : base()
+ {
+ grayBrush = new SolidBrush(Color.WhiteSmoke);
+
+ DrawMode = TreeViewDrawMode.OwnerDrawAll;
+ SetStyle(ControlStyles.DoubleBuffer, true);
+ SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
+ SetStyle(ControlStyles.Opaque, true);
+ SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+ UpdateStyles();
+ }
+
+ public TreeNode AddCategory(ProductCategory category)
+ {
+ TreeNode node = Nodes.Add(category.Title);
+ node.ToolTipText = category.Description;
+ node.Tag = category;
+ return node;
+ }
+
+ /// <summary>
+ /// Adds a new product node to the treeview.
+ /// </summary>
+ /// <param name="product">The product for which the node is to be created.</param>
+ /// <param name="parentNode">The parent of the new node (to collect similar products into one area)</param>
+ public void AddProduct(Product product, TreeNode parentNode)
+ {
+ // If no specific architecture is selected, include the architecture in the caption
+ // to show which product is actually in the list.
+ bool includeArchitecture = (Architecture == CatalogArchitecture.Any);
+ string caption = includeArchitecture ? product.TitleWithVersionAndArchitecture : product.TitleWithVersion;
+ TreeNode node = new TreeNode(caption);
+ node.ToolTipText = product.Description;
+ node.Tag = product;
+ if (parentNode == null)
+ Nodes.Add(node);
+ else
+ parentNode.Nodes.Add(node);
+ }
+
+ protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
+ {
+ int offset = GetOffset(e.Node);
+ Rectangle cbRect = new Rectangle();
+ cbRect.Location = new Point(offset+10, e.Node.Bounds.Top + ((ItemHeight - CBGlyphSize.Height) / 2));
+ cbRect.Size = CBGlyphSize;
+
+ Rectangle plusMinusRect = new Rectangle();
+ plusMinusRect.Location = new Point(CurrentWidth - 25,
+ e.Node.Bounds.Top + ((ItemHeight - PlusMinusSize.Height) / 2));
+ plusMinusRect.Size = PlusMinusSize;
+
+ if (cbRect.Contains(e.Location))
+ ClickNode(e.Node);
+ else if (plusMinusRect.Contains(e.Location))
+ {
+ if (e.Node.IsExpanded)
+ e.Node.Collapse();
+ else
+ e.Node.Expand();
+ }
+ base.OnNodeMouseClick(e);
+ }
+
+ private void ClickNode(TreeNode node)
+ {
+ ProductCategory pc = node.Tag as ProductCategory;
+ if (pc != null)
+ ClickCategoryNode(pc);
+ else
+ ClickProductNode(node.Tag as Product);
+ }
+
+ private void ClickCategoryNode(ProductCategory cat)
+ {
+ foreach (Product p in cat.Products)
+ {
+ if (!p.Installed)
+ p.ProposedInstalled = !p.ProposedInstalled;
+
+ List<ProductFeature> productFeatures = p.GetProductFeatures();
+ foreach (ProductFeature pf in productFeatures)
+ pf.ProposedInstalled = p.ProposedInstalled;
+ }
+ }
+
+ private void ClickProductNode(Product p)
+ {
+ if (!p.Installed)
+ p.ProposedInstalled = !p.ProposedInstalled;
+
+ List<ProductFeature> productFeatures = p.GetProductFeatures();
+ foreach (ProductFeature pf in productFeatures)
+ pf.ProposedInstalled = p.ProposedInstalled;
+ }
+
+ protected override void OnDrawNode(DrawTreeNodeEventArgs e)
+ {
+ e.DrawDefault = false;
+ if (e.Bounds.Width <= 0 || e.Bounds.Height <= 0)
+ return;
+
+ CurrentWidth = e.Bounds.Width;
+ DrawBackground(e);
+
+ Rectangle r = e.Bounds;
+ r.Offset(GetOffset(e.Node), 0);
+
+ DrawCheckbox(e, r);
+ if ((e.Node.Tag as ProductCategory) != null && ((e.Node.Tag as ProductCategory).Products.Count > 0))
+ DrawPlusMinus(e, r);
+ DrawState(e, r);
+ DrawText(e, r);
+ }
+
+ private CheckBoxState GetNodeCheckboxState(TreeNode node)
+ {
+ Product product = node.Tag as Product;
+ if (product !=null)
+ return GetStateForProduct(product);
+
+ List<ProductFeature> featureList = new List<ProductFeature>();
+ ProductCategory pc = node.Tag as ProductCategory;
+ foreach (Product p in pc.Products)
+ {
+ List<ProductFeature> productFeatures = p.GetProductFeatures();
+
+ foreach (ProductFeature pf in productFeatures)
+ featureList.Add(pf);
+ }
+ return GetStateFromFeatureList(featureList);
+ }
+
+ private CheckBoxState GetStateForProduct(Product p)
+ {
+ List<ProductFeature> productFeatures = p.GetProductFeatures();
+ CheckBoxState state = GetStateFromFeatureList(productFeatures);
+ if (state == CheckBoxState.CheckedNormal || state == CheckBoxState.MixedNormal)
+ {
+ if (!p.ProposedInstalled)
+ p.ProposedInstalled = true;
+ }
+ if (p.Installed)
+ state = (CheckBoxState)((int)state + 3);
+ return state;
+ }
+
+ private CheckBoxState GetStateFromFeatureList(List<ProductFeature> featureList)
+ {
+ bool allInstalled = true;
+ bool anyInstalled = false;
+ foreach (ProductFeature f in featureList)
+ {
+ allInstalled &= f.ProposedInstalled;
+ anyInstalled |= f.ProposedInstalled;
+ }
+ if (allInstalled)
+ return CheckBoxState.CheckedNormal;
+ if (anyInstalled)
+ return CheckBoxState.MixedNormal;
+
+ return CheckBoxState.UncheckedNormal;
+ }
+
+ private int GetOffset(TreeNode node)
+ {
+ return node.Level * 15;
+ }
+
+ private Image GetNodeIcon(TreeNode node)
+ {
+ while (node != null)
+ {
+ ProductCategory pc = node.Tag as ProductCategory;
+ if (pc != null)
+ return pc.SmallIcon;
+ Product p = node.Tag as Product;
+ if (p.SmallIcon != null)
+ return p.SmallIcon;
+ node = node.Parent;
+ }
+ return null;
+ }
+
+ private void DrawCheckbox(DrawTreeNodeEventArgs e, Rectangle r)
+ {
+ CheckBoxState state = GetNodeCheckboxState(e.Node);
+
+ if (CBGlyphSize.IsEmpty)
+ CBGlyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
+ int offset = (ItemHeight - CBGlyphSize.Height) / 2;
+ Point location = new Point(r.Left+10, r.Top + offset);
+
+ CheckBoxRenderer.DrawCheckBox(e.Graphics, location, state);
+ }
+
+ private void DrawPlusMinus(DrawTreeNodeEventArgs e, Rectangle r)
+ {
+ Image displayImage = (e.Node.IsExpanded) ? Resources.minus_sign : Resources.plus_sign;
+ if (PlusMinusSize.IsEmpty)
+ PlusMinusSize = displayImage.Size;
+ int top = r.Top + ((ItemHeight - displayImage.Height) / 2);
+ int left = r.Left + r.Width - 25;
+
+ e.Graphics.DrawImageUnscaled(displayImage, left, top);
+ }
+
+ private void DrawText(DrawTreeNodeEventArgs e, Rectangle r)
+ {
+ bool drawActive = ((e.State & TreeNodeStates.Selected) != 0) && Focused;
+ Brush brush = drawActive ? Brushes.White : Brushes.Black;
+
+ Rectangle textBounds = new Rectangle(r.Left + 62, r.Top, r.Width, r.Height);
+ StringFormat format = new StringFormat(StringFormatFlags.NoWrap);
+ format.LineAlignment = StringAlignment.Center;
+ format.Trimming = StringTrimming.EllipsisCharacter;
+ e.Graphics.DrawString(e.Node.Text, Font, brush, textBounds, format);
+ }
+
+ private void DrawState(DrawTreeNodeEventArgs e, Rectangle r)
+ {
+ int top = r.Top;
+ int left = r.Left;
+
+ Image icon = GetNodeIcon(e.Node);
+ if (icon != null)
+ e.Graphics.DrawImage(icon, left + 32, top + 6);
+
+ //ProductCategory pc = e.Node.Tag as ProductCategory;
+ //int index = -1;
+ // if (pc == null)
+ //{
+ // ProductFeature f = e.Node.Tag as ProductFeature;
// if ((!f.Installed && !f.ProposedInstalled))
- // DisableImage(b);
- // if (f.Installed != f.ProposedInstalled)
- // index = f.Installed ? 1 : 0;
- //}
-
- // if (index >= 0)
- // StateImageList.Draw(e.Graphics, left+44, top+20, index);
- }
-
- private void DrawBackground(DrawTreeNodeEventArgs e)
- {
- Color c = BackColor;
- if (e.Node.IsSelected)
- c = Color.LightGray;
-
- using (Brush backBrush = new SolidBrush(c))
- {
- e.Graphics.FillRectangle(backBrush, e.Bounds);
- }
- }
-
- private void PartiallyDisableImage(Bitmap b)
- {
- int width = b.Width;
- for (int y = 0; y < b.Height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- Color c = b.GetPixel(x, y);
- int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
- b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
- }
- width--;
- }
- }
-
- private void DisableImage(Bitmap b)
- {
- for (int y = 0; y < b.Height; y++)
- for (int x = 0; x < b.Width; x++)
- {
- Color c = b.GetPixel(x, y);
- int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
- b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
- }
- }
-
- private void InitializeComponent()
- {
- this.SuspendLayout();
- //
- // FeatureTreeView
- //
- this.Font = new System.Drawing.Font("Tahoma", 8.25F);
- this.ResumeLayout(false);
-
- }
- }
+// DisableImage(b);
+// if (f.Installed != f.ProposedInstalled)
+// index = f.Installed ? 1 : 0;
+ //}
+
+ // if (index >= 0)
+ // StateImageList.Draw(e.Graphics, left+44, top+20, index);
+ }
+
+ /// <summary>
+ /// Draws a custom background.
+ /// </summary>
+ private void DrawBackground(DrawTreeNodeEventArgs e)
+ {
+ Brush brush;
+ if ((e.State & TreeNodeStates.Selected) != 0)
+ {
+ if (Focused)
+ brush = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
+ else
+ brush = new SolidBrush(Color.LightGray);
+ }
+ else
+ brush = new SolidBrush(BackColor);
+
+ e.Graphics.FillRectangle(brush, e.Bounds);
+ brush.Dispose();
+ }
+
+ private void PartiallyDisableImage(Bitmap b)
+ {
+ // TODO: use a color matrix operation for that type of manipulation instead.
+ int width = b.Width;
+ for (int y = 0; y < b.Height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ Color c = b.GetPixel(x, y);
+ int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
+ b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
+ }
+ width--;
+ }
+ }
+
+ private void DisableImage(Bitmap b)
+ {
+ // TODO: use a color matrix operation for that type of manipulation instead.
+ for (int y = 0; y < b.Height; y++)
+ for (int x = 0; x < b.Width; x++)
+ {
+ Color c = b.GetPixel(x, y);
+ int lum = (int)(0.299 * c.R + 0.587 * c.G + 0.114 * c.B);
+ b.SetPixel(x, y, Color.FromArgb(lum, lum, lum));
+ }
+ }
+
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // FeatureTreeView
+ //
+ this.CausesValidation = false;
+ this.Font = new System.Drawing.Font("Tahoma", 8.25F);
+ this.FullRowSelect = true;
+ this.HideSelection = false;
+ this.ShowLines = false;
+ this.ShowPlusMinus = false;
+ this.ShowRootLines = false;
+ this.ResumeLayout(false);
+
+ }
+ }
}
=== added file 'WexInstaller/Controls/FeatureTreeView.resx'
--- a/WexInstaller/Controls/FeatureTreeView.resx 1970-01-01 00:00:00 +0000
+++ b/WexInstaller/Controls/FeatureTreeView.resx 2011-03-18 10:29:04 +0000
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>False</value>
+ </metadata>
+</root>
\ No newline at end of file
=== modified file 'WexInstaller/InstallWizard/Features.Designer.cs'
--- a/WexInstaller/InstallWizard/Features.Designer.cs 2011-03-07 16:27:05 +0000
+++ b/WexInstaller/InstallWizard/Features.Designer.cs 2011-03-18 10:29:04 +0000
@@ -37,6 +37,9 @@
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.label1 = new System.Windows.Forms.Label();
this.catalogImageList = new System.Windows.Forms.ImageList(this.components);
+ this.architectureCombobox = new System.Windows.Forms.ComboBox();
+ this.featureToolTip = new System.Windows.Forms.ToolTip(this.components);
+ this.architectureLabel = new System.Windows.Forms.Label();
this.featureTree = new WexInstaller.Controls.FeatureTreeView();
this.featureBox = new WexInstaller.Controls.FeatureBox();
this.driveSpace = new WexInstaller.Controls.DriveSpaceControl();
@@ -71,10 +74,10 @@
this.catalogList.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.catalogList.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.catalogList.FormattingEnabled = true;
- this.catalogList.ItemHeight = 20;
+ this.catalogList.ItemHeight = 18;
this.catalogList.Location = new System.Drawing.Point(53, 125);
this.catalogList.Name = "catalogList";
- this.catalogList.Size = new System.Drawing.Size(493, 26);
+ this.catalogList.Size = new System.Drawing.Size(397, 24);
this.catalogList.TabIndex = 13;
this.catalogList.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.catalogList_DrawItem);
this.catalogList.SelectedIndexChanged += new System.EventHandler(this.catalogList_SelectedIndexChanged);
@@ -108,6 +111,35 @@
this.catalogImageList.Images.SetKeyName(2, "MySQLInstallerProductCatalog_InPackage.png");
this.catalogImageList.Images.SetKeyName(3, "MySQLInstallerProductCatalog_OnDisk.png");
//
+ // architectureCombobox
+ //
+ this.architectureCombobox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.architectureCombobox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.architectureCombobox.Font = new System.Drawing.Font("Tahoma", 9.75F);
+ this.architectureCombobox.FormattingEnabled = true;
+ this.architectureCombobox.ItemHeight = 16;
+ this.architectureCombobox.Items.AddRange(new object[] {
+ "32-Bit",
+ "64-Bit",
+ "Any"});
+ this.architectureCombobox.Location = new System.Drawing.Point(456, 125);
+ this.architectureCombobox.Name = "architectureCombobox";
+ this.architectureCombobox.Size = new System.Drawing.Size(90, 24);
+ this.architectureCombobox.TabIndex = 16;
+ this.featureToolTip.SetToolTip(this.architectureCombobox, "Only products of the selected architecture type will be shown in the list below.");
+ this.architectureCombobox.SelectedIndexChanged += new System.EventHandler(this.architectureCombobox_SelectedIndexChanged);
+ //
+ // architectureLabel
+ //
+ this.architectureLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.architectureLabel.AutoSize = true;
+ this.architectureLabel.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.architectureLabel.Location = new System.Drawing.Point(453, 108);
+ this.architectureLabel.Name = "architectureLabel";
+ this.architectureLabel.Size = new System.Drawing.Size(79, 14);
+ this.architectureLabel.TabIndex = 17;
+ this.architectureLabel.Text = "Architecture:";
+ //
// featureTree
//
this.featureTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
@@ -118,6 +150,7 @@
this.featureTree.DrawMode = System.Windows.Forms.TreeViewDrawMode.OwnerDrawAll;
this.featureTree.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.featureTree.FullRowSelect = true;
+ this.featureTree.HideSelection = false;
this.featureTree.ImageIndex = 0;
this.featureTree.ImageList = this.imageList1;
this.featureTree.ItemHeight = 40;
@@ -130,7 +163,7 @@
this.featureTree.Size = new System.Drawing.Size(279, 256);
this.featureTree.TabIndex = 12;
this.featureTree.BeforeCheck += new System.Windows.Forms.TreeViewCancelEventHandler(this.featureTree_BeforeCheck);
- this.featureTree.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.featureTree_NodeMouseClick);
+ this.featureTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.featureTree_AfterSelect);
//
// featureBox
//
@@ -161,6 +194,8 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Window;
+ this.Controls.Add(this.architectureLabel);
+ this.Controls.Add(this.architectureCombobox);
this.Controls.Add(this.label1);
this.Controls.Add(this.pictureBox2);
this.Controls.Add(this.catalogList);
@@ -180,6 +215,8 @@
this.Controls.SetChildIndex(this.catalogList, 0);
this.Controls.SetChildIndex(this.pictureBox2, 0);
this.Controls.SetChildIndex(this.label1, 0);
+ this.Controls.SetChildIndex(this.architectureCombobox, 0);
+ this.Controls.SetChildIndex(this.architectureLabel, 0);
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@@ -197,5 +234,8 @@
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ImageList catalogImageList;
+ private System.Windows.Forms.ComboBox architectureCombobox;
+ private System.Windows.Forms.ToolTip featureToolTip;
+ private System.Windows.Forms.Label architectureLabel;
}
}
=== modified file 'WexInstaller/InstallWizard/Features.cs'
--- a/WexInstaller/InstallWizard/Features.cs 2011-03-07 16:27:05 +0000
+++ b/WexInstaller/InstallWizard/Features.cs 2011-03-18 10:29:04 +0000
@@ -7,39 +7,226 @@
using WexInstaller.Core;
using WexInstaller.Properties;
+using MySQL.Utilities.SysUtils;
+
namespace WexInstaller
{
public partial class FeatureSelection : InstallerPanel
{
+
+ #region Members and constants
+
+ // This class represents a line in the catalog drop down. The state item indicates the download
+ // state of the products
+ private class CatalogState
+ {
+ public const int ProductsDownload = 0;
+ public const int ProductsDownloadCommercial = 1;
+ public const int ProductsInCache = 2;
+ public const int InstalledProducts = 3;
+
+ public int DownloadState;
+ public string Text;
+ public ProductCatalog catalog;
+
+ public CatalogState(ProductCatalog catalog)
+ {
+ this.catalog = catalog;
+ Text = catalog.Description;
+ DownloadState = ProductsInCache;
+ DownloadState = GetCatalogDownloadState(catalog);
+ }
+
+ public CatalogState(string text, bool isAllProducts)
+ {
+ catalog = null;
+ Text = text;
+ DownloadState = ProductsInCache;
+ DownloadState = isAllProducts ? GetAllDownloadState() : InstalledProducts;
+ }
+
+ public bool NeedsDownload
+ {
+ get
+ {
+ return DownloadState == ProductsDownload || DownloadState == ProductsDownloadCommercial;
+ }
+ }
+
+ public string SubText
+ {
+ get
+ {
+ if (DownloadState == ProductsInCache)
+ return Resources.PackagesAvailable;
+ if (DownloadState == InstalledProducts)
+ return Resources.PackagesAlreadyInstalled;
+ if (DownloadState == ProductsDownloadCommercial)
+ return Resources.PackagesAvailableForCommercialDownload;
+ return Resources.PackagesAvailableForDownload;
+ }
+ }
+
+ public int GetCatalogDownloadState(ProductCatalog catalog)
+ {
+ int index = ProductsInCache;
+ foreach (CatalogProduct cp in catalog.Products)
+ if (!cp.ReferencedProduct.FoundLocal)
+ {
+ index = ProductsDownload;
+ break;
+ }
+ if (catalog.Commercial && index == ProductsDownload)
+ index = ProductsDownloadCommercial;
+ return index;
+ }
+
+ public int GetAllDownloadState()
+ {
+ int index = ProductsInCache;
+ foreach (ProductCategory cat in ProductManager.ProductCategories)
+ foreach (Product p in cat.Products)
+ if (!p.FoundLocal)
+ index = ProductsDownload;
+ return index;
+ }
+ }
+
+ #endregion
+
+ #region Construction and setup
+
public FeatureSelection()
{
InitializeComponent();
Caption = "Feature Selection";
featureBox.FeatureTree = featureTree;
+
+ // Hide the architecture selection box if we are on a 32 OS.
+ architectureCombobox.SelectedIndex = 0;
+ if (!Win32.Is64BitOS())
+ {
+ architectureCombobox.Visible = false;
+ architectureLabel.Visible = false;
+ catalogList.Width = featureBox.Right - catalogList.Left;
+ }
}
+
+ #endregion
+
+ #region Application logic
public override void Activate()
{
- // Load our catalog dropdown. Keep the last selected entry for re-selection.
- // We cannot use the active catalog here as not all entries have a catalog counterpart.
+ // Load the catalog dropdown. Display only one catalog per architecture and use the
+ // architectureCombobox to let the user select the architecture instead.
+ string currentCatalogName = "";
+ if (ProductManager.ActiveCatalog != null)
+ {
+ currentCatalogName = ProductManager.ActiveCatalog.Name;
+ if (ProductManager.ActiveCatalog.Requires64BitArchitecture)
+ architectureCombobox.SelectedIndex = 1;
+ }
+
int selectedIndex = catalogList.SelectedIndex;
- if (selectedIndex < 0)
- selectedIndex = 0;
catalogList.Items.Clear();
foreach (ProductCatalog catalog in ProductManager.Catalogs)
- catalogList.Items.Add(new CatalogState(catalog));
+ if (!catalog.Requires64BitArchitecture)
+ {
+ catalogList.Items.Add(new CatalogState(catalog));
+ if (selectedIndex == -1 && catalog.Name == currentCatalogName)
+ selectedIndex = catalogList.Items.Count - 1;
+ }
+ // These special "catalogs" are available for any architecture.
catalogList.Items.Add(new CatalogState(Resources.AllMySQLProducts, true));
catalogList.Items.Add(new CatalogState(Resources.InstalledMySQLProducts, false));
- catalogList.SelectedIndex = selectedIndex;
+ if (selectedIndex > -1)
+ catalogList.SelectedIndex = selectedIndex;
+ else
+ catalogList.SelectedIndex = 0;
+ catalogList.Focus();
NextButton.Text = Properties.Resources.NextButtonDefaultText;
base.Activate();
}
- private void featureTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
+ /// <summary>
+ /// Called when either the catalog or the architecture was changed by the user.
+ /// Updates the list of displayed products and their features.
+ /// </summary>
+ private void UpdateFeatureDisplay()
+ {
+ if (catalogList.SelectedIndex < 0)
+ return;
+
+ ProductCatalog catalog = null;
+ bool installedItems = catalogList.SelectedIndex == (catalogList.Items.Count - 1);
+ bool allProducts = catalogList.SelectedIndex == (catalogList.Items.Count - 2);
+ CatalogArchitecture architecture;
+ switch (architectureCombobox.SelectedIndex)
+ {
+ case 0:
+ architecture = CatalogArchitecture.X86;
+ break;
+ case 1:
+ architecture = CatalogArchitecture.X64;
+ break;
+ default:
+ architecture = CatalogArchitecture.Any;
+ break;
+ }
+
+ CatalogState state = catalogList.Items[catalogList.SelectedIndex] as CatalogState;
+ catalog = state.catalog;
+
+ FillFeatureTree(architecture, allProducts, installedItems, catalog);
+
+ if (featureTree.Nodes.Count > 0)
+ {
+ featureTree.SelectedNode = featureTree.Nodes[0];
+ featureBox.SelectedObject = featureTree.SelectedNode.Tag as ProductElement;
+ }
+ else
+ featureBox.SelectedObject = null;
+ driveSpace.Calculate();
+ }
+
+ /// <summary>
+ /// Responsible to set up the feature tree based on the given selection.
+ /// </summary>
+ /// <param name="architecture">The architecture to consider for each product.</param>
+ /// <param name="allProducts">True, if all products should be added (filtered by arch).</param>
+ /// <param name="installedItems">True, if already installed products should be added (filtered by arch).</param>
+ /// <param name="catalog">The catalog carrying the products to show if neither allProducts nor installedItems are true.
+ /// Also subject to the given architecture.</param>
+ private void FillFeatureTree(CatalogArchitecture architecture, bool allProducts, bool installedItems, ProductCatalog catalog)
+ {
+ featureTree.Nodes.Clear();
+ featureTree.Architecture = architecture;
+ featureBox.Catalog = catalog;
+ featureBox.ListAllItems = allProducts;
+ featureBox.ListInstalledItems = installedItems;
+
+ foreach (ProductCategory pc in ProductManager.ProductCategories)
+ {
+ List<Product> products = featureBox.GetProducts(pc);
+
+ TreeNode node = null;
+ if (products.Count > 1)
+ node = featureTree.AddCategory(pc);
+ foreach (Product p in products)
+ featureTree.AddProduct(p, node);
+ }
+ }
+
+ #endregion
+
+ #region Event handling
+
+ private void featureTree_AfterSelect(object sender, TreeViewEventArgs e)
{
featureBox.SelectedObject = e.Node.Tag as ProductElement;
}
@@ -48,7 +235,7 @@
{
FeatureTreeView ftv = sender as FeatureTreeView;
if (ftv != null)
- ftv.SelectedNode = e.Node;
+ ftv.SelectedNode = e.Node;
}
private void catalogList_DrawItem(object sender, DrawItemEventArgs e)
@@ -80,128 +267,49 @@
private void catalogList_SelectedIndexChanged(object sender, EventArgs e)
{
- // Keep track of the active catalog an refill the feature tree.
- if (catalogList.SelectedIndex < ProductManager.Catalogs.Count)
- ProductManager.ActiveCatalog = ProductManager.Catalogs[catalogList.SelectedIndex];
- else
+ // Keep track of the active catalog and refill the feature tree.
+ // Architecture selection is not possible with the two "virtual" categories,
+ // namely "All products" and "All installed products".
+ CatalogState state = catalogList.Items[catalogList.SelectedIndex] as CatalogState;
+
+ if (state.catalog == null)
ProductManager.ActiveCatalog = null;
- featureTree.Nodes.Clear();
-
- ProductCatalog catalog = null;
- bool installedItems = catalogList.SelectedIndex == (catalogList.Items.Count - 1);
- bool allProducts = catalogList.SelectedIndex == (catalogList.Items.Count - 2);
- if (!installedItems && !allProducts)
- catalog = ProductManager.Catalogs[catalogList.SelectedIndex];
-
- foreach (ProductCategory pc in ProductManager.ProductCategories)
- {
- List<Product> products = new List<Product>();
- foreach (Product p in pc.Products)
- {
- if (allProducts || installedItems)
- {
- if (allProducts || p.Installed)
- products.Add(p);
- }
- else
- {
- foreach (CatalogProduct cp in catalog.Products)
- if (String.Compare(cp.ProductId, p.Name, true) == 0)
- products.Add(p);
- }
- }
- if (products.Count == 1)
- featureTree.AddProduct(products[0], null);
- else
- if (products.Count > 1)
- {
- TreeNode node = featureTree.AddCategory(pc);
- foreach (Product p in products)
- featureTree.AddProduct(p, node);
- }
- }
-
- if (featureTree.Nodes.Count > 0)
- {
- featureTree.SelectedNode = featureTree.Nodes[0];
- featureBox.SelectedObject = featureTree.SelectedNode.Tag as ProductElement;
- }
else
- featureBox.SelectedObject = null;
- driveSpace.Calculate();
- }
- }
-
- // This class represents a line in the catalog drop down. The state item indicates the download
- // state of the products
- class CatalogState
- {
- public const int ProductsDownload = 0;
- public const int ProductsDownloadCommercial = 1;
- public const int ProductsInCache = 2;
- public const int InstalledProducts = 3;
-
- public int DownloadState;
- public string Text;
-
- public CatalogState(ProductCatalog catalog)
- {
- Text = catalog.Description;
- DownloadState = ProductsInCache;
- DownloadState = GetCatalogDownloadState(catalog);
- }
-
- public CatalogState(string text, bool isAllProducts)
- {
- Text = text;
- DownloadState = ProductsInCache;
- DownloadState = isAllProducts ? GetAllDownloadState() : InstalledProducts;
- }
-
- public bool NeedsDownload
- {
- get
- {
- return DownloadState == ProductsDownload || DownloadState == ProductsDownloadCommercial;
- }
- }
-
- public string SubText
- {
- get
- {
- if (DownloadState == ProductsInCache)
- return Resources.PackagesAvailable;
- if (DownloadState == InstalledProducts)
- return Resources.PackagesAlreadyInstalled;
- if (DownloadState == ProductsDownloadCommercial)
- return Resources.PackagesAvailableForCommercialDownload;
- return Resources.PackagesAvailableForDownload;
- }
- }
-
- public int GetCatalogDownloadState(ProductCatalog catalog)
- {
- int index = ProductsInCache;
- foreach (CatalogProduct cp in catalog.Products)
- if (!cp.ReferencedProduct.FoundLocal)
+ {
+ // Even though the catalog in the catalog list carries an architecture it is not
+ // meant to be used for selection of an architecture (the architectureCombobox is).
+ // So find the catalog with the same name as currently selected in the catalog list
+ // and combine this with the selected architecture to find the real catalog.
+ bool use64Bit;
+ switch (architectureCombobox.SelectedIndex)
{
- index = ProductsDownload;
+ case 0:
+ use64Bit = false;
+ break;
+ case 1:
+ use64Bit = true;
+ break;
+ default:
+ use64Bit = Win32.Is64BitOS();
break;
}
- if (catalog.Commercial && index == ProductsDownload)
- index = ProductsDownloadCommercial;
- return index;
+
+ foreach (ProductCatalog catalog in ProductManager.Catalogs)
+ if (catalog.Requires64BitArchitecture == use64Bit && catalog.Name == state.catalog.Name)
+ {
+ ProductManager.ActiveCatalog = catalog;
+ break;
+ }
+ }
+ UpdateFeatureDisplay();
}
- public int GetAllDownloadState()
+ private void architectureCombobox_SelectedIndexChanged(object sender, EventArgs e)
{
- int index = ProductsInCache;
- foreach (ProductCategory cat in ProductManager.ProductCategories)
- foreach (Product p in cat.Products)
- if (!p.FoundLocal)
- index = ProductsDownload;
- return index;
+ UpdateFeatureDisplay();
}
+
+ #endregion
+
}
}
=== modified file 'WexInstaller/InstallWizard/Features.resx'
--- a/WexInstaller/InstallWizard/Features.resx 2011-03-07 16:27:05 +0000
+++ b/WexInstaller/InstallWizard/Features.resx 2011-03-18 10:29:04 +0000
@@ -125,7 +125,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA4
- KAAAAk1TRnQBSQFMAgEBBAEAARgBAAEYAQABGAEAARgBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFg
+ KAAAAk1TRnQBSQFMAgEBBAEAAWgBAAFoAQABGAEAARgBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFg
AwABMAMAAQEBAAEgBgABSP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A
/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ADYAA+oB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
@@ -137,165 +137,165 @@
Af8BzAKZAf8BzAKZAf8BzAKZAf8BzAKZAf8DzAH/A+oB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wPMAf8BzAKZAf8BzAGZ
- ATAB/wLMAWMB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
- AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
- AZkB/wLMAWMB/wHMAZkBMAH/AcwCmQH/AcwBmQEwAf8CzAFjAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
- Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
- Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAFjAf8BzAGZATAB/wGkAqAB/wHMAZkBMAH/
- AswBYwH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBYwH/AcwBmQEwAf8CzAFjAf8CzAGZ
- Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
- Af8CzAFjAf8CmQEwAf8CzAGZAf8BzAGZATAB/wLMAWMB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
- AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
- AZkB/wLMAZkB/wLMAZkB/wLMAWMB/wLMAWMB/wLMAWMB/wHMAZkBMAH/ApkBYwH/AswBYwL/AewBzAH/
+ ASYB/wLMAVkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+ AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+ AZkB/wLMAVkB/wHMAZkBJgH/AcwCmQH/AcwBmQEmAf8CzAFZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
+ Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
+ Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAFZAf8BzAGZASYB/wGkAqAB/wHMAZkBJgH/
+ AswBWQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBWQH/AcwBmQEmAf8CzAFZAf8CzAGZ
+ Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
+ Af8CzAFZAf8CmQEmAf8CzAGZAf8BzAGZASYB/wLMAVkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+ AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+ AZkB/wLMAZkB/wLMAZkB/wLMAVkB/wLMAVkB/wLMAVkB/wHMAZkBJgH/ApkBWQH/AswBWQL/AewBzAH/
AfABygGmAf8D6gH/AfABygGmAv8B7AHMAf8D6gX/AfABygGmBf8B8AHKAaYB/wPqAf8D6iL/AewBzAH/
- AcwBmQEwAf8CmQFjAf8CzAFjBf8B8AHKAaYC/wHsAcwB/wHwAcoBpgL/AewBzAH/A/EC/wHsAcwB/wPq
+ AcwBmQEmAf8CmQFZAf8CzAFZBf8B8AHKAaYC/wHsAcwB/wHwAcoBpgL/AewBzAH/A/EC/wHsAcwB/wPq
Av8B7AHMAf8D8QL/AewBzAL/AewBzAH/A+oB/wHwAcoBpgH/A/EC/wHsAcwC/wHsAcwB/wHwAcoBpgL/
- AewBzAb/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D6gn/A/EC/wHsAcwB/wHwAcoBpgL/AewBzAH/
- AcwBmQFjAf8B8AHKAaYB/wPqAv8B7AHMAf8D6iL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D6gH/
+ AewBzAb/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D6gn/A/EC/wHsAcwB/wHwAcoBpgL/AewBzAH/
+ AcwBmQFZAf8B8AHKAaYB/wPqAv8B7AHMAf8D6iL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D6gH/
AfABygGmAf8D6gL/AewBzAH/AfABygGmAf8D8QH/AfABygGmAv8B7AHMAf8B8AHKAaYC/wHsAcwB/wPq
- Af8B8AHKAaYC/wHsAcwB/wPqAf8D6gH/AfABygGmAv8B7AHMAf8D8QH/AfABygGmAf8CzAFjAv8B7AHM
- Af8BzAGZATAB/wKZAWMB/wLMAWMC/wHsAcwB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAWMC/wHs
- AcwB/wHMAZkBMAH/AswBYwH/AswBYwH/AswBmQH/AswBYwH/A/Ee/wHsAcwB/wHMAZkBMAH/ApkBYwH/
- AswBYwH/AswBmQH/AfABygGmAf8B8AHKAaYB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAWMB/wLMAZkB/wLM
- AWMB/wLMAZkB/wHMAZkBMAH/AswBYwH/AswBYwH/AfABygGmAf8B8AHKAaYB/wHwAcoBpgH/AswBYwH/
- AswBYwH/AswBYwH/AfABygGmAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wLMAZkB/wLMAWMB/wHw
- AcoBpgH/AswBmQH/AswBYwH/AswBYwH/AswBYwH/AswBmQH/AswBYwH/AswBmQH/AswBYwH/AswBmQL/
- AewBzB7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8CzAGZAf8B8AHKAaYB/wLMAWMB/wLMAWMB/wLM
- AWMB/wLMAWMB/wHwAcoBpgH/AswBYwH/AfABygGmAf8CzAGZAf8CzAFjAf8CzAFjAf8CzAFjAf8CzAFj
- Af8B8AHKAaYB/wHMAZkBMAH/AswBYwH/AswBmQH/AfABygGmAf8CzAFjAv8B7AHMAf8BzAGZAWMB/wKZ
- AWMB/wLMAWMB/wHwAcoBpgH/AswBYwL/AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/
- AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAf8D8R7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8B8AHK
+ Af8B8AHKAaYC/wHsAcwB/wPqAf8D6gH/AfABygGmAv8B7AHMAf8D8QH/AfABygGmAf8CzAFZAv8B7AHM
+ Af8BzAGZASYB/wKZAVkB/wLMAVkC/wHsAcwB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAVkC/wHs
+ AcwB/wHMAZkBJgH/AswBWQH/AswBWQH/AswBmQH/AswBWQH/A/Ee/wHsAcwB/wHMAZkBJgH/ApkBWQH/
+ AswBWQH/AswBmQH/AfABygGmAf8B8AHKAaYB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAVkB/wLMAZkB/wLM
+ AVkB/wLMAZkB/wHMAZkBJgH/AswBWQH/AswBWQH/AfABygGmAf8B8AHKAaYB/wHwAcoBpgH/AswBWQH/
+ AswBWQH/AswBWQH/AfABygGmAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wLMAZkB/wLMAVkB/wHw
+ AcoBpgH/AswBmQH/AswBWQH/AswBWQH/AswBWQH/AswBmQH/AswBWQH/AswBmQH/AswBWQH/AswBmQL/
+ AewBzB7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8CzAGZAf8B8AHKAaYB/wLMAVkB/wLMAVkB/wLM
+ AVkB/wLMAVkB/wHwAcoBpgH/AswBWQH/AfABygGmAf8CzAGZAf8CzAFZAf8CzAFZAf8CzAFZAf8CzAFZ
+ Af8B8AHKAaYB/wHMAZkBJgH/AswBWQH/AswBmQH/AfABygGmAf8CzAFZAv8B7AHMAf8BzAGZAVkB/wKZ
+ AVkB/wLMAVkB/wHwAcoBpgH/AswBWQL/AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/
+ AewBzAH/AfABygGmAv8B7AHMAv8B7AHMAf8D8R7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8B8AHK
AaYB/wLMAZkC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxAf8B8AHKAaYC/wHsAcwC/wHs
AcwC/wHsAcwC/wHsAcwC/wHsAcwB/wHwAcoBpgH/AfABygGmAv8B7AHMAv8B7AHMAv8B7AHMAf8B8AHK
- AaYC/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/AfABygGmAf8CzAFjAf8CzAFjAf8B8AHKAaYC/wHs
+ AaYC/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/AfABygGmAf8CzAFZAf8CzAFZAf8B8AHKAaYC/wHs
AcwB/wPqAv8B7AHMAv8B7AHMAf8B8AHKAaYB/wHwAcoBpgH/AfABygGmAv8B7AHMIv8B7AHMAf8BzAGZ
- ATAB/wKZAWMB/wLMAWMB/wHwAcoBpgH/AswBYwH/AswBmQL/AewBzAL/AewBzAL/AewBzAL/AewBzAH/
- AswBYwL/AewBzAH/AfABygGmAf8CzAGZAf8CzAGZAv8B7AHMAf8B8AHKAaYC/wHsAcwB/wHwAcoBpgH/
- A+oB/wHwAcoBpgL/AewBzAL/AewBzAL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8QL/AewBzAL/
- AewBzAH/AfABygGmAf8BzAP/AcwD/wHGAdYB7wH/AcwD/wHWAucu/wHsAcwB/wHMAZkBMAH/ApkBYwH/
- AswBYwX/A+MC/wHsAcwB/wHwAcoBpgH/AcwD/wHMA/8BxgHWAe8B/wHMA/8BzDD/AewBzAH/AcwBmQEw
- Af8CmQFjAf8CzAFjAf8D8QH/A+MB/wPjAf8B8AHKAaYB/wHMA/8BzAP/AcYB1gHvAf8BzAP/AdYC5wH/
- A/Eq/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EB/wPjAv8B7AHMAf8B8AHKAaYB/wHMA/8BzAP/
- AcYB1gHvAf8B1gLnAf8BzAP/A/Eq/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/AfABygGmAf8CzAGZ
+ ASYB/wKZAVkB/wLMAVkB/wHwAcoBpgH/AswBWQH/AswBmQL/AewBzAL/AewBzAL/AewBzAL/AewBzAH/
+ AswBWQL/AewBzAH/AfABygGmAf8CzAGZAf8CzAGZAv8B7AHMAf8B8AHKAaYC/wHsAcwB/wHwAcoBpgH/
+ A+oB/wHwAcoBpgL/AewBzAL/AewBzAL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8QL/AewBzAL/
+ AewBzAH/AfABygGmAf8BzAP/AcwD/wHGAdYB7wH/AcwD/wHWAucu/wHsAcwB/wHMAZkBJgH/ApkBWQH/
+ AswBWQX/A+MC/wHsAcwB/wHwAcoBpgH/AcwD/wHMA/8BxgHWAe8B/wHMA/8BzDD/AewBzAH/AcwBmQEm
+ Af8CmQFZAf8CzAFZAf8D8QH/A+MB/wPjAf8B8AHKAaYB/wHMA/8BzAP/AcYB1gHvAf8BzAP/AdYC5wH/
+ A/Eq/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EB/wPjAv8B7AHMAf8B8AHKAaYB/wHMA/8BzAP/
+ AcYB1gHvAf8B1gLnAf8BzAP/A/Eq/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/AfABygGmAf8CzAGZ
Af8CzAGZAf8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7Hv8D8QL/AewBzAr/AewBzAH/
- AcwBmQEwAf8CmQFjAf8CzAFjAf8B8AHKAaYB/wLMAZkB/wLMAZkB/wPXAf8BmQHMAv8BmQHMAv8BmQHM
- Av8BxgHWAe8B/wHwAfsv/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/AfABygGmAf8CzAGZAf8CzAGZ
- Af8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7L/8B7AHMAf8BzAGZATAB/wHMAZkBYwH/
- AswBYwH/AfABygGmAf8CzAGZAf8CzAGZAf8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7
- L/8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfse/wHwAcoBpgH/
- AfABygGmAf8D8Qr/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7
- M/8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfsz/wHsAcwB/wHM
- AZkBMAH/AcwBmQFjAf8CzAFjEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7M/8B7AHMAf8BzAGZATAB/wKZ
- AWMC/wHMAWM5/wHwAcoBpgH/AfABygGmEv8B7AHMAf8BzAGZATAB/wKZAWMC/wHMAWNS/wHsAcwB/wHM
- AZkBMAH/ApkBYwL/AcwBYxn/A90B/wHwAcoBpgH/AfABygGmAf8D6gX/A9cB/wPdAf8D6hr/AewBzAH/
- AcwBmQEwAf8BzAGZAWMC/wHMAWMJ/wPxAv8B7AHMAf8D6hH/A/EC/wHsAcwB/wPxEf8D6gL/AewBzAH/
- A/EG/wHsAcwB/wHMAZkBMAH/AcwBmQFjAv8BzAFjIv8B7AHMAf8D8RL/AewBzAH/AfABygGmAf8CzAGZ
- Af8D6gr/AewBzAH/AcwBmQEwAf8BzAGZAWMC/wHMAWMB/wPxAf8D8Sn/A/EC/wHsAcwC/wHsAcwC/wHs
- AcwC/wHsAcwB/wPxCv8B7AHMAf8BzAGZATAB/wKZAWMC/wHMAWMV/wLMAZkB/wLMAZkB/wLMAZkB/wLM
- AWMC/wHsAcwB/wPqAf8CzAFjAf8CzAGZAf8CzAGZAf8CzAGZAf8D6hL/AewBzAH/AcwBmQEwAf8BzAGZ
- AWMC/wHMAWMK/wHsAcwB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wLMAZkB/wPjAf8D4wH/AswBmQH/
- AcwBmQEwAf8CzAFjAf8D4wH/A+MB/wLMAZkB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMC/wHsAcwG/wHs
- AcwB/wHMAZkBMAH/ApkBYwL/AcwBYxX/AfABygGmAf8B8AHKAaYB/wHwAcoBpgL/AewBzBX/A+MB/wHw
- AcoBpgL/AewBzA7/AewBzAH/AcwBmQEwAf8CmQFjAv8BzAFjAf8B8AHKAaYB/wLMAZkB/wHwAcoBpiL/
- AewBzAH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBYwH/AfABygGmAv8B7AHMAf8D6gL/AewBzAH/
- AcwBmQEwAf8CmQFjAv8BzAFjFf8CzAGZAf8CzAFjAf8CzAFjAf8CzAFjAf8D4wX/AswBYwH/AswBYwH/
- AswBYwH/AswBYwH/A+MS/wHsAcwB/wHMAZkBMAH/AcwBmQFjAv8BzAFjDv8B7AHMAf8B8AHKAaYB/wHM
- AZkBYwH/AZkBYwEwAf8BmQFjATAB/wKZATAB/wGZAWMBMAH/AcwBmQFjAf8BmQFjATAB/wGZAWMBMAH/
- AZkBYwEwAf8BmQFjATAB/wHMAZkBYwH/AfABygGmAv8B7AHMCv8B7AHMAf8BzAGZATAB/wKZAWMC/wHM
- AWMR/wPqAf8CzAGZAf8BzAGZAWMB/wLMAZkR/wPxAf8BzAGZAWMB/wLMAZkB/wPxEv8B7AHMAf8BzAGZ
- ATAB/wKZAWMC/wHMAWMB/wPqAf8B8AHKAaYB/wHMAZkBYwH/A90Z/wPxAf8CzAFjAf8BzAGZAWMB/wHM
- AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwL/AewBzAH/
- AcwBmQEwAf8CmQFjAv8BzAFjFf8B8AHKAaYB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/
- AswBmQH/AcwBmQFjAf8BzAGZAWMB/wLMAWMB/wLMAWMB/wPxEv8B7AHMAf8BzAGZATAB/wHMAZkBYwL/
- AcwBYxn/A+MB/wHMAZkBYwH/AcwBmQFjAf8B8AHKAaYF/wHwAcoBpgH/AcwBmQFjAf8BzAGZAWMB/wPj
- Bf8D6gH/A/EK/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYxH/AswBmQH/AfABygGmAf8CzAGZAf8D8RH/
- AswBmQH/AfABygGmGv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMJ/wLMAZkB/wHMAZkBYwH/A/EN/wHw
- AcoBpgH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEw
- Af8BzAGZATAB/wLMAZkB/wHwAcoBpgL/AewBzAL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjDf8D6gH/
- A+oB/wHwAcoBpgH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/
- AcwBmQEwAf8BzAGZATAB/wHMAZkBYwH/A+MB/wPjAf8D8Qr/AewBzAH/AcwBmQEwAf8BzAGZAWMB/wLM
- AWM5/wPxAf8B8AHKAaYC/wHsAcwO/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYxH/AswBmQH/A9cB/wPx
- Ef8D6gH/AswBYx7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjCf8D6gH/AcwBmQEwAf8BzAGZAWMJ/wHw
- AcoBpgH/AcwBmQEwAf8CzAGZAv8B7AHMAf8BzAGZAWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHM
- AZkBMAH/AcwBmQEwAf8BzAGZAWMB/wHMAZkBYwH/AswBmQL/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFj
- Cf8D4wH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEw
- Af8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQFjAf8BzAGZATAB/wLM
- AZkK/wHsAcwB/wHMAZkBMAH/AcwBmQFjAf8CzAFjKf8D8QH/A+oJ/wPxAf8B8AHKAaYB/wHwAcoBpg7/
- AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjEv8B7AHMAf8CzAGZFf8CzAGZAf8B8AHKAaYe/wHsAcwB/wHM
- AZkBMAH/ApkBYwH/AswBYw3/AfABygGmAf8BmQFjAQAB/wHMAZkBYwH/AcwBmQFjAf8BmQFjATAB/wHM
- AZkBYwr/AewBzAH/AcwBmQFjAf8CmQEwAf8CmQEwAf8CmQEwAf8CmQEwAf8CzAGZAv8B7AHMAf8D8QL/
- AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjCv8B7AHMAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZ
- AWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/ApkBMAH/ApkBMAH/ApkBMAH/ApkBMAH/
- ApkBMAH/ApkBAAH/AcwBmQFjCv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMi/wHsAcwB/wLMAZkB/wLM
- AZkB/wPxCv8B7AHMAf8B8AHKAaYB/wPxDv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMR/wHwAcoBpgH/
- AswBmRH/A/EB/wHMAZkBYwL/AewBzB7/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjEf8B8AHKAaYB/wHM
- AZkBYwH/AcwBmQFjAf8CzAGZAf8D8Q3/A/EC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxCv8B7AHM
- Af8BzAGZATAB/wKZAWMB/wLMAWMJ/wPqAf8CzAGZAf8CzAFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFj
- Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHM
- AZkBYwH/AcwBmQFjAf8B8AHKAaYK/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYyH/AfABygGmAf8CzAGZ
- Av8B7AHMCf8B8AHKAaYB/wHwAcoBpgH/A/ES/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EJ/wPx
- Af8BzAGZAWMB/wPqEf8CzAGZAf8CzAGZIv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wPxEf8D8QH/
- A/E2/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EJ/wPqAf8D6gH/AfABygGmAf8BzAGZAWMB/wHM
- AZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQFj
- Av8B7AHMAv8B7AHMAf8D8Qr/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8R3/AfABygGmAv8B7AHM
- Cf8D6gH/AcwBmQFjAf8D8Rb/AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8QH/A/EF/wHwAcoBpgH/
- AswBYwH/A/EC/wHsAcwJ/wLMAZkB/wLMAZkF/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/
- AewBzAH/AcwBmQEwAf8CmQFjAf8CzAFjAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
- Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/
- ApkBYwH/AswBYwH/A/EB/wPxAf8D8QH/A/EF/wLMAZkB/wKZATAB/wKZATAB/wKZATAB/wHMAZkBYwH/
- AcwBmQFjAf8BzAGZATAB/wKZATAB/wKZATAB/wHMAZkBYwH/A+oF/wPxAf8D8QH/A/EC/wHsAcwB/wHM
- AZkBMAH/ApkBYwH/AswBYwH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EF/wHwAcoBpgL/AewBzAn/
- AswBmQH/AfABygGmBf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/
+ AcwBmQEmAf8CmQFZAf8CzAFZAf8B8AHKAaYB/wLMAZkB/wLMAZkB/wPXAf8BmQHMAv8BmQHMAv8BmQHM
+ Av8BxgHWAe8B/wHwAfsv/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/AfABygGmAf8CzAGZAf8CzAGZ
+ Af8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7L/8B7AHMAf8BzAGZASYB/wHMAZkBWQH/
+ AswBWQH/AfABygGmAf8CzAGZAf8CzAGZAf8D1wH/AZkBzAL/AZkBzAL/AZkBzAL/AcYB1gHvAf8B8AH7
+ L/8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfse/wHwAcoBpgH/
+ AfABygGmAf8D8Qr/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7
+ M/8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkR/wHwAfsC/wHwAfsC/wHwAfsC/wHwAfsz/wHsAcwB/wHM
+ AZkBJgH/AcwBmQFZAf8CzAFZEf8B8AH7Av8B8AH7Av8B8AH7Av8B8AH7M/8B7AHMAf8BzAGZASYB/wKZ
+ AVkC/wHMAVk5/wHwAcoBpgH/AfABygGmEv8B7AHMAf8BzAGZASYB/wKZAVkC/wHMAVlS/wHsAcwB/wHM
+ AZkBJgH/ApkBWQL/AcwBWRn/A90B/wHwAcoBpgH/AfABygGmAf8D6gX/A9cB/wPdAf8D6hr/AewBzAH/
+ AcwBmQEmAf8BzAGZAVkC/wHMAVkJ/wPxAv8B7AHMAf8D6hH/A/EC/wHsAcwB/wPxEf8D6gL/AewBzAH/
+ A/EG/wHsAcwB/wHMAZkBJgH/AcwBmQFZAv8BzAFZIv8B7AHMAf8D8RL/AewBzAH/AfABygGmAf8CzAGZ
+ Af8D6gr/AewBzAH/AcwBmQEmAf8BzAGZAVkC/wHMAVkB/wPxAf8D8Sn/A/EC/wHsAcwC/wHsAcwC/wHs
+ AcwC/wHsAcwB/wPxCv8B7AHMAf8BzAGZASYB/wKZAVkC/wHMAVkV/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+ AVkC/wHsAcwB/wPqAf8CzAFZAf8CzAGZAf8CzAGZAf8CzAGZAf8D6hL/AewBzAH/AcwBmQEmAf8BzAGZ
+ AVkC/wHMAVkK/wHsAcwB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wLMAZkB/wPjAf8D4wH/AswBmQH/
+ AcwBmQEmAf8CzAFZAf8D4wH/A+MB/wLMAZkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkC/wHsAcwG/wHs
+ AcwB/wHMAZkBJgH/ApkBWQL/AcwBWRX/AfABygGmAf8B8AHKAaYB/wHwAcoBpgL/AewBzBX/A+MB/wHw
+ AcoBpgL/AewBzA7/AewBzAH/AcwBmQEmAf8CmQFZAv8BzAFZAf8B8AHKAaYB/wLMAZkB/wHwAcoBpiL/
+ AewBzAH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBWQH/AfABygGmAv8B7AHMAf8D6gL/AewBzAH/
+ AcwBmQEmAf8CmQFZAv8BzAFZFf8CzAGZAf8CzAFZAf8CzAFZAf8CzAFZAf8D4wX/AswBWQH/AswBWQH/
+ AswBWQH/AswBWQH/A+MS/wHsAcwB/wHMAZkBJgH/AcwBmQFZAv8BzAFZDv8B7AHMAf8B8AHKAaYB/wHM
+ AZkBWQH/AZkBWQEmAf8BmQFZASYB/wKZASYB/wGZAVkBJgH/AcwBmQFZAf8BmQFZASYB/wGZAVkBJgH/
+ AZkBWQEmAf8BmQFZASYB/wHMAZkBWQH/AfABygGmAv8B7AHMCv8B7AHMAf8BzAGZASYB/wKZAVkC/wHM
+ AVkR/wPqAf8CzAGZAf8BzAGZAVkB/wLMAZkR/wPxAf8BzAGZAVkB/wLMAZkB/wPxEv8B7AHMAf8BzAGZ
+ ASYB/wKZAVkC/wHMAVkB/wPqAf8B8AHKAaYB/wHMAZkBWQH/A90Z/wPxAf8CzAFZAf8BzAGZAVkB/wHM
+ AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQL/AewBzAH/
+ AcwBmQEmAf8CmQFZAv8BzAFZFf8B8AHKAaYB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/
+ AswBmQH/AcwBmQFZAf8BzAGZAVkB/wLMAVkB/wLMAVkB/wPxEv8B7AHMAf8BzAGZASYB/wHMAZkBWQL/
+ AcwBWRn/A+MB/wHMAZkBWQH/AcwBmQFZAf8B8AHKAaYF/wHwAcoBpgH/AcwBmQFZAf8BzAGZAVkB/wPj
+ Bf8D6gH/A/EK/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWRH/AswBmQH/AfABygGmAf8CzAGZAf8D8RH/
+ AswBmQH/AfABygGmGv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkJ/wLMAZkB/wHMAZkBWQH/A/EN/wHw
+ AcoBpgH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEm
+ Af8BzAGZASYB/wLMAZkB/wHwAcoBpgL/AewBzAL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZDf8D6gH/
+ A+oB/wHwAcoBpgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/
+ AcwBmQEmAf8BzAGZASYB/wHMAZkBWQH/A+MB/wPjAf8D8Qr/AewBzAH/AcwBmQEmAf8BzAGZAVkB/wLM
+ AVk5/wPxAf8B8AHKAaYC/wHsAcwO/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWRH/AswBmQH/A9cB/wPx
+ Ef8D6gH/AswBWR7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZCf8D6gH/AcwBmQEmAf8BzAGZAVkJ/wHw
+ AcoBpgH/AcwBmQEmAf8CzAGZAv8B7AHMAf8BzAGZAVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHM
+ AZkBJgH/AcwBmQEmAf8BzAGZAVkB/wHMAZkBWQH/AswBmQL/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZ
+ Cf8D4wH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEm
+ Af8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQFZAf8BzAGZASYB/wLM
+ AZkK/wHsAcwB/wHMAZkBJgH/AcwBmQFZAf8CzAFZKf8D8QH/A+oJ/wPxAf8B8AHKAaYB/wHwAcoBpg7/
+ AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZEv8B7AHMAf8CzAGZFf8CzAGZAf8B8AHKAaYe/wHsAcwB/wHM
+ AZkBJgH/ApkBWQH/AswBWQ3/AfABygGmAf8BmQFZAQAB/wHMAZkBWQH/AcwBmQFZAf8BmQFZASYB/wHM
+ AZkBWQr/AewBzAH/AcwBmQFZAf8CmQEmAf8CmQEmAf8CmQEmAf8CmQEmAf8CzAGZAv8B7AHMAf8D8QL/
+ AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZCv8B7AHMAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZ
+ AVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/ApkBJgH/ApkBJgH/ApkBJgH/ApkBJgH/
+ ApkBJgH/ApkBAAH/AcwBmQFZCv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVki/wHsAcwB/wLMAZkB/wLM
+ AZkB/wPxCv8B7AHMAf8B8AHKAaYB/wPxDv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkR/wHwAcoBpgH/
+ AswBmRH/A/EB/wHMAZkBWQL/AewBzB7/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZEf8B8AHKAaYB/wHM
+ AZkBWQH/AcwBmQFZAf8CzAGZAf8D8Q3/A/EC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxCv8B7AHM
+ Af8BzAGZASYB/wKZAVkB/wLMAVkJ/wPqAf8CzAGZAf8CzAFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZ
+ Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHM
+ AZkBWQH/AcwBmQFZAf8B8AHKAaYK/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWSH/AfABygGmAf8CzAGZ
+ Av8B7AHMCf8B8AHKAaYB/wHwAcoBpgH/A/ES/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EJ/wPx
+ Af8BzAGZAVkB/wPqEf8CzAGZAf8CzAGZIv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wPxEf8D8QH/
+ A/E2/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EJ/wPqAf8D6gH/AfABygGmAf8BzAGZAVkB/wHM
+ AZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQFZ
+ Av8B7AHMAv8B7AHMAf8D8Qr/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8R3/AfABygGmAv8B7AHM
+ Cf8D6gH/AcwBmQFZAf8D8Rb/AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8QH/A/EF/wHwAcoBpgH/
+ AswBWQH/A/EC/wHsAcwJ/wLMAZkB/wLMAZkF/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/
+ AewBzAH/AcwBmQEmAf8CmQFZAf8CzAFZAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
+ Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/
+ ApkBWQH/AswBWQH/A/EB/wPxAf8D8QH/A/EF/wLMAZkB/wKZASYB/wKZASYB/wKZASYB/wHMAZkBWQH/
+ AcwBmQFZAf8BzAGZASYB/wKZASYB/wKZASYB/wHMAZkBWQH/A+oF/wPxAf8D8QH/A/EC/wHsAcwB/wHM
+ AZkBJgH/ApkBWQH/AswBWQH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EF/wHwAcoBpgL/AewBzAn/
+ AswBmQH/AfABygGmBf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/
A/EB/wPxAv8B7AHMAf8CzAGZAv8B7AHMAf8B8AHKAaYB/wHwAcoBpgH/A+oB/wHwAcoBpgH/AswBmQH/
- A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/ApkBYwH/
- AswBYwH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
- Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wPxAf8D8QH/
- A/EB/wPxAf8D8QH/AcwBmQFjAf8CmQEwAf8CmQEwAf8CmQEwAf8B8AHKAaYB/wPxAf8BzAGZAWMB/wKZ
- ATAB/wKZATAB/wKZATAC/wHsAcwB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLM
- AWMB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/AswBmQL/AewBzAb/AewBzAH/AswBmQH/
- A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBMAH/ApkBYwH/AswBYwH/A/EB/wPx
+ A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/ApkBWQH/
+ AswBWQH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPx
+ Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wPxAf8D8QH/
+ A/EB/wPxAf8D8QH/AcwBmQFZAf8CmQEmAf8CmQEmAf8CmQEmAf8B8AHKAaYB/wPxAf8BzAGZAVkB/wKZ
+ ASYB/wKZASYB/wKZASYC/wHsAcwB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLM
+ AVkB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/AswBmQL/AewBzAb/AewBzAH/AswBmQH/
+ A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EC/wHsAcwB/wHMAZkBJgH/ApkBWQH/AswBWQH/A/EB/wPx
Af8B8AHKAaYB/wPXAv8B7AHMAf8B8AHKAaYB/wHwAcoBpgH/AswBmQH/AfABygGmAv8B7AHMAf8D8QH/
- A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBMAH/ApkBYwH/AswBYwH/
+ A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBJgH/ApkBWQH/AswBWQH/
A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/
- A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZATAB/wKZAWMB/wLMAWMB/wPxAf8D8QH/A/EB/wPx
- Av8B7AHMAf8BzAGZAWMB/wKZATAB/wGZAWMBMAH/AZkBYwEwAf8CzAGZAv8B7AHMAf8BmQFjATAB/wGZ
- AWMBMAH/ApkBMAH/ApkBMAH/AfABygGmAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBMAH/ApkBYwH/
- AswBYwH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wHwAcoBpgH/AfABygGmAf8B8AHKAaYB/wHw
- AcoBpgH/AfABygGmAv8B7AHMAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBMAH/
- ApkBYwH/AswBYwL/AewBzAH/A/EB/wHwAcoBpgH/AswBmQH/AswBmQH/AfABygGmAv8B7AHMAf8D8QH/
+ A/EB/wPxAf8D8QH/A/EB/wPxAv8B7AHMAf8BzAGZASYB/wKZAVkB/wLMAVkB/wPxAf8D8QH/A/EB/wPx
+ Av8B7AHMAf8BzAGZAVkB/wKZASYB/wGZAVkBJgH/AZkBWQEmAf8CzAGZAv8B7AHMAf8BmQFZASYB/wGZ
+ AVkBJgH/ApkBJgH/ApkBJgH/AfABygGmAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBJgH/ApkBWQH/
+ AswBWQH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wHwAcoBpgH/AfABygGmAf8B8AHKAaYB/wHw
+ AcoBpgH/AfABygGmAv8B7AHMAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QL/AewBzAH/ApkBJgH/
+ ApkBWQH/AswBWQL/AewBzAH/A/EB/wHwAcoBpgH/AswBmQH/AswBmQH/AfABygGmAv8B7AHMAf8D8QH/
A/EC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
- AcwC/wHsAcwC/wHsAcwB/wKZATAB/wKZAWMB/wLMAWMC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
+ AcwC/wHsAcwC/wHsAcwB/wKZASYB/wKZAVkB/wLMAVkC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
AcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHs
- AcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wKZATAB/wKZAWMB/wLMAWMC/wHs
+ AcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwC/wHsAcwB/wKZASYB/wKZAVkB/wLMAVkC/wHs
AcwC/wHsAcwC/wHsAcwC/wHsAcwB/wPxAf8D8QL/AewBzAH/AfABygGmAf8CzAGZAv8B7AHMAv8B7AHM
Af8CzAGZAf8CzAGZAf8B8AHKAaYC/wHsAcwB/wPxAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHM
- Af8CmQEwAf8CmQFjAf8CzAFjAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/AewBzAH/
+ Af8CmQEmAf8CmQFZAf8CzAFZAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAv8B7AHMAf8D8QL/AewBzAH/
AswBmQH/AfABygGmAf8CzAGZAf8B8AHKAaYB/wPxAf8D8QL/AewBzAL/AewBzAL/AewBzAL/AewBzAL/
- AewBzAL/AewBzAL/AewBzAL/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFjAf8D8Qb/AewBzAL/AewBzAL/
- AewBzD7/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFjAf8D8U7/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFj
- Af8D8U7/AewBzAH/ApkBMAH/ApkBYwH/AcwBmQFjAf8D8RX/A/EB/wPjAv8B7AHMLv8B7AHMAf8CmQEw
- Af8BpAKgAf8CmQEwAf8BzAGZAWMB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
+ AewBzAL/AewBzAL/AewBzAL/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZAf8D8Qb/AewBzAL/AewBzAL/
+ AewBzD7/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZAf8D8U7/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZ
+ Af8D8U7/AewBzAH/ApkBJgH/ApkBWQH/AcwBmQFZAf8D8RX/A/EB/wPjAv8B7AHMLv8B7AHMAf8CmQEm
+ Af8BpAKgAf8CmQEmAf8BzAGZAVkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
- AZkB/wLMAZkB/wLMAZkB/wHMAZkBYwH/ApkBMAH/AaQCoAH/ApkBMAH/AcwBmQFjAf8CzAGZAf8CzAGZ
+ AZkB/wLMAZkB/wLMAZkB/wHMAZkBWQH/ApkBJgH/AaQCoAH/ApkBJgH/AcwBmQFZAf8CzAGZAf8CzAGZ
Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZ
- Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8BzAGZAWMB/wKZATAB/wGk
- AqAB/wKZATAB/wHMAZkBYwH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/
+ Af8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8CzAGZAf8BzAGZAVkB/wKZASYB/wGk
+ AqAB/wKZASYB/wHMAZkBWQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/
AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/AswBmQH/
- AswBmQH/AswBmQH/AcwBmQFjAf8CmQEwAf8BpAKgAf8CmQEwAf8BzAGZAWMB/wLMAZkB/wLMAZkB/wLM
+ AswBmQH/AswBmQH/AcwBmQFZAf8CmQEmAf8BpAKgAf8CmQEmAf8BzAGZAVkB/wLMAZkB/wLMAZkB/wLM
AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLM
- AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wHMAZkBYwH/ApkBMAX/AswBYwH/
- AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZ
- AWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/
- AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/A8wF/wLMAWMB/wHM
- AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFj
- Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHM
- AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHwAcoBpgH/A/EB/wLM
- AWMB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/
- AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZ
- ATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZATAB/wHMAZkBMAH/AcwBmQEwAf8BzAGZAWMB/wPMBf8CzAFj
- Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHM
- AZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFj
- Af8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8BzAGZAWMB/wHMAZkBYwH/AcwBmQFjAf8DzAH/AUIBTQE+
+ AZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wLMAZkB/wHMAZkBWQH/ApkBJgX/AswBWQH/
+ AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZ
+ AVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/
+ AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/A8wF/wLMAVkB/wHM
+ AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZ
+ Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHM
+ AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHwAcoBpgH/A/EB/wLM
+ AVkB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/
+ AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZ
+ ASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZASYB/wHMAZkBJgH/AcwBmQEmAf8BzAGZAVkB/wPMBf8CzAFZ
+ Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHM
+ AZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZ
+ Af8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8BzAGZAVkB/wHMAZkBWQH/AcwBmQFZAf8DzAH/AUIBTQE+
BwABPgMAASgDAAFgAwABMAMAAQEBAAEBBQABQAECFgAD//8A/wBDAAs=
</value>
</data>
@@ -306,111 +306,108 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
- ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACw
- FwAAAk1TRnQBSQFMAgEBBAEAAQgBAAEIAQABFQEAARQBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFU
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABc
+ FgAAAk1TRnQBSQFMAgEBBAEAAVgBAAFYAQABFQEAARQBAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFU
AwABKAMAAQEBAAEgBQABgAE0/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A
- /wD/AP8A/wD/AP8A/wD/ADcAAwQBBVAAAwQBBUQAAUgCSQFaAU8BZwGBAdEBJQFXAY0B7QE3AV0BigHt
- AWABcgGGAcgBXgFgAWIBgAMkASyUAAFAAVIBQQFwAUkBZgFLAZADBQEHSAABQAFSAUEBcAFJAWYBSwGQ
- AwUBBzwAAkcBSAFZASQBUwGFAf8BCgFHAYcB/wEhAVkBlQH/ASMBWwGZAf8BGgFUAZQB/wEbAVABjAH/
- AUcBZgGNAfYBaAFrAW8BlQMqATOIAAE+AVABPwFvAYYBsAGJAd0BjAG2AZEB4AFKAWYBSwGQAwUBB0AA
- AT4BUAE/AW8BhgGwAYkB3QGMAbYBkQHgAUoBZgFLAZADBQEHMAADCQELAVwBXwFjAYIBJwFVAYYB/wEO
- AUoBiAH/ARYBTwGKAf8BIAFYAZQB/wElAVsBmAH/ASQBWgGWAf8BIwFZAZYB/wEbAVUBlQH/ARkBTwGM
- Af8BOwFgAYwB+wFmAW4BeAGlAUIBQwFEAVQDBwEJKwAEAQECAwMBBAMgASoDAAEBPAABPAFPAT0BbgF5
- Aa0BfwHcAbwB+gHQAf0BvwH+AdQB/wGCAbYBiwHgAUkBZgFLAZADBQEHOAABPAFPAT0BbgF5Aa0BfwHc
- AbwB+gHQAf0BvwH+AdQB/wGCAbYBiwHgAUkBZgFLAZADBQEHKAADBwEJAWYBbgF3AaYBCAFCAX0B/wEQ
- AUsBiAH/ARcBTwGJAf8BFgFOAYoB/wEgAVcBlAH/ASYBXAGZAf8BIQFUAY0B/wEYAUUBdgH/AR0BTgGF
- Af8BIAFXAZQB/wEcAVQBlQH/ARQBTQGNAf8BGgFNAYYB/wFMAU0BUAFlIAADDAEPAzsBUQNZAYgCbgFt
- AcACegF5AfQDlgH/A3kB4gNRAXk0AAE4AUsBOQFrAXIBpwF4AdoBpQH0AbwB/QGVAfgBtAH/AZcB+gG3
- Af8BqwH9AcYB/wF/AbYBhwHgAUgBZQFJAY8DBQEHMAABOAFLATkBawFyAacBeAHaAaUB9AG8Af0BlQH4
- AbQB/wGXAfoBtwH/AasB/QHGAf8BfwG2AYcB4AFEAWIBRwGhATwBVgFYAYIBQAFyAXgBlgE5AU0BUQF4
- AxYBHxgAAUgBSgFMAWEBDQFFAX4B/wEQAUgBggH/ARUBSwGFAf8BFgFPAYoB/wEVAU4BiQH/ASABVwGU
- Af8BIwFYAZMB/wEoAVoBkgH/ATsBawGkAf8BKQFXAYsB/wEcAUkBegH/ARkBSQF+Af8BHwFUAZAB/wEZ
- AVIBkQH/AUcBTQFTAXAUAAMVARsDTQFsA3MBtwKXAZYB/wO9Af8B0QLQAf8B1QHUAdUB/wGtAcoBqwH/
- AccB1wHFAf8BvQGvAa0B/wGkAZsBmAH/Am4BbQGxAzUBSCgAATYBSAE2AWkBbgGhAXEB1wGgAe4BswH9
- AYEB7wGgAf8BcwHxAZgB/wF4AfMBnQH/AYsB9gGsAf8BqgH6AcMB/wF/AbIBhQHfAUQBYgFFAY0DBQEH
- KAABNgFIATYBaQFuAaEBcQHXAaAB7gGzAf0BgQHvAaAB/wFzAfEBmAH/AXgB8wGdAf8BiwH2AawB/wF9
- AcEBmwH/AUUB1AHcAf0BPQHvAv8BMQHhAv8BKgHiAv8BLAGmAcIB5QEkASUBJgE4FAABRQFJAU8BcAEO
- AUYBgAH/AREBPgFuAf8BDAE2AWQB/wEQAUgBgQH/ARQBTgGJAf8BIAFWAZMB/wEgAVABiAH/AUcBewG5
- Af8BVwGQAdIB/wFTAY0BzgH/AUcBewG5Af8BLwFdAZIB/wEZAUUBdQH/AQsBPgF3Af8BTwFSAVYBbRAA
- A2QBkAKnAaYB/wHNAssB/wHcAtkB/wHdAtoB/wHVAdABzwH/AdMBzQHMAf8B1wHVAdYB/wGGAcQBfgH/
- AbIB1wGrAf8BvQGtAakB/wGlAYoBgwH/Aa4BmwGXAf8BlwGUAZIB/wNbAYcgAAE2AUgBNgFpAXgBoAF5
- AdYBmgHTAaMB8gGAAecBmgH/AWQB5QGGAf8BWwHmAYEB/wFgAegBhwH/AXEB7gGVAf8BkQH0Aa0B/wGm
- AeIBtQH1AYcBrgGKAd0BQgFfAUIBiwMFAQcgAAE2AUgBNgFpAXgBoAF5AdYBmgHTAaMB8gGAAecBmgH/
- AWQB5QGGAf8BWwHmAYEB/wFgAegBhwH/AVEBtAF5Af8BUgHcAeYB/wFLAfIC/wE9AeUB/QH/ATMB3wH9
- Af8BLAHbAv8BKAHjAv8BJgGdAb4B5AMUARsQAAE/AUQBSgFsAR8BUAGIAf8BXgGNAckB/wFRAXsBswH/
- ASQBUAGDAf8BFQFKAYQB/wEdAU4BiQH/AUIBcgGuAf8BWwGSAdMB/wFVAYwBzAH/AVQBiwHLAf8BVAGN
- Ac4B/wFUAY4B0AH/AUkBfgG9Af8BJQFWAY0B/wFYAV4BZQGIDAADDAEPAqYBpwH/AdIBzAHLAf8BwQG5
- AbcB/wHMAcYBxQH/Ac8CygH/Ac4ByAHGAf8BzQHHAcUB/wHOAskB/wHSAs8B/wHeAtwB/wHaAdQB1QH/
- AbEBnQGYAf8BpQGKAYMB/wGoAY4BiAH/AaoBoAGeAf8DdgG3AzoBThQAAQ8BEAEPARQBLQE2AS0BSgEt
- ATYBLQFKATUBaAE2Aa0BbwHVAYMB+gFSAdkBcAH/AUgB2gFrAf8BTQHeAXEB/wFhAeQBgwH/AYIB7AGf
- Af8BagGoAXEB2wEyAT0BMwFUATABOQEwAU0BGQEaARkBIhwAASgBKwEqAUIBNAFWAVEBoAEtATYBLQFK
- ASQBYAFDAdEBRgGeAW8B/AFIAcABZAH/AUABxAFhAf8BLQGfAWUB/wEeAcAB5QH/AVYB7gL/AUYB5QH8
- Af8BQgHoAf0B/wE3AeQB/gH/AUsBwgHTAfABZwGeAaYB1QFPAeQC/wE2AU0BUwF8EAABVgFfAWwBlQFh
- AZQB1QH/AXIBpQHjAf8BdgGoAeQB/wF6AaYB4QH/AWgBjwHIAf8BPQGAAbIB/wFdAZUB0gH/AWIBkAHR
- Af8BXQGPAdAB/wFZAY4BzgH/AVcBjgHNAf8BVAGMAcwB/wFUAY0BzQH/AVMBjgHPAf8BUwGJAcUB+gFk
- AX4BmwHFAioBKwE0BAADGgEhA7gB/wHNAcYBxQH/AbcBrgGsAf8BuwG0AbEB/wHGAcEBvwH/AcwByAHG
- Af8B1wHTAdQB/wHiAeAB3wH/AeYC4gH/AekB4wHiAf8B4gHbAdoB/wHmAuEB/wHJAb4BvQH/AacBjgGH
- Af8BpQGKAYMB/wGvAZsBlwH/AaICngH/A0MBWhwAATYBYwE3AaQBbQHLAX4B9wFOAdMBaAH/AToB0QFa
- Af8BPAHSAVwB/wFTAdoBcgH/AXsB5QGVAf8BPgF3AT8BwQMIAQsgAAEhAiIBMQFSAb8BygHqAUoB8wL/
- AUEBeAF/AbcBMQHgAfoB/wEqAdgB9gH/ASUByAHkAf8BHwHBAd0B/wEYAdcC/wEiAdAC/wFZAegB/AH/
- AUoB5wH8Af8BRgHqAf0B/wE9Ae8C/wE2AUABQQFqBAABbgHUAeYB/QE8AXkBiQGiDAABWQFeAWUBfgFq
- AZ4B3wH/AW0BoAHgAf8BcAGhAd4B/wF4AaMB3wH/AXgBpQHdAf8BPQGtAdcB/wEOAb4B4QH/AQ0BrwHX
- Af8BMgGgAc8B/wFUAZUBzwH/AV0BkQHPAf8BYAGPAc8B/wFcAY8BzwH/AVcBjgHNAf8BVQGNAcwB/wFO
- AYkBywH/AVsBjAHDAfYCHAEdASMEAAMCAQMDsgH/AegC5wH/AecB4wHkAf8B6gHnAegB/wHpAeUB5gH/
- AesB5QHmAf8B7gLnAf8B8wHuAe0B/wHtAuYB/wHXAcwBywH/AdEBxQHEAf8B1AHLAcoB/wHdAtYB/wHg
- AtsB/wG1AaEBngH/AaUBigGDAf8BrgGaAZQB/wKEAYMBwxwAATYBYwE3AaQBbwHKAX8B9wFLAc0BYwH/
- ATMByQFQAf8BMwHLAVEB/wFLAdIBZgH/AXgB3wGOAf8BOQFzAToBvwMIAQsgAAFDAVYBVwGLAXID/wFc
- AfwC/wFOA/8BQAH1Av8BNgHwAv8BLgHsAv8BJwHmAv8BHgHcAv8BJwHcAv8BXwHqAf4B/wFOAecB/AH/
- AUsB7AH9Af8BPAHoAf4B/wE0AZQBqQHXAUEBagFwAaoBRAHmAv8BOQFWAV4BhgQAAxoBIAFwAX4BkgGx
- AWIBlwHaAf8BagGdAd4B/wFvAaAB3gH/AXsBowHgAf8BZQGjAdcB/wEUAbAB2AH/AQABuwHiAf8BDAHB
- AecB/wEAAb0B5QH/AQABvQHkAf8BBAG4AeAB/wETAa4B2QH/ATMBngHNAf8BUQGUAcwB/wFgAY8BzwH/
- AV0BjwHQAf8BUQGLAcwB/wFLAU0BUAFgDAADOwFLA4UBtAHHAcYBxQH/AeMB4AHhAf8B8wHtAe4B/wHu
- AecB6AH/AfIC7gH/AfgC9QH/AfQC8QH/AfEC7AH/AewB6AHnAf8B6QHjAeIB/wHjAd0B3AH/AdgC1AH/
- AfEB6wHsAf8B0gHJAcgB/wGxAZ4BmQH/AokBiAHDHAABNgFjATYBpQFyAcgBgAH3AUgByAFdAf8BLQHC
- AUcB/wEsAcMBRwH/AUcBywFeAf8BeQHcAYwB/wE4AXMBOQG+AwgBCyQAATkBQQFCAWoBQAFUAVUBhwE9
- AVMBVQGHAS0BbAFVAdUBQwGWAXkB+wEsAZUBagH/AR4BkQFfAf8BHAGQAV8B/wErAZMBbgH/AWsB5wHz
- Af8BXwHzAv8BTgHsAf0B/wFBAecB/QH/ATcB5gL/ATMB7gL/ASkBtwHXAfEBGwIcASgEAAFbAWABZwGB
- AWABlwHbAf8BZgGcAd4B/wFuAZ8B3gH/AXgBoQHeAf8BVAGjAdQB/wEKAbEB2AH/AQABvQHlAf8BAAG7
- AeQB/wELAb8B5QH/AQABugHjAf8BAAG8AeUB/wEAAb0B5gH/AQABvQHlAf8BAAG8AeMB/wEDAbQB2wH/
- ASEBpAHRAf8BQAGSAcoB/wFsAYQBoAHKGAADHwEnA24BkAG+Ar0B/wHaAdcB2QH/AfIB7QHuAf8B+AL1
- Af8B8wLuAf8B6wLkAf8B5gHgAd8B/wHiAtoB/wHkAt0B/wH0Ae0B7gH/AfgB8gH0Af8B7AHnAekB/wHB
- Ab8BwAH/A0YBWhwAATYBYwE2AaUBcAHFAX0B9wFCAcIBVQH/ASYBuwE+Af8BJQG8AT4B/wFBAcYBVwH/
- AXYB1wGHAf8BOAFyATkBvgMIAQswAAE2AWMBNgGlAXABxQF9AfcBQgHCAVUB/wEmAbsBPgH/ASUBvAE+
- Af8BQQHGAVcB/wFXAaIBcgH/AWcB8QH3Af8BWAH7Av8BRgHuAv8BPgHyAv8BMwHOAeYB9wEuATIBMwFP
- CAADAQECAiIBIwErAWoBdwGJAaUBbgGcAdQB+gEzAaUB0wH/AQABtwHeAf8BAAG8AeQB/wEAAboB4wH/
- ARYBwQHmAf8BOQHHAegB/wEkAcQB5wH/AQ0BwAHmAf8BAAG8AeUB/wEAAboB4wH/AQABuwHkAf8BAAG8
- AeUB/wEAAbwB5QH/AQ4BvgHoAf8BfQGkAcQB3QMWARscAAMHAQkDTAFgA5YBxgHNAcwBzQH/AeoB5gHo
- Af8B6wHlAecB/wHqAeYB6AH/AeAB3gHfAf8B2gHXAdkB/wHJAsgB/wOmAeEDdwGcAzABPCAAATYBYwE2
- AaUBgwHJAYsB9wFXAcYBZwH/ATwBvgFNAf8BOwG+AU0B/wFUAccBZgH/AYgB2QGVAf8BOQFyAToBvgMI
- AQswAAE2AWMBNgGlAYMByQGLAfcBVwHGAWcB/wE8Ab4BTQH/ATsBvgFNAf8BVAHHAWYB/wGIAdkBlQH/
- ATMBZwE3AcoBQwFjAWQBlwFJAYoBjwGxAT0BWAFaAYkDGgElFAADAgEDAWUBlwG6Ad0BAgG/AekB/wEA
- AbsB5QH/AQABugHiAf8BKAHDAeUB/wFEAcUB5QH/AToBwAHjAf8BPgHCAeQB/wFBAcYB5wH/ATQBxwHp
- Af8BGwHCAeYB/wECAbsB4wH/AQABvAHmAf8BFAHLAfUB/wEsAdYC/wGIAcoC/wGDAZYBqwHBAwgBCiQA
- AycBMAN1AZYDkgG9A3cBmQNTAWkDPAFLAxgBHiwAATYBYwE2AaUBpgHUAasB9wGIAdMBkgH/AW8BzAF6
- Af8BbQHNAXoB/wGGAdUBkQH/AbMB5AG6Af8BOgFyAToBvwMIAQswAAE2AWMBNgGlAaYB1AGrAfcBiAHT
- AZIB/wFvAcwBegH/AW0BzQF6Af8BhgHVAZEB/wGzAeQBugH/AToBcgE6Ab8DCAELIAABSQFLAU8BYAFf
- AbIB8wH/ARgB0QH+Af8BKQHQAfkB/wFEAdEB9QH/AUwBzQHwAf8BOwHEAegB/wE2AcAB4wH/ATQBvgHh
- Af8BNwHAAeQB/wE8AcEB5AH/AUEBxAHmAf8BRwHRAfMB/wFHAdgB+wH/AUEB2wL/ATEB1wH+Af8BhwHH
- AfsB/wGTAccC/wFsAXkBhwGebAABNgFjATYBpQExAWwBMQG7ATEBbAExAbsBMQFsATEBuwExAWwBMQG7
- ATEBbAExAbsBMQFsATEBuwExAWwBMQG7AwgBCzAAATYBYwE2AaUBMQFsATEBuwExAWwBMQG7ATEBbAEx
- AbsBMQFsATEBuwExAWwBMQG7ATEBbAExAbsBMQFsATEBuwMIAQsgAAFxAYABlgGyAVoBsgH1Af8BMgHW
- Af4B/wFXAdoB/gH/AVIB1gH9Af8BTwHVAfwB/wFQAdUB/AH/AUoB0QH3Af8BQgHKAe8B/wE9AcUB6AH/
- AUEByQHsAf8BTQHTAfgB/wFVAdkB/gH/AVUB2gH9Af8BWAHcAf4B/wFnAdUB/gH/AY8BxQH7Af8BegGL
- AZ0BrwEsAS0BLgE4/wAFAAEYAhkBHwE8AT8BQQFOAVgBawFxAYMBYgGmAboBzQFUAdEB9AH8AUoB1QH9
- Af8BSgHVAf0B/wFOAdUB/AH/AVEB1gH9Af8BUQHWAfsB/wFTAdgB/AH/AVIB2AH9Af8BTQHZAf0B/wFZ
- AdMB/AH/AXUBxwH4Af8BegGNAaIBtgE7ATwBPgFL/wAdAAElASYBJwEvAVYBagFvAYIBZwGmAbkBywFR
- AdQB+gH/AU0B1gH8Af8BTgHYAf0B/wFNAdgB/QH/AVUB1gH4Af0BbAHBAecB9AGBAa0B2AHqAUcBSgFO
- AV3/ADEAATABMgEzAT4BUQFqAXABgQFgAZMBoQGuAV8BkgGhAa8BNAE7ATwBRwIlASYBLgEdAh4BJWgA
- AUIBTQE+BwABPgMAASgDAAFUAwABKAMAAQEBAAEBBQAB4AEBFgAD//EACv8B8AEACv8B8AEAAf8B3wH/
- Af4C/wGAA/8B8AEAAf8BjwH/AfwBfwH/AQABPwL/AfABAAH/AQcB/wH4AT8B/AEAAQcB/gEPAfABAAH+
- AQMB/wHwAR8B+AEAAQcB+AEHAfABAAH8AQEB/wHgAQEB+AEAAQcBwAEBAfABAAH4AQAB/wHAAQAB+AEA
- AQcBgAEAAfABAAHwAQABfwGAAQABeAEAAQcCAAEwAQAB4AEAAX8CAAF4AQABAQIAARABAAH8AQEB/gEA
- AQIBcAEAAQECAAEQAQAB/AEBAf4CAAFAAQABAwGAAQABEAEAAfwBAQH/AgABQAEAAQcB4AEAARABAAH8
- AQEB/wHgAQABwAEAAQMB+AEAATABAAH8AQEB/wHgAQEB8AEAAQEB/wEBAfABAAH8AQEB/wHgAQ8B8AEA
- AQEC/wHwAQAB/AEBAf8B4AEPAfABAAEBAv8B8AEABf8B8AEAAQcC/wHwAQAG/wEAAR8C/wHwAQAG/wHg
- AT8C/wHwAQAL
+ /wD/AP8A/wD/AP8A/wD/ADcAAwQBBVAAAwQBBUQAAzcBWgFYAlwB0QFQAV0BaQHtAVMBXQFpAe0DWwHI
+ A0cBgAMfASyUAANAAXABSwFMAUsBkAMFAQdIAANAAXABSwFMAUsBkAMFAQc8AAM2AVkBGgFJAYUB/wEA
+ AT0BhwH/ARcBTwGVAf8BGQFRAZkB/wEQAUoBlAH/AREBRgGMAf8BSAFiAXEB9gNOAZUDIwEziAABPwFA
+ AT8BbwFhAWMBYQHdAWMBZgFkAeABSwFMAUsBkAMFAQdAAAE/AUABPwFvAWEBYwFhAd0BYwFmAWQB4AFL
+ AUwBSwGQAwUBBzAAAwgBCwNHAYIBHQFLAYYB/wEEAUABiAH/AQwBRQGKAf8BFgFOAZQB/wEbAVEBmAH/
+ ARoBUAGWAf8BGQFPAZYB/wERAUsBlQH/AQ8BRQGMAf8BMgFfAYIB+wNTAaUDNAFUAwcBCSsABAEBAgMD
+ AQQDHQEqAwABATwAAT8BQAE/AW4DYQHcAbIB3AG6Af0BvwH+AdQB/wFiAWYBYwHgAUsBTAFLAZADBQEH
+ OAABPwFAAT8BbgNhAdwBsgHcAboB/QG/Af4B1AH/AWIBZgFjAeABSwFMAUsBkAMFAQcoAAMHAQkDVAGm
+ AQABOAFzAf8BBgFBAYgB/wENAUUBiQH/AQwBRAGKAf8BFgFNAZQB/wEcAVIBmQH/ARcBSgGNAf8BDgE7
+ AWwB/wETAUQBhQH/ARYBTQGUAf8BEgFKAZUB/wEKAUMBjQH/ARABQwGGAf8DOwFlIAADCwEPAzIBUQNJ
+ AYgDWgHAA2UB9AOWAf8DYQHiA0QBeTQAAz4BawFhAWIBYQHaAaUB1gGyAf0BlQH4AbQB/wGXAfoBtwH/
+ AasB/QHGAf8BYgFmAWMB4AFLAUwBSwGPAwUBBzAAAz4BawFhAWIBYQHaAaUB1gGyAf0BlQH4AbQB/wGX
+ AfoBtwH/AasB/QHGAf8BYgFmAWMB4AFRAVIBUQGhA0cBggFNAk4BlgNDAXgDFgEfGAADOgFhAQMBOwF0
+ Af8BBgE+AYIB/wELAUEBhQH/AQwBRQGKAf8BCwFEAYkB/wEWAU0BlAH/ARkBTgGTAf8BHgFQAZIB/wEx
+ AWEBpAH/AR8BTQGLAf8BEgE/AXAB/wEPAT8BdAH/ARUBSgGQAf8BDwFIAZEB/wNAAXAUAAMUARsDPwFs
+ A1cBtwKXAZYB/wO9Af8B0QLQAf8B1QHUAdUB/wGtAcoBqwH/AccB1wHFAf8BvQGvAa0B/wGkAZsBmAH/
+ A1YBsQMuAUgoAAM9AWkBXQFfAV0B1wGgAdABqQH9AYEB7wGgAf8BaQHxAZgB/wFuAfMBnQH/AYsB9gGs
+ Af8BqgH6AcMB/wFeAWIBXwHfA0oBjQMFAQcoAAM9AWkBXQFfAV0B1wGgAdABqQH9AYEB7wGgAf8BaQHx
+ AZgB/wFuAfMBnQH/AYsB9gGsAf8BcwHBAZsB/wFAAbwBvgH9ATMB7wL/AScB4QL/ASAB4gL/AVgBagFu
+ AeUDJgE4FAADQAFwAQQBPAGAAf8BBwE0AWQB/wECASwBWgH/AQYBPgGBAf8BCgFEAYkB/wEWAUwBkwH/
+ ARYBRgGIAf8BPQFxAbkB/wFNAZAB0gH/AUkBjQHOAf8BPQFxAbkB/wElAVMBkgH/AQ8BOwFrAf8BAQE0
+ AW0B/wM/AW0QAANMAZACpwGmAf8BzQLLAf8B3ALZAf8B3QLaAf8B1QHQAc8B/wHTAc0BzAH/AdcB1QHW
+ Af8BhgHEAXQB/wGyAdcBqwH/Ab0BrQGpAf8BpQGKAYMB/wGuAZsBlwH/AZcBlAGSAf8DSQGHIAADPQFp
+ A2AB1gF3AYsBewHyAYAB5wGaAf8BWgHlAYYB/wFRAeYBgQH/AVYB6AGHAf8BZwHuAZUB/wGRAfQBrQH/
+ AYABmQGEAfUBYQFjAWEB3QNKAYsDBQEHIAADPQFpA2AB1gF3AYsBewHyAYAB5wGaAf8BWgHlAYYB/wFR
+ AeYBgQH/AVYB6AGHAf8BRwG0AW8B/wFIAdwB5gH/AUEB8gL/ATMB5QH9Af8BKQHfAf0B/wEiAdsC/wEe
+ AeMC/wFVAWQBaQHkAxQBGxAAAz8BbAEVAUYBiAH/AVQBjQHJAf8BRwFxAbMB/wEaAUYBgwH/AQsBQAGE
+ Af8BEwFEAYkB/wE4AWgBrgH/AVEBkgHTAf8BSwGMAcwB/wFKAYsBywH/AUoBjQHOAf8BSgGOAdAB/wE/
+ AXQBvQH/ARsBTAGNAf8DSQGIDAADCwEPAqYBpwH/AdIBzAHLAf8BwQG5AbcB/wHMAcYBxQH/Ac8CygH/
+ Ac4ByAHGAf8BzQHHAcUB/wHOAskB/wHSAs8B/wHeAtwB/wHaAdQB1QH/AbEBnQGYAf8BpQGKAYMB/wGo
+ AY4BiAH/AaoBoAGeAf8DVwG3AzEBThQAAw8BFAMvAUoDLwFKAVMBVQFTAa0BZAGpAXYB+gFIAdkBZgH/
+ AT4B2gFhAf8BQwHeAWcB/wFXAeQBgwH/AYIB7AGfAf8BXwFhAV8B2wM0AVQBMAExATABTQMYASIcAAMr
+ AUIDUQGgAy8BSgFYAVwBWAHRATkBgAFlAfwBPgHAAVoB/wE2AcQBVwH/ASMBnwFbAf8BFAHAAeUB/wFM
+ Ae4C/wE8AeUB/AH/ATgB6AH9Af8BLQHkAf4B/wFOAXwBgQHwAV4CXwHVAUUB5AL/AUQCRQF8EAADTgGV
+ AVcBlAHVAf8BaAGlAeMB/wFsAagB5AH/AXABpgHhAf8BXgGPAcgB/wEzAYABsgH/AVMBlQHSAf8BWAGQ
+ AdEB/wFTAY8B0AH/AU8BjgHOAf8BTQGOAc0B/wFKAYwBzAH/AUoBjQHNAf8BSQGOAc8B/wFNAXgBogH6
+ A1oBxQMjATQEAAMYASEDuAH/Ac0BxgHFAf8BtwGuAawB/wG7AbQBsQH/AcYBwQG/Af8BzAHIAcYB/wHX
+ AdMB1AH/AeIB4AHfAf8B5gLiAf8B6QHjAeIB/wHiAdsB2gH/AeYC4QH/AckBvgG9Af8BpwGOAYcB/wGl
+ AYoBgwH/Aa8BmwGXAf8BogKeAf8DNwFaHAABUAFSAVABpAFtAZ4BbQH3AUQB0wFeAf8BMAHRAVAB/wEy
+ AdIBUgH/AUkB2gFoAf8BcQHlAZUB/wFWAVgBVgHBAwgBCyAAASECIgExAVUBbwFyAeoBQAHzAv8BVQJX
+ AbcBJwHgAfoB/wEgAdgB9gH/ARsByAHkAf8BFQHBAd0B/wEOAdcC/wEYAdAC/wFPAegB/AH/AUAB5wH8
+ Af8BPAHqAf0B/wEzAe8C/wE9Aj4BagQAAVoBvAHIAf0DUQGiDAADRgF+AWABngHfAf8BYwGgAeAB/wFm
+ AaEB3gH/AW4BowHfAf8BbgGlAd0B/wEzAa0B1wH/AQQBvgHhAf8BAwGvAdcB/wEoAaABzwH/AUoBlQHP
+ Af8BUwGRAc8B/wFWAY8BzwH/AVIBjwHPAf8BTQGOAc0B/wFLAY0BzAH/AUQBiQHLAf8BWwFxAY0B9gMZ
+ ASMEAAMCAQMDsgH/AegC5wH/AecB4wHkAf8B6gHnAegB/wHpAeUB5gH/AesB5QHmAf8B7gLnAf8B8wHu
+ Ae0B/wHtAuYB/wHXAcwBywH/AdEBxQHEAf8B1AHLAcoB/wHdAtYB/wHgAtsB/wG1AaEBngH/AaUBigGD
+ Af8BrgGaAZQB/wNbAcMcAAFQAVIBUAGkAW0BmwFtAfcBQQHNAVkB/wEpAckBRgH/ASkBywFHAf8BQQHS
+ AVwB/wFuAd8BjgH/AVcBWQFXAb8DCAELIAADSgGLAWgD/wFSAfwC/wFEA/8BNgH1Av8BLAHwAv8BJAHs
+ Av8BHQHmAv8BFAHcAv8BHQHcAv8BVQHqAf4B/wFEAecB/AH/AUEB7AH9Af8BMgHoAf4B/wFZAV4BXwHX
+ A1MBqgE6AeYC/wNIAYYEAAMXASADVgGxAVgBlwHaAf8BYAGdAd4B/wFlAaAB3gH/AXEBowHgAf8BWwGj
+ AdcB/wEKAbAB2AH/AQABuwHiAf8BAgHBAecB/wEAAb0B5QH/AQABvQHkAf8BAAG4AeAB/wEJAa4B2QH/
+ ASkBngHNAf8BRwGUAcwB/wFWAY8BzwH/AVMBjwHQAf8BRwGLAcwB/wM6AWAMAAMwAUsDVgG0AccBxgHF
+ Af8B4wHgAeEB/wHzAe0B7gH/Ae4B5wHoAf8B8gLuAf8B+AL1Af8B9ALxAf8B8QLsAf8B7AHoAecB/wHp
+ AeMB4gH/AeMB3QHcAf8B2ALUAf8B8QHrAewB/wHSAckByAH/AbEBngGZAf8DWwHDHAABTwFTAU8BpQFt
+ AZoBbQH3AT4ByAFTAf8BIwHCAT0B/wEiAcMBPQH/AT0BywFUAf8BbwHcAYwB/wFWAVkBVgG+AwgBCyQA
+ AT0CPgFqAUgCSQGHAUgCSQGHAVoBXgFaAdUBQwGMAV8B+wEiAZUBYAH/ARQBkQFVAf8BEgGQAVUB/wEh
+ AZMBZAH/AWEB5wHzAf8BVQHzAv8BRAHsAf0B/wE3AecB/QH/AS0B5gL/ASkB7gL/AUwBgAGLAfEDHAEo
+ BAADRwGBAVYBlwHbAf8BXAGcAd4B/wFkAZ8B3gH/AW4BoQHeAf8BSgGjAdQB/wEAAbEB2AH/AQABvQHl
+ Af8BAAG7AeQB/wEBAb8B5QH/AQABugHjAf8BAAG8AeUB/wEAAb0B5gH/AQABvQHlAf8BAAG8AeMB/wEA
+ AbQB2wH/ARcBpAHRAf8BNgGSAcoB/wNdAcoYAAMcAScDTAGQAb4CvQH/AdoB1wHZAf8B8gHtAe4B/wH4
+ AvUB/wHzAu4B/wHrAuQB/wHmAeAB3wH/AeIC2gH/AeQC3QH/AfQB7QHuAf8B+AHyAfQB/wHsAecB6QH/
+ AcEBvwHAAf8DNwFaHAABTwFTAU8BpQFtAZoBbQH3ATgBwgFLAf8BHAG7ATQB/wEbAbwBNAH/ATcBxgFN
+ Af8BbAHXAYcB/wFWAVkBVgG+AwgBCzAAAU8BUwFPAaUBbQGaAW0B9wE4AcIBSwH/ARwBuwE0Af8BGwG8
+ ATQB/wE3AcYBTQH/AU0BogFoAf8BXQHxAfcB/wFOAfsC/wE8Ae4C/wE0AfIC/wE+AZ4BpwH3AzEBTwgA
+ AwEBAgMeASsDUwGlAWIBgAGpAfoBKQGlAdMB/wEAAbcB3gH/AQABvAHkAf8BAAG6AeMB/wEMAcEB5gH/
+ AS8BxwHoAf8BGgHEAecB/wEDAcAB5gH/AQABvAHlAf8BAAG6AeMB/wEAAbsB5AH/AQABvAHlAf8BAAG8
+ AeUB/wEEAb4B6AH/AV8BYwFkAd0DFAEbHAADBwEJAzoBYANbAcYBzQHMAc0B/wHqAeYB6AH/AesB5QHn
+ Af8B6gHmAegB/wHgAd4B3wH/AdoB1wHZAf8ByQLIAf8DZQHhA1EBnAMoATwgAAFPAVMBTwGlAW4BmgGA
+ AfcBTQHGAV0B/wEyAb4BQwH/ATEBvgFDAf8BSgHHAVwB/wGIAdkBlQH/AVYBWQFWAb4DCAELMAABTwFT
+ AU8BpQFuAZoBgAH3AU0BxgFdAf8BMgG+AUMB/wExAb4BQwH/AUoBxwFcAf8BiAHZAZUB/wFaAV0BWgHK
+ AU4CTwGXAVUCVgGxAUkCSgGJAxoBJRQAAwIBAwFeAWIBZAHdAQABvwHpAf8BAAG7AeUB/wEAAboB4gH/
+ AR4BwwHlAf8BOgHFAeUB/wEwAcAB4wH/ATQBwgHkAf8BNwHGAecB/wEqAccB6QH/AREBwgHmAf8BAAG7
+ AeMB/wEAAbwB5gH/AQoBywH1Af8BIgHWAv8BiAHKAv8DWAHBAwcBCiQAAyEBMANOAZYDWgG9A04BmQM9
+ AWkDMAFLAxYBHiwAAU8BUwFPAaUBiAGhAYoB9wGIAdMBkgH/AWUBzAFwAf8BYwHNAXAB/wGGAdUBkQH/
+ AbMB5AG6Af8BVwFZAVcBvwMIAQswAAFPAVMBTwGlAYgBoQGKAfcBiAHTAZIB/wFlAcwBcAH/AWMBzQFw
+ Af8BhgHVAZEB/wGzAeQBugH/AVcBWQFXAb8DCAELIAADOgFgAVUBsgHzAf8BDgHRAf4B/wEfAdAB+QH/
+ AToB0QH1Af8BQgHNAfAB/wExAcQB6AH/ASwBwAHjAf8BKgG+AeEB/wEtAcAB5AH/ATIBwQHkAf8BNwHE
+ AeYB/wE9AdEB8wH/AT0B2AH7Af8BNwHbAv8BJwHXAf4B/wGHAccB+wH/AZMBxwL/A1ABnmwAAU8BUwFP
+ AaUBVgFYAVYBuwFWAVgBVgG7AVYBWAFWAbsBVgFYAVYBuwFWAVgBVgG7AVYBWAFWAbsBVgFYAVYBuwMI
+ AQswAAFPAVMBTwGlAVYBWAFWAbsBVgFYAVYBuwFWAVgBVgG7AVYBWAFWAbsBVgFYAVYBuwFWAVgBVgG7
+ AVYBWAFWAbsDCAELIAADVQGyAVABsgH1Af8BKAHWAf4B/wFNAdoB/gH/AUgB1gH9Af8BRQHVAfwB/wFG
+ AdUB/AH/AUAB0QH3Af8BOAHKAe8B/wEzAcUB6AH/ATcByQHsAf8BQwHTAfgB/wFLAdkB/gH/AUsB2gH9
+ Af8BTgHcAf4B/wFdAdUB/gH/AY8BxQH7Af8DVAGvAyYBOP8ABQADFgEfAzEBTgNIAYMDXAHNAUABtwHI
+ AfwBQAHVAf0B/wFAAdUB/QH/AUQB1QH8Af8BRwHWAf0B/wFHAdYB+wH/AUkB2AH8Af8BSAHYAf0B/wFD
+ AdkB/QH/AU8B0wH8Af8BawHHAfgB/wNWAbYDMAFL/wAdAAMgAS8DRwGCA1sBywFHAdQB+gH/AUMB1gH8
+ Af8BRAHYAf0B/wFDAdgB/QH/AUsBvAHaAf0BZQGHAZYB9AFjAWwBcwHqAzgBXf8AMQADKQE+A0cBgQNU
+ Aa4DVAGvAy4BRwMgAS4DGgElaAABQgFNAT4HAAE+AwABKAMAAVQDAAEoAwABAQEAAQEFAAHgAQEWAAP/
+ 8QAK/wHwAQAK/wHwAQAB/wHfAf8B/gL/AYAD/wHwAQAB/wGPAf8B/AF/Af8BAAE/Av8B8AEAAf8BBwH/
+ AfgBPwH8AQABBwH+AQ8B8AEAAf4BAwH/AfABHwH4AQABBwH4AQcB8AEAAfwBAQH/AeABAQH4AQABBwHA
+ AQEB8AEAAfgBAAH/AcABAAH4AQABBwGAAQAB8AEAAfABAAF/AYABAAF4AQABBwIAATABAAHgAQABfwIA
+ AXgBAAEBAgABEAEAAfwBAQH+AQABAgFwAQABAQIAARABAAH8AQEB/gIAAUABAAEDAYABAAEQAQAB/AEB
+ Af8CAAFAAQABBwHgAQABEAEAAfwBAQH/AeABAAHAAQABAwH4AQABMAEAAfwBAQH/AeABAQHwAQABAQH/
+ AQEB8AEAAfwBAQH/AeABDwHwAQABAQL/AfABAAH8AQEB/wHgAQ8B8AEAAQEC/wHwAQAF/wHwAQABBwL/
+ AfABAAb/AQABHwL/AfABAAb/AeABPwL/AfABAAs=
</value>
</data>
+ <metadata name="featureToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>255, 18</value>
+ </metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>62</value>
</metadata>
=== modified file 'WexInstaller/InstallWizard/InstallType.cs'
--- a/WexInstaller/InstallWizard/InstallType.cs 2011-03-10 18:30:35 +0000
+++ b/WexInstaller/InstallWizard/InstallType.cs 2011-03-18 10:29:04 +0000
@@ -1,129 +1,129 @@
using System;
-using System.Collections.Generic;
-using System.ComponentModel;
using System.Drawing;
-using System.Text;
+using System.IO;
using System.Windows.Forms;
+
+using WexInstaller.Core;
using WexInstaller.Properties;
-using WexInstaller.Core;
-using System.IO;
-using System.Resources;
+
+using MySQL.Utilities.SysUtils;
namespace WexInstaller
{
- public partial class InstallType : InstallerPanel
- {
- private SetupType currentType;
- private ProductCatalog catalog;
-
- public InstallType()
- {
- InitializeComponent();
- Caption = Resources.InstallTypeCaption;
- installPath.Text = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + Path.DirectorySeparatorChar + "MySQL";
- nextOk = true;
- }
-
- public override void Activate()
- {
- base.Activate();
-
- catalog = ProductManager.ActiveCatalog;
- if (catalog == null)
- catalog = ProductManager.Catalogs[0];
-
- if (currentType == null)
- {
- int tabIndex = 1;
- foreach (SetupType setupType in catalog.SetupTypes)
- {
- RadioButton radio = new RadioButton();
- radio.AutoSize = true;
- radio.TabIndex = tabIndex++;
- radio.TabStop = true;
- radio.UseVisualStyleBackColor = true;
- radio.Text = setupType.Name;
- radio.Padding = new Padding(4);
- radio.Tag = setupType;
- radio.Font = new Font(Font, FontStyle.Bold);
- radio.Click += new EventHandler(setupTypeClicked);
- setupTypePanel.Controls.Add(radio);
- }
- (setupTypePanel.Controls[0] as RadioButton).PerformClick();
- }
- }
-
- void setupTypeClicked(object sender, EventArgs e)
- {
- RadioButton rb = sender as RadioButton;
- currentType = rb.Tag as SetupType;
- setupTypeDescription.Text = currentType.Description;
-
- (ParentControl as InstallWizardControl).ShowFeatureSelection(currentType.Flag == (int)SetupTypeFlag.Custom);
- SignalChange();
- }
-
- private void pathBrowseButton_Click(object sender, EventArgs e)
- {
- FolderBrowserDialog d = new FolderBrowserDialog();
- if (d.ShowDialog() != DialogResult.OK) return;
- installPath.Text = d.SelectedPath;
- nextOk = true;
- SignalChange();
- }
-
- public override bool Next()
- {
- // turn off installation of all products as we are redoing it here
- ProductManager.SetGlobalProposedInstalled(false);
-
- foreach (CatalogProduct product in catalog.Products)
- {
- product.ReferencedProduct.ProposedInstalled = currentType.Includes(product);
- }
-
- return base.Next();
- }
-
- private void installPath_TextChanged(object sender, EventArgs e)
- {
- nextOk = installPath.Text.Trim().Length > 0 && !invalidPath.Visible;
- SignalChange();
- string newPath = installPath.Text.Trim();
-
- bool exists = Directory.Exists(newPath);
- warningSign.Visible = exists;
- pathExistsLabel.Visible = exists;
-
- bool rooted = false;
- try
- {
- rooted = Path.IsPathRooted(newPath) || newPath.Length == 0;
- }
- catch (ArgumentException)
- {
- }
- abort.Visible = !rooted;
- invalidPath.Visible = !rooted;
-
- if (rooted && newPath.Length > 0)
- {
- string root = Directory.GetDirectoryRoot(newPath);
- if (!newPath.StartsWith(root))
- newPath = root.Substring(0, 2) + newPath;
- InstallerConfiguration.ProposedInstallationPath = installPath.Text.Trim();
- }
- }
-
- private void InstallType_Paint(object sender, PaintEventArgs e)
- {
- Graphics gfx = e.Graphics;
- Pen myPen = new Pen(Color.LightGray);
- Point top = setupTypePanel.Location;
- top.X += setupTypePanel.Width + 4;
- Point bottom = top;
- bottom.Y += setupTypePanel.Height;
- gfx.DrawLine(myPen, top, bottom);
- }
- }
+ public partial class InstallType : InstallerPanel
+ {
+ private SetupType currentType;
+
+ public InstallType()
+ {
+ InitializeComponent();
+ Caption = Resources.InstallTypeCaption;
+ installPath.Text = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + Path.DirectorySeparatorChar + "MySQL";
+ nextOk = true;
+ }
+
+ public override void Activate()
+ {
+ base.Activate();
+
+ if (currentType == null)
+ {
+ int tabIndex = 1;
+ foreach (SetupType setupType in ProductManager.ActiveCatalog.SetupTypes)
+ {
+ RadioButton radio = new RadioButton();
+ radio.AutoSize = true;
+ radio.TabIndex = tabIndex++;
+ radio.TabStop = true;
+ radio.UseVisualStyleBackColor = true;
+ radio.Text = setupType.Name;
+ radio.Padding = new Padding(4);
+ radio.Tag = setupType;
+ radio.Font = new Font(Font, FontStyle.Bold);
+ radio.Click += new EventHandler(setupTypeClicked);
+ setupTypePanel.Controls.Add(radio);
+ }
+ (setupTypePanel.Controls[0] as RadioButton).PerformClick();
+ }
+ }
+
+ void setupTypeClicked(object sender, EventArgs e)
+ {
+ RadioButton rb = sender as RadioButton;
+ currentType = rb.Tag as SetupType;
+ setupTypeDescription.Text = currentType.Description;
+
+ (ParentControl as InstallWizardControl).ShowFeatureSelection(currentType.Flag == (int)SetupTypeFlag.Custom);
+ SignalChange();
+ }
+
+ private void pathBrowseButton_Click(object sender, EventArgs e)
+ {
+ FolderBrowserDialog d = new FolderBrowserDialog();
+ if (d.ShowDialog() != DialogResult.OK) return;
+ installPath.Text = d.SelectedPath;
+ nextOk = true;
+ SignalChange();
+ }
+
+ public override bool Next()
+ {
+ // Turn off installation of all products as we are redoing it here.
+ ProductManager.SetGlobalProposedInstalled(false);
+
+ // Reset the active catalog to our default if no customization was required.
+ if (currentType.Flag != (int)SetupTypeFlag.Custom)
+ ProductManager.ActiveCatalog = ProductManager.DefaultCatalog;
+
+ foreach (CatalogProduct product in ProductManager.ActiveCatalog.Products)
+ product.ReferencedProduct.ProposedInstalled = currentType.Includes(product);
+
+ return base.Next();
+ }
+
+ private void installPath_TextChanged(object sender, EventArgs e)
+ {
+ nextOk = installPath.Text.Trim().Length > 0 && !invalidPath.Visible;
+ SignalChange();
+ string newPath = installPath.Text.Trim();
+
+ bool exists = Directory.Exists(newPath);
+ warningSign.Visible = exists;
+ pathExistsLabel.Visible = exists;
+
+ bool rooted = false;
+ try
+ {
+ rooted = Path.IsPathRooted(newPath) || newPath.Length == 0;
+ }
+ catch (ArgumentException)
+ {
+ }
+ abort.Visible = !rooted;
+ invalidPath.Visible = !rooted;
+
+ if (rooted && newPath.Length > 0)
+ {
+ string root = Directory.GetDirectoryRoot(newPath);
+ if (!newPath.StartsWith(root))
+ newPath = root.Substring(0, 2) + newPath;
+ InstallerConfiguration.ProposedInstallationPath = installPath.Text.Trim();
+ }
+ }
+
+ /// <summary>
+ /// Draws a vertical separator line between the list of setup types and their
+ /// description text on the right.
+ /// </summary>
+ private void InstallType_Paint(object sender, PaintEventArgs e)
+ {
+ Graphics gfx = e.Graphics;
+ Pen myPen = new Pen(Color.LightGray);
+ Point top = setupTypeDescriptionLabel.Location;
+ top.X = setupTypePanel.Right;
+ Point bottom = top;
+ bottom.Y += setupTypePanel.Height;
+ gfx.DrawLine(myPen, top, bottom);
+ }
+ }
}
=== modified file 'WexInstaller/Program.cs'
--- a/WexInstaller/Program.cs 2011-03-10 03:08:26 +0000
+++ b/WexInstaller/Program.cs 2011-03-18 10:29:04 +0000
@@ -1,85 +1,68 @@
using System;
-using System.Collections.Generic;
using System.Windows.Forms;
-using Mono.Options;
-using System.Runtime.InteropServices;
-using WexInstaller.Properties;
+
using WexInstaller.Core;
-using System.Reflection;
-using System.IO;
-using System.Diagnostics;
namespace WexInstaller
{
- public class Program
+ public class Program
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
{
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- [STAThread]
- static void Main()
- {
- Logger.LogInformation("Installer starting up.");
-
- InstallerConfiguration.Load();
-
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
-
- Logger.LogInformation("Loading product manifest");
- ProductManager.Load();
-
- Logger.LogInformation("Setting default catalog.");
- string[] args = Environment.GetCommandLineArgs();
- if (args.Length > 2)
- {
- ProductManager.DefaultCatalog = args[1]; // this should be the default catalog name
- }
- else
- {
- ProductManager.DefaultCatalog = null;
- }
-
- Application.Run(new MainForm());
-
- InstallerConfiguration.Save();
- Logger.LogInformation("Installer exit");
- }
+ Logger.LogInformation("Installer starting up.");
+
+ InstallerConfiguration.Load();
+
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+
+ Logger.LogInformation("Loading product manifest");
+ ProductManager.Load();
+
+ Application.Run(new MainForm());
+
+ InstallerConfiguration.Save();
+ Logger.LogInformation("Installer exit");
+ }
/* static bool ProcessCommandLineArguments()
- {
- bool checkForUpdates = false;
- bool showHelp = false;
-
- string[] args = Environment.GetCommandLineArgs();
- OptionSet options = new OptionSet();
- options.Add(Resources.HelpOptions, Resources.HelpDescription, o => showHelp = true);
- options.Add(Resources.CheckForUpdatesOptions, Resources.CheckForUpdatesDescription, o => checkForUpdates = true);
- List<string> extra = options.Parse(Environment.GetCommandLineArgs());
- if (showHelp)
- ShowHelp(options);
- else if (checkForUpdates)
- CheckForUpdates();
- else
- return false;
- return true;
- }
-
- static void ShowHelp(OptionSet options)
- {
- Console.WriteLine(Resources.AppName);
- options.WriteOptionDescriptions(Console.Out);
- }
-
- public static void CheckForUpdates()
- {
- //DialogResult result = MessageBox.Show(Resources.UpdatesAreAvailable, Resources.UpdatesAreAvailableCaption,
- // MessageBoxButtons.YesNo, MessageBoxIcon.Question);
- //if (result == DialogResult.Yes)
- //{
- // // need to jump to the udpate form here
- // Program.FormManager.CurrentForm = new Overview(2);
- //}
- }*/
- }
+ {
+ bool checkForUpdates = false;
+ bool showHelp = false;
+
+ string[] args = Environment.GetCommandLineArgs();
+ OptionSet options = new OptionSet();
+ options.Add(Resources.HelpOptions, Resources.HelpDescription, o => showHelp = true);
+ options.Add(Resources.CheckForUpdatesOptions, Resources.CheckForUpdatesDescription, o => checkForUpdates = true);
+ List<string> extra = options.Parse(Environment.GetCommandLineArgs());
+ if (showHelp)
+ ShowHelp(options);
+ else if (checkForUpdates)
+ CheckForUpdates();
+ else
+ return false;
+ return true;
+ }
+
+ static void ShowHelp(OptionSet options)
+ {
+ Console.WriteLine(Resources.AppName);
+ options.WriteOptionDescriptions(Console.Out);
+ }
+
+ public static void CheckForUpdates()
+ {
+ //DialogResult result = MessageBox.Show(Resources.UpdatesAreAvailable, Resources.UpdatesAreAvailableCaption,
+ // MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+ //if (result == DialogResult.Yes)
+ //{
+ // // need to jump to the udpate form here
+ // Program.FormManager.CurrentForm = new Overview(2);
+ //}
+ }*/
+ }
}
=== modified file 'WexInstaller/RemovePanels/RemoveComplete.cs'
--- a/WexInstaller/RemovePanels/RemoveComplete.cs 2011-03-10 18:30:35 +0000
+++ b/WexInstaller/RemovePanels/RemoveComplete.cs 2011-03-18 10:29:04 +0000
@@ -3,6 +3,7 @@
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
+using System.Threading;
using WexInstaller.Core;
using WexInstaller.Properties;
@@ -77,9 +78,7 @@
foreach (Product p in serverProducts)
{
string dataDirectory = p.GetInstalledProductRegistryKey("DataLocation");
-
- if (!String.IsNullOrEmpty(dataDirectory) && Directory.Exists(dataDirectory))
- Directory.Delete(dataDirectory, true);
+ DeleteDirectory(dataDirectory);
}
}
}
@@ -106,5 +105,52 @@
return base.Next();
}
+
+ /// <summary>
+ /// Helper method to recursively remove a folder with some additional handling
+ /// not provided by Directory.Delete().
+ /// </summary>
+ /// <param name="target">The folder to remove (including all its content).</param>
+ /// <returns>True if removal was successful, otherwise false.</returns>
+ public static bool DeleteDirectory(string target)
+ {
+ bool result = !String.IsNullOrEmpty(target) && Directory.Exists(target);
+ if (!result)
+ return false;
+
+ string[] files = Directory.GetFiles(target);
+ string[] dirs = Directory.GetDirectories(target);
+
+ foreach (string file in files)
+ {
+ // In the case a file is set to read-only we would get an IO exception.
+ File.SetAttributes(file, FileAttributes.Normal);
+ File.Delete(file);
+ }
+
+ foreach (string dir in dirs)
+ DeleteDirectory(dir);
+
+ File.SetAttributes(target, FileAttributes.Normal);
+ try
+ {
+ Directory.Delete(target, false);
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // Ignore. Folder might be removed outside of the application already.
+ }
+ catch (IOException)
+ {
+ // Usually thrown if the folder is blocked.
+ if (Directory.GetCurrentDirectory().Equals(target, StringComparison.InvariantCultureIgnoreCase))
+ Directory.SetCurrentDirectory("..");
+ Thread.Sleep(0);
+ Directory.Delete(target, false);
+ }
+
+ return result;
+ }
+
}
}
=== modified file 'WexInstaller/WexInstaller.csproj'
--- a/WexInstaller/WexInstaller.csproj 2011-02-25 15:04:43 +0000
+++ b/WexInstaller/WexInstaller.csproj 2011-03-18 10:29:04 +0000
@@ -235,6 +235,9 @@
<DependentUpon>FeatureBox.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
+ <EmbeddedResource Include="Controls\FeatureTreeView.resx">
+ <DependentUpon>FeatureTreeView.cs</DependentUpon>
+ </EmbeddedResource>
<EmbeddedResource Include="Controls\RemoveControl.resx">
<DependentUpon>RemoveControl.cs</DependentUpon>
<SubType>Designer</SubType>
=== modified file 'installer-vs2010.sln'
--- a/installer-vs2010.sln 2011-03-10 03:08:26 +0000
+++ b/installer-vs2010.sln 2011-03-18 10:29:04 +0000
@@ -122,7 +122,6 @@
{13190F97-5D72-4949-A77A-500A57DA44BB}.Debug|x86.Build.0 = Debug|x86
{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Any CPU.ActiveCfg = Release|x86
{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Mixed Platforms.Build.0 = Release|x86
{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|Win32.ActiveCfg = Release|x86
{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|x86.ActiveCfg = Release|x86
{13190F97-5D72-4949-A77A-500A57DA44BB}.Release|x86.Build.0 = Release|x86
@@ -146,7 +145,6 @@
{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Debug|x86.Build.0 = Debug|x86
{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Any CPU.ActiveCfg = Release|x86
{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Mixed Platforms.Build.0 = Release|x86
{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|Win32.ActiveCfg = Release|x86
{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|x86.ActiveCfg = Release|x86
{FBC6C598-EC89-49E6-8FE4-4140141761CC}.Release|x86.Build.0 = Release|x86
@@ -193,7 +191,6 @@
{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Debug|x86.Build.0 = Debug|x86
{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Any CPU.ActiveCfg = Release|x86
{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Mixed Platforms.Build.0 = Release|x86
{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|Win32.ActiveCfg = Release|x86
{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|x86.ActiveCfg = Release|x86
{D2E2842E-20B1-4167-8FE4-32CCD9D63214}.Release|x86.Build.0 = Release|x86
Attachment: [text/bzr-bundle] bzr/mike.lischke@oracle.com-20110318102904-q1xhttrx7ubu91rn.bundle
| Thread |
|---|
| • bzr commit into wex-installer-1.0 branch (mike.lischke:371) | Mike Lischke | 18 Mar |