diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..558fe14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,428 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates +*.env + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ + +[Dd]ebug/x64/ +[Dd]ebugPublic/x64/ +[Rr]elease/x64/ +[Rr]eleases/x64/ +bin/x64/ +obj/x64/ + +[Dd]ebug/x86/ +[Dd]ebugPublic/x86/ +[Rr]elease/x86/ +[Rr]eleases/x86/ +bin/x86/ +obj/x86/ + +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +[Aa][Rr][Mm]64[Ee][Cc]/ +bld/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Build results on 'Bin' directories +**/[Bb]in/* +# Uncomment if you have tasks that rely on *.refresh files to move binaries +# (https://github.com/github/gitignore/pull/3736) +#!**/[Bb]in/*.refresh + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* +*.trx + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Approval Tests result files +*.received.* + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.idb +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +# but not Directory.Build.rsp, as it configures directory-level build defaults +!Directory.Build.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +**/.paket/paket.exe +paket-files/ + +# FAKE - F# Make +**/.fake/ + +# CodeRush personal settings +**/.cr/personal + +# Python Tools for Visual Studio (PTVS) +**/__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +#tools/** +#!tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog +MSBuild_Logs/ + +# AWS SAM Build and Temporary Artifacts folder +.aws-sam + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +**/.mfractor/ + +# Local History for Visual Studio +**/.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +**/.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp \ No newline at end of file diff --git a/JRCookbook.sln b/JRCookbook.sln new file mode 100644 index 0000000..b244007 --- /dev/null +++ b/JRCookbook.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33122.133 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JRCookbookBusiness", "JRCookbookBusiness\JRCookbookBusiness.csproj", "{A3A35111-FE61-4634-9BAD-0208C574D3D0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JRCookbook", "JRCookbook\JRCookbook.csproj", "{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JRCookbookControls", "JRCookbookControls\JRCookbookControls.csproj", "{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A3A35111-FE61-4634-9BAD-0208C574D3D0}.Debug|x86.ActiveCfg = Debug|x86 + {A3A35111-FE61-4634-9BAD-0208C574D3D0}.Debug|x86.Build.0 = Debug|x86 + {A3A35111-FE61-4634-9BAD-0208C574D3D0}.Release|x86.ActiveCfg = Release|x86 + {A3A35111-FE61-4634-9BAD-0208C574D3D0}.Release|x86.Build.0 = Release|x86 + {F9644AEA-63C8-48DB-ABB4-1AA8E666469E}.Debug|x86.ActiveCfg = Debug|x86 + {F9644AEA-63C8-48DB-ABB4-1AA8E666469E}.Debug|x86.Build.0 = Debug|x86 + {F9644AEA-63C8-48DB-ABB4-1AA8E666469E}.Release|x86.ActiveCfg = Release|x86 + {F9644AEA-63C8-48DB-ABB4-1AA8E666469E}.Release|x86.Build.0 = Release|x86 + {28B4EDFB-20F5-41EB-9759-5697EABD1EE3}.Debug|x86.ActiveCfg = Debug|x86 + {28B4EDFB-20F5-41EB-9759-5697EABD1EE3}.Debug|x86.Build.0 = Debug|x86 + {28B4EDFB-20F5-41EB-9759-5697EABD1EE3}.Release|x86.ActiveCfg = Release|x86 + {28B4EDFB-20F5-41EB-9759-5697EABD1EE3}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F13F137E-80EA-4693-81C8-3D88F49A4E87} + EndGlobalSection +EndGlobal diff --git a/JRCookbook/CommonRoutines.cs b/JRCookbook/CommonRoutines.cs new file mode 100644 index 0000000..c422e72 --- /dev/null +++ b/JRCookbook/CommonRoutines.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace JRCookbook +{ + internal static class CommonRoutines + { + + } +} diff --git a/JRCookbook/Constants.cs b/JRCookbook/Constants.cs new file mode 100644 index 0000000..0c8cb06 --- /dev/null +++ b/JRCookbook/Constants.cs @@ -0,0 +1,19 @@ +using System; +//using System.Net; +//using System.Collections.Generic; +//using System.Data; +//using System.IO; +//using System.Linq; +//using System.Text; +//using System.Threading.Tasks; + +namespace JRCookbook +{ + static class Constants + { + public static String CRLF = "\r\n"; + + + } + +} diff --git a/JRCookbook/CopilotIndices/18.3.511.5503/CodeChunks.db b/JRCookbook/CopilotIndices/18.3.511.5503/CodeChunks.db new file mode 100644 index 0000000..9917891 Binary files /dev/null and b/JRCookbook/CopilotIndices/18.3.511.5503/CodeChunks.db differ diff --git a/JRCookbook/CopilotIndices/18.3.511.5503/SemanticSymbols.db b/JRCookbook/CopilotIndices/18.3.511.5503/SemanticSymbols.db new file mode 100644 index 0000000..f40f534 Binary files /dev/null and b/JRCookbook/CopilotIndices/18.3.511.5503/SemanticSymbols.db differ diff --git a/JRCookbook/DesignTimeBuild/.dtbcache.v2 b/JRCookbook/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000..158a82c Binary files /dev/null and b/JRCookbook/DesignTimeBuild/.dtbcache.v2 differ diff --git a/JRCookbook/FileContentIndex/01a4d00a-b844-4bf4-83a8-37c4396f6203.vsidx b/JRCookbook/FileContentIndex/01a4d00a-b844-4bf4-83a8-37c4396f6203.vsidx new file mode 100644 index 0000000..84558eb Binary files /dev/null and b/JRCookbook/FileContentIndex/01a4d00a-b844-4bf4-83a8-37c4396f6203.vsidx differ diff --git a/JRCookbook/FileContentIndex/17107a6e-83c4-46f1-b2bc-9f3254d89b22.vsidx b/JRCookbook/FileContentIndex/17107a6e-83c4-46f1-b2bc-9f3254d89b22.vsidx new file mode 100644 index 0000000..bdb8ba2 Binary files /dev/null and b/JRCookbook/FileContentIndex/17107a6e-83c4-46f1-b2bc-9f3254d89b22.vsidx differ diff --git a/JRCookbook/JRCookbook.csproj b/JRCookbook/JRCookbook.csproj new file mode 100644 index 0000000..b1e44f1 --- /dev/null +++ b/JRCookbook/JRCookbook.csproj @@ -0,0 +1,58 @@ + + + + WinExe + net10.0-windows7.0 + true + true + JRCookbookStrongNameKey.snk + x86 + x86 + + + + x86 + true + + + + x86 + + + + + + + + + + + + + + Form + + + frmEditCookbook.Designer.cs + + + True + True + Resources.resx + + + + + + frmEditCookbook - Copy.resx + + + frmEditCookbook.resx + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/JRCookbook/JRCookbookStrongNameKey.snk b/JRCookbook/JRCookbookStrongNameKey.snk new file mode 100644 index 0000000..4ae9cf8 Binary files /dev/null and b/JRCookbook/JRCookbookStrongNameKey.snk differ diff --git a/JRCookbook/JRJRAdhocUpdateForm.Designer.cs b/JRCookbook/JRJRAdhocUpdateForm.Designer.cs new file mode 100644 index 0000000..2a4d1ad --- /dev/null +++ b/JRCookbook/JRJRAdhocUpdateForm.Designer.cs @@ -0,0 +1,114 @@ + +namespace JRCookbook +{ + partial class JRJRAdhocUpdateForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtAdhocUpdateSQL = new System.Windows.Forms.TextBox(); + this.btnRunUpdateSQL = new System.Windows.Forms.Button(); + this.btnRunScriptInCode = new System.Windows.Forms.Button(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // txtAdhocUpdateSQL + // + this.txtAdhocUpdateSQL.Location = new System.Drawing.Point(32, 36); + this.txtAdhocUpdateSQL.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.txtAdhocUpdateSQL.Multiline = true; + this.txtAdhocUpdateSQL.Name = "txtAdhocUpdateSQL"; + this.txtAdhocUpdateSQL.Size = new System.Drawing.Size(1515, 775); + this.txtAdhocUpdateSQL.TabIndex = 0; + // + // btnRunUpdateSQL + // + this.btnRunUpdateSQL.Location = new System.Drawing.Point(1605, 36); + this.btnRunUpdateSQL.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.btnRunUpdateSQL.Name = "btnRunUpdateSQL"; + this.btnRunUpdateSQL.Size = new System.Drawing.Size(308, 63); + this.btnRunUpdateSQL.TabIndex = 1; + this.btnRunUpdateSQL.Text = "Run Update SQL"; + this.btnRunUpdateSQL.UseVisualStyleBackColor = true; + this.btnRunUpdateSQL.Click += new System.EventHandler(this.btnRunUpdateSQL_Click); + // + // btnRunScriptInCode + // + this.btnRunScriptInCode.Location = new System.Drawing.Point(1605, 118); + this.btnRunScriptInCode.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.btnRunScriptInCode.Name = "btnRunScriptInCode"; + this.btnRunScriptInCode.Size = new System.Drawing.Size(308, 63); + this.btnRunScriptInCode.TabIndex = 2; + this.btnRunScriptInCode.Text = "RunScriptInCode"; + this.btnRunScriptInCode.UseVisualStyleBackColor = true; + this.btnRunScriptInCode.Click += new System.EventHandler(this.btnRunScriptInCode_Click); + // + // richTextBox1 + // + this.richTextBox1.Location = new System.Drawing.Point(41, 858); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(2274, 500); + this.richTextBox1.TabIndex = 3; + this.richTextBox1.Text = ""; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(1874, 726); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(188, 58); + this.button1.TabIndex = 4; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // JRJRAdhocUpdateForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(2449, 1490); + this.Controls.Add(this.button1); + this.Controls.Add(this.richTextBox1); + this.Controls.Add(this.btnRunScriptInCode); + this.Controls.Add(this.btnRunUpdateSQL); + this.Controls.Add(this.txtAdhocUpdateSQL); + this.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.Name = "JRJRAdhocUpdateForm"; + this.Text = "JRJRAdhocUpdateForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtAdhocUpdateSQL; + private System.Windows.Forms.Button btnRunUpdateSQL; + private System.Windows.Forms.Button btnRunScriptInCode; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.Button button1; + } +} \ No newline at end of file diff --git a/JRCookbook/JRJRAdhocUpdateForm.cs b/JRCookbook/JRJRAdhocUpdateForm.cs new file mode 100644 index 0000000..1ca56b6 --- /dev/null +++ b/JRCookbook/JRJRAdhocUpdateForm.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Documents; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbook +{ + public partial class JRJRAdhocUpdateForm : Form + { + public JRJRAdhocUpdateForm() + { + InitializeComponent(); + } + + private void btnRunUpdateSQL_Click(object sender, EventArgs e) + { + try + { + if (txtAdhocUpdateSQL.Text.Trim() == String.Empty) + { + MessageBox.Show("SQL Required"); + return; + } + + var intResult = JRCookbookBusinessAppManagement.JRJRUpdateAdhoc(txtAdhocUpdateSQL.Text); + + MessageBox.Show(intResult.ToString() + " record(s) affected"); + + } + catch (Exception ex) + { + MessageBox.Show(ex.ToString()); + } + } + + private void btnRunScriptInCode_Click(object sender, EventArgs e) + { + try + { + var rowsAffected = 0; + + //List JRJRItems = new List(); + //JRJRItems.Add("size"); + //JRJRItems.Add("volume"); + //JRJRItems.Add("scant"); + //JRJRItems.Add("are"); + //JRJRItems.Add("oz"); + //JRJRItems.Add("ounce"); + //JRJRItems.Add("ounces"); + //JRJRItems.Add("approximate"); + //JRJRItems.Add("approximately"); + //JRJRItems.Add("approx"); + //JRJRItems.Add("lbs"); + //JRJRItems.Add("lb"); + //JRJRItems.Add("pound"); + //JRJRItems.Add("pounds"); + //JRJRItems.Add("etc"); + //JRJRItems.Add("teaspoons"); + //JRJRItems.Add("teaspoon"); + //JRJRItems.Add("tsp"); + //JRJRItems.Add("tbsp"); + //JRJRItems.Add("cup"); + //JRJRItems.Add("cups"); + //JRJRItems.Add("enough"); + //JRJRItems.Add("not"); + + //foreach (var item in JRJRItems) + //{ + // var insertStatement = "INSERT INTO ingredientskipsearchword (wordid,word) VALUES ({" + Guid.NewGuid().ToString() + "},'" + item + "')"; + // rowsAffected += JRCookbookBusinessAppManagement.JRJRUpdateAdhoc(insertStatement); + + //} + + + //var selectStatement = "SELECT DISTINCT ingredientfolderid FROM ingredientfolder"; + //var resultSet = JRCookbookBusinessAppManagement.JRJRSelectAdhoc(selectStatement); + //foreach (DataRow row in resultSet.Tables[0].Rows) + //{ + // Int32 oldID = (Int32)row["ingredientfolderid"]; + // Guid newID = Guid.NewGuid(); + + // if (oldID == 0) + // { + // newID = Guid.Empty; + // } + + // var updateStatement = "UPDATE ingredientfolder SET ingredientfolderidnew={" + newID.ToString() + "} WHERE ingredientfolderid=" + oldID.ToString(); + // rowsAffected += JRCookbookBusinessAppManagement.JRJRUpdateAdhoc(updateStatement); + + // updateStatement = "UPDATE ingredientfolder SET parentfolderidnew={" + newID.ToString() + "} WHERE parentfolderid=" + oldID.ToString(); + // rowsAffected += JRCookbookBusinessAppManagement.JRJRUpdateAdhoc(updateStatement); + + // updateStatement = "UPDATE ingredient SET ingredientfolderidnew={" + newID.ToString() + "} WHERE ingredientfolderid=" + oldID.ToString(); + // rowsAffected += JRCookbookBusinessAppManagement.JRJRUpdateAdhoc(updateStatement); + + //} + + MessageBox.Show(rowsAffected.ToString() + " rows affected"); + } + catch (Exception ex) + { + MessageBox.Show(ex.ToString()); + } + + } + + private void button1_Click(object sender, EventArgs e) + { + + JRCookbookBusiness.Recipe asdf = new Recipe(new Guid("{5D9DF038-21BE-432E-A357-04C1DA7183E9}")); + String strHTML = asdf.GetHTML(null); + String strRTF = JRCookbookBusiness.Utility.ConvertHTLMLToRTF(strHTML); + richTextBox1.Rtf = strRTF; + } + } + +} diff --git a/JRCookbook/JRJRAdhocUpdateForm.resx b/JRCookbook/JRJRAdhocUpdateForm.resx new file mode 100644 index 0000000..b5ae26c --- /dev/null +++ b/JRCookbook/JRJRAdhocUpdateForm.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/JRCookbook/Program.cs b/JRCookbook/Program.cs new file mode 100644 index 0000000..7df375d --- /dev/null +++ b/JRCookbook/Program.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace JRCookbook +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.SetHighDpiMode(HighDpiMode.SystemAware); + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new frmMainRecipe()); + } + } +} diff --git a/JRCookbook/Properties/Resources.Designer.cs b/JRCookbook/Properties/Resources.Designer.cs new file mode 100644 index 0000000..d623d37 --- /dev/null +++ b/JRCookbook/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace JRCookbook.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JRCookbook.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Search { + get { + object obj = ResourceManager.GetObject("Search", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/JRCookbook/Properties/Resources.resx b/JRCookbook/Properties/Resources.resx new file mode 100644 index 0000000..424784b --- /dev/null +++ b/JRCookbook/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Search.BMP;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/JRCookbook/Search.BMP b/JRCookbook/Search.BMP new file mode 100644 index 0000000..18c8408 Binary files /dev/null and b/JRCookbook/Search.BMP differ diff --git a/JRCookbook/frmEditCookbook.Designer.cs b/JRCookbook/frmEditCookbook.Designer.cs new file mode 100644 index 0000000..60d3c5c --- /dev/null +++ b/JRCookbook/frmEditCookbook.Designer.cs @@ -0,0 +1,180 @@ + +namespace JRCookbook +{ + partial class frmEditCookbook + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + label1 = new System.Windows.Forms.Label(); + txtCookbookName = new System.Windows.Forms.TextBox(); + label2 = new System.Windows.Forms.Label(); + txtAuthor = new System.Windows.Forms.TextBox(); + label3 = new System.Windows.Forms.Label(); + txtCopyright = new System.Windows.Forms.TextBox(); + label4 = new System.Windows.Forms.Label(); + txtComments = new System.Windows.Forms.TextBox(); + btnOK = new System.Windows.Forms.Button(); + btnCancel = new System.Windows.Forms.Button(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(29, 44); + label1.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(244, 41); + label1.TabIndex = 0; + label1.Text = "Cookbook Name"; + // + // txtCookbookName + // + txtCookbookName.Location = new System.Drawing.Point(284, 36); + txtCookbookName.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtCookbookName.MaxLength = 250; + txtCookbookName.Name = "txtCookbookName"; + txtCookbookName.Size = new System.Drawing.Size(1017, 47); + txtCookbookName.TabIndex = 1; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(29, 123); + label2.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(109, 41); + label2.TabIndex = 2; + label2.Text = "Author"; + // + // txtAuthor + // + txtAuthor.Location = new System.Drawing.Point(284, 115); + txtAuthor.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtAuthor.MaxLength = 250; + txtAuthor.Name = "txtAuthor"; + txtAuthor.Size = new System.Drawing.Size(677, 47); + txtAuthor.TabIndex = 3; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new System.Drawing.Point(29, 202); + label3.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(150, 41); + label3.TabIndex = 4; + label3.Text = "Copyright"; + // + // txtCopyright + // + txtCopyright.Location = new System.Drawing.Point(284, 194); + txtCopyright.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtCopyright.MaxLength = 250; + txtCopyright.Name = "txtCopyright"; + txtCopyright.Size = new System.Drawing.Size(1017, 47); + txtCopyright.TabIndex = 5; + // + // label4 + // + label4.AutoSize = true; + label4.Location = new System.Drawing.Point(29, 282); + label4.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label4.Name = "label4"; + label4.Size = new System.Drawing.Size(163, 41); + label4.TabIndex = 6; + label4.Text = "Comments"; + // + // txtComments + // + txtComments.Location = new System.Drawing.Point(284, 273); + txtComments.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtComments.MaxLength = 2000; + txtComments.Multiline = true; + txtComments.Name = "txtComments"; + txtComments.Size = new System.Drawing.Size(1017, 521); + txtComments.TabIndex = 7; + // + // btnOK + // + btnOK.Location = new System.Drawing.Point(901, 820); + btnOK.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnOK.Name = "btnOK"; + btnOK.Size = new System.Drawing.Size(182, 63); + btnOK.TabIndex = 8; + btnOK.Text = "&OK"; + btnOK.UseVisualStyleBackColor = true; + btnOK.Click += btnOK_Click; + // + // btnCancel + // + btnCancel.Location = new System.Drawing.Point(1124, 820); + btnCancel.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new System.Drawing.Size(182, 63); + btnCancel.TabIndex = 9; + btnCancel.Text = "&Cancel"; + btnCancel.UseVisualStyleBackColor = true; + btnCancel.Click += btnCancel_Click; + // + // frmEditCookbook + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(1336, 905); + ControlBox = false; + Controls.Add(btnCancel); + Controls.Add(btnOK); + Controls.Add(txtComments); + Controls.Add(label4); + Controls.Add(txtCopyright); + Controls.Add(label3); + Controls.Add(txtAuthor); + Controls.Add(label2); + Controls.Add(txtCookbookName); + Controls.Add(label1); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + Name = "frmEditCookbook"; + Text = "Edit Cookbook"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtCookbookName; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtAuthor; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtCopyright; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtComments; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/JRCookbook/frmEditCookbook.cs b/JRCookbook/frmEditCookbook.cs new file mode 100644 index 0000000..2a370fb --- /dev/null +++ b/JRCookbook/frmEditCookbook.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbook +{ + public partial class frmEditCookbook : Form + { + private Cookbook _editedCookbook = null; + + + //Since this is a very simple object, going to just edit the existing object and return it + public Cookbook editedCookbook + { + get + { + return _editedCookbook; + } + private set + { + _editedCookbook = value; + } + } + + + public frmEditCookbook(Cookbook cookbookToEdit) + { + InitializeComponent(); + + if (cookbookToEdit == null) + { + _editedCookbook = new Cookbook(); + } + else + { + //Since this is a very simple object, going to just edit the existing object and return it + _editedCookbook = cookbookToEdit; + } + + txtCookbookName.Text = _editedCookbook.name; + txtAuthor.Text = _editedCookbook.author; + txtCopyright.Text = _editedCookbook.copyright; + txtComments.Text = _editedCookbook.comments; + } + + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (String.IsNullOrWhiteSpace(txtCookbookName.Text)) + { + MessageBox.Show("Cookbook Name is required"); + return; + } + + txtCookbookName.Text = txtCookbookName.Text.Trim(); + txtAuthor.Text = txtAuthor.Text.Trim(); + txtCopyright.Text = txtCopyright.Text.Trim(); + txtComments.Text = txtComments.Text.Trim(); + + //Since this is a very simple object, going to just edit the existing object and return it + _editedCookbook.name = txtCookbookName.Text.Trim(); + _editedCookbook.author = txtAuthor.Text.Trim(); + _editedCookbook.copyright = txtCopyright.Text.Trim(); + _editedCookbook.comments = txtComments.Text.Trim(); + + try + { + _editedCookbook.Save(); + } + catch (Exception ex) + { + MessageBox.Show("Error saving: " + ex.ToString()); + return; + } + + this.DialogResult = DialogResult.OK; + this.Close(); + } + } +} diff --git a/JRCookbook/frmEditCookbook.resx b/JRCookbook/frmEditCookbook.resx new file mode 100644 index 0000000..b92c163 --- /dev/null +++ b/JRCookbook/frmEditCookbook.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/JRCookbook/frmEditCookbookChapter.Designer.cs b/JRCookbook/frmEditCookbookChapter.Designer.cs new file mode 100644 index 0000000..d65dce6 --- /dev/null +++ b/JRCookbook/frmEditCookbookChapter.Designer.cs @@ -0,0 +1,130 @@ + +namespace JRCookbook +{ + partial class frmEditCookbookChapter + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + label1 = new System.Windows.Forms.Label(); + txtCookbookChapterName = new System.Windows.Forms.TextBox(); + label4 = new System.Windows.Forms.Label(); + txtComments = new System.Windows.Forms.TextBox(); + btnOK = new System.Windows.Forms.Button(); + btnCancel = new System.Windows.Forms.Button(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(29, 44); + label1.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(357, 41); + label1.TabIndex = 0; + label1.Text = "Cookbook Chapter Name"; + // + // txtCookbookChapterName + // + txtCookbookChapterName.Location = new System.Drawing.Point(420, 36); + txtCookbookChapterName.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtCookbookChapterName.MaxLength = 250; + txtCookbookChapterName.Name = "txtCookbookChapterName"; + txtCookbookChapterName.Size = new System.Drawing.Size(1017, 47); + txtCookbookChapterName.TabIndex = 1; + // + // label4 + // + label4.AutoSize = true; + label4.Location = new System.Drawing.Point(29, 123); + label4.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label4.Name = "label4"; + label4.Size = new System.Drawing.Size(163, 41); + label4.TabIndex = 6; + label4.Text = "Comments"; + // + // txtComments + // + txtComments.Location = new System.Drawing.Point(420, 115); + txtComments.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtComments.MaxLength = 2000; + txtComments.Multiline = true; + txtComments.Name = "txtComments"; + txtComments.Size = new System.Drawing.Size(1017, 521); + txtComments.TabIndex = 7; + // + // btnOK + // + btnOK.Location = new System.Drawing.Point(901, 659); + btnOK.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnOK.Name = "btnOK"; + btnOK.Size = new System.Drawing.Size(182, 63); + btnOK.TabIndex = 8; + btnOK.Text = "&OK"; + btnOK.UseVisualStyleBackColor = true; + btnOK.Click += btnOK_Click; + // + // btnCancel + // + btnCancel.Location = new System.Drawing.Point(1124, 659); + btnCancel.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new System.Drawing.Size(182, 63); + btnCancel.TabIndex = 9; + btnCancel.Text = "&Cancel"; + btnCancel.UseVisualStyleBackColor = true; + btnCancel.Click += btnCancel_Click; + // + // frmEditCookbookChapter + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(1487, 750); + ControlBox = false; + Controls.Add(btnCancel); + Controls.Add(btnOK); + Controls.Add(txtComments); + Controls.Add(label4); + Controls.Add(txtCookbookChapterName); + Controls.Add(label1); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + Name = "frmEditCookbookChapter"; + Text = "Edit Cookbook Chapter"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtCookbookChapterName; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtComments; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/JRCookbook/frmEditCookbookChapter.cs b/JRCookbook/frmEditCookbookChapter.cs new file mode 100644 index 0000000..85c7843 --- /dev/null +++ b/JRCookbook/frmEditCookbookChapter.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbook +{ + public partial class frmEditCookbookChapter : Form + { + private CookbookChapter _editedCookbookChapter = null; + + + public CookbookChapter editedCookbookChapter + { + get + { + return _editedCookbookChapter; + } + private set + { + _editedCookbookChapter = value; + } + } + + //Use when adding new chapter + public frmEditCookbookChapter(Guid cookbookID, Guid? parentChapterID) + { + InitializeComponent(); + + _editedCookbookChapter = new CookbookChapter(); + + _editedCookbookChapter.cookbookID = cookbookID; + _editedCookbookChapter.parentChapterID = parentChapterID; + + txtCookbookChapterName.Text = _editedCookbookChapter.name; + txtComments.Text = _editedCookbookChapter.comments; + } + + public frmEditCookbookChapter(CookbookChapter cookbookChapterToEdit) + { + InitializeComponent(); + + if (cookbookChapterToEdit == null) + { + throw new ApplicationException("Missing chapter to edit"); + } + else + { + //Since this is a very simple object, going to just edit the existing object and return it + _editedCookbookChapter = cookbookChapterToEdit; + } + + + //_editedCookbookChapter.cookbookID = cookbookID; + //_editedCookbookChapter.parentChapterID = parentChapterID; + + txtCookbookChapterName.Text = _editedCookbookChapter.name; + txtComments.Text = _editedCookbookChapter.comments; + } + + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (String.IsNullOrWhiteSpace(txtCookbookChapterName.Text)) + { + MessageBox.Show("Cookbook Chapter Name is required"); + return; + } + + txtCookbookChapterName.Text = txtCookbookChapterName.Text.Trim(); + txtComments.Text = txtComments.Text.Trim(); + + //Since this is a very simple object, going to just edit the existing object and return it + _editedCookbookChapter.name = txtCookbookChapterName.Text.Trim(); + _editedCookbookChapter.comments = txtComments.Text.Trim(); + + try + { + _editedCookbookChapter.Save(); + } + catch (Exception ex) + { + MessageBox.Show("Error saving: " + ex.ToString()); + return; + } + + this.DialogResult = DialogResult.OK; + this.Close(); + } + } +} diff --git a/JRCookbook/frmEditCookbookChapter.resx b/JRCookbook/frmEditCookbookChapter.resx new file mode 100644 index 0000000..b92c163 --- /dev/null +++ b/JRCookbook/frmEditCookbookChapter.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/JRCookbook/frmEditRecipe.Designer.cs b/JRCookbook/frmEditRecipe.Designer.cs new file mode 100644 index 0000000..5f21c6f --- /dev/null +++ b/JRCookbook/frmEditRecipe.Designer.cs @@ -0,0 +1,456 @@ + +namespace JRCookbook +{ + partial class frmEditRecipe + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.panel1 = new System.Windows.Forms.Panel(); + this.txtComments = new JRCookbookControls.JRCookbookAutoVerticalGrowTextBox(); + this.lblComments = new System.Windows.Forms.Label(); + this.txtRecipeName = new System.Windows.Forms.TextBox(); + this.lblRecipeName = new System.Windows.Forms.Label(); + this.grpIngredients = new System.Windows.Forms.GroupBox(); + this.pnlIngredients = new System.Windows.Forms.FlowLayoutPanel(); + this.grpProcedures = new System.Windows.Forms.GroupBox(); + this.pnlProcedures = new System.Windows.Forms.FlowLayoutPanel(); + this.pnlServingsYield = new System.Windows.Forms.Panel(); + this.txtServings = new JRCookbookControls.JRCookbookNumericTextBox(); + this.txtYield = new System.Windows.Forms.TextBox(); + this.lblYield = new System.Windows.Forms.Label(); + this.lblServings = new System.Windows.Forms.Label(); + this.grpTips = new System.Windows.Forms.GroupBox(); + this.pnlTips = new System.Windows.Forms.FlowLayoutPanel(); + this.pnlSourceInfo = new System.Windows.Forms.Panel(); + this.txtCopyright = new System.Windows.Forms.TextBox(); + this.lblCopyright = new System.Windows.Forms.Label(); + this.txtWebPage = new System.Windows.Forms.TextBox(); + this.lblWebPage = new System.Windows.Forms.Label(); + this.txtSource = new System.Windows.Forms.TextBox(); + this.lblSource = new System.Windows.Forms.Label(); + this.btnSave = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.mnuInsert = new System.Windows.Forms.MenuStrip(); + this.insertToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuInsertDegreeSign = new System.Windows.Forms.ToolStripMenuItem(); + this.btnViewNutrition = new System.Windows.Forms.Button(); + this.flowLayoutPanel1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.grpIngredients.SuspendLayout(); + this.grpProcedures.SuspendLayout(); + this.pnlServingsYield.SuspendLayout(); + this.grpTips.SuspendLayout(); + this.pnlSourceInfo.SuspendLayout(); + this.mnuInsert.SuspendLayout(); + this.SuspendLayout(); + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.flowLayoutPanel1.AutoScroll = true; + this.flowLayoutPanel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.flowLayoutPanel1.Controls.Add(this.panel1); + this.flowLayoutPanel1.Controls.Add(this.grpIngredients); + this.flowLayoutPanel1.Controls.Add(this.grpProcedures); + this.flowLayoutPanel1.Controls.Add(this.pnlServingsYield); + this.flowLayoutPanel1.Controls.Add(this.grpTips); + this.flowLayoutPanel1.Controls.Add(this.pnlSourceInfo); + this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.flowLayoutPanel1.Location = new System.Drawing.Point(12, 27); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(913, 420); + this.flowLayoutPanel1.TabIndex = 1; + this.flowLayoutPanel1.WrapContents = false; + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.AutoSize = true; + this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel1.Controls.Add(this.txtComments); + this.panel1.Controls.Add(this.lblComments); + this.panel1.Controls.Add(this.txtRecipeName); + this.panel1.Controls.Add(this.lblRecipeName); + this.panel1.Location = new System.Drawing.Point(3, 3); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(878, 68); + this.panel1.TabIndex = 0; + // + // txtComments + // + this.txtComments.Location = new System.Drawing.Point(90, 42); + this.txtComments.MinCharactersToMultiLine = 0; + this.txtComments.Multiline = true; + this.txtComments.Name = "txtComments"; + this.txtComments.Size = new System.Drawing.Size(771, 23); + this.txtComments.TabIndex = 3; + // + // lblComments + // + this.lblComments.AutoSize = true; + this.lblComments.Location = new System.Drawing.Point(7, 47); + this.lblComments.Name = "lblComments"; + this.lblComments.Size = new System.Drawing.Size(66, 15); + this.lblComments.TabIndex = 2; + this.lblComments.Text = "Comments"; + // + // txtRecipeName + // + this.txtRecipeName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtRecipeName.Location = new System.Drawing.Point(90, 13); + this.txtRecipeName.Name = "txtRecipeName"; + this.txtRecipeName.Size = new System.Drawing.Size(771, 23); + this.txtRecipeName.TabIndex = 1; + // + // lblRecipeName + // + this.lblRecipeName.AutoSize = true; + this.lblRecipeName.Location = new System.Drawing.Point(7, 16); + this.lblRecipeName.Name = "lblRecipeName"; + this.lblRecipeName.Size = new System.Drawing.Size(77, 15); + this.lblRecipeName.TabIndex = 0; + this.lblRecipeName.Text = "Recipe Name"; + // + // grpIngredients + // + this.grpIngredients.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.grpIngredients.AutoSize = true; + this.grpIngredients.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.grpIngredients.Controls.Add(this.pnlIngredients); + this.grpIngredients.Location = new System.Drawing.Point(3, 77); + this.grpIngredients.Name = "grpIngredients"; + this.grpIngredients.Size = new System.Drawing.Size(878, 52); + this.grpIngredients.TabIndex = 5; + this.grpIngredients.TabStop = false; + this.grpIngredients.Text = "Ingredients"; + // + // pnlIngredients + // + this.pnlIngredients.AllowDrop = true; + this.pnlIngredients.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlIngredients.AutoSize = true; + this.pnlIngredients.Location = new System.Drawing.Point(3, 17); + this.pnlIngredients.Margin = new System.Windows.Forms.Padding(0); + this.pnlIngredients.Name = "pnlIngredients"; + this.pnlIngredients.Size = new System.Drawing.Size(868, 16); + this.pnlIngredients.TabIndex = 0; + // + // grpProcedures + // + this.grpProcedures.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.grpProcedures.AutoSize = true; + this.grpProcedures.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.grpProcedures.Controls.Add(this.pnlProcedures); + this.grpProcedures.Location = new System.Drawing.Point(3, 135); + this.grpProcedures.Name = "grpProcedures"; + this.grpProcedures.Size = new System.Drawing.Size(878, 52); + this.grpProcedures.TabIndex = 6; + this.grpProcedures.TabStop = false; + this.grpProcedures.Text = "Procedures"; + // + // pnlProcedures + // + this.pnlProcedures.AllowDrop = true; + this.pnlProcedures.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlProcedures.AutoSize = true; + this.pnlProcedures.Location = new System.Drawing.Point(3, 17); + this.pnlProcedures.Margin = new System.Windows.Forms.Padding(0); + this.pnlProcedures.Name = "pnlProcedures"; + this.pnlProcedures.Size = new System.Drawing.Size(862, 16); + this.pnlProcedures.TabIndex = 1; + // + // pnlServingsYield + // + this.pnlServingsYield.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlServingsYield.Controls.Add(this.txtServings); + this.pnlServingsYield.Controls.Add(this.txtYield); + this.pnlServingsYield.Controls.Add(this.lblYield); + this.pnlServingsYield.Controls.Add(this.lblServings); + this.pnlServingsYield.Location = new System.Drawing.Point(3, 193); + this.pnlServingsYield.Name = "pnlServingsYield"; + this.pnlServingsYield.Size = new System.Drawing.Size(878, 70); + this.pnlServingsYield.TabIndex = 3; + // + // txtServings + // + this.txtServings.AllowDecimal = false; + this.txtServings.AllowEmpty = true; + this.txtServings.AllowNegative = false; + this.txtServings.Location = new System.Drawing.Point(72, 5); + this.txtServings.Name = "txtServings"; + this.txtServings.Size = new System.Drawing.Size(100, 23); + this.txtServings.TabIndex = 3; + // + // txtYield + // + this.txtYield.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtYield.Location = new System.Drawing.Point(72, 34); + this.txtYield.Name = "txtYield"; + this.txtYield.Size = new System.Drawing.Size(789, 23); + this.txtYield.TabIndex = 4; + // + // lblYield + // + this.lblYield.AutoSize = true; + this.lblYield.Location = new System.Drawing.Point(7, 37); + this.lblYield.Name = "lblYield"; + this.lblYield.Size = new System.Drawing.Size(33, 15); + this.lblYield.TabIndex = 2; + this.lblYield.Text = "Yield"; + // + // lblServings + // + this.lblServings.AutoSize = true; + this.lblServings.Location = new System.Drawing.Point(7, 8); + this.lblServings.Name = "lblServings"; + this.lblServings.Size = new System.Drawing.Size(51, 15); + this.lblServings.TabIndex = 0; + this.lblServings.Text = "Servings"; + // + // grpTips + // + this.grpTips.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.grpTips.AutoSize = true; + this.grpTips.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.grpTips.Controls.Add(this.pnlTips); + this.grpTips.Location = new System.Drawing.Point(3, 269); + this.grpTips.Name = "grpTips"; + this.grpTips.Size = new System.Drawing.Size(878, 52); + this.grpTips.TabIndex = 7; + this.grpTips.TabStop = false; + this.grpTips.Text = "Tips"; + // + // pnlTips + // + this.pnlTips.AllowDrop = true; + this.pnlTips.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlTips.AutoSize = true; + this.pnlTips.Location = new System.Drawing.Point(3, 17); + this.pnlTips.Margin = new System.Windows.Forms.Padding(0); + this.pnlTips.Name = "pnlTips"; + this.pnlTips.Size = new System.Drawing.Size(868, 16); + this.pnlTips.TabIndex = 1; + // + // pnlSourceInfo + // + this.pnlSourceInfo.Controls.Add(this.txtCopyright); + this.pnlSourceInfo.Controls.Add(this.lblCopyright); + this.pnlSourceInfo.Controls.Add(this.txtWebPage); + this.pnlSourceInfo.Controls.Add(this.lblWebPage); + this.pnlSourceInfo.Controls.Add(this.txtSource); + this.pnlSourceInfo.Controls.Add(this.lblSource); + this.pnlSourceInfo.Location = new System.Drawing.Point(3, 327); + this.pnlSourceInfo.Name = "pnlSourceInfo"; + this.pnlSourceInfo.Size = new System.Drawing.Size(878, 95); + this.pnlSourceInfo.TabIndex = 4; + // + // txtCopyright + // + this.txtCopyright.Location = new System.Drawing.Point(72, 63); + this.txtCopyright.Name = "txtCopyright"; + this.txtCopyright.Size = new System.Drawing.Size(100, 23); + this.txtCopyright.TabIndex = 5; + // + // lblCopyright + // + this.lblCopyright.AutoSize = true; + this.lblCopyright.Location = new System.Drawing.Point(7, 66); + this.lblCopyright.Name = "lblCopyright"; + this.lblCopyright.Size = new System.Drawing.Size(60, 15); + this.lblCopyright.TabIndex = 4; + this.lblCopyright.Text = "Copyright"; + // + // txtWebPage + // + this.txtWebPage.Location = new System.Drawing.Point(72, 33); + this.txtWebPage.Name = "txtWebPage"; + this.txtWebPage.Size = new System.Drawing.Size(789, 23); + this.txtWebPage.TabIndex = 3; + // + // lblWebPage + // + this.lblWebPage.AutoSize = true; + this.lblWebPage.Location = new System.Drawing.Point(7, 36); + this.lblWebPage.Name = "lblWebPage"; + this.lblWebPage.Size = new System.Drawing.Size(60, 15); + this.lblWebPage.TabIndex = 2; + this.lblWebPage.Text = "Web Page"; + // + // txtSource + // + this.txtSource.Location = new System.Drawing.Point(72, 3); + this.txtSource.Name = "txtSource"; + this.txtSource.Size = new System.Drawing.Size(789, 23); + this.txtSource.TabIndex = 1; + // + // lblSource + // + this.lblSource.AutoSize = true; + this.lblSource.Location = new System.Drawing.Point(7, 6); + this.lblSource.Name = "lblSource"; + this.lblSource.Size = new System.Drawing.Size(43, 15); + this.lblSource.TabIndex = 0; + this.lblSource.Text = "Source"; + // + // btnSave + // + this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnSave.Location = new System.Drawing.Point(940, 18); + this.btnSave.Name = "btnSave"; + this.btnSave.Size = new System.Drawing.Size(75, 23); + this.btnSave.TabIndex = 2; + this.btnSave.Text = "Save"; + this.btnSave.UseVisualStyleBackColor = true; + this.btnSave.Click += new System.EventHandler(this.btnSave_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.Location = new System.Drawing.Point(940, 48); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // mnuInsert + // + this.mnuInsert.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.insertToolStripMenuItem}); + this.mnuInsert.Location = new System.Drawing.Point(0, 0); + this.mnuInsert.Name = "mnuInsert"; + this.mnuInsert.Size = new System.Drawing.Size(1035, 24); + this.mnuInsert.TabIndex = 4; + this.mnuInsert.Text = "Insert"; + // + // insertToolStripMenuItem + // + this.insertToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mnuInsertDegreeSign}); + this.insertToolStripMenuItem.Name = "insertToolStripMenuItem"; + this.insertToolStripMenuItem.Size = new System.Drawing.Size(48, 20); + this.insertToolStripMenuItem.Text = "Insert"; + // + // mnuInsertDegreeSign + // + this.mnuInsertDegreeSign.Name = "mnuInsertDegreeSign"; + this.mnuInsertDegreeSign.Size = new System.Drawing.Size(145, 22); + this.mnuInsertDegreeSign.Text = "Degree Sign °"; + this.mnuInsertDegreeSign.Click += new System.EventHandler(this.mnuInsertDegreeSign_Click); + // + // btnViewNutrition + // + this.btnViewNutrition.Location = new System.Drawing.Point(940, 105); + this.btnViewNutrition.Name = "btnViewNutrition"; + this.btnViewNutrition.Size = new System.Drawing.Size(75, 52); + this.btnViewNutrition.TabIndex = 5; + this.btnViewNutrition.Text = "View Nutrition"; + this.btnViewNutrition.UseVisualStyleBackColor = true; + this.btnViewNutrition.Click += new System.EventHandler(this.btnViewNutrition_Click); + // + // frmEditRecipe + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1035, 439); + this.ControlBox = false; + this.Controls.Add(this.btnViewNutrition); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.flowLayoutPanel1); + this.Controls.Add(this.btnSave); + this.Controls.Add(this.mnuInsert); + this.MainMenuStrip = this.mnuInsert; + this.Name = "frmEditRecipe"; + this.Text = " Edit Recipe"; + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.grpIngredients.ResumeLayout(false); + this.grpIngredients.PerformLayout(); + this.grpProcedures.ResumeLayout(false); + this.grpProcedures.PerformLayout(); + this.pnlServingsYield.ResumeLayout(false); + this.pnlServingsYield.PerformLayout(); + this.grpTips.ResumeLayout(false); + this.grpTips.PerformLayout(); + this.pnlSourceInfo.ResumeLayout(false); + this.pnlSourceInfo.PerformLayout(); + this.mnuInsert.ResumeLayout(false); + this.mnuInsert.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Button btnSave; + private System.Windows.Forms.Panel pnlSourceInfo; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label lblComments; + private System.Windows.Forms.TextBox txtRecipeName; + private System.Windows.Forms.Label lblRecipeName; + private System.Windows.Forms.Panel pnlServingsYield; + private System.Windows.Forms.TextBox txtYield; + private System.Windows.Forms.Label lblYield; + private System.Windows.Forms.Label lblServings; + private JRCookbookControls.JRCookbookNumericTextBox txtServings; + private System.Windows.Forms.TextBox txtCopyright; + private System.Windows.Forms.Label lblCopyright; + private System.Windows.Forms.TextBox txtWebPage; + private System.Windows.Forms.Label lblWebPage; + private System.Windows.Forms.TextBox txtSource; + private System.Windows.Forms.Label lblSource; + private JRCookbookControls.JRCookbookAutoVerticalGrowTextBox txtComments; + private System.Windows.Forms.GroupBox grpIngredients; + private System.Windows.Forms.GroupBox grpProcedures; + private System.Windows.Forms.FlowLayoutPanel pnlProcedures; + private System.Windows.Forms.FlowLayoutPanel pnlIngredients; + private System.Windows.Forms.GroupBox grpTips; + private System.Windows.Forms.FlowLayoutPanel pnlTips; + private System.Windows.Forms.MenuStrip mnuInsert; + private System.Windows.Forms.ToolStripMenuItem insertToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem mnuInsertDegreeSign; + private System.Windows.Forms.Button btnViewNutrition; + } +} \ No newline at end of file diff --git a/JRCookbook/frmEditRecipe.cs b/JRCookbook/frmEditRecipe.cs new file mode 100644 index 0000000..9748d40 --- /dev/null +++ b/JRCookbook/frmEditRecipe.cs @@ -0,0 +1,725 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; +using JRCookbookControls; + +namespace JRCookbook +{ + public partial class frmEditRecipe : Form + { + private Recipe _editedRecipe = null; + + + public Recipe editedRecipe + { + get + { + return _editedRecipe; + } + private set + { + _editedRecipe = value; + } + } + + + public frmEditRecipe(Recipe recipeToEdit, Guid cookbookID, Guid? parentChapterID) + { + InitializeComponent(); + + if (recipeToEdit == null) + { + _editedRecipe = new Recipe(); + _editedRecipe.cookbookID = cookbookID; + _editedRecipe.cookbookchapterID = parentChapterID; + } + else + { + _editedRecipe = (Recipe)recipeToEdit.Clone(); + } + + + //Load name/comments + txtRecipeName.Text = _editedRecipe.recipename; + txtComments.Text = _editedRecipe.comments; + + + //Load recipe ingredients + JRCookbookEditRecipeIngredient newEditRecipeIngredient = null; + + foreach (var recipeIngredient in _editedRecipe.recipeIngredients) + { + newEditRecipeIngredient = new JRCookbookEditRecipeIngredient(recipeIngredient); + + WireEventsForEditIngredient(newEditRecipeIngredient); + this.pnlIngredients.Controls.Add(newEditRecipeIngredient); + } + + AddEmptyIngredient(); + + RecalcIngredientControlsEnabled(); + + //Load procedures + JRCookbookEditProcedure newEditProcedure = null; + + foreach (var recipeProcedure in _editedRecipe.recipeProcedures) + { + newEditProcedure = new JRCookbookEditProcedure(recipeProcedure); + + WireEventsForEditProcedure(newEditProcedure); + this.pnlProcedures.Controls.Add(newEditProcedure); + } + + AddEmptyProcedure(); + + RecalcProcedureControlsEnabled(); + + //Load tips + JRCookbookEditTip newEditTip = null; + + foreach (var recipeTip in _editedRecipe.recipeTips) + { + newEditTip = new JRCookbookEditTip(recipeTip); + + WireEventsForEditTip(newEditTip); + this.pnlTips.Controls.Add(newEditTip); + } + + AddEmptyTip(); + + RecalcTipControlsEnabled(); + + //Load Servings/Yield + txtServings.Text = _editedRecipe.servings.ToString(); + txtYield.Text = _editedRecipe.yield; + + //Load Source info + txtSource.Text = _editedRecipe.source; + txtWebPage.Text = _editedRecipe.webpage; + txtCopyright.Text = _editedRecipe.copyright; + } + + private void AddEmptyIngredient() + { + RecipeIngredient newIngredient = new RecipeIngredientItem(this._editedRecipe); + var newEditIngredient = new JRCookbookEditRecipeIngredient(newIngredient); + newEditIngredient.DeleteAllowed = false; + + WireEventsForEditIngredient(newEditIngredient); + this.pnlIngredients.Controls.Add(newEditIngredient); + } + + private void AddEmptyProcedure() + { + RecipeProcedure newProcedure = new RecipeProcedure(this._editedRecipe); + var newEditProcedure = new JRCookbookEditProcedure(newProcedure); + newEditProcedure.DeleteAllowed = false; + + WireEventsForEditProcedure(newEditProcedure); + this.pnlProcedures.Controls.Add(newEditProcedure); + } + + private void AddEmptyTip() + { + RecipeTip newTip = new RecipeTip(this._editedRecipe); + var newEditTip = new JRCookbookEditTip(newTip); + newEditTip.DeleteAllowed = false; + + WireEventsForEditTip(newEditTip); + this.pnlTips.Controls.Add(newEditTip); + } + + + private void btnSave_Click(object sender, EventArgs e) + { + _editedRecipe.recipename = txtRecipeName.Text; + _editedRecipe.comments = txtComments.Text; + + if (txtServings.Text == String.Empty) + { + _editedRecipe.servings = 1; + } + else + { + _editedRecipe.servings = Single.Parse(txtServings.Text); + } + + if (_editedRecipe.servings == 0) + { + _editedRecipe.servings = 1; + } + + _editedRecipe.yield = txtYield.Text; + + _editedRecipe.source = txtSource.Text; + _editedRecipe.webpage = txtWebPage.Text; + _editedRecipe.copyright = txtCopyright.Text; + + _editedRecipe.recipeIngredients.Clear(); + + Int32 ingredientIndex = 0; + + foreach (JRCookbookEditRecipeIngredient ingredientEdit in pnlIngredients.Controls) + { + if (!ingredientEdit.IsEmpty) + { + ingredientEdit.recipeIngredient.ingredientIndex = ingredientIndex; + _editedRecipe.recipeIngredients.Add(ingredientEdit.recipeIngredient); + + ingredientIndex += 1; + } + } + + _editedRecipe.recipeProcedures.Clear(); + + Int32 procedureIndex = 0; + + foreach(JRCookbookEditProcedure procedureEdit in pnlProcedures.Controls) + { + if (!procedureEdit.IsEmpty) + { + procedureEdit.recipeProcedure.procedureIndex = procedureIndex; + _editedRecipe.recipeProcedures.Add(procedureEdit.recipeProcedure); + + procedureIndex += 1; + } + } + + + + _editedRecipe.recipeTips.Clear(); + + Int32 tipIndex = 0; + + foreach (JRCookbookEditTip tipEdit in pnlTips.Controls) + { + if (!tipEdit.IsEmpty) + { + tipEdit.recipeTip.tipIndex = tipIndex; + _editedRecipe.recipeTips.Add(tipEdit.recipeTip); + + tipIndex += 1; + } + } + + _editedRecipe.CalcNutrition(); + + try + { + _editedRecipe.Save(); + + + //RecipeIngredient.DeleteAllByRecipeID(_editedRecipe.recipeID.Value); + //foreach (var ingredient in _editedRecipe.recipeIngredients) + //{ + // ingredient.recipeID = _editedRecipe.recipeID; + // ingredient.Save(); + //} + + //RecipeProcedure.DeleteAllByRecipeID(_editedRecipe.recipeID.Value); + //foreach (var procedure in _editedRecipe.recipeProcedures) + //{ + // procedure.recipeID = _editedRecipe.recipeID; + // procedure.Save(); + //} + + //RecipeTip.DeleteAllByRecipeID(_editedRecipe.recipeID.Value); + //foreach (var tip in _editedRecipe.recipeTips) + //{ + // tip.recipeID = _editedRecipe.recipeID; + // tip.Save(); + //} + } + catch (Exception ex) + { + MessageBox.Show("Error saving: " + ex.ToString()); + return; + } + + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + private void WireEventsForEditIngredient(JRCookbookEditRecipeIngredient editIngredient) + { + editIngredient.Width = pnlSourceInfo.Width - 3; + editIngredient.Anchor = AnchorStyles.Left | AnchorStyles.Right; + editIngredient.IngredientLinkRequested += EditIngredient_IngredientLinkRequested; + editIngredient.DeleteRequested += EditIngredient_DeleteRequested; + editIngredient.IsEmpty_Changed += EditIngredient_IsEmpty_Changed; + editIngredient.MouseDown += EditIngredient_MouseDown; + editIngredient.DragOver += EditIngredient_DragOver; + editIngredient.DragDrop += EditIngredient_DragDrop; + editIngredient.DragLeave += EditIngredient_DragLeave; + editIngredient.AllowDrop = true; + } + + private void EditIngredient_IngredientLinkRequested(object sender, EventArgs e) + { + var itemChanged = (JRCookbookEditRecipeIngredient)sender; + + var pickRecipeIngredientForm = new frmPickRecipeIngredient((RecipeIngredientItem)itemChanged.recipeIngredient); + + pickRecipeIngredientForm.ShowDialog(); + } + + private void EditIngredient_IsEmpty_Changed(object sender, EventArgs e) + { + var itemChanged = (JRCookbookEditRecipeIngredient)sender; + var indexOfItemChanged = pnlIngredients.Controls.IndexOf(itemChanged); + if (indexOfItemChanged == pnlIngredients.Controls.Count - 1 && itemChanged.IsEmpty == false) + { + AddEmptyIngredient(); + RecalcIngredientControlsEnabled(); + } + //user removed info on last "editing" ingredient + else if (indexOfItemChanged == pnlIngredients.Controls.Count - 2 && itemChanged.IsEmpty) + { + pnlIngredients.Controls.RemoveAt(pnlIngredients.Controls.Count - 1); + RecalcIngredientControlsEnabled(); + } + } + + private void EditIngredient_DeleteRequested(object sender, EventArgs e) + { + var itemToRemove = (JRCookbookEditRecipeIngredient)sender; + + pnlIngredients.Controls.Remove(itemToRemove); + RecalcIngredientControlsEnabled(); + } + + private void RecalcIngredientControlsEnabled() + { + + for (Int32 index = 0; index <= pnlIngredients.Controls.Count - 1; index++) + { + var editIngredient = (JRCookbookEditRecipeIngredient)(pnlIngredients.Controls[index]); + + //Can delete all except the last "new" item + editIngredient.DeleteAllowed = (index < pnlIngredients.Controls.Count - 1); + } + } + + /////////////////// + private void WireEventsForEditProcedure(JRCookbookEditProcedure editProcedure) + { + editProcedure.Width = pnlSourceInfo.Width - 3; + editProcedure.Anchor = AnchorStyles.Left | AnchorStyles.Right; + editProcedure.DeleteRequested += EditProcedure_DeleteRequested; + editProcedure.IsEmpty_Changed += EditProcedure_IsEmpty_Changed; + editProcedure.MouseDown += EditProcedure_MouseDown; + editProcedure.DragOver += EditProcedure_DragOver; + editProcedure.DragDrop += EditProcedure_DragDrop; + editProcedure.DragLeave += EditProcedure_DragLeave; + editProcedure.AllowDrop = true; + } + + private void EditProcedure_IsEmpty_Changed(object sender, EventArgs e) + { + var itemChanged = (JRCookbookEditProcedure)sender; + var indexOfItemChanged = pnlProcedures.Controls.IndexOf(itemChanged); + if (indexOfItemChanged == pnlProcedures.Controls.Count - 1 && itemChanged.IsEmpty == false) + { + AddEmptyProcedure(); + RecalcProcedureControlsEnabled(); + } + //user removed info on last "editing" procedure + else if(indexOfItemChanged == pnlProcedures.Controls.Count - 2 && itemChanged.IsEmpty) + { + pnlProcedures.Controls.RemoveAt(pnlProcedures.Controls.Count - 1); + RecalcProcedureControlsEnabled(); + } + } + + private void EditProcedure_DeleteRequested(object sender, EventArgs e) + { + var itemToRemove = (JRCookbookEditProcedure)sender; + + pnlProcedures.Controls.Remove(itemToRemove); + RecalcProcedureControlsEnabled(); + } + + private void RecalcProcedureControlsEnabled() + { + + for (Int32 index = 0; index <= pnlProcedures.Controls.Count - 1; index++) + { + var editProcedure = (JRCookbookEditProcedure)(pnlProcedures.Controls[index]); + + //Can delete all except the last "new" item + editProcedure.DeleteAllowed = (index < pnlProcedures.Controls.Count - 1); + } + } + + /////////////////// + private void WireEventsForEditTip(JRCookbookEditTip editTip) + { + editTip.Width = pnlSourceInfo.Width - 3; + editTip.Anchor = AnchorStyles.Left | AnchorStyles.Right; + editTip.DeleteRequested += EditTip_DeleteRequested; + editTip.IsEmpty_Changed += EditTip_IsEmpty_Changed; + editTip.MouseDown += EditTip_MouseDown; + editTip.DragOver += EditTip_DragOver; + editTip.DragDrop += EditTip_DragDrop; + editTip.DragLeave += EditTip_DragLeave; + editTip.AllowDrop = true; + } + + private void EditTip_IsEmpty_Changed(object sender, EventArgs e) + { + var itemChanged = (JRCookbookEditTip)sender; + var indexOfItemChanged = pnlTips.Controls.IndexOf(itemChanged); + if (indexOfItemChanged == pnlTips.Controls.Count - 1 && itemChanged.IsEmpty == false) + { + AddEmptyTip(); + RecalcTipControlsEnabled(); + } + //user removed info on last "editing" tip + else if (indexOfItemChanged == pnlTips.Controls.Count - 2 && itemChanged.IsEmpty) + { + pnlTips.Controls.RemoveAt(pnlTips.Controls.Count - 1); + RecalcTipControlsEnabled(); + } + } + + private void EditTip_DeleteRequested(object sender, EventArgs e) + { + var itemToRemove = (JRCookbookEditTip)sender; + + pnlTips.Controls.Remove(itemToRemove); + RecalcTipControlsEnabled(); + } + + private void RecalcTipControlsEnabled() + { + + for (Int32 index = 0; index <= pnlTips.Controls.Count - 1; index++) + { + var editTip = (JRCookbookEditTip)(pnlTips.Controls[index]); + + //Can delete all except the last "new" item + editTip.DeleteAllowed = (index < pnlTips.Controls.Count - 1); + } + } + + void EditIngredient_DragOver(object sender, DragEventArgs e) + { + base.OnDragOver(e); + + e.Effect = DragDropEffects.None; + + // is another dragable + if (e.Data.GetData(typeof(JRCookbookEditRecipeIngredient)) != null) + { + JRCookbookEditRecipeIngredient myControl = (JRCookbookEditRecipeIngredient)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl.Parent); + //Current Position + int myIndex = p.Controls.GetChildIndex((sender as JRCookbookEditRecipeIngredient)); + + JRCookbookEditRecipeIngredient q = (JRCookbookEditRecipeIngredient)e.Data.GetData(typeof(JRCookbookEditRecipeIngredient)); + int movedItemIndex = p.Controls.GetChildIndex(q); + + //Can't move last "new" item or move item onto last position + if (myIndex != p.Controls.Count - 1 && movedItemIndex != p.Controls.Count) + { + if (myIndex < movedItemIndex) + { + myControl.ShowInsertionBar(JRCookbookControls.InsertLocation.InsertBefore); + } + else if (myIndex > movedItemIndex) + { + myControl.ShowInsertionBar(JRCookbookControls.InsertLocation.InsertAfter); + } + e.Effect = DragDropEffects.Move; + } + } + } + + void EditIngredient_DragLeave(object sender, EventArgs e) + { + base.OnDragLeave(e); + + JRCookbookEditRecipeIngredient c = (JRCookbookEditRecipeIngredient)sender; + + c.HideInsertionBar(); + } + + void EditIngredient_DragDrop(object sender, DragEventArgs e) + { + base.OnDragDrop(e); + // is another dragable + if (e.Data.GetData(typeof(JRCookbookEditRecipeIngredient)) != null) + { + JRCookbookEditRecipeIngredient myControl = (JRCookbookEditRecipeIngredient)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl.Parent); + //Current Position + int myIndex = p.Controls.GetChildIndex((sender as JRCookbookEditRecipeIngredient)); + + //Dragged to control to location of next JRCookbookEditRecipeIngredient + JRCookbookEditRecipeIngredient q = (JRCookbookEditRecipeIngredient)e.Data.GetData(typeof(JRCookbookEditRecipeIngredient)); + + myControl.HideInsertionBar(); + myControl.DragEnded(); + q.HideInsertionBar(); + q.DragEnded(); + int movedItemIndex = p.Controls.GetChildIndex(q); + + //Can't move last "new" item or move item onto last position + if (myIndex != p.Controls.Count - 1 && movedItemIndex != p.Controls.Count) + { + if (myIndex != movedItemIndex) + { + p.Controls.SetChildIndex(q, myIndex); + RecalcIngredientControlsEnabled(); + } + } + } + } + + void EditIngredient_MouseDown(object sender, MouseEventArgs e) + { + base.OnMouseDown(e); + JRCookbookEditRecipeIngredient myControl = (JRCookbookEditRecipeIngredient)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl).Parent; + if (p.Controls.GetChildIndex((JRCookbookEditRecipeIngredient)sender) < p.Controls.Count - 1) + { + myControl.DragStarted(); + DoDragDrop(sender, DragDropEffects.Move | DragDropEffects.Scroll); + myControl.DragEnded(); + } + } + + /////procedure + void EditProcedure_DragOver(object sender, DragEventArgs e) + { + base.OnDragOver(e); + + e.Effect = DragDropEffects.None; + + // is another dragable + if (e.Data.GetData(typeof(JRCookbookEditProcedure)) != null) + { + JRCookbookEditProcedure myControl = (JRCookbookEditProcedure)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl.Parent); + //Current Position + int myIndex = p.Controls.GetChildIndex((sender as JRCookbookEditProcedure)); + + JRCookbookEditProcedure q = (JRCookbookEditProcedure)e.Data.GetData(typeof(JRCookbookEditProcedure)); + int movedItemIndex = p.Controls.GetChildIndex(q); + + //Can't move last "new" item or move item onto last position + if (myIndex != p.Controls.Count - 1 && movedItemIndex != p.Controls.Count) + { + if (myIndex < movedItemIndex) + { + myControl.ShowInsertionBar(JRCookbookControls.InsertLocation.InsertBefore); + } + else if (myIndex > movedItemIndex) + { + myControl.ShowInsertionBar(JRCookbookControls.InsertLocation.InsertAfter); + } + e.Effect = DragDropEffects.Move; + } + } + } + + void EditProcedure_DragLeave(object sender, EventArgs e) + { + base.OnDragLeave(e); + + JRCookbookEditProcedure c = (JRCookbookEditProcedure)sender; + + c.HideInsertionBar(); + } + + void EditProcedure_DragDrop(object sender, DragEventArgs e) + { + base.OnDragDrop(e); + // is another dragable + if (e.Data.GetData(typeof(JRCookbookEditProcedure)) != null) + { + JRCookbookEditProcedure myControl = (JRCookbookEditProcedure)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl.Parent); + //Current Position + int myIndex = p.Controls.GetChildIndex((sender as JRCookbookEditProcedure)); + + //Dragged to control to location of next JRCookbookEditProcedure + JRCookbookEditProcedure q = (JRCookbookEditProcedure)e.Data.GetData(typeof(JRCookbookEditProcedure)); + + myControl.HideInsertionBar(); + myControl.DragEnded(); + q.HideInsertionBar(); + q.DragEnded(); + int movedItemIndex = p.Controls.GetChildIndex(q); + + //Can't move last "new" item or move item onto last position + if (myIndex != p.Controls.Count - 1 && movedItemIndex != p.Controls.Count) + { + if (myIndex != movedItemIndex) + { + p.Controls.SetChildIndex(q, myIndex); + RecalcProcedureControlsEnabled(); + } + } + } + } + + void EditProcedure_MouseDown(object sender, MouseEventArgs e) + { + base.OnMouseDown(e); + JRCookbookEditProcedure myControl = (JRCookbookEditProcedure)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl).Parent; + if (p.Controls.GetChildIndex((JRCookbookEditProcedure)sender) < p.Controls.Count - 1) + { + myControl.DragStarted(); + DoDragDrop(sender, DragDropEffects.Move | DragDropEffects.Scroll); + myControl.DragEnded(); + } + } + + + /////tip + void EditTip_DragOver(object sender, DragEventArgs e) + { + base.OnDragOver(e); + + e.Effect = DragDropEffects.None; + + // is another dragable + if (e.Data.GetData(typeof(JRCookbookEditTip)) != null) + { + JRCookbookEditTip myControl = (JRCookbookEditTip)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl.Parent); + //Current Position + int myIndex = p.Controls.GetChildIndex((sender as JRCookbookEditTip)); + + JRCookbookEditTip q = (JRCookbookEditTip)e.Data.GetData(typeof(JRCookbookEditTip)); + int movedItemIndex = p.Controls.GetChildIndex(q); + + //Can't move last "new" item or move item onto last position + if (myIndex != p.Controls.Count - 1 && movedItemIndex != p.Controls.Count) + { + if (myIndex < movedItemIndex) + { + myControl.ShowInsertionBar(JRCookbookControls.InsertLocation.InsertBefore); + } + else if (myIndex > movedItemIndex) + { + myControl.ShowInsertionBar(JRCookbookControls.InsertLocation.InsertAfter); + } + e.Effect = DragDropEffects.Move; + } + } + } + + void EditTip_DragLeave(object sender, EventArgs e) + { + base.OnDragLeave(e); + + JRCookbookEditTip c = (JRCookbookEditTip)sender; + + c.HideInsertionBar(); + } + + void EditTip_DragDrop(object sender, DragEventArgs e) + { + base.OnDragDrop(e); + // is another dragable + if (e.Data.GetData(typeof(JRCookbookEditTip)) != null) + { + JRCookbookEditTip myControl = (JRCookbookEditTip)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl.Parent); + //Current Position + int myIndex = p.Controls.GetChildIndex((sender as JRCookbookEditTip)); + + //Dragged to control to location of next JRCookbookEditTip + JRCookbookEditTip q = (JRCookbookEditTip)e.Data.GetData(typeof(JRCookbookEditTip)); + + myControl.HideInsertionBar(); + myControl.DragEnded(); + q.HideInsertionBar(); + q.DragEnded(); + int movedItemIndex = p.Controls.GetChildIndex(q); + + //Can't move last "new" item or move item onto last position + if (myIndex != p.Controls.Count - 1 && movedItemIndex != p.Controls.Count) + { + if (myIndex != movedItemIndex) + { + p.Controls.SetChildIndex(q, myIndex); + RecalcTipControlsEnabled(); + } + } + } + } + + void EditTip_MouseDown(object sender, MouseEventArgs e) + { + base.OnMouseDown(e); + JRCookbookEditTip myControl = (JRCookbookEditTip)sender; + FlowLayoutPanel p = (FlowLayoutPanel)(myControl).Parent; + if (p.Controls.GetChildIndex((JRCookbookEditTip)sender) < p.Controls.Count - 1) + { + myControl.DragStarted(); + DoDragDrop(sender, DragDropEffects.Move | DragDropEffects.Scroll); + myControl.DragEnded(); + } + } + + private void mnuInsertDegreeSign_Click(object sender, EventArgs e) + { + if (this.ActiveControl is TextBox) + { + var textBox = (TextBox)this.ActiveControl; + textBox.SelectedText = "°"; + } + else if (this.ActiveControl is JRCookbookEditProcedure) + { + var editProcedure = (JRCookbookEditProcedure)this.ActiveControl; + if (editProcedure.ActiveControl is TextBox) + { + var textBox = (TextBox)editProcedure.ActiveControl; + textBox.SelectedText = "°"; + } + } + else if (this.ActiveControl is JRCookbookEditRecipeIngredient) + { + var editIngredient = (JRCookbookEditRecipeIngredient)this.ActiveControl; + if (editIngredient.ActiveControl is TextBox) + { + var textBox = (TextBox)editIngredient.ActiveControl; + textBox.SelectedText = "°"; + } + } + else if (this.ActiveControl is JRCookbookEditTip) + { + var editTip = (JRCookbookEditTip)this.ActiveControl; + if (editTip.ActiveControl is TextBox) + { + var textBox = (TextBox)editTip.ActiveControl; + textBox.SelectedText = "°"; + } + } + + } + + private void btnViewNutrition_Click(object sender, EventArgs e) + { + var nutritionForm = new frmViewRecipeNutritionAll(this.editedRecipe); + nutritionForm.ShowDialog(); + } + } +} diff --git a/JRCookbook/frmEditRecipe.resx b/JRCookbook/frmEditRecipe.resx new file mode 100644 index 0000000..d66c78a --- /dev/null +++ b/JRCookbook/frmEditRecipe.resx @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/JRCookbook/frmFindIngredient.Designer.cs b/JRCookbook/frmFindIngredient.Designer.cs new file mode 100644 index 0000000..1d1cad6 --- /dev/null +++ b/JRCookbook/frmFindIngredient.Designer.cs @@ -0,0 +1,127 @@ + +namespace JRCookbook +{ + partial class frmFindIngredient + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + txtSearchFor = new System.Windows.Forms.TextBox(); + imageList1 = new System.Windows.Forms.ImageList(components); + btnSearch = new System.Windows.Forms.Button(); + btnOK = new System.Windows.Forms.Button(); + btnCancel = new System.Windows.Forms.Button(); + lvwFoundItems = new System.Windows.Forms.ListView(); + SuspendLayout(); + // + // txtSearchFor + // + txtSearchFor.Location = new System.Drawing.Point(32, 36); + txtSearchFor.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtSearchFor.Name = "txtSearchFor"; + txtSearchFor.Size = new System.Drawing.Size(1731, 47); + txtSearchFor.TabIndex = 0; + // + // imageList1 + // + imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit; + imageList1.ImageSize = new System.Drawing.Size(16, 16); + imageList1.TransparentColor = System.Drawing.Color.Transparent; + // + // btnSearch + // + btnSearch.ImageKey = "(none)"; + btnSearch.Location = new System.Drawing.Point(1783, 36); + btnSearch.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnSearch.Name = "btnSearch"; + btnSearch.Size = new System.Drawing.Size(61, 63); + btnSearch.TabIndex = 1; + btnSearch.UseVisualStyleBackColor = true; + btnSearch.Click += btnSearch_Click; + // + // btnOK + // + btnOK.Location = new System.Drawing.Point(1462, 1134); + btnOK.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnOK.Name = "btnOK"; + btnOK.Size = new System.Drawing.Size(182, 63); + btnOK.TabIndex = 3; + btnOK.Text = "OK"; + btnOK.UseVisualStyleBackColor = true; + btnOK.Click += btnOK_Click; + // + // btnCancel + // + btnCancel.Location = new System.Drawing.Point(1659, 1134); + btnCancel.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new System.Drawing.Size(182, 63); + btnCancel.TabIndex = 4; + btnCancel.Text = "Cancel"; + btnCancel.UseVisualStyleBackColor = true; + btnCancel.Click += btnCancel_Click; + // + // lvwFoundItems + // + lvwFoundItems.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + lvwFoundItems.FullRowSelect = true; + lvwFoundItems.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; + lvwFoundItems.Location = new System.Drawing.Point(29, 110); + lvwFoundItems.MultiSelect = false; + lvwFoundItems.Name = "lvwFoundItems"; + lvwFoundItems.Size = new System.Drawing.Size(1880, 991); + lvwFoundItems.TabIndex = 5; + lvwFoundItems.UseCompatibleStateImageBehavior = false; + lvwFoundItems.View = System.Windows.Forms.View.Details; + // + // frmFindIngredient + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(1943, 1230); + Controls.Add(lvwFoundItems); + Controls.Add(btnCancel); + Controls.Add(btnOK); + Controls.Add(btnSearch); + Controls.Add(txtSearchFor); + Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + Name = "frmFindIngredient"; + Text = "frmFindIngredient"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.TextBox txtSearchFor; + private System.Windows.Forms.ImageList imageList1; + private System.Windows.Forms.Button btnSearch; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.ListView lvwFoundItems; + } +} \ No newline at end of file diff --git a/JRCookbook/frmFindIngredient.cs b/JRCookbook/frmFindIngredient.cs new file mode 100644 index 0000000..6450380 --- /dev/null +++ b/JRCookbook/frmFindIngredient.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbook +{ + public partial class frmFindIngredient : Form + { + public Ingredient selectedIngredient = null; + + private static ImageList _allButtonImagesList = new ImageList(); + private static bool _ImagesAlreadyLoaded = false; + + private const string SEARCH_IMAGE = "Search.bmp"; + + public frmFindIngredient(String initialSearchString) + { + InitializeComponent(); + LoadImages(); + txtSearchFor.Text = initialSearchString; + DoSearch(); + } + + private void btnSearch_Click(object sender, EventArgs e) + { + DoSearch(); + } + private void DoSearch() + { + lvwFoundItems.Items.Clear(); + + if (String.IsNullOrWhiteSpace(txtSearchFor.Text) == false) + { + String searchString = RecipeIngredient.NormalizeRecipeIngredientName(txtSearchFor.Text); + searchString = "%" + searchString.Replace(" ", "%") + "%"; + var ingredientList = Ingredient.GetIngredientsBySearchString(searchString); + + var preferredIngredients = new List>(); + foreach(var ingredient in ingredientList) + { + Int32 ingredientUsageCount = 0; + ingredientUsageCount = IngredientUsage.GetIngredientUsageCount(ingredient); + + if (ingredientUsageCount > 0) + { + preferredIngredients.Add(new KeyValuePair(ingredientUsageCount, ingredient)); + } + } + + //Add the preferred ingredients in usage order + List> sortedPreferredIngredients = preferredIngredients.OrderByDescending(x => x.Key).ThenBy(x => x.Value.name).ToList(); + var alreadyAddedIngredients = new SortedList(); + + var fntBoldFont = new Font(lvwFoundItems.Font.Name, lvwFoundItems.Font.Size, FontStyle.Bold); + + foreach (var item in sortedPreferredIngredients) + { + if (!alreadyAddedIngredients.ContainsKey(item.Value.ingredientID.Value)) + { + var newListViewItem = new ListViewItem(item.Value.ToString()); + newListViewItem.Tag = item.Value; + + newListViewItem.Font = fntBoldFont; + + lvwFoundItems.Items.Add(newListViewItem); + alreadyAddedIngredients.Add(item.Value.ingredientID.Value, item.Value.ingredientID.Value); + } + } + + foreach(var item in ingredientList) + { + if (!alreadyAddedIngredients.ContainsKey(item.ingredientID.Value)) + { + var newListViewItem = new ListViewItem(item.ToString()); + newListViewItem.Tag = item; + lvwFoundItems.Items.Add(newListViewItem); + } + } + } + } + + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (lvwFoundItems.Items == null || lvwFoundItems.SelectedItems.Count == 0) + { + MessageBox.Show("No ingredient selected"); + return; + } + + selectedIngredient = (Ingredient)lvwFoundItems.SelectedItems[0].Tag; + + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void LoadImages() + { + if (!_ImagesAlreadyLoaded) + { + _allButtonImagesList = new ImageList(); + _allButtonImagesList.ImageSize = btnSearch.ClientSize; + _allButtonImagesList.Images.Clear(); + _allButtonImagesList.Images.Add(Properties.Resources.Search); + _allButtonImagesList.Images.SetKeyName(0, SEARCH_IMAGE); + + _ImagesAlreadyLoaded = true; + } + + this.btnSearch.ImageList = _allButtonImagesList; + this.btnSearch.ImageKey = SEARCH_IMAGE; + + lvwFoundItems.Columns.Add("Ingredient"); + lvwFoundItems.Columns[0].Width = lvwFoundItems.Width; + + } + + } +} diff --git a/JRCookbook/frmFindIngredient.resx b/JRCookbook/frmFindIngredient.resx new file mode 100644 index 0000000..93e304d --- /dev/null +++ b/JRCookbook/frmFindIngredient.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/JRCookbook/frmMainRecipe.Designer.cs b/JRCookbook/frmMainRecipe.Designer.cs new file mode 100644 index 0000000..c8433cb --- /dev/null +++ b/JRCookbook/frmMainRecipe.Designer.cs @@ -0,0 +1,398 @@ + +namespace JRCookbook +{ + partial class frmMainRecipe + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + JRCookbookBusiness.JRCookbookBusinessAppManagement.ShutDownApp(); + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.wbRecipeViewer = new Microsoft.Web.WebView2.WinForms.WebView2(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.tvwRecipes = new System.Windows.Forms.TreeView(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.JRJRbutton1 = new System.Windows.Forms.Button(); + this.panel1 = new System.Windows.Forms.Panel(); + this.cmenuRecipe = new System.Windows.Forms.ContextMenuStrip(this.components); + this.cmenuRecipeEdit = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.cmenuRecipeCopyRecipe = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuRecipeCutRecipe = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuRecipeDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuRecipePrint = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuCookbook = new System.Windows.Forms.ContextMenuStrip(this.components); + this.cmenuCookbookEdit = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuCookbookDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.cmenuCookbookAddChapter = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.mnuCookbookGenerateWebPages = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuCookbookGenerateWordDoc = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuRoot = new System.Windows.Forms.ContextMenuStrip(this.components); + this.cmenuRootAddCookbook = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuCookbookChapter = new System.Windows.Forms.ContextMenuStrip(this.components); + this.cmenuCookbookChapterEdit = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuCookbookChapterDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.cmenuCookbookChapterAddRecipe = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.cmenuCookbookChapterAdd = new System.Windows.Forms.ToolStripMenuItem(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + ((System.ComponentModel.ISupportInitialize)(this.wbRecipeViewer)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.cmenuRecipe.SuspendLayout(); + this.cmenuCookbook.SuspendLayout(); + this.cmenuRoot.SuspendLayout(); + this.cmenuCookbookChapter.SuspendLayout(); + this.SuspendLayout(); + // + // wbRecipeViewer + // + this.wbRecipeViewer.AllowExternalDrop = true; + this.wbRecipeViewer.CreationProperties = null; + this.wbRecipeViewer.DefaultBackgroundColor = System.Drawing.Color.White; + this.wbRecipeViewer.Dock = System.Windows.Forms.DockStyle.Fill; + this.wbRecipeViewer.Location = new System.Drawing.Point(0, 0); + this.wbRecipeViewer.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.wbRecipeViewer.Name = "wbRecipeViewer"; + this.wbRecipeViewer.Size = new System.Drawing.Size(1753, 1301); + this.wbRecipeViewer.TabIndex = 3; + this.wbRecipeViewer.ZoomFactor = 1D; + // + // splitContainer1 + // + this.splitContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.splitContainer1.Cursor = System.Windows.Forms.Cursors.VSplit; + this.splitContainer1.Location = new System.Drawing.Point(32, 36); + this.splitContainer1.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.tvwRecipes); + this.splitContainer1.Panel1.Cursor = System.Windows.Forms.Cursors.Default; + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.progressBar1); + this.splitContainer1.Panel2.Controls.Add(this.JRJRbutton1); + this.splitContainer1.Panel2.Controls.Add(this.panel1); + this.splitContainer1.Panel2.Cursor = System.Windows.Forms.Cursors.Default; + this.splitContainer1.Size = new System.Drawing.Size(2467, 1460); + this.splitContainer1.SplitterDistance = 655; + this.splitContainer1.SplitterWidth = 10; + this.splitContainer1.TabIndex = 4; + // + // tvwRecipes + // + this.tvwRecipes.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tvwRecipes.Location = new System.Drawing.Point(7, 8); + this.tvwRecipes.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.tvwRecipes.Name = "tvwRecipes"; + this.tvwRecipes.Size = new System.Drawing.Size(634, 1436); + this.tvwRecipes.TabIndex = 0; + this.tvwRecipes.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvwRecipes_AfterSelect); + // + // progressBar1 + // + this.progressBar1.Location = new System.Drawing.Point(8, 1410); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(1765, 34); + this.progressBar1.TabIndex = 5; + // + // JRJRbutton1 + // + this.JRJRbutton1.Location = new System.Drawing.Point(100, 11); + this.JRJRbutton1.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.JRJRbutton1.Name = "JRJRbutton1"; + this.JRJRbutton1.Size = new System.Drawing.Size(182, 63); + this.JRJRbutton1.TabIndex = 4; + this.JRJRbutton1.Text = "JRJRbutton1"; + this.JRJRbutton1.UseVisualStyleBackColor = true; + this.JRJRbutton1.Click += new System.EventHandler(this.JRJRbutton1_Click); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel1.Controls.Add(this.wbRecipeViewer); + this.panel1.Location = new System.Drawing.Point(7, 96); + this.panel1.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(1755, 1303); + this.panel1.TabIndex = 3; + // + // cmenuRecipe + // + this.cmenuRecipe.ImageScalingSize = new System.Drawing.Size(40, 40); + this.cmenuRecipe.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmenuRecipeEdit, + this.toolStripSeparator4, + this.cmenuRecipeCopyRecipe, + this.cmenuRecipeCutRecipe, + this.cmenuRecipeDelete, + this.cmenuRecipePrint}); + this.cmenuRecipe.Name = "cmenuRecipe"; + this.cmenuRecipe.Size = new System.Drawing.Size(328, 250); + // + // cmenuRecipeEdit + // + this.cmenuRecipeEdit.Name = "cmenuRecipeEdit"; + this.cmenuRecipeEdit.Size = new System.Drawing.Size(327, 48); + this.cmenuRecipeEdit.Text = "Edit Recipe..."; + this.cmenuRecipeEdit.Click += new System.EventHandler(this.cmenuRecipeEdit_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(324, 6); + // + // cmenuRecipeCopyRecipe + // + this.cmenuRecipeCopyRecipe.Name = "cmenuRecipeCopyRecipe"; + this.cmenuRecipeCopyRecipe.Size = new System.Drawing.Size(327, 48); + this.cmenuRecipeCopyRecipe.Text = "Copy Recipe To..."; + this.cmenuRecipeCopyRecipe.Click += new System.EventHandler(this.cmenuRecipeCopyTo_Click); + // + // cmenuRecipeCutRecipe + // + this.cmenuRecipeCutRecipe.Name = "cmenuRecipeCutRecipe"; + this.cmenuRecipeCutRecipe.Size = new System.Drawing.Size(327, 48); + this.cmenuRecipeCutRecipe.Text = "Move Recipe To..."; + this.cmenuRecipeCutRecipe.Click += new System.EventHandler(this.cmenuRecipeMoveTo_Click); + // + // cmenuRecipeDelete + // + this.cmenuRecipeDelete.Name = "cmenuRecipeDelete"; + this.cmenuRecipeDelete.Size = new System.Drawing.Size(327, 48); + this.cmenuRecipeDelete.Text = "Delete Recipe"; + this.cmenuRecipeDelete.Click += new System.EventHandler(this.cmenuRecipeDelete_Click); + // + // cmenuRecipePrint + // + this.cmenuRecipePrint.Name = "cmenuRecipePrint"; + this.cmenuRecipePrint.Size = new System.Drawing.Size(327, 48); + this.cmenuRecipePrint.Text = "Print Recipe"; + this.cmenuRecipePrint.Click += new System.EventHandler(this.cmenuRecipePrint_Click); + // + // cmenuCookbook + // + this.cmenuCookbook.ImageScalingSize = new System.Drawing.Size(40, 40); + this.cmenuCookbook.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmenuCookbookEdit, + this.cmenuCookbookDelete, + this.toolStripSeparator1, + this.cmenuCookbookAddChapter, + this.toolStripSeparator3, + this.mnuCookbookGenerateWebPages, + this.mnuCookbookGenerateWordDoc}); + this.cmenuCookbook.Name = "cmenuCookbook"; + this.cmenuCookbook.Size = new System.Drawing.Size(394, 256); + // + // cmenuCookbookEdit + // + this.cmenuCookbookEdit.Name = "cmenuCookbookEdit"; + this.cmenuCookbookEdit.Size = new System.Drawing.Size(393, 48); + this.cmenuCookbookEdit.Text = "Edit Cookbook..."; + this.cmenuCookbookEdit.Click += new System.EventHandler(this.cmenuCookbookEdit_Click); + // + // cmenuCookbookDelete + // + this.cmenuCookbookDelete.Name = "cmenuCookbookDelete"; + this.cmenuCookbookDelete.Size = new System.Drawing.Size(393, 48); + this.cmenuCookbookDelete.Text = "Delete Cookbook"; + this.cmenuCookbookDelete.Click += new System.EventHandler(this.cmenuCookbookDelete_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(390, 6); + // + // cmenuCookbookAddChapter + // + this.cmenuCookbookAddChapter.Name = "cmenuCookbookAddChapter"; + this.cmenuCookbookAddChapter.Size = new System.Drawing.Size(393, 48); + this.cmenuCookbookAddChapter.Text = "Add Chapter..."; + this.cmenuCookbookAddChapter.Click += new System.EventHandler(this.cmenuCookbookAddChapter_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(390, 6); + // + // mnuCookbookGenerateWebPages + // + this.mnuCookbookGenerateWebPages.Name = "mnuCookbookGenerateWebPages"; + this.mnuCookbookGenerateWebPages.Size = new System.Drawing.Size(393, 48); + this.mnuCookbookGenerateWebPages.Text = "Generate Web Pages..."; + this.mnuCookbookGenerateWebPages.Click += new System.EventHandler(this.mnuCookbookGenerateWebPages_Click); + // + // mnuCookbookGenerateWordDoc + // + this.mnuCookbookGenerateWordDoc.Name = "mnuCookbookGenerateWordDoc"; + this.mnuCookbookGenerateWordDoc.Size = new System.Drawing.Size(393, 48); + this.mnuCookbookGenerateWordDoc.Text = "Generate Word Doc..."; + this.mnuCookbookGenerateWordDoc.Click += new System.EventHandler(this.mnuCookbookGenerateWordDoc_Click); + // + // cmenuRoot + // + this.cmenuRoot.ImageScalingSize = new System.Drawing.Size(40, 40); + this.cmenuRoot.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmenuRootAddCookbook}); + this.cmenuRoot.Name = "cmenuRoot"; + this.cmenuRoot.Size = new System.Drawing.Size(320, 52); + // + // cmenuRootAddCookbook + // + this.cmenuRootAddCookbook.Name = "cmenuRootAddCookbook"; + this.cmenuRootAddCookbook.Size = new System.Drawing.Size(319, 48); + this.cmenuRootAddCookbook.Text = "Add Cookbook..."; + this.cmenuRootAddCookbook.Click += new System.EventHandler(this.cmenuRootAddCookbook_Click); + // + // cmenuCookbookChapter + // + this.cmenuCookbookChapter.ImageScalingSize = new System.Drawing.Size(40, 40); + this.cmenuCookbookChapter.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.cmenuCookbookChapterEdit, + this.cmenuCookbookChapterDelete, + this.toolStripSeparator2, + this.cmenuCookbookChapterAddRecipe, + this.toolStripSeparator5, + this.cmenuCookbookChapterAdd}); + this.cmenuCookbookChapter.Name = "cmenuCookbookChapter"; + this.cmenuCookbookChapter.Size = new System.Drawing.Size(349, 208); + // + // cmenuCookbookChapterEdit + // + this.cmenuCookbookChapterEdit.Name = "cmenuCookbookChapterEdit"; + this.cmenuCookbookChapterEdit.Size = new System.Drawing.Size(348, 48); + this.cmenuCookbookChapterEdit.Text = "Edit Chapter..."; + this.cmenuCookbookChapterEdit.Click += new System.EventHandler(this.cmenuCookbookChapterEdit_Click); + // + // cmenuCookbookChapterDelete + // + this.cmenuCookbookChapterDelete.Name = "cmenuCookbookChapterDelete"; + this.cmenuCookbookChapterDelete.Size = new System.Drawing.Size(348, 48); + this.cmenuCookbookChapterDelete.Text = "Delete Chapter"; + this.cmenuCookbookChapterDelete.Click += new System.EventHandler(this.cmenuCookbookChapterDelete_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(345, 6); + // + // cmenuCookbookChapterAddRecipe + // + this.cmenuCookbookChapterAddRecipe.Name = "cmenuCookbookChapterAddRecipe"; + this.cmenuCookbookChapterAddRecipe.Size = new System.Drawing.Size(348, 48); + this.cmenuCookbookChapterAddRecipe.Text = "Add Recipe..."; + this.cmenuCookbookChapterAddRecipe.Click += new System.EventHandler(this.cmenuCookbookChapterAddRecipe_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(345, 6); + // + // cmenuCookbookChapterAdd + // + this.cmenuCookbookChapterAdd.Name = "cmenuCookbookChapterAdd"; + this.cmenuCookbookChapterAdd.Size = new System.Drawing.Size(348, 48); + this.cmenuCookbookChapterAdd.Text = "Add Sub-Chapter..."; + this.cmenuCookbookChapterAdd.Click += new System.EventHandler(this.cmenuCookbookChapterAdd_Click); + // + // frmMainRecipe + // + this.AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(2531, 1528); + this.Controls.Add(this.splitContainer1); + this.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + this.Name = "frmMainRecipe"; + this.Text = "Recipes"; + this.Load += new System.EventHandler(this.Form1_Load); + ((System.ComponentModel.ISupportInitialize)(this.wbRecipeViewer)).EndInit(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.cmenuRecipe.ResumeLayout(false); + this.cmenuCookbook.ResumeLayout(false); + this.cmenuRoot.ResumeLayout(false); + this.cmenuCookbookChapter.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + private Microsoft.Web.WebView2.WinForms.WebView2 wbRecipeViewer; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.TreeView tvwRecipes; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.ContextMenuStrip cmenuRecipe; + private System.Windows.Forms.ToolStripMenuItem cmenuRecipeEdit; + private System.Windows.Forms.ContextMenuStrip cmenuCookbook; + private System.Windows.Forms.ToolStripMenuItem cmenuCookbookEdit; + private System.Windows.Forms.ToolStripMenuItem cmenuCookbookDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem cmenuCookbookAddChapter; + private System.Windows.Forms.ContextMenuStrip cmenuRoot; + private System.Windows.Forms.ToolStripMenuItem cmenuRootAddCookbook; + private System.Windows.Forms.ContextMenuStrip cmenuCookbookChapter; + private System.Windows.Forms.ToolStripMenuItem cmenuCookbookChapterEdit; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem cmenuCookbookChapterAdd; + private System.Windows.Forms.ToolStripMenuItem cmenuCookbookChapterDelete; + private System.Windows.Forms.ToolStripMenuItem cmenuRecipeDelete; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem mnuCookbookGenerateWebPages; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + private System.Windows.Forms.Button JRJRbutton1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripMenuItem cmenuRecipeCutRecipe; + private System.Windows.Forms.ToolStripMenuItem cmenuRecipeCopyRecipe; + private System.Windows.Forms.ToolStripMenuItem cmenuRecipePrint; + private System.Windows.Forms.ToolStripMenuItem cmenuCookbookChapterAddRecipe; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem mnuCookbookGenerateWordDoc; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.ProgressBar progressBar1; + } +} + diff --git a/JRCookbook/frmMainRecipe.cs b/JRCookbook/frmMainRecipe.cs new file mode 100644 index 0000000..e569c68 --- /dev/null +++ b/JRCookbook/frmMainRecipe.cs @@ -0,0 +1,651 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Microsoft.Web.WebView2.WinForms; +using JRCookbookBusiness; +using System.IO; +using Microsoft.Win32; + +namespace JRCookbook +{ + public partial class frmMainRecipe : Form + { + bool JRJRCalcAll = false; + String JRJRallOriginalRecipeNutrients = String.Empty + Constants.CRLF; + String JRJRallRecalcRecipeNutrients = String.Empty + Constants.CRLF; + bool _AllRecipesRecalced = false; + + public frmMainRecipe() + { + InitializeComponent(); + } + + private void ShowRecipe(Guid recipeID) + { + try + { + + var myRecipe = Recipe.GetRecipeByID(recipeID); + var myHTML = myRecipe.GetHTML(null); + //txtResults.Text = myHTML; + + wbRecipeViewer.NavigateToString(myHTML); + wbRecipeViewer.Show(); + } + catch (Exception ex) + { + MessageBox.Show("Error getting recipe HTML: " + ex.ToString()); + } + return; + + } + + private async void Form1_Load(object sender, EventArgs e) + { + this.tvwRecipes.NodeMouseClick += (sender, args) => tvwRecipes.SelectedNode = args.Node; + this.tvwRecipes.NodeMouseDoubleClick += (sender, args) => tvwRecipes.SelectedNode = args.Node; + this.tvwRecipes.NodeMouseDoubleClick += TvwRecipes_NodeMouseDoubleClick; + + await wbRecipeViewer.EnsureCoreWebView2Async(); + HideRecipe(); + ReloadRecipesTreeview(); + } + + private void TvwRecipes_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) + { + if (tvwRecipes.SelectedNode != null && tvwRecipes.SelectedNode.Tag != null) + { + if (tvwRecipes.SelectedNode.Tag is RecipeHighlights) + { + cmenuRecipeEdit_Click(tvwRecipes.SelectedNode, new EventArgs()); + } + } + } + + private void ReloadRecipesTreeview() + { + this.UseWaitCursor = true; + tvwRecipes.Nodes.Clear(); + var allCookbooksNode = new TreeNode("All Cookbooks"); + tvwRecipes.Nodes.Add(allCookbooksNode); + + allCookbooksNode.ContextMenuStrip = cmenuRoot; + + AddAllCookbooksToNode(allCookbooksNode); + + allCookbooksNode.Expand(); + + this.UseWaitCursor = false; + } + + private void AddAllCookbooksToNode(TreeNode parentNode) + { + if (_AllRecipesRecalced == false) + { + JRJRallOriginalRecipeNutrients = String.Empty + Constants.CRLF; + JRJRallRecalcRecipeNutrients = String.Empty + Constants.CRLF; + } + + var allCookbooks = Cookbook.GetAllCookbooks(); + foreach (var cookbook in allCookbooks) + { + var newNode = new TreeNode(cookbook.name); + newNode.Tag = cookbook; + newNode.Collapse(); + parentNode.Nodes.Add(newNode); + newNode.Name = NodeNameForCookbook(cookbook); + newNode.ContextMenuStrip = cmenuCookbook; + AddAllChapters(newNode, cookbook.cookbookChapters); + AddAllRecipes(newNode, cookbook.recipeHighlights); + } + + _AllRecipesRecalced = true; + + } + + private void AddAllChapters(TreeNode parentNode, List cookbookChapterList) + { + foreach (var cookbookChapter in cookbookChapterList) + { + var newNode = new TreeNode(cookbookChapter.name); + newNode.Tag = cookbookChapter; + newNode.Collapse(); + parentNode.Nodes.Add(newNode); + newNode.Name = NodeNameForCookbookChapter(cookbookChapter); + newNode.ContextMenuStrip = cmenuCookbookChapter; + AddAllChapters(newNode, cookbookChapter.cookbookChapters); + AddAllRecipes(newNode, cookbookChapter.recipeHighlights); + + } + } + + private void AddAllRecipes(TreeNode parentNode, List allRecipes) + { + foreach (var recipe in allRecipes) + { + var newNode = new TreeNode(recipe.recipename); + newNode.Tag = recipe; + newNode.Collapse(); + newNode.Name = NodeNameForRecipe(recipe); + newNode.ContextMenuStrip = cmenuRecipe; + + parentNode.Nodes.Add(newNode); + + if (_AllRecipesRecalced == false && JRJRCalcAll) + { + var recFull = new Recipe(recipe.recipeID.Value); + String originalNutrition = String.Empty; + String recalcNutrition = String.Empty; + recFull.JRJRTestNutritionRecalc(ref originalNutrition, ref recalcNutrition); + JRJRallOriginalRecipeNutrients += originalNutrition; + JRJRallRecalcRecipeNutrients += recalcNutrition; + } + } + } + + private void tvwRecipes_AfterSelect(object sender, TreeViewEventArgs e) + { + if (tvwRecipes.SelectedNode.Tag is RecipeHighlights) + { + ShowRecipe(((RecipeHighlights)tvwRecipes.SelectedNode.Tag).recipeID.Value); + } + else + { + HideRecipe(); + } + } + + private void HideRecipe() + { + wbRecipeViewer.Hide(); + } + + private void cmenuRecipeEdit_Click(object sender, EventArgs e) + { + var selectedNodeName = tvwRecipes.SelectedNode.Name; + + var recipeHighlights = (RecipeHighlights)tvwRecipes.SelectedNode.Tag; + var recipe = Recipe.GetRecipeByID(recipeHighlights.recipeID.Value); + //String originalNutrition = String.Empty; + //String recalcNutrition = String.Empty; + //recipe.JRJRTestNutritionRecalc(ref originalNutrition, ref recalcNutrition); + //Clipboard.Clear(); + //Clipboard.SetText(originalNutrition); + //MessageBox.Show("Original nutrition is now on clipboard"); + //Clipboard.SetText(recalcNutrition); + //MessageBox.Show("Recalc nutrition is now on clipboard"); + + //Clipboard.Clear(); + //Clipboard.SetText(JRJRallOriginalRecipeNutrients); + //MessageBox.Show("Original nutrition is now on clipboard"); + //Clipboard.SetText(JRJRallRecalcRecipeNutrients); + //MessageBox.Show("Recalc nutrition is now on clipboard"); + + var editForm = new frmEditRecipe(recipe, recipe.cookbookID.Value, recipe.cookbookchapterID); + var result = editForm.ShowDialog(); + + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + var nodesWithKey = tvwRecipes.Nodes.Find(selectedNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + + private String NodeNameForRecipe(RecipeHighlights recipe) + { + return "Recipe" + recipe.recipeID.ToString(); + } + + private String NodeNameForRecipe(Recipe recipe) + { + return "Recipe" + recipe.recipeID.ToString(); + } + + private String NodeNameForCookbook(Cookbook cookbook) + { + return "Cookbook" + cookbook.cookbookID.ToString(); + } + + private String NodeNameForCookbookChapter(CookbookChapter cookbookChapter) + { + return "CookbookChapter" + cookbookChapter.cookbookID.ToString() + "-" + cookbookChapter.cookbookChapterID.ToString(); + } + + private void cmenuCookbookEdit_Click(object sender, EventArgs e) + { + var selectedNodeName = tvwRecipes.SelectedNode.Name; + + using (var editForm = new frmEditCookbook((Cookbook)tvwRecipes.SelectedNode.Tag)) + { + var result = editForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + var nodesWithKey = tvwRecipes.Nodes.Find(selectedNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + } + + private void cmenuCookbookDelete_Click(object sender, EventArgs e) + { + var cookbookToDelete = (Cookbook)tvwRecipes.SelectedNode.Tag; + + if (cookbookToDelete.cookbookChapters.Count > 0 || cookbookToDelete.recipeHighlights.Count > 0) + { + var response = MessageBox.Show("This cookbook has chapters or recipes. They will be deleted along with the cookbook." + Constants.CRLF + + "Is that OK?", "Deleting cookbook and chapters/recipes", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); + + if (response == DialogResult.No) + { + MessageBox.Show("Delete cancelled"); + return; + } + } + else + { + var response = MessageBox.Show("Are you sure you want to delete this cookbook?", "Deleting cookbook", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); + + if (response == DialogResult.No) + { + MessageBox.Show("Delete cancelled"); + return; + } + } + + try + { + cookbookToDelete.Delete(); + } + catch (Exception ex) + { + MessageBox.Show("Error deleting cookbook: " + ex.ToString()); + } + this.ReloadRecipesTreeview(); + } + + private void cmenuRootAddCookbook_Click(object sender, EventArgs e) + { + using (var editForm = new frmEditCookbook(null)) + { + var result = editForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + + var newNodeName = NodeNameForCookbook(editForm.editedCookbook); + + var nodesWithKey = tvwRecipes.Nodes.Find(newNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + } + + private void cmenuCookbookAddChapter_Click(object sender, EventArgs e) + { + var cookbook = (Cookbook)tvwRecipes.SelectedNode.Tag; + using (var editForm = new frmEditCookbookChapter(cookbook.cookbookID.Value, null)) + { + var result = editForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + + var newNodeName = NodeNameForCookbookChapter(editForm.editedCookbookChapter); + + var nodesWithKey = tvwRecipes.Nodes.Find(newNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + } + + private void cmenuCookbookChapterAdd_Click(object sender, EventArgs e) + { + var parentChapter = (CookbookChapter)tvwRecipes.SelectedNode.Tag; + + using (var editForm = new frmEditCookbookChapter(parentChapter.cookbookID.Value, parentChapter.cookbookChapterID)) + { + var result = editForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + + var newNodeName = NodeNameForCookbookChapter(editForm.editedCookbookChapter); + + var nodesWithKey = tvwRecipes.Nodes.Find(newNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + } + + private void cmenuCookbookChapterDelete_Click(object sender, EventArgs e) + { + var cookbookChapterToDelete = (CookbookChapter)tvwRecipes.SelectedNode.Tag; + + if (cookbookChapterToDelete.cookbookChapters.Count > 0 || cookbookChapterToDelete.recipeHighlights.Count > 0) + { + var response = MessageBox.Show("This cookbook has sub-chapters or recipes. They will be deleted along with the chapter." + Constants.CRLF + + "Is that OK?", "Deleting chapter and sub-chapters/recipes", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); + + if (response == DialogResult.No) + { + MessageBox.Show("Delete cancelled"); + return; + } + } + else + { + var response = MessageBox.Show("Are you sure you want to delete this chapter?", "Deleting chapter", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); + + if (response == DialogResult.No) + { + MessageBox.Show("Delete cancelled"); + return; + } + } + + try + { + cookbookChapterToDelete.Delete(); + } + catch (Exception ex) + { + MessageBox.Show("Error deleting cookbook chapter: " + ex.ToString()); + } + this.ReloadRecipesTreeview(); + } + + private void cmenuCookbookChapterEdit_Click(object sender, EventArgs e) + { + var selectedNodeName = tvwRecipes.SelectedNode.Name; + var cookbookChapter = (CookbookChapter)tvwRecipes.SelectedNode.Tag; + + using (var editForm = new frmEditCookbookChapter(cookbookChapter)) + { + var result = editForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + var nodesWithKey = tvwRecipes.Nodes.Find(selectedNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + } + + private void cmenuRecipeDelete_Click(object sender, EventArgs e) + { + var recipeToDelete = (RecipeHighlights)tvwRecipes.SelectedNode.Tag; + + var response = MessageBox.Show("Are you sure you want to delete this recipe?", "Deleting recipe", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); + + if (response == DialogResult.No) + { + MessageBox.Show("Delete cancelled"); + return; + } + + try + { + recipeToDelete.Delete(); + } + catch (Exception ex) + { + MessageBox.Show("Error deleting recipe: " + ex.ToString()); + } + this.ReloadRecipesTreeview(); + } + + private void mnuCookbookGenerateWebPages_Click(object sender, EventArgs e) + { + var cookbookToGenerate = (Cookbook)tvwRecipes.SelectedNode.Tag; + + folderBrowserDialog1.Description = "Choose folder to save web pages"; + folderBrowserDialog1.ShowNewFolderButton = true; + folderBrowserDialog1.UseDescriptionForTitle = true; + + var folderBrowserResult = folderBrowserDialog1.ShowDialog(); + + if (folderBrowserResult != DialogResult.OK) + { + return; + } + + var folderToSaveTo = folderBrowserDialog1.SelectedPath; + + try + { + cookbookToGenerate.LongRunningStatusUpdatedEvent += HandleLongRunningStatusUpdatedEvent; + cookbookToGenerate.GenerateWebPages(folderToSaveTo); + + MessageBox.Show("Pages generated"); + } + catch (Exception ex) + { + MessageBox.Show("Error generating web pages for cookbook: " + ex.ToString()); + } + finally + { + cookbookToGenerate.LongRunningStatusUpdatedEvent -= HandleLongRunningStatusUpdatedEvent; + progressBar1.Maximum = 1; + progressBar1.Value = 0; + } + + } + + private void JRJRbutton1_Click(object sender, EventArgs e) + { + JRCookbookBusiness.IngredientUsage.RebuildIngredientUsage(); + using (var editForm = new JRJRAdhocUpdateForm()) + { + editForm.ShowDialog(); + } + + } + + private void cmenuRecipeMoveTo_Click(object sender, EventArgs e) + { + var selectedNodeName = tvwRecipes.SelectedNode.Name; + var recipeHighlights = (RecipeHighlights)tvwRecipes.SelectedNode.Tag; + var recipeToMove = Recipe.GetRecipeByID(recipeHighlights.recipeID.Value); + + using (var recipeCopyMoveToForm = new frmRecipeCopyMoveTo(recipeToMove, true)) + { + var result = recipeCopyMoveToForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + var nodesWithKey = tvwRecipes.Nodes.Find(selectedNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + } + + private void cmenuRecipeCopyTo_Click(object sender, EventArgs e) + { + var selectedNodeName = tvwRecipes.SelectedNode.Name; + var recipeHighlights = (RecipeHighlights)tvwRecipes.SelectedNode.Tag; + var recipeToCopy = Recipe.GetRecipeByID(recipeHighlights.recipeID.Value); + + using (var recipeCopyMoveToForm = new frmRecipeCopyMoveTo(recipeToCopy, false)) + { + var result = recipeCopyMoveToForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + var nodesWithKey = tvwRecipes.Nodes.Find(selectedNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + } + + private async void cmenuRecipePrint_Click(object sender, EventArgs e) + { + await wbRecipeViewer.ExecuteScriptAsync("window.print();"); + } + + private void cmenuCookbookChapterAddRecipe_Click(object sender, EventArgs e) + { + var parentChapter = (CookbookChapter)tvwRecipes.SelectedNode.Tag; + using (var editForm = new frmEditRecipe(null, parentChapter.cookbookID.Value, parentChapter.cookbookChapterID)) + { + var result = editForm.ShowDialog(); + if (result == DialogResult.OK) + { + this.ReloadRecipesTreeview(); + + var newNodeName = NodeNameForRecipe(editForm.editedRecipe); + + var nodesWithKey = tvwRecipes.Nodes.Find(newNodeName, true); + if (nodesWithKey.Length > 0) + { + nodesWithKey[0].EnsureVisible(); + nodesWithKey[0].Expand(); + tvwRecipes.SelectedNode = nodesWithKey[0]; + } + } + } + return; + + } + + private void mnuCookbookGenerateWordDoc_Click(object sender, EventArgs e) + { + var cookbookToGenerate = (Cookbook)tvwRecipes.SelectedNode.Tag; + + string fileNameToSave; + + saveFileDialog1.CheckPathExists = true; + saveFileDialog1.AddExtension = true; + saveFileDialog1.DefaultExt = "docx"; + saveFileDialog1.CheckFileExists = false; + saveFileDialog1.OverwritePrompt = false; + saveFileDialog1.CreatePrompt = false; + saveFileDialog1.Filter = "Word documents (*.docx)|*.docx"; + + var saveFileDialogResult = saveFileDialog1.ShowDialog(); + + if (saveFileDialogResult != DialogResult.OK) + { + return; + } + + fileNameToSave = saveFileDialog1.FileName; + + if (File.Exists(fileNameToSave)) + { + var overWriteFileResult = MessageBox.Show(fileNameToSave + " already exists. Do you want to replace it?", "Replace file?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2); + + if (overWriteFileResult == DialogResult.No) + { + return; + } + + try + { + File.Delete(fileNameToSave); + } + catch (Exception exDelete) + { + MessageBox.Show("Unable to delete the file"); + return; + } + + } + + try + { + cookbookToGenerate.LongRunningStatusUpdatedEvent += HandleLongRunningStatusUpdatedEvent; + cookbookToGenerate.GenerateWordDoc(fileNameToSave); + + MessageBox.Show("Document generated"); + } + catch (Exception ex) + { + MessageBox.Show("Error generating Word document for cookbook: " + ex.ToString()); + } + finally + { + cookbookToGenerate.LongRunningStatusUpdatedEvent -= HandleLongRunningStatusUpdatedEvent; + progressBar1.Maximum = 1; + progressBar1.Value = 0; + } + } + + private void HandleLongRunningStatusUpdatedEvent(object sender, LongRunningStatusUpdatedEventArgs e) + { + if (e.TotalItemCount == 0) + { + progressBar1.Maximum = 1; + progressBar1.Value = 0; + } + else + { + progressBar1.Maximum = e.TotalItemCount; + + if (e.CompletedItemCount >= e.TotalItemCount) + { + progressBar1.Value = e.TotalItemCount; + } + else + { + progressBar1.Value = e.CompletedItemCount; + } + } + progressBar1.Refresh(); + } + + } +} diff --git a/JRCookbook/frmMainRecipe.resx b/JRCookbook/frmMainRecipe.resx new file mode 100644 index 0000000..344ddb2 --- /dev/null +++ b/JRCookbook/frmMainRecipe.resx @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 142, 17 + + + 286, 17 + + + 400, 17 + + + 588, 17 + + + 964, 17 + + \ No newline at end of file diff --git a/JRCookbook/frmPickRecipeIngredient.Designer.cs b/JRCookbook/frmPickRecipeIngredient.Designer.cs new file mode 100644 index 0000000..1524043 --- /dev/null +++ b/JRCookbook/frmPickRecipeIngredient.Designer.cs @@ -0,0 +1,232 @@ + +namespace JRCookbook +{ + partial class frmPickRecipeIngredient + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + lblRecipeIngredient = new System.Windows.Forms.Label(); + txtCurrentRecipeIngredient = new System.Windows.Forms.TextBox(); + chkLinkedToIngredient = new System.Windows.Forms.CheckBox(); + grpLinkedIngredient = new System.Windows.Forms.GroupBox(); + btnSearch = new System.Windows.Forms.Button(); + txtIngredient = new System.Windows.Forms.TextBox(); + label3 = new System.Windows.Forms.Label(); + cboUnit = new System.Windows.Forms.ComboBox(); + label2 = new System.Windows.Forms.Label(); + txtQuantity = new JRCookbookControls.JRCookbookNumericTextBox(); + label1 = new System.Windows.Forms.Label(); + btnOK = new System.Windows.Forms.Button(); + btnCancel = new System.Windows.Forms.Button(); + grpLinkedIngredient.SuspendLayout(); + SuspendLayout(); + // + // lblRecipeIngredient + // + lblRecipeIngredient.AutoSize = true; + lblRecipeIngredient.Location = new System.Drawing.Point(32, 36); + lblRecipeIngredient.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + lblRecipeIngredient.Name = "lblRecipeIngredient"; + lblRecipeIngredient.Size = new System.Drawing.Size(358, 41); + lblRecipeIngredient.TabIndex = 0; + lblRecipeIngredient.Text = "Current Recipe Ingredient"; + // + // txtCurrentRecipeIngredient + // + txtCurrentRecipeIngredient.Location = new System.Drawing.Point(32, 87); + txtCurrentRecipeIngredient.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtCurrentRecipeIngredient.Multiline = true; + txtCurrentRecipeIngredient.Name = "txtCurrentRecipeIngredient"; + txtCurrentRecipeIngredient.ReadOnly = true; + txtCurrentRecipeIngredient.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + txtCurrentRecipeIngredient.Size = new System.Drawing.Size(1833, 102); + txtCurrentRecipeIngredient.TabIndex = 1; + // + // chkLinkedToIngredient + // + chkLinkedToIngredient.AutoSize = true; + chkLinkedToIngredient.Checked = true; + chkLinkedToIngredient.CheckState = System.Windows.Forms.CheckState.Checked; + chkLinkedToIngredient.Location = new System.Drawing.Point(32, 216); + chkLinkedToIngredient.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + chkLinkedToIngredient.Name = "chkLinkedToIngredient"; + chkLinkedToIngredient.Size = new System.Drawing.Size(324, 45); + chkLinkedToIngredient.TabIndex = 2; + chkLinkedToIngredient.Text = "Linked to Ingredient"; + chkLinkedToIngredient.UseVisualStyleBackColor = true; + chkLinkedToIngredient.CheckedChanged += chkLinkedToIngredient_CheckedChanged; + // + // grpLinkedIngredient + // + grpLinkedIngredient.Controls.Add(btnSearch); + grpLinkedIngredient.Controls.Add(txtIngredient); + grpLinkedIngredient.Controls.Add(label3); + grpLinkedIngredient.Controls.Add(cboUnit); + grpLinkedIngredient.Controls.Add(label2); + grpLinkedIngredient.Controls.Add(txtQuantity); + grpLinkedIngredient.Controls.Add(label1); + grpLinkedIngredient.Location = new System.Drawing.Point(32, 287); + grpLinkedIngredient.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + grpLinkedIngredient.Name = "grpLinkedIngredient"; + grpLinkedIngredient.Padding = new System.Windows.Forms.Padding(7, 8, 7, 8); + grpLinkedIngredient.Size = new System.Drawing.Size(1838, 279); + grpLinkedIngredient.TabIndex = 3; + grpLinkedIngredient.TabStop = false; + grpLinkedIngredient.Text = "Linked Ingredient"; + // + // btnSearch + // + btnSearch.ImageKey = "(none)"; + btnSearch.Location = new System.Drawing.Point(1768, 44); + btnSearch.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnSearch.Name = "btnSearch"; + btnSearch.Size = new System.Drawing.Size(61, 63); + btnSearch.TabIndex = 6; + btnSearch.UseVisualStyleBackColor = true; + btnSearch.Click += btnSearch_Click; + // + // txtIngredient + // + txtIngredient.Location = new System.Drawing.Point(180, 44); + txtIngredient.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtIngredient.Name = "txtIngredient"; + txtIngredient.Size = new System.Drawing.Size(1583, 47); + txtIngredient.TabIndex = 5; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new System.Drawing.Point(17, 52); + label3.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(155, 41); + label3.TabIndex = 4; + label3.Text = "Ingredient"; + // + // cboUnit + // + cboUnit.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + cboUnit.FormattingEnabled = true; + cboUnit.Location = new System.Drawing.Point(369, 200); + cboUnit.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + cboUnit.Name = "cboUnit"; + cboUnit.Size = new System.Drawing.Size(419, 49); + cboUnit.TabIndex = 10; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(17, 210); + label2.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(73, 41); + label2.TabIndex = 9; + label2.Text = "Unit"; + // + // txtQuantity + // + txtQuantity.AllowDecimal = true; + txtQuantity.AllowEmpty = true; + txtQuantity.AllowNegative = true; + txtQuantity.Location = new System.Drawing.Point(369, 123); + txtQuantity.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + txtQuantity.Name = "txtQuantity"; + txtQuantity.Size = new System.Drawing.Size(312, 47); + txtQuantity.TabIndex = 8; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(17, 131); + label1.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(338, 41); + label1.TabIndex = 7; + label1.Text = "Quantity (decimal value)"; + // + // btnOK + // + btnOK.Location = new System.Drawing.Point(29, 582); + btnOK.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnOK.Name = "btnOK"; + btnOK.Size = new System.Drawing.Size(182, 63); + btnOK.TabIndex = 11; + btnOK.Text = "OK"; + btnOK.UseVisualStyleBackColor = true; + btnOK.Click += btnOK_Click; + // + // btnCancel + // + btnCancel.Location = new System.Drawing.Point(253, 582); + btnCancel.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new System.Drawing.Size(182, 63); + btnCancel.TabIndex = 12; + btnCancel.Text = "Cancel"; + btnCancel.UseVisualStyleBackColor = true; + btnCancel.Click += btnCancel_Click; + // + // frmPickRecipeIngredient + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + AutoSize = true; + ClientSize = new System.Drawing.Size(1894, 675); + ControlBox = false; + Controls.Add(btnCancel); + Controls.Add(btnOK); + Controls.Add(grpLinkedIngredient); + Controls.Add(chkLinkedToIngredient); + Controls.Add(txtCurrentRecipeIngredient); + Controls.Add(lblRecipeIngredient); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + Name = "frmPickRecipeIngredient"; + Text = "Recipe Ingredient"; + grpLinkedIngredient.ResumeLayout(false); + grpLinkedIngredient.PerformLayout(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.Label lblRecipeIngredient; + private System.Windows.Forms.TextBox txtCurrentRecipeIngredient; + private System.Windows.Forms.CheckBox chkLinkedToIngredient; + private System.Windows.Forms.GroupBox grpLinkedIngredient; + private System.Windows.Forms.Button btnSearch; + private System.Windows.Forms.TextBox txtIngredient; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.ComboBox cboUnit; + private System.Windows.Forms.Label label2; + private JRCookbookControls.JRCookbookNumericTextBox txtQuantity; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/JRCookbook/frmPickRecipeIngredient.cs b/JRCookbook/frmPickRecipeIngredient.cs new file mode 100644 index 0000000..3dc3e70 --- /dev/null +++ b/JRCookbook/frmPickRecipeIngredient.cs @@ -0,0 +1,238 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbook +{ + public partial class frmPickRecipeIngredient : Form + { + private RecipeIngredientItem _editedRecipeIngredientItem = null; + private Guid? _IngredientID = null; + + private static ImageList _allButtonImagesList = new ImageList(); + private static bool _ImagesAlreadyLoaded = false; + + private const string SEARCH_IMAGE = "Search.bmp"; + + public frmPickRecipeIngredient() + { + InitializeComponent(); + LoadImages(); + grpLinkedIngredient.Visible = chkLinkedToIngredient.Checked; + } + + + + public RecipeIngredientItem editedRecipeIngredientItem + { + get + { + return _editedRecipeIngredientItem; + } + private set + { + _editedRecipeIngredientItem = value; + } + } + + public frmPickRecipeIngredient(RecipeIngredientItem recipeIngredientItemToEdit) + { + InitializeComponent(); + LoadImages(); + + if (recipeIngredientItemToEdit == null) + { + throw new ApplicationException("Missing recipe ingredient to edit"); + } + else + { + //Since this is a very simple object, going to just edit the existing object and return it + _editedRecipeIngredientItem = recipeIngredientItemToEdit; + } + + txtCurrentRecipeIngredient.Text = ((_editedRecipeIngredientItem.quantityText + " " + _editedRecipeIngredientItem.unitText).Trim() + " " + _editedRecipeIngredientItem.ingredientText).Trim(); + + _IngredientID = _editedRecipeIngredientItem.ingredientID; + + if (_IngredientID == null) + { + chkLinkedToIngredient.Checked = false; + } + else + { + chkLinkedToIngredient.Checked = true; + + var ingredient = Ingredient.GetIngredientByID(_IngredientID.Value); + + txtIngredient.Text = ingredient.name; + + txtQuantity.Text = _editedRecipeIngredientItem.measureQuantity.ToString(); + + LoadMeasuresForIngredient(); + + SelectMeasuresByID(_editedRecipeIngredientItem.measureID); + + if (cboUnit.SelectedItem == null) + { + SelectMeasuresByName(_editedRecipeIngredientItem.measureName); + } + } + } + + private void chkLinkedToIngredient_CheckedChanged(object sender, EventArgs e) + { + grpLinkedIngredient.Visible = chkLinkedToIngredient.Checked; + if (chkLinkedToIngredient.Checked == false) + { + _IngredientID = null; + } + } + + + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (chkLinkedToIngredient.Checked) + { + if (String.IsNullOrWhiteSpace(txtIngredient.Text)) + { + MessageBox.Show("Ingredient is required"); + return; + } + + if (String.IsNullOrWhiteSpace(txtQuantity.Text)) + { + MessageBox.Show("Quantity is required"); + return; + } + + if (cboUnit.SelectedItem == null) + { + MessageBox.Show("Unit is required"); + return; + } + } + + _editedRecipeIngredientItem.ingredientID = _IngredientID; + if (chkLinkedToIngredient.Checked) + { + _editedRecipeIngredientItem.measureQuantity = Single.Parse(txtQuantity.Text); + _editedRecipeIngredientItem.measure = (Measure)(cboUnit.SelectedItem); + + + _editedRecipeIngredientItem.linkQuality = 4; + _editedRecipeIngredientItem.linkType = RecipeIngredientLinkType.Ingredient; + } + else + { + + + _editedRecipeIngredientItem.linkQuality = 0; + _editedRecipeIngredientItem.linkType = RecipeIngredientLinkType.NoLink; + } + + + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void LoadMeasuresForIngredient() + { + cboUnit.Items.Clear(); + var measureList = Measure.GetMeasuresByIngredientID(_IngredientID.Value); + cboUnit.Items.AddRange(measureList.ToArray()); + } + + private void SelectMeasuresByID(Guid? measureID) + { + cboUnit.SelectedItem = null; + + if (measureID != null) + { + for (var i = 0; i < cboUnit.Items.Count; i += 1) + { + if (((Measure)cboUnit.Items[i]).measureID == measureID) + { + cboUnit.SelectedIndex = i; + break; + } + } + } + } + + private void SelectMeasuresByName(String measureName) + { + cboUnit.SelectedItem = null; + + for (var i = 0; i < cboUnit.Items.Count; i += 1) + { + if (String.Compare(((Measure)cboUnit.Items[i]).description, measureName, true) == 0) + { + cboUnit.SelectedIndex = i; + break; + } + } + } + + private void btnSearch_Click(object sender, EventArgs e) + { + String searchFor; + if (String.IsNullOrEmpty(txtIngredient.Text)) + { + searchFor = _editedRecipeIngredientItem.ingredientText.Trim(); + } + else + { + searchFor = txtIngredient.Text; + } + var findIngredientForm = new frmFindIngredient(searchFor); + + var dialogResult = findIngredientForm.ShowDialog(); + + if (dialogResult == DialogResult.OK) + { + _IngredientID = findIngredientForm.selectedIngredient.ingredientID; + txtIngredient.Text = findIngredientForm.selectedIngredient.name; + + LoadMeasuresForIngredient(); + + SelectMeasuresByID(_editedRecipeIngredientItem.measureID); + + if (cboUnit.SelectedItem == null) + { + SelectMeasuresByName(_editedRecipeIngredientItem.measureName); + } + } + } + + private void LoadImages() + { + if (!_ImagesAlreadyLoaded) + { + _allButtonImagesList = new ImageList(); + _allButtonImagesList.ImageSize = btnSearch.ClientSize; + _allButtonImagesList.Images.Clear(); + _allButtonImagesList.Images.Add(Properties.Resources.Search); + _allButtonImagesList.Images.SetKeyName(0, SEARCH_IMAGE); + + _ImagesAlreadyLoaded = true; + } + + this.btnSearch.ImageList = _allButtonImagesList; + this.btnSearch.ImageKey = SEARCH_IMAGE; + + } + } +} diff --git a/JRCookbook/frmPickRecipeIngredient.resx b/JRCookbook/frmPickRecipeIngredient.resx new file mode 100644 index 0000000..b92c163 --- /dev/null +++ b/JRCookbook/frmPickRecipeIngredient.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/JRCookbook/frmRecipeCopyMoveTo.Designer.cs b/JRCookbook/frmRecipeCopyMoveTo.Designer.cs new file mode 100644 index 0000000..8e0abea --- /dev/null +++ b/JRCookbook/frmRecipeCopyMoveTo.Designer.cs @@ -0,0 +1,92 @@ + +namespace JRCookbook +{ + partial class frmRecipeCopyMoveTo + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tvwChapters = new System.Windows.Forms.TreeView(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // tvwChapters + // + this.tvwChapters.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tvwChapters.Cursor = System.Windows.Forms.Cursors.Arrow; + this.tvwChapters.Location = new System.Drawing.Point(12, 12); + this.tvwChapters.Name = "tvwChapters"; + this.tvwChapters.Size = new System.Drawing.Size(625, 385); + this.tvwChapters.TabIndex = 1; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point(478, 407); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(77, 23); + this.btnOK.TabIndex = 2; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.Location = new System.Drawing.Point(561, 407); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // frmRecipeCopyMoveTo + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(649, 440); + this.ControlBox = false; + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.tvwChapters); + this.Name = "frmRecipeCopyMoveTo"; + this.Text = "Move Recipe To"; + this.Load += new System.EventHandler(this.frmRecipeCopyMoveTo_Load); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView tvwChapters; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/JRCookbook/frmRecipeCopyMoveTo.cs b/JRCookbook/frmRecipeCopyMoveTo.cs new file mode 100644 index 0000000..a596a01 --- /dev/null +++ b/JRCookbook/frmRecipeCopyMoveTo.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbook +{ + public partial class frmRecipeCopyMoveTo : Form + { + private bool _moveRecipe = false; + private Recipe _editedRecipe = null; + + public Recipe editedRecipe + { + get + { + return _editedRecipe; + } + private set + { + _editedRecipe = value; + } + } + + + public frmRecipeCopyMoveTo(Recipe recipeToCopyMove, bool moveRecipe) + { + InitializeComponent(); + editedRecipe = recipeToCopyMove; + _moveRecipe = moveRecipe; + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (tvwChapters.SelectedNode == null || tvwChapters.SelectedNode.Tag == null) + { + MessageBox.Show("Must select cookbook or chapter"); + return; + } + + Guid cookbookID = Guid.Empty; + Guid? cookbookChapterID = null; + + if (tvwChapters.SelectedNode.Tag is Cookbook) + { + cookbookID = ((Cookbook)tvwChapters.SelectedNode.Tag).cookbookID.Value; + } + else if (tvwChapters.SelectedNode.Tag is CookbookChapter) + { + cookbookID = ((CookbookChapter)tvwChapters.SelectedNode.Tag).cookbookID.Value; + cookbookChapterID = ((CookbookChapter)tvwChapters.SelectedNode.Tag).cookbookChapterID; + } + else + { + MessageBox.Show("Must select cookbook or chapter"); + return; + } + + if (_moveRecipe) + { + _editedRecipe.cookbookID = cookbookID; + _editedRecipe.cookbookchapterID = cookbookChapterID; + _editedRecipe.Save(); + } + else + { + Recipe newRecipe = (Recipe)_editedRecipe.Clone(); + newRecipe.PasteIntoChapter(cookbookID, cookbookChapterID); + //newRecipe.Save(); + } + + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void btnCancel_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + private void frmRecipeCopyMoveTo_Load(object sender, EventArgs e) + { + ReloadChaptersTreeview(); + } + + private void ReloadChaptersTreeview() + { + this.UseWaitCursor = true; + tvwChapters.Nodes.Clear(); + var allCookbooksNode = new TreeNode("All Cookbooks"); + tvwChapters.Nodes.Add(allCookbooksNode); + + AddAllCookbooksToNode(allCookbooksNode); + + allCookbooksNode.Expand(); + + this.UseWaitCursor = false; + } + + private void AddAllCookbooksToNode(TreeNode parentNode) + { + var allCookbooks = Cookbook.GetAllCookbooks(); + foreach (var cookbook in allCookbooks) + { + var newNode = new TreeNode(cookbook.name); + newNode.Tag = cookbook; + newNode.Collapse(); + parentNode.Nodes.Add(newNode); + newNode.Name = NodeNameForCookbook(cookbook); + AddAllChapters(newNode, cookbook.cookbookChapters); + } + + } + + private void AddAllChapters(TreeNode parentNode, List cookbookChapterList) + { + foreach (var cookbookChapter in cookbookChapterList) + { + var newNode = new TreeNode(cookbookChapter.name); + newNode.Tag = cookbookChapter; + newNode.Collapse(); + parentNode.Nodes.Add(newNode); + newNode.Name = NodeNameForCookbookChapter(cookbookChapter); + AddAllChapters(newNode, cookbookChapter.cookbookChapters); + + } + } + + private String NodeNameForCookbook(Cookbook cookbook) + { + return "Cookbook" + cookbook.cookbookID.ToString(); + } + + private String NodeNameForCookbookChapter(CookbookChapter cookbookChapter) + { + return "CookbookChapter" + cookbookChapter.cookbookID.ToString() + "-" + cookbookChapter.cookbookChapterID.ToString(); + } + + } +} diff --git a/JRCookbook/frmRecipeCopyMoveTo.resx b/JRCookbook/frmRecipeCopyMoveTo.resx new file mode 100644 index 0000000..b5ae26c --- /dev/null +++ b/JRCookbook/frmRecipeCopyMoveTo.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/JRCookbook/frmViewRecipeNutritionAll.Designer.cs b/JRCookbook/frmViewRecipeNutritionAll.Designer.cs new file mode 100644 index 0000000..235d2c3 --- /dev/null +++ b/JRCookbook/frmViewRecipeNutritionAll.Designer.cs @@ -0,0 +1,1552 @@ + +namespace JRCookbook +{ + partial class frmViewRecipeNutritionAll + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + dgvwRecipeNutrition = new System.Windows.Forms.DataGridView(); + Ingredient = new System.Windows.Forms.DataGridViewTextBoxColumn(); + percentcaloriesfromalcohol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + percentcaloriesfromcarbs = new System.Windows.Forms.DataGridViewTextBoxColumn(); + percentcaloriesfromfat = new System.Windows.Forms.DataGridViewTextBoxColumn(); + percentcaloriesfromprotein = new System.Windows.Forms.DataGridViewTextBoxColumn(); + alanine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + alcohol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + alcoholfactor = new System.Windows.Forms.DataGridViewTextBoxColumn(); + alphacarotene = new System.Windows.Forms.DataGridViewTextBoxColumn(); + alphalinolenicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + arachidonicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + arginine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + ash = new System.Windows.Forms.DataGridViewTextBoxColumn(); + asparticacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + betacarotene = new System.Windows.Forms.DataGridViewTextBoxColumn(); + betacryptoxanthin = new System.Windows.Forms.DataGridViewTextBoxColumn(); + betasitosterol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + betatocopherol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + biotin = new System.Windows.Forms.DataGridViewTextBoxColumn(); + caffeine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + calcium = new System.Windows.Forms.DataGridViewTextBoxColumn(); + calories = new System.Windows.Forms.DataGridViewTextBoxColumn(); + caloriesfromalcohol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + caloriesfromcarbs = new System.Windows.Forms.DataGridViewTextBoxColumn(); + caloriesfromfat = new System.Windows.Forms.DataGridViewTextBoxColumn(); + caloriesfromprotein = new System.Windows.Forms.DataGridViewTextBoxColumn(); + campesterol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + carbohydratefactor = new System.Windows.Forms.DataGridViewTextBoxColumn(); + chloride = new System.Windows.Forms.DataGridViewTextBoxColumn(); + cholesterol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + choline = new System.Windows.Forms.DataGridViewTextBoxColumn(); + chromium = new System.Windows.Forms.DataGridViewTextBoxColumn(); + copper = new System.Windows.Forms.DataGridViewTextBoxColumn(); + cystine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + deltatocopherol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + dihomogammalinolenicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + docosahexaenoicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + docosapentaenoicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + eicosadienoicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + eicosapentaenoicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + energy = new System.Windows.Forms.DataGridViewTextBoxColumn(); + energyfromalcohol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + energyfromcarbs = new System.Windows.Forms.DataGridViewTextBoxColumn(); + energyfromfat = new System.Windows.Forms.DataGridViewTextBoxColumn(); + energyfromprotein = new System.Windows.Forms.DataGridViewTextBoxColumn(); + fatfactor = new System.Windows.Forms.DataGridViewTextBoxColumn(); + fiber = new System.Windows.Forms.DataGridViewTextBoxColumn(); + fluoride = new System.Windows.Forms.DataGridViewTextBoxColumn(); + folate = new System.Windows.Forms.DataGridViewTextBoxColumn(); + fructose = new System.Windows.Forms.DataGridViewTextBoxColumn(); + galactose = new System.Windows.Forms.DataGridViewTextBoxColumn(); + gammalinolenicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + gammatocopherol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + glucose = new System.Windows.Forms.DataGridViewTextBoxColumn(); + glutamicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + glycine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + histidine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + hydroxyproline = new System.Windows.Forms.DataGridViewTextBoxColumn(); + iodine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + iron = new System.Windows.Forms.DataGridViewTextBoxColumn(); + isoleucine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + lactose = new System.Windows.Forms.DataGridViewTextBoxColumn(); + leucine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + linoleicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + lycopene = new System.Windows.Forms.DataGridViewTextBoxColumn(); + lysine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + magnesium = new System.Windows.Forms.DataGridViewTextBoxColumn(); + maltose = new System.Windows.Forms.DataGridViewTextBoxColumn(); + manganese = new System.Windows.Forms.DataGridViewTextBoxColumn(); + mass = new System.Windows.Forms.DataGridViewTextBoxColumn(); + methionine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + molybdenum = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfat = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_14_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_15_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_16_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_17_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_18_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_20_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_22_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + monounsaturatedfattyacid_24_1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + netcarbohydrates = new System.Windows.Forms.DataGridViewTextBoxColumn(); + niacin = new System.Windows.Forms.DataGridViewTextBoxColumn(); + omega3fattyacids = new System.Windows.Forms.DataGridViewTextBoxColumn(); + omega6fattyacids = new System.Windows.Forms.DataGridViewTextBoxColumn(); + pantothenicacid = new System.Windows.Forms.DataGridViewTextBoxColumn(); + phenylalanine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + phosphorus = new System.Windows.Forms.DataGridViewTextBoxColumn(); + phytosterols = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfat = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfattyacid_18_2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfattyacid_18_3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfattyacid_18_4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfattyacid_20_3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfattyacid_20_4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfattyacid_21_5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + polyunsaturatedfattyacid_22_4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + potassium = new System.Windows.Forms.DataGridViewTextBoxColumn(); + proline = new System.Windows.Forms.DataGridViewTextBoxColumn(); + protein = new System.Windows.Forms.DataGridViewTextBoxColumn(); + proteinfactor = new System.Windows.Forms.DataGridViewTextBoxColumn(); + refuse = new System.Windows.Forms.DataGridViewTextBoxColumn(); + retinol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + riboflavin = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfat = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_10_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_12_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_13_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_14_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_15_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_16_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_17_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_18_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_20_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_22_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_24_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_4_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_6_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + saturatedfattyacid_8_0 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + selenium = new System.Windows.Forms.DataGridViewTextBoxColumn(); + serine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + sodium = new System.Windows.Forms.DataGridViewTextBoxColumn(); + starch = new System.Windows.Forms.DataGridViewTextBoxColumn(); + stigmasterol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + sucrose = new System.Windows.Forms.DataGridViewTextBoxColumn(); + sugar = new System.Windows.Forms.DataGridViewTextBoxColumn(); + sugaralcohols = new System.Windows.Forms.DataGridViewTextBoxColumn(); + theobromine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + thiamin = new System.Windows.Forms.DataGridViewTextBoxColumn(); + threonine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + totalcarbohydrate = new System.Windows.Forms.DataGridViewTextBoxColumn(); + totalfat = new System.Windows.Forms.DataGridViewTextBoxColumn(); + transfattyacids = new System.Windows.Forms.DataGridViewTextBoxColumn(); + transmonoenoicfattyacids = new System.Windows.Forms.DataGridViewTextBoxColumn(); + transpolyenoicfattyacids = new System.Windows.Forms.DataGridViewTextBoxColumn(); + tryptophan = new System.Windows.Forms.DataGridViewTextBoxColumn(); + tyrosine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + valine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + vitamina = new System.Windows.Forms.DataGridViewTextBoxColumn(); + vitaminb12 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + vitaminb6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + vitaminc = new System.Windows.Forms.DataGridViewTextBoxColumn(); + vitamind = new System.Windows.Forms.DataGridViewTextBoxColumn(); + vitamine = new System.Windows.Forms.DataGridViewTextBoxColumn(); + vitamink = new System.Windows.Forms.DataGridViewTextBoxColumn(); + volume = new System.Windows.Forms.DataGridViewTextBoxColumn(); + water = new System.Windows.Forms.DataGridViewTextBoxColumn(); + zinc = new System.Windows.Forms.DataGridViewTextBoxColumn(); + ((System.ComponentModel.ISupportInitialize)dgvwRecipeNutrition).BeginInit(); + SuspendLayout(); + // + // dgvwRecipeNutrition + // + dgvwRecipeNutrition.AllowUserToAddRows = false; + dgvwRecipeNutrition.AllowUserToDeleteRows = false; + dgvwRecipeNutrition.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + dgvwRecipeNutrition.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dgvwRecipeNutrition.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { Ingredient, percentcaloriesfromalcohol, percentcaloriesfromcarbs, percentcaloriesfromfat, percentcaloriesfromprotein, alanine, alcohol, alcoholfactor, alphacarotene, alphalinolenicacid, arachidonicacid, arginine, ash, asparticacid, betacarotene, betacryptoxanthin, betasitosterol, betatocopherol, biotin, caffeine, calcium, calories, caloriesfromalcohol, caloriesfromcarbs, caloriesfromfat, caloriesfromprotein, campesterol, carbohydratefactor, chloride, cholesterol, choline, chromium, copper, cystine, deltatocopherol, dihomogammalinolenicacid, docosahexaenoicacid, docosapentaenoicacid, eicosadienoicacid, eicosapentaenoicacid, energy, energyfromalcohol, energyfromcarbs, energyfromfat, energyfromprotein, fatfactor, fiber, fluoride, folate, fructose, galactose, gammalinolenicacid, gammatocopherol, glucose, glutamicacid, glycine, histidine, hydroxyproline, iodine, iron, isoleucine, lactose, leucine, linoleicacid, lycopene, lysine, magnesium, maltose, manganese, mass, methionine, molybdenum, monounsaturatedfat, monounsaturatedfattyacid_14_1, monounsaturatedfattyacid_15_1, monounsaturatedfattyacid_16_1, monounsaturatedfattyacid_17_1, monounsaturatedfattyacid_18_1, monounsaturatedfattyacid_20_1, monounsaturatedfattyacid_22_1, monounsaturatedfattyacid_24_1, netcarbohydrates, niacin, omega3fattyacids, omega6fattyacids, pantothenicacid, phenylalanine, phosphorus, phytosterols, polyunsaturatedfat, polyunsaturatedfattyacid_18_2, polyunsaturatedfattyacid_18_3, polyunsaturatedfattyacid_18_4, polyunsaturatedfattyacid_20_3, polyunsaturatedfattyacid_20_4, polyunsaturatedfattyacid_21_5, polyunsaturatedfattyacid_22_4, potassium, proline, protein, proteinfactor, refuse, retinol, riboflavin, saturatedfat, saturatedfattyacid_10_0, saturatedfattyacid_12_0, saturatedfattyacid_13_0, saturatedfattyacid_14_0, saturatedfattyacid_15_0, saturatedfattyacid_16_0, saturatedfattyacid_17_0, saturatedfattyacid_18_0, saturatedfattyacid_20_0, saturatedfattyacid_22_0, saturatedfattyacid_24_0, saturatedfattyacid_4_0, saturatedfattyacid_6_0, saturatedfattyacid_8_0, selenium, serine, sodium, starch, stigmasterol, sucrose, sugar, sugaralcohols, theobromine, thiamin, threonine, totalcarbohydrate, totalfat, transfattyacids, transmonoenoicfattyacids, transpolyenoicfattyacids, tryptophan, tyrosine, valine, vitamina, vitaminb12, vitaminb6, vitaminc, vitamind, vitamine, vitamink, volume, water, zinc }); + dgvwRecipeNutrition.Location = new System.Drawing.Point(32, 36); + dgvwRecipeNutrition.Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + dgvwRecipeNutrition.Name = "dgvwRecipeNutrition"; + dgvwRecipeNutrition.ReadOnly = true; + dgvwRecipeNutrition.RowHeadersWidth = 50; + dgvwRecipeNutrition.RowTemplate.Height = 25; + dgvwRecipeNutrition.Size = new System.Drawing.Size(2708, 1041); + dgvwRecipeNutrition.TabIndex = 0; + // + // Ingredient + // + Ingredient.Frozen = true; + Ingredient.HeaderText = "IngredientText"; + Ingredient.MinimumWidth = 12; + Ingredient.Name = "Ingredient"; + Ingredient.ReadOnly = true; + Ingredient.Width = 250; + // + // percentcaloriesfromalcohol + // + percentcaloriesfromalcohol.HeaderText = "percentcaloriesfromalcohol"; + percentcaloriesfromalcohol.MinimumWidth = 12; + percentcaloriesfromalcohol.Name = "percentcaloriesfromalcohol"; + percentcaloriesfromalcohol.ReadOnly = true; + percentcaloriesfromalcohol.Width = 250; + // + // percentcaloriesfromcarbs + // + percentcaloriesfromcarbs.HeaderText = "percentcaloriesfromcarbs"; + percentcaloriesfromcarbs.MinimumWidth = 12; + percentcaloriesfromcarbs.Name = "percentcaloriesfromcarbs"; + percentcaloriesfromcarbs.ReadOnly = true; + percentcaloriesfromcarbs.Width = 250; + // + // percentcaloriesfromfat + // + percentcaloriesfromfat.HeaderText = "percentcaloriesfromfat"; + percentcaloriesfromfat.MinimumWidth = 12; + percentcaloriesfromfat.Name = "percentcaloriesfromfat"; + percentcaloriesfromfat.ReadOnly = true; + percentcaloriesfromfat.Width = 250; + // + // percentcaloriesfromprotein + // + percentcaloriesfromprotein.HeaderText = "percentcaloriesfromprotein"; + percentcaloriesfromprotein.MinimumWidth = 12; + percentcaloriesfromprotein.Name = "percentcaloriesfromprotein"; + percentcaloriesfromprotein.ReadOnly = true; + percentcaloriesfromprotein.Width = 250; + // + // alanine + // + alanine.HeaderText = "alanine"; + alanine.MinimumWidth = 12; + alanine.Name = "alanine"; + alanine.ReadOnly = true; + alanine.Width = 250; + // + // alcohol + // + alcohol.HeaderText = "alcohol"; + alcohol.MinimumWidth = 12; + alcohol.Name = "alcohol"; + alcohol.ReadOnly = true; + alcohol.Width = 250; + // + // alcoholfactor + // + alcoholfactor.HeaderText = "alcoholfactor"; + alcoholfactor.MinimumWidth = 12; + alcoholfactor.Name = "alcoholfactor"; + alcoholfactor.ReadOnly = true; + alcoholfactor.Width = 250; + // + // alphacarotene + // + alphacarotene.HeaderText = "alphacarotene"; + alphacarotene.MinimumWidth = 12; + alphacarotene.Name = "alphacarotene"; + alphacarotene.ReadOnly = true; + alphacarotene.Width = 250; + // + // alphalinolenicacid + // + alphalinolenicacid.HeaderText = "alphalinolenicacid"; + alphalinolenicacid.MinimumWidth = 12; + alphalinolenicacid.Name = "alphalinolenicacid"; + alphalinolenicacid.ReadOnly = true; + alphalinolenicacid.Width = 250; + // + // arachidonicacid + // + arachidonicacid.HeaderText = "arachidonicacid"; + arachidonicacid.MinimumWidth = 12; + arachidonicacid.Name = "arachidonicacid"; + arachidonicacid.ReadOnly = true; + arachidonicacid.Width = 250; + // + // arginine + // + arginine.HeaderText = "arginine"; + arginine.MinimumWidth = 12; + arginine.Name = "arginine"; + arginine.ReadOnly = true; + arginine.Width = 250; + // + // ash + // + ash.HeaderText = "ash"; + ash.MinimumWidth = 12; + ash.Name = "ash"; + ash.ReadOnly = true; + ash.Width = 250; + // + // asparticacid + // + asparticacid.HeaderText = "asparticacid"; + asparticacid.MinimumWidth = 12; + asparticacid.Name = "asparticacid"; + asparticacid.ReadOnly = true; + asparticacid.Width = 250; + // + // betacarotene + // + betacarotene.HeaderText = "betacarotene"; + betacarotene.MinimumWidth = 12; + betacarotene.Name = "betacarotene"; + betacarotene.ReadOnly = true; + betacarotene.Width = 250; + // + // betacryptoxanthin + // + betacryptoxanthin.HeaderText = "betacryptoxanthin"; + betacryptoxanthin.MinimumWidth = 12; + betacryptoxanthin.Name = "betacryptoxanthin"; + betacryptoxanthin.ReadOnly = true; + betacryptoxanthin.Width = 250; + // + // betasitosterol + // + betasitosterol.HeaderText = "betasitosterol"; + betasitosterol.MinimumWidth = 12; + betasitosterol.Name = "betasitosterol"; + betasitosterol.ReadOnly = true; + betasitosterol.Width = 250; + // + // betatocopherol + // + betatocopherol.HeaderText = "betatocopherol"; + betatocopherol.MinimumWidth = 12; + betatocopherol.Name = "betatocopherol"; + betatocopherol.ReadOnly = true; + betatocopherol.Width = 250; + // + // biotin + // + biotin.HeaderText = "biotin"; + biotin.MinimumWidth = 12; + biotin.Name = "biotin"; + biotin.ReadOnly = true; + biotin.Width = 250; + // + // caffeine + // + caffeine.HeaderText = "caffeine"; + caffeine.MinimumWidth = 12; + caffeine.Name = "caffeine"; + caffeine.ReadOnly = true; + caffeine.Width = 250; + // + // calcium + // + calcium.HeaderText = "calcium"; + calcium.MinimumWidth = 12; + calcium.Name = "calcium"; + calcium.ReadOnly = true; + calcium.Width = 250; + // + // calories + // + calories.HeaderText = "calories"; + calories.MinimumWidth = 12; + calories.Name = "calories"; + calories.ReadOnly = true; + calories.Width = 250; + // + // caloriesfromalcohol + // + caloriesfromalcohol.HeaderText = "caloriesfromalcohol"; + caloriesfromalcohol.MinimumWidth = 12; + caloriesfromalcohol.Name = "caloriesfromalcohol"; + caloriesfromalcohol.ReadOnly = true; + caloriesfromalcohol.Width = 250; + // + // caloriesfromcarbs + // + caloriesfromcarbs.HeaderText = "caloriesfromcarbs"; + caloriesfromcarbs.MinimumWidth = 12; + caloriesfromcarbs.Name = "caloriesfromcarbs"; + caloriesfromcarbs.ReadOnly = true; + caloriesfromcarbs.Width = 250; + // + // caloriesfromfat + // + caloriesfromfat.HeaderText = "caloriesfromfat"; + caloriesfromfat.MinimumWidth = 12; + caloriesfromfat.Name = "caloriesfromfat"; + caloriesfromfat.ReadOnly = true; + caloriesfromfat.Width = 250; + // + // caloriesfromprotein + // + caloriesfromprotein.HeaderText = "caloriesfromprotein"; + caloriesfromprotein.MinimumWidth = 12; + caloriesfromprotein.Name = "caloriesfromprotein"; + caloriesfromprotein.ReadOnly = true; + caloriesfromprotein.Width = 250; + // + // campesterol + // + campesterol.HeaderText = "campesterol"; + campesterol.MinimumWidth = 12; + campesterol.Name = "campesterol"; + campesterol.ReadOnly = true; + campesterol.Width = 250; + // + // carbohydratefactor + // + carbohydratefactor.HeaderText = "carbohydratefactor"; + carbohydratefactor.MinimumWidth = 12; + carbohydratefactor.Name = "carbohydratefactor"; + carbohydratefactor.ReadOnly = true; + carbohydratefactor.Width = 250; + // + // chloride + // + chloride.HeaderText = "chloride"; + chloride.MinimumWidth = 12; + chloride.Name = "chloride"; + chloride.ReadOnly = true; + chloride.Width = 250; + // + // cholesterol + // + cholesterol.HeaderText = "cholesterol"; + cholesterol.MinimumWidth = 12; + cholesterol.Name = "cholesterol"; + cholesterol.ReadOnly = true; + cholesterol.Width = 250; + // + // choline + // + choline.HeaderText = "choline"; + choline.MinimumWidth = 12; + choline.Name = "choline"; + choline.ReadOnly = true; + choline.Width = 250; + // + // chromium + // + chromium.HeaderText = "chromium"; + chromium.MinimumWidth = 12; + chromium.Name = "chromium"; + chromium.ReadOnly = true; + chromium.Width = 250; + // + // copper + // + copper.HeaderText = "copper"; + copper.MinimumWidth = 12; + copper.Name = "copper"; + copper.ReadOnly = true; + copper.Width = 250; + // + // cystine + // + cystine.HeaderText = "cystine"; + cystine.MinimumWidth = 12; + cystine.Name = "cystine"; + cystine.ReadOnly = true; + cystine.Width = 250; + // + // deltatocopherol + // + deltatocopherol.HeaderText = "deltatocopherol"; + deltatocopherol.MinimumWidth = 12; + deltatocopherol.Name = "deltatocopherol"; + deltatocopherol.ReadOnly = true; + deltatocopherol.Width = 250; + // + // dihomogammalinolenicacid + // + dihomogammalinolenicacid.HeaderText = "dihomogammalinolenicacid"; + dihomogammalinolenicacid.MinimumWidth = 12; + dihomogammalinolenicacid.Name = "dihomogammalinolenicacid"; + dihomogammalinolenicacid.ReadOnly = true; + dihomogammalinolenicacid.Width = 250; + // + // docosahexaenoicacid + // + docosahexaenoicacid.HeaderText = "docosahexaenoicacid"; + docosahexaenoicacid.MinimumWidth = 12; + docosahexaenoicacid.Name = "docosahexaenoicacid"; + docosahexaenoicacid.ReadOnly = true; + docosahexaenoicacid.Width = 250; + // + // docosapentaenoicacid + // + docosapentaenoicacid.HeaderText = "docosapentaenoicacid"; + docosapentaenoicacid.MinimumWidth = 12; + docosapentaenoicacid.Name = "docosapentaenoicacid"; + docosapentaenoicacid.ReadOnly = true; + docosapentaenoicacid.Width = 250; + // + // eicosadienoicacid + // + eicosadienoicacid.HeaderText = "eicosadienoicacid"; + eicosadienoicacid.MinimumWidth = 12; + eicosadienoicacid.Name = "eicosadienoicacid"; + eicosadienoicacid.ReadOnly = true; + eicosadienoicacid.Width = 250; + // + // eicosapentaenoicacid + // + eicosapentaenoicacid.HeaderText = "eicosapentaenoicacid"; + eicosapentaenoicacid.MinimumWidth = 12; + eicosapentaenoicacid.Name = "eicosapentaenoicacid"; + eicosapentaenoicacid.ReadOnly = true; + eicosapentaenoicacid.Width = 250; + // + // energy + // + energy.HeaderText = "energy"; + energy.MinimumWidth = 12; + energy.Name = "energy"; + energy.ReadOnly = true; + energy.Width = 250; + // + // energyfromalcohol + // + energyfromalcohol.HeaderText = "energyfromalcohol"; + energyfromalcohol.MinimumWidth = 12; + energyfromalcohol.Name = "energyfromalcohol"; + energyfromalcohol.ReadOnly = true; + energyfromalcohol.Width = 250; + // + // energyfromcarbs + // + energyfromcarbs.HeaderText = "energyfromcarbs"; + energyfromcarbs.MinimumWidth = 12; + energyfromcarbs.Name = "energyfromcarbs"; + energyfromcarbs.ReadOnly = true; + energyfromcarbs.Width = 250; + // + // energyfromfat + // + energyfromfat.HeaderText = "energyfromfat"; + energyfromfat.MinimumWidth = 12; + energyfromfat.Name = "energyfromfat"; + energyfromfat.ReadOnly = true; + energyfromfat.Width = 250; + // + // energyfromprotein + // + energyfromprotein.HeaderText = "energyfromprotein"; + energyfromprotein.MinimumWidth = 12; + energyfromprotein.Name = "energyfromprotein"; + energyfromprotein.ReadOnly = true; + energyfromprotein.Width = 250; + // + // fatfactor + // + fatfactor.HeaderText = "fatfactor"; + fatfactor.MinimumWidth = 12; + fatfactor.Name = "fatfactor"; + fatfactor.ReadOnly = true; + fatfactor.Width = 250; + // + // fiber + // + fiber.HeaderText = "fiber"; + fiber.MinimumWidth = 12; + fiber.Name = "fiber"; + fiber.ReadOnly = true; + fiber.Width = 250; + // + // fluoride + // + fluoride.HeaderText = "fluoride"; + fluoride.MinimumWidth = 12; + fluoride.Name = "fluoride"; + fluoride.ReadOnly = true; + fluoride.Width = 250; + // + // folate + // + folate.HeaderText = "folate"; + folate.MinimumWidth = 12; + folate.Name = "folate"; + folate.ReadOnly = true; + folate.Width = 250; + // + // fructose + // + fructose.HeaderText = "fructose"; + fructose.MinimumWidth = 12; + fructose.Name = "fructose"; + fructose.ReadOnly = true; + fructose.Width = 250; + // + // galactose + // + galactose.HeaderText = "galactose"; + galactose.MinimumWidth = 12; + galactose.Name = "galactose"; + galactose.ReadOnly = true; + galactose.Width = 250; + // + // gammalinolenicacid + // + gammalinolenicacid.HeaderText = "gammalinolenicacid"; + gammalinolenicacid.MinimumWidth = 12; + gammalinolenicacid.Name = "gammalinolenicacid"; + gammalinolenicacid.ReadOnly = true; + gammalinolenicacid.Width = 250; + // + // gammatocopherol + // + gammatocopherol.HeaderText = "gammatocopherol"; + gammatocopherol.MinimumWidth = 12; + gammatocopherol.Name = "gammatocopherol"; + gammatocopherol.ReadOnly = true; + gammatocopherol.Width = 250; + // + // glucose + // + glucose.HeaderText = "glucose"; + glucose.MinimumWidth = 12; + glucose.Name = "glucose"; + glucose.ReadOnly = true; + glucose.Width = 250; + // + // glutamicacid + // + glutamicacid.HeaderText = "glutamicacid"; + glutamicacid.MinimumWidth = 12; + glutamicacid.Name = "glutamicacid"; + glutamicacid.ReadOnly = true; + glutamicacid.Width = 250; + // + // glycine + // + glycine.HeaderText = "glycine"; + glycine.MinimumWidth = 12; + glycine.Name = "glycine"; + glycine.ReadOnly = true; + glycine.Width = 250; + // + // histidine + // + histidine.HeaderText = "histidine"; + histidine.MinimumWidth = 12; + histidine.Name = "histidine"; + histidine.ReadOnly = true; + histidine.Width = 250; + // + // hydroxyproline + // + hydroxyproline.HeaderText = "hydroxyproline"; + hydroxyproline.MinimumWidth = 12; + hydroxyproline.Name = "hydroxyproline"; + hydroxyproline.ReadOnly = true; + hydroxyproline.Width = 250; + // + // iodine + // + iodine.HeaderText = "iodine"; + iodine.MinimumWidth = 12; + iodine.Name = "iodine"; + iodine.ReadOnly = true; + iodine.Width = 250; + // + // iron + // + iron.HeaderText = "iron"; + iron.MinimumWidth = 12; + iron.Name = "iron"; + iron.ReadOnly = true; + iron.Width = 250; + // + // isoleucine + // + isoleucine.HeaderText = "isoleucine"; + isoleucine.MinimumWidth = 12; + isoleucine.Name = "isoleucine"; + isoleucine.ReadOnly = true; + isoleucine.Width = 250; + // + // lactose + // + lactose.HeaderText = "lactose"; + lactose.MinimumWidth = 12; + lactose.Name = "lactose"; + lactose.ReadOnly = true; + lactose.Width = 250; + // + // leucine + // + leucine.HeaderText = "leucine"; + leucine.MinimumWidth = 12; + leucine.Name = "leucine"; + leucine.ReadOnly = true; + leucine.Width = 250; + // + // linoleicacid + // + linoleicacid.HeaderText = "linoleicacid"; + linoleicacid.MinimumWidth = 12; + linoleicacid.Name = "linoleicacid"; + linoleicacid.ReadOnly = true; + linoleicacid.Width = 250; + // + // lycopene + // + lycopene.HeaderText = "lycopene"; + lycopene.MinimumWidth = 12; + lycopene.Name = "lycopene"; + lycopene.ReadOnly = true; + lycopene.Width = 250; + // + // lysine + // + lysine.HeaderText = "lysine"; + lysine.MinimumWidth = 12; + lysine.Name = "lysine"; + lysine.ReadOnly = true; + lysine.Width = 250; + // + // magnesium + // + magnesium.HeaderText = "magnesium"; + magnesium.MinimumWidth = 12; + magnesium.Name = "magnesium"; + magnesium.ReadOnly = true; + magnesium.Width = 250; + // + // maltose + // + maltose.HeaderText = "maltose"; + maltose.MinimumWidth = 12; + maltose.Name = "maltose"; + maltose.ReadOnly = true; + maltose.Width = 250; + // + // manganese + // + manganese.HeaderText = "manganese"; + manganese.MinimumWidth = 12; + manganese.Name = "manganese"; + manganese.ReadOnly = true; + manganese.Width = 250; + // + // mass + // + mass.HeaderText = "mass"; + mass.MinimumWidth = 12; + mass.Name = "mass"; + mass.ReadOnly = true; + mass.Width = 250; + // + // methionine + // + methionine.HeaderText = "methionine"; + methionine.MinimumWidth = 12; + methionine.Name = "methionine"; + methionine.ReadOnly = true; + methionine.Width = 250; + // + // molybdenum + // + molybdenum.HeaderText = "molybdenum"; + molybdenum.MinimumWidth = 12; + molybdenum.Name = "molybdenum"; + molybdenum.ReadOnly = true; + molybdenum.Width = 250; + // + // monounsaturatedfat + // + monounsaturatedfat.HeaderText = "monounsaturatedfat"; + monounsaturatedfat.MinimumWidth = 12; + monounsaturatedfat.Name = "monounsaturatedfat"; + monounsaturatedfat.ReadOnly = true; + monounsaturatedfat.Width = 250; + // + // monounsaturatedfattyacid_14_1 + // + monounsaturatedfattyacid_14_1.HeaderText = "monounsaturatedfattyacid_14_1"; + monounsaturatedfattyacid_14_1.MinimumWidth = 12; + monounsaturatedfattyacid_14_1.Name = "monounsaturatedfattyacid_14_1"; + monounsaturatedfattyacid_14_1.ReadOnly = true; + monounsaturatedfattyacid_14_1.Width = 250; + // + // monounsaturatedfattyacid_15_1 + // + monounsaturatedfattyacid_15_1.HeaderText = "monounsaturatedfattyacid_15_1"; + monounsaturatedfattyacid_15_1.MinimumWidth = 12; + monounsaturatedfattyacid_15_1.Name = "monounsaturatedfattyacid_15_1"; + monounsaturatedfattyacid_15_1.ReadOnly = true; + monounsaturatedfattyacid_15_1.Width = 250; + // + // monounsaturatedfattyacid_16_1 + // + monounsaturatedfattyacid_16_1.HeaderText = "monounsaturatedfattyacid_16_1"; + monounsaturatedfattyacid_16_1.MinimumWidth = 12; + monounsaturatedfattyacid_16_1.Name = "monounsaturatedfattyacid_16_1"; + monounsaturatedfattyacid_16_1.ReadOnly = true; + monounsaturatedfattyacid_16_1.Width = 250; + // + // monounsaturatedfattyacid_17_1 + // + monounsaturatedfattyacid_17_1.HeaderText = "monounsaturatedfattyacid_17_1"; + monounsaturatedfattyacid_17_1.MinimumWidth = 12; + monounsaturatedfattyacid_17_1.Name = "monounsaturatedfattyacid_17_1"; + monounsaturatedfattyacid_17_1.ReadOnly = true; + monounsaturatedfattyacid_17_1.Width = 250; + // + // monounsaturatedfattyacid_18_1 + // + monounsaturatedfattyacid_18_1.HeaderText = "monounsaturatedfattyacid_18_1"; + monounsaturatedfattyacid_18_1.MinimumWidth = 12; + monounsaturatedfattyacid_18_1.Name = "monounsaturatedfattyacid_18_1"; + monounsaturatedfattyacid_18_1.ReadOnly = true; + monounsaturatedfattyacid_18_1.Width = 250; + // + // monounsaturatedfattyacid_20_1 + // + monounsaturatedfattyacid_20_1.HeaderText = "monounsaturatedfattyacid_20_1"; + monounsaturatedfattyacid_20_1.MinimumWidth = 12; + monounsaturatedfattyacid_20_1.Name = "monounsaturatedfattyacid_20_1"; + monounsaturatedfattyacid_20_1.ReadOnly = true; + monounsaturatedfattyacid_20_1.Width = 250; + // + // monounsaturatedfattyacid_22_1 + // + monounsaturatedfattyacid_22_1.HeaderText = "monounsaturatedfattyacid_22_1"; + monounsaturatedfattyacid_22_1.MinimumWidth = 12; + monounsaturatedfattyacid_22_1.Name = "monounsaturatedfattyacid_22_1"; + monounsaturatedfattyacid_22_1.ReadOnly = true; + monounsaturatedfattyacid_22_1.Width = 250; + // + // monounsaturatedfattyacid_24_1 + // + monounsaturatedfattyacid_24_1.HeaderText = "monounsaturatedfattyacid_24_1"; + monounsaturatedfattyacid_24_1.MinimumWidth = 12; + monounsaturatedfattyacid_24_1.Name = "monounsaturatedfattyacid_24_1"; + monounsaturatedfattyacid_24_1.ReadOnly = true; + monounsaturatedfattyacid_24_1.Width = 250; + // + // netcarbohydrates + // + netcarbohydrates.HeaderText = "netcarbohydrates"; + netcarbohydrates.MinimumWidth = 12; + netcarbohydrates.Name = "netcarbohydrates"; + netcarbohydrates.ReadOnly = true; + netcarbohydrates.Width = 250; + // + // niacin + // + niacin.HeaderText = "niacin"; + niacin.MinimumWidth = 12; + niacin.Name = "niacin"; + niacin.ReadOnly = true; + niacin.Width = 250; + // + // omega3fattyacids + // + omega3fattyacids.HeaderText = "omega3fattyacids"; + omega3fattyacids.MinimumWidth = 12; + omega3fattyacids.Name = "omega3fattyacids"; + omega3fattyacids.ReadOnly = true; + omega3fattyacids.Width = 250; + // + // omega6fattyacids + // + omega6fattyacids.HeaderText = "omega6fattyacids"; + omega6fattyacids.MinimumWidth = 12; + omega6fattyacids.Name = "omega6fattyacids"; + omega6fattyacids.ReadOnly = true; + omega6fattyacids.Width = 250; + // + // pantothenicacid + // + pantothenicacid.HeaderText = "pantothenicacid"; + pantothenicacid.MinimumWidth = 12; + pantothenicacid.Name = "pantothenicacid"; + pantothenicacid.ReadOnly = true; + pantothenicacid.Width = 250; + // + // phenylalanine + // + phenylalanine.HeaderText = "phenylalanine"; + phenylalanine.MinimumWidth = 12; + phenylalanine.Name = "phenylalanine"; + phenylalanine.ReadOnly = true; + phenylalanine.Width = 250; + // + // phosphorus + // + phosphorus.HeaderText = "phosphorus"; + phosphorus.MinimumWidth = 12; + phosphorus.Name = "phosphorus"; + phosphorus.ReadOnly = true; + phosphorus.Width = 250; + // + // phytosterols + // + phytosterols.HeaderText = "phytosterols"; + phytosterols.MinimumWidth = 12; + phytosterols.Name = "phytosterols"; + phytosterols.ReadOnly = true; + phytosterols.Width = 250; + // + // polyunsaturatedfat + // + polyunsaturatedfat.HeaderText = "polyunsaturatedfat"; + polyunsaturatedfat.MinimumWidth = 12; + polyunsaturatedfat.Name = "polyunsaturatedfat"; + polyunsaturatedfat.ReadOnly = true; + polyunsaturatedfat.Width = 250; + // + // polyunsaturatedfattyacid_18_2 + // + polyunsaturatedfattyacid_18_2.HeaderText = "polyunsaturatedfattyacid_18_2"; + polyunsaturatedfattyacid_18_2.MinimumWidth = 12; + polyunsaturatedfattyacid_18_2.Name = "polyunsaturatedfattyacid_18_2"; + polyunsaturatedfattyacid_18_2.ReadOnly = true; + polyunsaturatedfattyacid_18_2.Width = 250; + // + // polyunsaturatedfattyacid_18_3 + // + polyunsaturatedfattyacid_18_3.HeaderText = "polyunsaturatedfattyacid_18_3"; + polyunsaturatedfattyacid_18_3.MinimumWidth = 12; + polyunsaturatedfattyacid_18_3.Name = "polyunsaturatedfattyacid_18_3"; + polyunsaturatedfattyacid_18_3.ReadOnly = true; + polyunsaturatedfattyacid_18_3.Width = 250; + // + // polyunsaturatedfattyacid_18_4 + // + polyunsaturatedfattyacid_18_4.HeaderText = "polyunsaturatedfattyacid_18_4"; + polyunsaturatedfattyacid_18_4.MinimumWidth = 12; + polyunsaturatedfattyacid_18_4.Name = "polyunsaturatedfattyacid_18_4"; + polyunsaturatedfattyacid_18_4.ReadOnly = true; + polyunsaturatedfattyacid_18_4.Width = 250; + // + // polyunsaturatedfattyacid_20_3 + // + polyunsaturatedfattyacid_20_3.HeaderText = "polyunsaturatedfattyacid_20_3"; + polyunsaturatedfattyacid_20_3.MinimumWidth = 12; + polyunsaturatedfattyacid_20_3.Name = "polyunsaturatedfattyacid_20_3"; + polyunsaturatedfattyacid_20_3.ReadOnly = true; + polyunsaturatedfattyacid_20_3.Width = 250; + // + // polyunsaturatedfattyacid_20_4 + // + polyunsaturatedfattyacid_20_4.HeaderText = "polyunsaturatedfattyacid_20_4"; + polyunsaturatedfattyacid_20_4.MinimumWidth = 12; + polyunsaturatedfattyacid_20_4.Name = "polyunsaturatedfattyacid_20_4"; + polyunsaturatedfattyacid_20_4.ReadOnly = true; + polyunsaturatedfattyacid_20_4.Width = 250; + // + // polyunsaturatedfattyacid_21_5 + // + polyunsaturatedfattyacid_21_5.HeaderText = "polyunsaturatedfattyacid_21_5"; + polyunsaturatedfattyacid_21_5.MinimumWidth = 12; + polyunsaturatedfattyacid_21_5.Name = "polyunsaturatedfattyacid_21_5"; + polyunsaturatedfattyacid_21_5.ReadOnly = true; + polyunsaturatedfattyacid_21_5.Width = 250; + // + // polyunsaturatedfattyacid_22_4 + // + polyunsaturatedfattyacid_22_4.HeaderText = "polyunsaturatedfattyacid_22_4"; + polyunsaturatedfattyacid_22_4.MinimumWidth = 12; + polyunsaturatedfattyacid_22_4.Name = "polyunsaturatedfattyacid_22_4"; + polyunsaturatedfattyacid_22_4.ReadOnly = true; + polyunsaturatedfattyacid_22_4.Width = 250; + // + // potassium + // + potassium.HeaderText = "potassium"; + potassium.MinimumWidth = 12; + potassium.Name = "potassium"; + potassium.ReadOnly = true; + potassium.Width = 250; + // + // proline + // + proline.HeaderText = "proline"; + proline.MinimumWidth = 12; + proline.Name = "proline"; + proline.ReadOnly = true; + proline.Width = 250; + // + // protein + // + protein.HeaderText = "protein"; + protein.MinimumWidth = 12; + protein.Name = "protein"; + protein.ReadOnly = true; + protein.Width = 250; + // + // proteinfactor + // + proteinfactor.HeaderText = "proteinfactor"; + proteinfactor.MinimumWidth = 12; + proteinfactor.Name = "proteinfactor"; + proteinfactor.ReadOnly = true; + proteinfactor.Width = 250; + // + // refuse + // + refuse.HeaderText = "refuse"; + refuse.MinimumWidth = 12; + refuse.Name = "refuse"; + refuse.ReadOnly = true; + refuse.Width = 250; + // + // retinol + // + retinol.HeaderText = "retinol"; + retinol.MinimumWidth = 12; + retinol.Name = "retinol"; + retinol.ReadOnly = true; + retinol.Width = 250; + // + // riboflavin + // + riboflavin.HeaderText = "riboflavin"; + riboflavin.MinimumWidth = 12; + riboflavin.Name = "riboflavin"; + riboflavin.ReadOnly = true; + riboflavin.Width = 250; + // + // saturatedfat + // + saturatedfat.HeaderText = "saturatedfat"; + saturatedfat.MinimumWidth = 12; + saturatedfat.Name = "saturatedfat"; + saturatedfat.ReadOnly = true; + saturatedfat.Width = 250; + // + // saturatedfattyacid_10_0 + // + saturatedfattyacid_10_0.HeaderText = "saturatedfattyacid_10_0"; + saturatedfattyacid_10_0.MinimumWidth = 12; + saturatedfattyacid_10_0.Name = "saturatedfattyacid_10_0"; + saturatedfattyacid_10_0.ReadOnly = true; + saturatedfattyacid_10_0.Width = 250; + // + // saturatedfattyacid_12_0 + // + saturatedfattyacid_12_0.HeaderText = "saturatedfattyacid_12_0"; + saturatedfattyacid_12_0.MinimumWidth = 12; + saturatedfattyacid_12_0.Name = "saturatedfattyacid_12_0"; + saturatedfattyacid_12_0.ReadOnly = true; + saturatedfattyacid_12_0.Width = 250; + // + // saturatedfattyacid_13_0 + // + saturatedfattyacid_13_0.HeaderText = "saturatedfattyacid_13_0"; + saturatedfattyacid_13_0.MinimumWidth = 12; + saturatedfattyacid_13_0.Name = "saturatedfattyacid_13_0"; + saturatedfattyacid_13_0.ReadOnly = true; + saturatedfattyacid_13_0.Width = 250; + // + // saturatedfattyacid_14_0 + // + saturatedfattyacid_14_0.HeaderText = "saturatedfattyacid_14_0"; + saturatedfattyacid_14_0.MinimumWidth = 12; + saturatedfattyacid_14_0.Name = "saturatedfattyacid_14_0"; + saturatedfattyacid_14_0.ReadOnly = true; + saturatedfattyacid_14_0.Width = 250; + // + // saturatedfattyacid_15_0 + // + saturatedfattyacid_15_0.HeaderText = "saturatedfattyacid_15_0"; + saturatedfattyacid_15_0.MinimumWidth = 12; + saturatedfattyacid_15_0.Name = "saturatedfattyacid_15_0"; + saturatedfattyacid_15_0.ReadOnly = true; + saturatedfattyacid_15_0.Width = 250; + // + // saturatedfattyacid_16_0 + // + saturatedfattyacid_16_0.HeaderText = "saturatedfattyacid_16_0"; + saturatedfattyacid_16_0.MinimumWidth = 12; + saturatedfattyacid_16_0.Name = "saturatedfattyacid_16_0"; + saturatedfattyacid_16_0.ReadOnly = true; + saturatedfattyacid_16_0.Width = 250; + // + // saturatedfattyacid_17_0 + // + saturatedfattyacid_17_0.HeaderText = "saturatedfattyacid_17_0"; + saturatedfattyacid_17_0.MinimumWidth = 12; + saturatedfattyacid_17_0.Name = "saturatedfattyacid_17_0"; + saturatedfattyacid_17_0.ReadOnly = true; + saturatedfattyacid_17_0.Width = 250; + // + // saturatedfattyacid_18_0 + // + saturatedfattyacid_18_0.HeaderText = "saturatedfattyacid_18_0"; + saturatedfattyacid_18_0.MinimumWidth = 12; + saturatedfattyacid_18_0.Name = "saturatedfattyacid_18_0"; + saturatedfattyacid_18_0.ReadOnly = true; + saturatedfattyacid_18_0.Width = 250; + // + // saturatedfattyacid_20_0 + // + saturatedfattyacid_20_0.HeaderText = "saturatedfattyacid_20_0"; + saturatedfattyacid_20_0.MinimumWidth = 12; + saturatedfattyacid_20_0.Name = "saturatedfattyacid_20_0"; + saturatedfattyacid_20_0.ReadOnly = true; + saturatedfattyacid_20_0.Width = 250; + // + // saturatedfattyacid_22_0 + // + saturatedfattyacid_22_0.HeaderText = "saturatedfattyacid_22_0"; + saturatedfattyacid_22_0.MinimumWidth = 12; + saturatedfattyacid_22_0.Name = "saturatedfattyacid_22_0"; + saturatedfattyacid_22_0.ReadOnly = true; + saturatedfattyacid_22_0.Width = 250; + // + // saturatedfattyacid_24_0 + // + saturatedfattyacid_24_0.HeaderText = "saturatedfattyacid_24_0"; + saturatedfattyacid_24_0.MinimumWidth = 12; + saturatedfattyacid_24_0.Name = "saturatedfattyacid_24_0"; + saturatedfattyacid_24_0.ReadOnly = true; + saturatedfattyacid_24_0.Width = 250; + // + // saturatedfattyacid_4_0 + // + saturatedfattyacid_4_0.HeaderText = "saturatedfattyacid_4_0"; + saturatedfattyacid_4_0.MinimumWidth = 12; + saturatedfattyacid_4_0.Name = "saturatedfattyacid_4_0"; + saturatedfattyacid_4_0.ReadOnly = true; + saturatedfattyacid_4_0.Width = 250; + // + // saturatedfattyacid_6_0 + // + saturatedfattyacid_6_0.HeaderText = "saturatedfattyacid_6_0"; + saturatedfattyacid_6_0.MinimumWidth = 12; + saturatedfattyacid_6_0.Name = "saturatedfattyacid_6_0"; + saturatedfattyacid_6_0.ReadOnly = true; + saturatedfattyacid_6_0.Width = 250; + // + // saturatedfattyacid_8_0 + // + saturatedfattyacid_8_0.HeaderText = "saturatedfattyacid_8_0"; + saturatedfattyacid_8_0.MinimumWidth = 12; + saturatedfattyacid_8_0.Name = "saturatedfattyacid_8_0"; + saturatedfattyacid_8_0.ReadOnly = true; + saturatedfattyacid_8_0.Width = 250; + // + // selenium + // + selenium.HeaderText = "selenium"; + selenium.MinimumWidth = 12; + selenium.Name = "selenium"; + selenium.ReadOnly = true; + selenium.Width = 250; + // + // serine + // + serine.HeaderText = "serine"; + serine.MinimumWidth = 12; + serine.Name = "serine"; + serine.ReadOnly = true; + serine.Width = 250; + // + // sodium + // + sodium.HeaderText = "sodium"; + sodium.MinimumWidth = 12; + sodium.Name = "sodium"; + sodium.ReadOnly = true; + sodium.Width = 250; + // + // starch + // + starch.HeaderText = "starch"; + starch.MinimumWidth = 12; + starch.Name = "starch"; + starch.ReadOnly = true; + starch.Width = 250; + // + // stigmasterol + // + stigmasterol.HeaderText = "stigmasterol"; + stigmasterol.MinimumWidth = 12; + stigmasterol.Name = "stigmasterol"; + stigmasterol.ReadOnly = true; + stigmasterol.Width = 250; + // + // sucrose + // + sucrose.HeaderText = "sucrose"; + sucrose.MinimumWidth = 12; + sucrose.Name = "sucrose"; + sucrose.ReadOnly = true; + sucrose.Width = 250; + // + // sugar + // + sugar.HeaderText = "sugar"; + sugar.MinimumWidth = 12; + sugar.Name = "sugar"; + sugar.ReadOnly = true; + sugar.Width = 250; + // + // sugaralcohols + // + sugaralcohols.HeaderText = "sugaralcohols"; + sugaralcohols.MinimumWidth = 12; + sugaralcohols.Name = "sugaralcohols"; + sugaralcohols.ReadOnly = true; + sugaralcohols.Width = 250; + // + // theobromine + // + theobromine.HeaderText = "theobromine"; + theobromine.MinimumWidth = 12; + theobromine.Name = "theobromine"; + theobromine.ReadOnly = true; + theobromine.Width = 250; + // + // thiamin + // + thiamin.HeaderText = "thiamin"; + thiamin.MinimumWidth = 12; + thiamin.Name = "thiamin"; + thiamin.ReadOnly = true; + thiamin.Width = 250; + // + // threonine + // + threonine.HeaderText = "threonine"; + threonine.MinimumWidth = 12; + threonine.Name = "threonine"; + threonine.ReadOnly = true; + threonine.Width = 250; + // + // totalcarbohydrate + // + totalcarbohydrate.HeaderText = "totalcarbohydrate"; + totalcarbohydrate.MinimumWidth = 12; + totalcarbohydrate.Name = "totalcarbohydrate"; + totalcarbohydrate.ReadOnly = true; + totalcarbohydrate.Width = 250; + // + // totalfat + // + totalfat.HeaderText = "totalfat"; + totalfat.MinimumWidth = 12; + totalfat.Name = "totalfat"; + totalfat.ReadOnly = true; + totalfat.Width = 250; + // + // transfattyacids + // + transfattyacids.HeaderText = "transfattyacids"; + transfattyacids.MinimumWidth = 12; + transfattyacids.Name = "transfattyacids"; + transfattyacids.ReadOnly = true; + transfattyacids.Width = 250; + // + // transmonoenoicfattyacids + // + transmonoenoicfattyacids.HeaderText = "transmonoenoicfattyacids"; + transmonoenoicfattyacids.MinimumWidth = 12; + transmonoenoicfattyacids.Name = "transmonoenoicfattyacids"; + transmonoenoicfattyacids.ReadOnly = true; + transmonoenoicfattyacids.Width = 250; + // + // transpolyenoicfattyacids + // + transpolyenoicfattyacids.HeaderText = "transpolyenoicfattyacids"; + transpolyenoicfattyacids.MinimumWidth = 12; + transpolyenoicfattyacids.Name = "transpolyenoicfattyacids"; + transpolyenoicfattyacids.ReadOnly = true; + transpolyenoicfattyacids.Width = 250; + // + // tryptophan + // + tryptophan.HeaderText = "tryptophan"; + tryptophan.MinimumWidth = 12; + tryptophan.Name = "tryptophan"; + tryptophan.ReadOnly = true; + tryptophan.Width = 250; + // + // tyrosine + // + tyrosine.HeaderText = "tyrosine"; + tyrosine.MinimumWidth = 12; + tyrosine.Name = "tyrosine"; + tyrosine.ReadOnly = true; + tyrosine.Width = 250; + // + // valine + // + valine.HeaderText = "valine"; + valine.MinimumWidth = 12; + valine.Name = "valine"; + valine.ReadOnly = true; + valine.Width = 250; + // + // vitamina + // + vitamina.HeaderText = "vitamina"; + vitamina.MinimumWidth = 12; + vitamina.Name = "vitamina"; + vitamina.ReadOnly = true; + vitamina.Width = 250; + // + // vitaminb12 + // + vitaminb12.HeaderText = "vitaminb12"; + vitaminb12.MinimumWidth = 12; + vitaminb12.Name = "vitaminb12"; + vitaminb12.ReadOnly = true; + vitaminb12.Width = 250; + // + // vitaminb6 + // + vitaminb6.HeaderText = "vitaminb6"; + vitaminb6.MinimumWidth = 12; + vitaminb6.Name = "vitaminb6"; + vitaminb6.ReadOnly = true; + vitaminb6.Width = 250; + // + // vitaminc + // + vitaminc.HeaderText = "vitaminc"; + vitaminc.MinimumWidth = 12; + vitaminc.Name = "vitaminc"; + vitaminc.ReadOnly = true; + vitaminc.Width = 250; + // + // vitamind + // + vitamind.HeaderText = "vitamind"; + vitamind.MinimumWidth = 12; + vitamind.Name = "vitamind"; + vitamind.ReadOnly = true; + vitamind.Width = 250; + // + // vitamine + // + vitamine.HeaderText = "vitamine"; + vitamine.MinimumWidth = 12; + vitamine.Name = "vitamine"; + vitamine.ReadOnly = true; + vitamine.Width = 250; + // + // vitamink + // + vitamink.HeaderText = "vitamink"; + vitamink.MinimumWidth = 12; + vitamink.Name = "vitamink"; + vitamink.ReadOnly = true; + vitamink.Width = 250; + // + // volume + // + volume.HeaderText = "volume"; + volume.MinimumWidth = 12; + volume.Name = "volume"; + volume.ReadOnly = true; + volume.Width = 250; + // + // water + // + water.HeaderText = "water"; + water.MinimumWidth = 12; + water.Name = "water"; + water.ReadOnly = true; + water.Width = 250; + // + // zinc + // + zinc.HeaderText = "zinc"; + zinc.MinimumWidth = 12; + zinc.Name = "zinc"; + zinc.ReadOnly = true; + zinc.Width = 250; + // + // frmViewRecipeNutritionAll + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(2769, 1115); + Controls.Add(dgvwRecipeNutrition); + Margin = new System.Windows.Forms.Padding(7, 8, 7, 8); + MaximizeBox = false; + MinimizeBox = false; + Name = "frmViewRecipeNutritionAll"; + Text = "View All Nutrition for Recipe"; + ((System.ComponentModel.ISupportInitialize)dgvwRecipeNutrition).EndInit(); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.DataGridView dgvwRecipeNutrition; + private System.Windows.Forms.DataGridViewTextBoxColumn Ingredient; + private System.Windows.Forms.DataGridViewTextBoxColumn percentcaloriesfromalcohol; + private System.Windows.Forms.DataGridViewTextBoxColumn percentcaloriesfromcarbs; + private System.Windows.Forms.DataGridViewTextBoxColumn percentcaloriesfromfat; + private System.Windows.Forms.DataGridViewTextBoxColumn percentcaloriesfromprotein; + private System.Windows.Forms.DataGridViewTextBoxColumn alanine; + private System.Windows.Forms.DataGridViewTextBoxColumn alcohol; + private System.Windows.Forms.DataGridViewTextBoxColumn alcoholfactor; + private System.Windows.Forms.DataGridViewTextBoxColumn alphacarotene; + private System.Windows.Forms.DataGridViewTextBoxColumn alphalinolenicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn arachidonicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn arginine; + private System.Windows.Forms.DataGridViewTextBoxColumn ash; + private System.Windows.Forms.DataGridViewTextBoxColumn asparticacid; + private System.Windows.Forms.DataGridViewTextBoxColumn betacarotene; + private System.Windows.Forms.DataGridViewTextBoxColumn betacryptoxanthin; + private System.Windows.Forms.DataGridViewTextBoxColumn betasitosterol; + private System.Windows.Forms.DataGridViewTextBoxColumn betatocopherol; + private System.Windows.Forms.DataGridViewTextBoxColumn biotin; + private System.Windows.Forms.DataGridViewTextBoxColumn caffeine; + private System.Windows.Forms.DataGridViewTextBoxColumn calcium; + private System.Windows.Forms.DataGridViewTextBoxColumn calories; + private System.Windows.Forms.DataGridViewTextBoxColumn caloriesfromalcohol; + private System.Windows.Forms.DataGridViewTextBoxColumn caloriesfromcarbs; + private System.Windows.Forms.DataGridViewTextBoxColumn caloriesfromfat; + private System.Windows.Forms.DataGridViewTextBoxColumn caloriesfromprotein; + private System.Windows.Forms.DataGridViewTextBoxColumn campesterol; + private System.Windows.Forms.DataGridViewTextBoxColumn carbohydratefactor; + private System.Windows.Forms.DataGridViewTextBoxColumn chloride; + private System.Windows.Forms.DataGridViewTextBoxColumn cholesterol; + private System.Windows.Forms.DataGridViewTextBoxColumn choline; + private System.Windows.Forms.DataGridViewTextBoxColumn chromium; + private System.Windows.Forms.DataGridViewTextBoxColumn copper; + private System.Windows.Forms.DataGridViewTextBoxColumn cystine; + private System.Windows.Forms.DataGridViewTextBoxColumn deltatocopherol; + private System.Windows.Forms.DataGridViewTextBoxColumn dihomogammalinolenicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn docosahexaenoicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn docosapentaenoicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn eicosadienoicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn eicosapentaenoicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn energy; + private System.Windows.Forms.DataGridViewTextBoxColumn energyfromalcohol; + private System.Windows.Forms.DataGridViewTextBoxColumn energyfromcarbs; + private System.Windows.Forms.DataGridViewTextBoxColumn energyfromfat; + private System.Windows.Forms.DataGridViewTextBoxColumn energyfromprotein; + private System.Windows.Forms.DataGridViewTextBoxColumn fatfactor; + private System.Windows.Forms.DataGridViewTextBoxColumn fiber; + private System.Windows.Forms.DataGridViewTextBoxColumn fluoride; + private System.Windows.Forms.DataGridViewTextBoxColumn folate; + private System.Windows.Forms.DataGridViewTextBoxColumn fructose; + private System.Windows.Forms.DataGridViewTextBoxColumn galactose; + private System.Windows.Forms.DataGridViewTextBoxColumn gammalinolenicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn gammatocopherol; + private System.Windows.Forms.DataGridViewTextBoxColumn glucose; + private System.Windows.Forms.DataGridViewTextBoxColumn glutamicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn glycine; + private System.Windows.Forms.DataGridViewTextBoxColumn histidine; + private System.Windows.Forms.DataGridViewTextBoxColumn hydroxyproline; + private System.Windows.Forms.DataGridViewTextBoxColumn iodine; + private System.Windows.Forms.DataGridViewTextBoxColumn iron; + private System.Windows.Forms.DataGridViewTextBoxColumn isoleucine; + private System.Windows.Forms.DataGridViewTextBoxColumn lactose; + private System.Windows.Forms.DataGridViewTextBoxColumn leucine; + private System.Windows.Forms.DataGridViewTextBoxColumn linoleicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn lycopene; + private System.Windows.Forms.DataGridViewTextBoxColumn lysine; + private System.Windows.Forms.DataGridViewTextBoxColumn magnesium; + private System.Windows.Forms.DataGridViewTextBoxColumn maltose; + private System.Windows.Forms.DataGridViewTextBoxColumn manganese; + private System.Windows.Forms.DataGridViewTextBoxColumn mass; + private System.Windows.Forms.DataGridViewTextBoxColumn methionine; + private System.Windows.Forms.DataGridViewTextBoxColumn molybdenum; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfat; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_14_1; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_15_1; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_16_1; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_17_1; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_18_1; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_20_1; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_22_1; + private System.Windows.Forms.DataGridViewTextBoxColumn monounsaturatedfattyacid_24_1; + private System.Windows.Forms.DataGridViewTextBoxColumn netcarbohydrates; + private System.Windows.Forms.DataGridViewTextBoxColumn niacin; + private System.Windows.Forms.DataGridViewTextBoxColumn omega3fattyacids; + private System.Windows.Forms.DataGridViewTextBoxColumn omega6fattyacids; + private System.Windows.Forms.DataGridViewTextBoxColumn pantothenicacid; + private System.Windows.Forms.DataGridViewTextBoxColumn phenylalanine; + private System.Windows.Forms.DataGridViewTextBoxColumn phosphorus; + private System.Windows.Forms.DataGridViewTextBoxColumn phytosterols; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfat; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfattyacid_18_2; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfattyacid_18_3; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfattyacid_18_4; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfattyacid_20_3; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfattyacid_20_4; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfattyacid_21_5; + private System.Windows.Forms.DataGridViewTextBoxColumn polyunsaturatedfattyacid_22_4; + private System.Windows.Forms.DataGridViewTextBoxColumn potassium; + private System.Windows.Forms.DataGridViewTextBoxColumn proline; + private System.Windows.Forms.DataGridViewTextBoxColumn protein; + private System.Windows.Forms.DataGridViewTextBoxColumn proteinfactor; + private System.Windows.Forms.DataGridViewTextBoxColumn refuse; + private System.Windows.Forms.DataGridViewTextBoxColumn retinol; + private System.Windows.Forms.DataGridViewTextBoxColumn riboflavin; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfat; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_10_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_12_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_13_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_14_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_15_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_16_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_17_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_18_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_20_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_22_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_24_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_4_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_6_0; + private System.Windows.Forms.DataGridViewTextBoxColumn saturatedfattyacid_8_0; + private System.Windows.Forms.DataGridViewTextBoxColumn selenium; + private System.Windows.Forms.DataGridViewTextBoxColumn serine; + private System.Windows.Forms.DataGridViewTextBoxColumn sodium; + private System.Windows.Forms.DataGridViewTextBoxColumn starch; + private System.Windows.Forms.DataGridViewTextBoxColumn stigmasterol; + private System.Windows.Forms.DataGridViewTextBoxColumn sucrose; + private System.Windows.Forms.DataGridViewTextBoxColumn sugar; + private System.Windows.Forms.DataGridViewTextBoxColumn sugaralcohols; + private System.Windows.Forms.DataGridViewTextBoxColumn theobromine; + private System.Windows.Forms.DataGridViewTextBoxColumn thiamin; + private System.Windows.Forms.DataGridViewTextBoxColumn threonine; + private System.Windows.Forms.DataGridViewTextBoxColumn totalcarbohydrate; + private System.Windows.Forms.DataGridViewTextBoxColumn totalfat; + private System.Windows.Forms.DataGridViewTextBoxColumn transfattyacids; + private System.Windows.Forms.DataGridViewTextBoxColumn transmonoenoicfattyacids; + private System.Windows.Forms.DataGridViewTextBoxColumn transpolyenoicfattyacids; + private System.Windows.Forms.DataGridViewTextBoxColumn tryptophan; + private System.Windows.Forms.DataGridViewTextBoxColumn tyrosine; + private System.Windows.Forms.DataGridViewTextBoxColumn valine; + private System.Windows.Forms.DataGridViewTextBoxColumn vitamina; + private System.Windows.Forms.DataGridViewTextBoxColumn vitaminb12; + private System.Windows.Forms.DataGridViewTextBoxColumn vitaminb6; + private System.Windows.Forms.DataGridViewTextBoxColumn vitaminc; + private System.Windows.Forms.DataGridViewTextBoxColumn vitamind; + private System.Windows.Forms.DataGridViewTextBoxColumn vitamine; + private System.Windows.Forms.DataGridViewTextBoxColumn vitamink; + private System.Windows.Forms.DataGridViewTextBoxColumn volume; + private System.Windows.Forms.DataGridViewTextBoxColumn water; + private System.Windows.Forms.DataGridViewTextBoxColumn zinc; + } +} \ No newline at end of file diff --git a/JRCookbook/frmViewRecipeNutritionAll.cs b/JRCookbook/frmViewRecipeNutritionAll.cs new file mode 100644 index 0000000..69f0672 --- /dev/null +++ b/JRCookbook/frmViewRecipeNutritionAll.cs @@ -0,0 +1,359 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbook +{ + public partial class frmViewRecipeNutritionAll : Form + { + public frmViewRecipeNutritionAll(Recipe recipeToView) + { + InitializeComponent(); + + recipeToView.CalcNutrition(); + + foreach (DataGridViewColumn dgvc in dgvwRecipeNutrition.Columns) + { + dgvc.SortMode = DataGridViewColumnSortMode.NotSortable; + } + + dgvwRecipeNutrition.Rows.Add(); + var rowToUpdate = dgvwRecipeNutrition.Rows[dgvwRecipeNutrition.Rows.Count - 1]; + rowToUpdate.MinimumHeight = (int)dgvwRecipeNutrition.Font.GetHeight(); + rowToUpdate.Cells["ingredient"].Value = "Total"; + rowToUpdate.Cells["percentcaloriesfromcarbs"].Value = recipeToView.percentcaloriesfromcarbs.ToString(); + rowToUpdate.Cells["percentcaloriesfromfat"].Value = recipeToView.percentcaloriesfromfat.ToString(); + rowToUpdate.Cells["percentcaloriesfromprotein"].Value = recipeToView.percentcaloriesfromprotein.ToString(); + rowToUpdate.Cells["alanine"].Value = recipeToView.alanine.ToString(); + rowToUpdate.Cells["alcohol"].Value = recipeToView.alcohol.ToString(); + rowToUpdate.Cells["alcoholfactor"].Value = recipeToView.alcoholfactor.ToString(); + rowToUpdate.Cells["alphacarotene"].Value = recipeToView.alphacarotene.ToString(); + rowToUpdate.Cells["alphalinolenicacid"].Value = recipeToView.alphalinolenicacid.ToString(); + rowToUpdate.Cells["arachidonicacid"].Value = recipeToView.arachidonicacid.ToString(); + rowToUpdate.Cells["arginine"].Value = recipeToView.arginine.ToString(); + rowToUpdate.Cells["ash"].Value = recipeToView.ash.ToString(); + rowToUpdate.Cells["asparticacid"].Value = recipeToView.asparticacid.ToString(); + rowToUpdate.Cells["betacarotene"].Value = recipeToView.betacarotene.ToString(); + rowToUpdate.Cells["betacryptoxanthin"].Value = recipeToView.betacryptoxanthin.ToString(); + rowToUpdate.Cells["betasitosterol"].Value = recipeToView.betasitosterol.ToString(); + rowToUpdate.Cells["betatocopherol"].Value = recipeToView.betatocopherol.ToString(); + rowToUpdate.Cells["biotin"].Value = recipeToView.biotin.ToString(); + rowToUpdate.Cells["caffeine"].Value = recipeToView.caffeine.ToString(); + rowToUpdate.Cells["calcium"].Value = recipeToView.calcium.ToString(); + rowToUpdate.Cells["calories"].Value = recipeToView.calories.ToString(); + rowToUpdate.Cells["caloriesfromalcohol"].Value = recipeToView.caloriesfromalcohol.ToString(); + rowToUpdate.Cells["caloriesfromcarbs"].Value = recipeToView.caloriesfromcarbs.ToString(); + rowToUpdate.Cells["caloriesfromfat"].Value = recipeToView.caloriesfromfat.ToString(); + rowToUpdate.Cells["caloriesfromprotein"].Value = recipeToView.caloriesfromprotein.ToString(); + rowToUpdate.Cells["campesterol"].Value = recipeToView.campesterol.ToString(); + rowToUpdate.Cells["carbohydratefactor"].Value = recipeToView.carbohydratefactor.ToString(); + rowToUpdate.Cells["chloride"].Value = recipeToView.chloride.ToString(); + rowToUpdate.Cells["cholesterol"].Value = recipeToView.cholesterol.ToString(); + rowToUpdate.Cells["choline"].Value = recipeToView.choline.ToString(); + rowToUpdate.Cells["chromium"].Value = recipeToView.chromium.ToString(); + rowToUpdate.Cells["copper"].Value = recipeToView.copper.ToString(); + rowToUpdate.Cells["cystine"].Value = recipeToView.cystine.ToString(); + rowToUpdate.Cells["deltatocopherol"].Value = recipeToView.deltatocopherol.ToString(); + rowToUpdate.Cells["dihomogammalinolenicacid"].Value = recipeToView.dihomogammalinolenicacid.ToString(); + rowToUpdate.Cells["docosahexaenoicacid"].Value = recipeToView.docosahexaenoicacid.ToString(); + rowToUpdate.Cells["docosapentaenoicacid"].Value = recipeToView.docosapentaenoicacid.ToString(); + rowToUpdate.Cells["eicosadienoicacid"].Value = recipeToView.eicosadienoicacid.ToString(); + rowToUpdate.Cells["eicosapentaenoicacid"].Value = recipeToView.eicosapentaenoicacid.ToString(); + rowToUpdate.Cells["energy"].Value = recipeToView.energy.ToString(); + rowToUpdate.Cells["energyfromalcohol"].Value = recipeToView.energyfromalcohol.ToString(); + rowToUpdate.Cells["energyfromcarbs"].Value = recipeToView.energyfromcarbs.ToString(); + rowToUpdate.Cells["energyfromfat"].Value = recipeToView.energyfromfat.ToString(); + rowToUpdate.Cells["energyfromprotein"].Value = recipeToView.energyfromprotein.ToString(); + rowToUpdate.Cells["fatfactor"].Value = recipeToView.fatfactor.ToString(); + rowToUpdate.Cells["fiber"].Value = recipeToView.fiber.ToString(); + rowToUpdate.Cells["fluoride"].Value = recipeToView.fluoride.ToString(); + rowToUpdate.Cells["folate"].Value = recipeToView.folate.ToString(); + rowToUpdate.Cells["fructose"].Value = recipeToView.fructose.ToString(); + rowToUpdate.Cells["galactose"].Value = recipeToView.galactose.ToString(); + rowToUpdate.Cells["gammalinolenicacid"].Value = recipeToView.gammalinolenicacid.ToString(); + rowToUpdate.Cells["gammatocopherol"].Value = recipeToView.gammatocopherol.ToString(); + rowToUpdate.Cells["glucose"].Value = recipeToView.glucose.ToString(); + rowToUpdate.Cells["glutamicacid"].Value = recipeToView.glutamicacid.ToString(); + rowToUpdate.Cells["glycine"].Value = recipeToView.glycine.ToString(); + rowToUpdate.Cells["histidine"].Value = recipeToView.histidine.ToString(); + rowToUpdate.Cells["hydroxyproline"].Value = recipeToView.hydroxyproline.ToString(); + rowToUpdate.Cells["iodine"].Value = recipeToView.iodine.ToString(); + rowToUpdate.Cells["iron"].Value = recipeToView.iron.ToString(); + rowToUpdate.Cells["isoleucine"].Value = recipeToView.isoleucine.ToString(); + rowToUpdate.Cells["lactose"].Value = recipeToView.lactose.ToString(); + rowToUpdate.Cells["leucine"].Value = recipeToView.leucine.ToString(); + rowToUpdate.Cells["linoleicacid"].Value = recipeToView.linoleicacid.ToString(); + rowToUpdate.Cells["lycopene"].Value = recipeToView.lycopene.ToString(); + rowToUpdate.Cells["lysine"].Value = recipeToView.lysine.ToString(); + rowToUpdate.Cells["magnesium"].Value = recipeToView.magnesium.ToString(); + rowToUpdate.Cells["maltose"].Value = recipeToView.maltose.ToString(); + rowToUpdate.Cells["manganese"].Value = recipeToView.manganese.ToString(); + rowToUpdate.Cells["mass"].Value = recipeToView.mass.ToString(); + rowToUpdate.Cells["methionine"].Value = recipeToView.methionine.ToString(); + rowToUpdate.Cells["molybdenum"].Value = recipeToView.molybdenum.ToString(); + rowToUpdate.Cells["monounsaturatedfat"].Value = recipeToView.monounsaturatedfat.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_14_1"].Value = recipeToView.monounsaturatedfattyacid_14_1.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_15_1"].Value = recipeToView.monounsaturatedfattyacid_15_1.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_16_1"].Value = recipeToView.monounsaturatedfattyacid_16_1.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_17_1"].Value = recipeToView.monounsaturatedfattyacid_17_1.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_18_1"].Value = recipeToView.monounsaturatedfattyacid_18_1.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_20_1"].Value = recipeToView.monounsaturatedfattyacid_20_1.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_22_1"].Value = recipeToView.monounsaturatedfattyacid_22_1.ToString(); + rowToUpdate.Cells["monounsaturatedfattyacid_24_1"].Value = recipeToView.monounsaturatedfattyacid_24_1.ToString(); + rowToUpdate.Cells["netcarbohydrates"].Value = recipeToView.netcarbohydrates.ToString(); + rowToUpdate.Cells["niacin"].Value = recipeToView.niacin.ToString(); + rowToUpdate.Cells["omega3fattyacids"].Value = recipeToView.omega3fattyacids.ToString(); + rowToUpdate.Cells["omega6fattyacids"].Value = recipeToView.omega6fattyacids.ToString(); + rowToUpdate.Cells["pantothenicacid"].Value = recipeToView.pantothenicacid.ToString(); + rowToUpdate.Cells["phenylalanine"].Value = recipeToView.phenylalanine.ToString(); + rowToUpdate.Cells["phosphorus"].Value = recipeToView.phosphorus.ToString(); + rowToUpdate.Cells["phytosterols"].Value = recipeToView.phytosterols.ToString(); + rowToUpdate.Cells["polyunsaturatedfat"].Value = recipeToView.polyunsaturatedfat.ToString(); + rowToUpdate.Cells["polyunsaturatedfattyacid_18_2"].Value = recipeToView.polyunsaturatedfattyacid_18_2.ToString(); + rowToUpdate.Cells["polyunsaturatedfattyacid_18_3"].Value = recipeToView.polyunsaturatedfattyacid_18_3.ToString(); + rowToUpdate.Cells["polyunsaturatedfattyacid_18_4"].Value = recipeToView.polyunsaturatedfattyacid_18_4.ToString(); + rowToUpdate.Cells["polyunsaturatedfattyacid_20_3"].Value = recipeToView.polyunsaturatedfattyacid_20_3.ToString(); + rowToUpdate.Cells["polyunsaturatedfattyacid_20_4"].Value = recipeToView.polyunsaturatedfattyacid_20_4.ToString(); + rowToUpdate.Cells["polyunsaturatedfattyacid_21_5"].Value = recipeToView.polyunsaturatedfattyacid_21_5.ToString(); + rowToUpdate.Cells["polyunsaturatedfattyacid_22_4"].Value = recipeToView.polyunsaturatedfattyacid_22_4.ToString(); + rowToUpdate.Cells["potassium"].Value = recipeToView.potassium.ToString(); + rowToUpdate.Cells["proline"].Value = recipeToView.proline.ToString(); + rowToUpdate.Cells["protein"].Value = recipeToView.protein.ToString(); + rowToUpdate.Cells["proteinfactor"].Value = recipeToView.proteinfactor.ToString(); + rowToUpdate.Cells["refuse"].Value = recipeToView.refuse.ToString(); + rowToUpdate.Cells["retinol"].Value = recipeToView.retinol.ToString(); + rowToUpdate.Cells["riboflavin"].Value = recipeToView.riboflavin.ToString(); + rowToUpdate.Cells["saturatedfat"].Value = recipeToView.saturatedfat.ToString(); + rowToUpdate.Cells["saturatedfattyacid_10_0"].Value = recipeToView.saturatedfattyacid_10_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_12_0"].Value = recipeToView.saturatedfattyacid_12_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_13_0"].Value = recipeToView.saturatedfattyacid_13_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_14_0"].Value = recipeToView.saturatedfattyacid_14_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_15_0"].Value = recipeToView.saturatedfattyacid_15_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_16_0"].Value = recipeToView.saturatedfattyacid_16_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_17_0"].Value = recipeToView.saturatedfattyacid_17_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_18_0"].Value = recipeToView.saturatedfattyacid_18_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_20_0"].Value = recipeToView.saturatedfattyacid_20_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_22_0"].Value = recipeToView.saturatedfattyacid_22_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_24_0"].Value = recipeToView.saturatedfattyacid_24_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_4_0"].Value = recipeToView.saturatedfattyacid_4_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_6_0"].Value = recipeToView.saturatedfattyacid_6_0.ToString(); + rowToUpdate.Cells["saturatedfattyacid_8_0"].Value = recipeToView.saturatedfattyacid_8_0.ToString(); + rowToUpdate.Cells["selenium"].Value = recipeToView.selenium.ToString(); + rowToUpdate.Cells["serine"].Value = recipeToView.serine.ToString(); + rowToUpdate.Cells["sodium"].Value = recipeToView.sodium.ToString(); + rowToUpdate.Cells["starch"].Value = recipeToView.starch.ToString(); + rowToUpdate.Cells["stigmasterol"].Value = recipeToView.stigmasterol.ToString(); + rowToUpdate.Cells["sucrose"].Value = recipeToView.sucrose.ToString(); + rowToUpdate.Cells["sugar"].Value = recipeToView.sugar.ToString(); + rowToUpdate.Cells["sugaralcohols"].Value = recipeToView.sugaralcohols.ToString(); + rowToUpdate.Cells["theobromine"].Value = recipeToView.theobromine.ToString(); + rowToUpdate.Cells["thiamin"].Value = recipeToView.thiamin.ToString(); + rowToUpdate.Cells["threonine"].Value = recipeToView.threonine.ToString(); + rowToUpdate.Cells["totalcarbohydrate"].Value = recipeToView.totalcarbohydrate.ToString(); + rowToUpdate.Cells["totalfat"].Value = recipeToView.totalfat.ToString(); + rowToUpdate.Cells["transfattyacids"].Value = recipeToView.transfattyacids.ToString(); + rowToUpdate.Cells["transmonoenoicfattyacids"].Value = recipeToView.transmonoenoicfattyacids.ToString(); + rowToUpdate.Cells["transpolyenoicfattyacids"].Value = recipeToView.transpolyenoicfattyacids.ToString(); + rowToUpdate.Cells["tryptophan"].Value = recipeToView.tryptophan.ToString(); + rowToUpdate.Cells["tyrosine"].Value = recipeToView.tyrosine.ToString(); + rowToUpdate.Cells["valine"].Value = recipeToView.valine.ToString(); + rowToUpdate.Cells["vitamina"].Value = recipeToView.vitamina.ToString(); + rowToUpdate.Cells["vitaminb12"].Value = recipeToView.vitaminb12.ToString(); + rowToUpdate.Cells["vitaminb6"].Value = recipeToView.vitaminb6.ToString(); + rowToUpdate.Cells["vitaminc"].Value = recipeToView.vitaminc.ToString(); + rowToUpdate.Cells["vitamind"].Value = recipeToView.vitamind.ToString(); + rowToUpdate.Cells["vitamine"].Value = recipeToView.vitamine.ToString(); + rowToUpdate.Cells["vitamink"].Value = recipeToView.vitamink.ToString(); + rowToUpdate.Cells["volume"].Value = recipeToView.volume.ToString(); + rowToUpdate.Cells["water"].Value = recipeToView.water.ToString(); + rowToUpdate.Cells["zinc"].Value = recipeToView.zinc.ToString(); + + for (int i = 0; i < dgvwRecipeNutrition.ColumnCount; i++) + { + dgvwRecipeNutrition.Rows[dgvwRecipeNutrition.RowCount - 1].Cells[i].Style.Font = new Font(dgvwRecipeNutrition.Font, FontStyle.Bold); + } + + Single servingsToUse = recipeToView.servings; + if (servingsToUse == 0) + { + servingsToUse = 1; + } + + foreach (var recipeIngredient in recipeToView.recipeIngredients) + { + if (recipeIngredient is RecipeIngredientItem) + { + var recipeIngredientItem = (RecipeIngredientItem)recipeIngredient; + + if (recipeIngredientItem.ingredientID != null && recipeIngredientItem.measureID != null) + { + var ingredient = new Ingredient(recipeIngredientItem.ingredientID.Value); + + var gramWeight = ingredient.GramWeightByMeasureID(recipeIngredientItem.measureID.Value); + + dgvwRecipeNutrition.Rows.Add(); + var rowToUpdate2 = dgvwRecipeNutrition.Rows[dgvwRecipeNutrition.Rows.Count - 1]; + rowToUpdate2.MinimumHeight = (int)dgvwRecipeNutrition.Font.GetHeight(); + rowToUpdate2.Cells["ingredient"].Value = recipeIngredientItem.ingredientText; + rowToUpdate2.Cells["alanine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alanine)/servingsToUse).ToString(); + rowToUpdate2.Cells["alcohol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alcohol) / servingsToUse).ToString(); + //rowToUpdate2.Cells["alcoholfactor"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alcoholfactor)/servingsToUse).ToString(); + rowToUpdate2.Cells["alphacarotene"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alphacarotene) / servingsToUse).ToString(); + rowToUpdate2.Cells["alphalinolenicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alphalinolenicacid) / servingsToUse).ToString(); + rowToUpdate2.Cells["arachidonicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.arachidonicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["arginine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.arginine)/servingsToUse).ToString(); + rowToUpdate2.Cells["ash"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.ash)/servingsToUse).ToString(); + rowToUpdate2.Cells["asparticacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.asparticacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["betacarotene"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betacarotene)/servingsToUse).ToString(); + rowToUpdate2.Cells["betacryptoxanthin"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betacryptoxanthin)/servingsToUse).ToString(); + rowToUpdate2.Cells["betasitosterol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betasitosterol)/servingsToUse).ToString(); + rowToUpdate2.Cells["betatocopherol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betatocopherol)/servingsToUse).ToString(); + rowToUpdate2.Cells["biotin"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.biotin)/servingsToUse).ToString(); + rowToUpdate2.Cells["caffeine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caffeine)/servingsToUse).ToString(); + rowToUpdate2.Cells["calcium"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.calcium)/servingsToUse).ToString(); + rowToUpdate2.Cells["calories"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.calories)/servingsToUse).ToString(); + rowToUpdate2.Cells["caloriesfromalcohol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromalcohol)/servingsToUse).ToString(); + rowToUpdate2.Cells["caloriesfromcarbs"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromcarbs)/servingsToUse).ToString(); + rowToUpdate2.Cells["caloriesfromfat"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromfat)/servingsToUse).ToString(); + rowToUpdate2.Cells["caloriesfromprotein"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromprotein)/servingsToUse).ToString(); + rowToUpdate2.Cells["campesterol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.campesterol)/servingsToUse).ToString(); + rowToUpdate2.Cells["carbohydratefactor"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.carbohydratefactor)/servingsToUse).ToString(); + rowToUpdate2.Cells["chloride"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.chloride)/servingsToUse).ToString(); + rowToUpdate2.Cells["cholesterol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.cholesterol)/servingsToUse).ToString(); + rowToUpdate2.Cells["choline"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.choline)/servingsToUse).ToString(); + rowToUpdate2.Cells["chromium"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.chromium)/servingsToUse).ToString(); + rowToUpdate2.Cells["copper"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.copper)/servingsToUse).ToString(); + rowToUpdate2.Cells["cystine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.cystine)/servingsToUse).ToString(); + rowToUpdate2.Cells["deltatocopherol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.deltatocopherol)/servingsToUse).ToString(); + rowToUpdate2.Cells["dihomogammalinolenicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.dihomogammalinolenicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["docosahexaenoicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.docosahexaenoicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["docosapentaenoicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.docosapentaenoicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["eicosadienoicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.eicosadienoicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["eicosapentaenoicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.eicosapentaenoicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["energy"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energy)/servingsToUse).ToString(); + rowToUpdate2.Cells["energyfromalcohol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromalcohol)/servingsToUse).ToString(); + rowToUpdate2.Cells["energyfromcarbs"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromcarbs)/servingsToUse).ToString(); + rowToUpdate2.Cells["energyfromfat"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromfat)/servingsToUse).ToString(); + rowToUpdate2.Cells["energyfromprotein"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromprotein)/servingsToUse).ToString(); + //rowToUpdate2.Cells["fatfactor"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fatfactor)/servingsToUse).ToString(); + rowToUpdate2.Cells["fiber"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fiber)/servingsToUse).ToString(); + rowToUpdate2.Cells["fluoride"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fluoride)/servingsToUse).ToString(); + rowToUpdate2.Cells["folate"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.folate)/servingsToUse).ToString(); + rowToUpdate2.Cells["fructose"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fructose)/servingsToUse).ToString(); + rowToUpdate2.Cells["galactose"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.galactose)/servingsToUse).ToString(); + rowToUpdate2.Cells["gammalinolenicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.gammalinolenicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["gammatocopherol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.gammatocopherol)/servingsToUse).ToString(); + rowToUpdate2.Cells["glucose"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.glucose)/servingsToUse).ToString(); + rowToUpdate2.Cells["glutamicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.glutamicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["glycine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.glycine)/servingsToUse).ToString(); + rowToUpdate2.Cells["histidine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.histidine)/servingsToUse).ToString(); + rowToUpdate2.Cells["hydroxyproline"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.hydroxyproline)/servingsToUse).ToString(); + rowToUpdate2.Cells["iodine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.iodine)/servingsToUse).ToString(); + rowToUpdate2.Cells["iron"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.iron)/servingsToUse).ToString(); + rowToUpdate2.Cells["isoleucine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.isoleucine)/servingsToUse).ToString(); + rowToUpdate2.Cells["lactose"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.lactose)/servingsToUse).ToString(); + rowToUpdate2.Cells["leucine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.leucine)/servingsToUse).ToString(); + rowToUpdate2.Cells["linoleicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.linoleicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["lycopene"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.lycopene)/servingsToUse).ToString(); + rowToUpdate2.Cells["lysine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.lysine)/servingsToUse).ToString(); + rowToUpdate2.Cells["magnesium"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.magnesium)/servingsToUse).ToString(); + rowToUpdate2.Cells["maltose"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.maltose)/servingsToUse).ToString(); + rowToUpdate2.Cells["manganese"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.manganese)/servingsToUse).ToString(); + + //mass calculated differently, since it directly uses gramWeight of ingredient + rowToUpdate2.Cells["mass"].Value = ((recipeIngredientItem.measureQuantity * gramWeight)/servingsToUse).ToString(); + + rowToUpdate2.Cells["methionine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.methionine)/servingsToUse).ToString(); + rowToUpdate2.Cells["molybdenum"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.molybdenum)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfat"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfat)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_14_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_14_1)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_15_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_15_1)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_16_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_16_1)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_17_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_17_1)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_18_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_18_1)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_20_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_20_1)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_22_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_22_1)/servingsToUse).ToString(); + rowToUpdate2.Cells["monounsaturatedfattyacid_24_1"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_24_1)/servingsToUse).ToString(); + //rowToUpdate2.Cells["netcarbohydrates"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.netcarbohydrates)/servingsToUse).ToString(); + rowToUpdate2.Cells["niacin"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.niacin)/servingsToUse).ToString(); + rowToUpdate2.Cells["omega3fattyacids"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.omega3fattyacids)/servingsToUse).ToString(); + rowToUpdate2.Cells["omega6fattyacids"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.omega6fattyacids)/servingsToUse).ToString(); + rowToUpdate2.Cells["pantothenicacid"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.pantothenicacid)/servingsToUse).ToString(); + rowToUpdate2.Cells["phenylalanine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.phenylalanine)/servingsToUse).ToString(); + rowToUpdate2.Cells["phosphorus"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.phosphorus)/servingsToUse).ToString(); + rowToUpdate2.Cells["phytosterols"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.phytosterols)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfat"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfat)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfattyacid_18_2"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_18_2)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfattyacid_18_3"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_18_3)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfattyacid_18_4"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_18_4)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfattyacid_20_3"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_20_3)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfattyacid_20_4"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_20_4)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfattyacid_21_5"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_21_5)/servingsToUse).ToString(); + rowToUpdate2.Cells["polyunsaturatedfattyacid_22_4"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_22_4)/servingsToUse).ToString(); + rowToUpdate2.Cells["potassium"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.potassium)/servingsToUse).ToString(); + rowToUpdate2.Cells["proline"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.proline)/servingsToUse).ToString(); + rowToUpdate2.Cells["protein"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.protein)/servingsToUse).ToString(); + //rowToUpdate2.Cells["proteinfactor"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.proteinfactor)/servingsToUse).ToString(); + rowToUpdate2.Cells["refuse"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.refuse)/servingsToUse).ToString(); + rowToUpdate2.Cells["retinol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.retinol)/servingsToUse).ToString(); + rowToUpdate2.Cells["riboflavin"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.riboflavin)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfat"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfat)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_10_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_10_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_12_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_12_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_13_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_13_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_14_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_14_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_15_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_15_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_16_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_16_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_17_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_17_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_18_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_18_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_20_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_20_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_22_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_22_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_24_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_24_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_4_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_4_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_6_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_6_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["saturatedfattyacid_8_0"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_8_0)/servingsToUse).ToString(); + rowToUpdate2.Cells["selenium"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.selenium)/servingsToUse).ToString(); + rowToUpdate2.Cells["serine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.serine)/servingsToUse).ToString(); + rowToUpdate2.Cells["sodium"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sodium)/servingsToUse).ToString(); + rowToUpdate2.Cells["starch"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.starch)/servingsToUse).ToString(); + rowToUpdate2.Cells["stigmasterol"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.stigmasterol)/servingsToUse).ToString(); + rowToUpdate2.Cells["sucrose"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sucrose)/servingsToUse).ToString(); + rowToUpdate2.Cells["sugar"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sugar)/servingsToUse).ToString(); + rowToUpdate2.Cells["sugaralcohols"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sugaralcohols)/servingsToUse).ToString(); + rowToUpdate2.Cells["theobromine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.theobromine)/servingsToUse).ToString(); + rowToUpdate2.Cells["thiamin"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.thiamin)/servingsToUse).ToString(); + rowToUpdate2.Cells["threonine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.threonine)/servingsToUse).ToString(); + rowToUpdate2.Cells["totalcarbohydrate"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.totalcarbohydrate)/servingsToUse).ToString(); + rowToUpdate2.Cells["totalfat"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.totalfat)/servingsToUse).ToString(); + rowToUpdate2.Cells["transfattyacids"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.transfattyacids)/servingsToUse).ToString(); + rowToUpdate2.Cells["transmonoenoicfattyacids"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.transmonoenoicfattyacids)/servingsToUse).ToString(); + rowToUpdate2.Cells["transpolyenoicfattyacids"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.transpolyenoicfattyacids)/servingsToUse).ToString(); + rowToUpdate2.Cells["tryptophan"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.tryptophan)/servingsToUse).ToString(); + rowToUpdate2.Cells["tyrosine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.tyrosine)/servingsToUse).ToString(); + rowToUpdate2.Cells["valine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.valine)/servingsToUse).ToString(); + rowToUpdate2.Cells["vitamina"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamina)/servingsToUse).ToString(); + rowToUpdate2.Cells["vitaminb12"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitaminb12)/servingsToUse).ToString(); + rowToUpdate2.Cells["vitaminb6"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitaminb6)/servingsToUse).ToString(); + rowToUpdate2.Cells["vitaminc"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitaminc)/servingsToUse).ToString(); + rowToUpdate2.Cells["vitamind"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamind)/servingsToUse).ToString(); + rowToUpdate2.Cells["vitamine"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamine)/servingsToUse).ToString(); + rowToUpdate2.Cells["vitamink"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamink)/servingsToUse).ToString(); + rowToUpdate2.Cells["volume"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.volume)/servingsToUse).ToString(); + rowToUpdate2.Cells["water"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.water)/servingsToUse).ToString(); + rowToUpdate2.Cells["zinc"].Value = (recipeToView.GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.zinc)/servingsToUse).ToString(); + + } + } + } + } + + + } +} diff --git a/JRCookbook/frmViewRecipeNutritionAll.resx b/JRCookbook/frmViewRecipeNutritionAll.resx new file mode 100644 index 0000000..83ac734 --- /dev/null +++ b/JRCookbook/frmViewRecipeNutritionAll.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + \ No newline at end of file diff --git a/JRCookbook/v18/.futdcache.v2 b/JRCookbook/v18/.futdcache.v2 new file mode 100644 index 0000000..64996d5 Binary files /dev/null and b/JRCookbook/v18/.futdcache.v2 differ diff --git a/JRCookbook/v18/DocumentLayout.backup.json b/JRCookbook/v18/DocumentLayout.backup.json new file mode 100644 index 0000000..529074f --- /dev/null +++ b/JRCookbook/v18/DocumentLayout.backup.json @@ -0,0 +1,242 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookbusiness\\ingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|solutionrelative:jrcookbookbusiness\\ingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbooknumerictextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbooknumerictextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookmaskedtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookmaskedtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookedittip.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookedittip.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookeditrecipeingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookeditrecipeingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookeditprocedure.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookeditprocedure.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookautoverticalgrowtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookautoverticalgrowtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbook\\jrcookbook.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|solutionrelative:jrcookbook\\jrcookbook.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbook\\jrcookbook.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|solutionrelative:jrcookbook\\jrcookbook.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + }, + { + "AbsoluteMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookbusiness\\jrcookbookbusiness.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|solutionrelative:jrcookbookbusiness\\jrcookbookbusiness.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookbusiness\\jrcookbookbusiness.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|solutionrelative:jrcookbookbusiness\\jrcookbookbusiness.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookcontrols.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookcontrols.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookcontrols.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookcontrols.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Ingredient.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\Ingredient.cs", + "RelativeDocumentMoniker": "JRCookbookBusiness\\Ingredient.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\Ingredient.cs", + "RelativeToolTip": "JRCookbookBusiness\\Ingredient.cs", + "ViewState": "AgIAALoAAAAAAAAAAAAUwMsAAAAJAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:30:37.281Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "JRCookbookNumericTextBox.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookNumericTextBox.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookNumericTextBox.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookNumericTextBox.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookNumericTextBox.cs", + "ViewState": "AgIAACcAAAAAAAAAAAA8wDUAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:28:51.904Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "JRCookbookMaskedTextBox.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "ViewState": "AgIAAAgAAAAAAAAAAAAuwBcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:28:42.175Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "JRCookbookEditTip.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditTip.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookEditTip.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditTip.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookEditTip.cs", + "ViewState": "AgIAADkAAAAAAAAAAAAmwEYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:28:08.069Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "JRCookbookEditRecipeIngredient.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "ViewState": "AgIAAEMAAAAAAAAAAAAmwFAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:27:43.046Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "JRCookbookEditProcedure.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditProcedure.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookEditProcedure.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditProcedure.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookEditProcedure.cs", + "ViewState": "AgIAADgAAAAAAAAAAAAmwEUAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:26:43.521Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "JRCookbookAutoVerticalGrowTextBox.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "ViewState": "AgIAAAsAAAAAAAAAAAA+wBoAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:25:18.989Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "JRCookbook", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeDocumentMoniker": "JRCookbook\\JRCookbook.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeToolTip": "JRCookbook\\JRCookbook.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:44.488Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "JRCookbook", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeDocumentMoniker": "JRCookbook\\JRCookbook.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeToolTip": "JRCookbook\\JRCookbook.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:48.8Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "JRCookbookBusiness", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeDocumentMoniker": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeToolTip": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:31.639Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "JRCookbookBusiness", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeDocumentMoniker": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeToolTip": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:36.89Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "JRCookbookControls", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookControls.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeToolTip": "JRCookbookControls\\JRCookbookControls.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:15.879Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "JRCookbookControls", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookControls.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeToolTip": "JRCookbookControls\\JRCookbookControls.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:16:17.658Z", + "EditorCaption": "" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/JRCookbook/v18/DocumentLayout.json b/JRCookbook/v18/DocumentLayout.json new file mode 100644 index 0000000..ebc3407 --- /dev/null +++ b/JRCookbook/v18/DocumentLayout.json @@ -0,0 +1,226 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookbusiness\\ingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|solutionrelative:jrcookbookbusiness\\ingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbooknumerictextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbooknumerictextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookmaskedtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookmaskedtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookedittip.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookedittip.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookeditrecipeingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookeditrecipeingredient.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookeditprocedure.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookeditprocedure.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookautoverticalgrowtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookautoverticalgrowtextbox.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbook\\jrcookbook.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|solutionrelative:jrcookbook\\jrcookbook.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbook\\jrcookbook.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{F9644AEA-63C8-48DB-ABB4-1AA8E666469E}|JRCookbook\\JRCookbook.csproj|solutionrelative:jrcookbook\\jrcookbook.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + }, + { + "AbsoluteMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookbusiness\\jrcookbookbusiness.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|solutionrelative:jrcookbookbusiness\\jrcookbookbusiness.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookbusiness\\jrcookbookbusiness.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{A3A35111-FE61-4634-9BAD-0208C574D3D0}|JRCookbookBusiness\\JRCookbookBusiness.csproj|solutionrelative:jrcookbookbusiness\\jrcookbookbusiness.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookcontrols.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookcontrols.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|c:\\users\\jon\\source\\repos\\jrcookbook\\jrcookbookcontrols\\jrcookbookcontrols.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{28B4EDFB-20F5-41EB-9759-5697EABD1EE3}|JRCookbookControls\\JRCookbookControls.csproj|solutionrelative:jrcookbookcontrols\\jrcookbookcontrols.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Ingredient.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\Ingredient.cs", + "RelativeDocumentMoniker": "JRCookbookBusiness\\Ingredient.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\Ingredient.cs", + "RelativeToolTip": "JRCookbookBusiness\\Ingredient.cs", + "ViewState": "AgIAALoAAAAAAAAAAAAUwMsAAAAJAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:30:37.281Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "JRCookbookNumericTextBox.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookNumericTextBox.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookNumericTextBox.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookNumericTextBox.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookNumericTextBox.cs", + "ViewState": "AgIAACcAAAAAAAAAAAA8wDUAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:28:51.904Z" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "JRCookbookMaskedTextBox.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookMaskedTextBox.cs", + "ViewState": "AgIAAAgAAAAAAAAAAAAuwBcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:28:42.175Z" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "JRCookbookEditTip.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditTip.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookEditTip.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditTip.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookEditTip.cs", + "ViewState": "AgIAADkAAAAAAAAAAAAmwEYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:28:08.069Z" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "JRCookbookEditRecipeIngredient.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookEditRecipeIngredient.cs", + "ViewState": "AgIAAEMAAAAAAAAAAAAmwFAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:27:43.046Z" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "JRCookbookEditProcedure.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditProcedure.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookEditProcedure.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookEditProcedure.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookEditProcedure.cs", + "ViewState": "AgIAADgAAAAAAAAAAAAmwEUAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:26:43.521Z" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "JRCookbookAutoVerticalGrowTextBox.cs", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "RelativeToolTip": "JRCookbookControls\\JRCookbookAutoVerticalGrowTextBox.cs", + "ViewState": "AgIAAAsAAAAAAAAAAAA+wBoAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-03-06T02:25:18.989Z" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "JRCookbook.csproj", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeDocumentMoniker": "JRCookbook\\JRCookbook.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeToolTip": "JRCookbook\\JRCookbook.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:44.488Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "JRCookbook", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeDocumentMoniker": "JRCookbook\\JRCookbook.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbook\\JRCookbook.csproj", + "RelativeToolTip": "JRCookbook\\JRCookbook.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:48.8Z" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "JRCookbookBusiness.csproj", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeDocumentMoniker": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeToolTip": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:31.639Z" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "JRCookbookBusiness", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeDocumentMoniker": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookBusiness\\JRCookbookBusiness.csproj", + "RelativeToolTip": "JRCookbookBusiness\\JRCookbookBusiness.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:36.89Z" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "JRCookbookControls.csproj", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookControls.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeToolTip": "JRCookbookControls\\JRCookbookControls.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:24:15.879Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "JRCookbookControls", + "DocumentMoniker": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeDocumentMoniker": "JRCookbookControls\\JRCookbookControls.csproj", + "ToolTip": "C:\\Users\\Jon\\source\\repos\\JRCookbook\\JRCookbookControls\\JRCookbookControls.csproj", + "RelativeToolTip": "JRCookbookControls\\JRCookbookControls.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2026-03-06T02:16:17.658Z" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/JRCookbookBusiness/Constants.cs b/JRCookbookBusiness/Constants.cs new file mode 100644 index 0000000..b49b0f2 --- /dev/null +++ b/JRCookbookBusiness/Constants.cs @@ -0,0 +1,55 @@ +using System; +//using System.Net; +//using System.Collections.Generic; +//using System.Data; +//using System.IO; +//using System.Linq; +//using System.Text; +//using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + static class Constants + { + public static String CRLF = "\r\n"; + public static String TAB = "\t"; + + public static Single DAILY_VALUE_ADDED_SUGARS = 50; + public static Single DAILY_VALUE_BIOTIN = 30; + public static Single DAILY_VALUE_CALCIUM = 1300; + public static Single DAILY_VALUE_CHLORIDE = 2300; + public static Single DAILY_VALUE_CHOLESTEROL = 300; + public static Single DAILY_VALUE_CHOLINE = 550; + public static Single DAILY_VALUE_CHROMIUM = 35; + public static Single DAILY_VALUE_COPPER = 0.9F; + public static Single DAILY_VALUE_DIETARY_FIBER = 28; + public static Single DAILY_VALUE_FAT = 78; + public static Single DAILY_VALUE_FOLATE_FOLIC_ACID = 400; + public static Single DAILY_VALUE_IODINE = 150; + public static Single DAILY_VALUE_IRON = 18; + public static Single DAILY_VALUE_MAGNESIUM = 420; + public static Single DAILY_VALUE_MANGANESE = 2.3F; + public static Single DAILY_VALUE_MOLYBDENUM = 45; + public static Single DAILY_VALUE_NIACIN = 16; + public static Single DAILY_VALUE_PANTOTHENIC_ACID = 5; + public static Single DAILY_VALUE_PHOSPHORUS = 1250; + public static Single DAILY_VALUE_POTASSIUM = 4700; + public static Single DAILY_VALUE_PROTEIN = 50; + public static Single DAILY_VALUE_RIBOFLAVIN = 1.3F; + public static Single DAILY_VALUE_SATURATED_FAT = 20; + public static Single DAILY_VALUE_SELENIUM = 55; + public static Single DAILY_VALUE_SODIUM = 2300; + public static Single DAILY_VALUE_THIAMIN = 1.2F; + public static Single DAILY_VALUE_TOTAL_CARBOHYDRATE = 275; + public static Single DAILY_VALUE_VITAMIN_A = 900; + public static Single DAILY_VALUE_VITAMIN_B12 = 2.4F; + public static Single DAILY_VALUE_VITAMIN_B6 = 1.7F; + public static Single DAILY_VALUE_VITAMIN_C = 90; + public static Single DAILY_VALUE_VITAMIN_D = 20; + public static Single DAILY_VALUE_VITAMIN_E = 15; + public static Single DAILY_VALUE_VITAMIN_K = 120; + public static Single DAILY_VALUE_ZINC = 11; + + } + +} diff --git a/JRCookbookBusiness/Converters/CssStylesheet.cs b/JRCookbookBusiness/Converters/CssStylesheet.cs new file mode 100644 index 0000000..ccbb841 --- /dev/null +++ b/JRCookbookBusiness/Converters/CssStylesheet.cs @@ -0,0 +1,255 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Xml; + +namespace HtmlToXamlDemo +{ + internal class CssStylesheet + { + private List _styleDefinitions; + // Constructor + public CssStylesheet(XmlElement htmlElement) + { + if (htmlElement != null) + { + DiscoverStyleDefinitions(htmlElement); + } + } + + // Recursively traverses an html tree, discovers STYLE elements and creates a style definition table + // for further cascading style application + public void DiscoverStyleDefinitions(XmlElement htmlElement) + { + if (htmlElement.LocalName.ToLower() == "link") + { + return; + // Add LINK elements processing for included stylesheets + // + } + + if (htmlElement.LocalName.ToLower() != "style") + { + // This is not a STYLE element. Recurse into it + for (var htmlChildNode = htmlElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + if (htmlChildNode is XmlElement) + { + DiscoverStyleDefinitions((XmlElement) htmlChildNode); + } + } + return; + } + + // Add style definitions from this style. + + // Collect all text from this style definition + var stylesheetBuffer = new StringBuilder(); + + for (var htmlChildNode = htmlElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + if (htmlChildNode is XmlText || htmlChildNode is XmlComment) + { + stylesheetBuffer.Append(RemoveComments(htmlChildNode.Value)); + } + } + + // CssStylesheet has the following syntactical structure: + // @import declaration; + // selector { definition } + // where "selector" is one of: ".classname", "tagname" + // It can contain comments in the following form: /*...*/ + + var nextCharacterIndex = 0; + while (nextCharacterIndex < stylesheetBuffer.Length) + { + // Extract selector + var selectorStart = nextCharacterIndex; + while (nextCharacterIndex < stylesheetBuffer.Length && stylesheetBuffer[nextCharacterIndex] != '{') + { + // Skip declaration directive starting from @ + if (stylesheetBuffer[nextCharacterIndex] == '@') + { + while (nextCharacterIndex < stylesheetBuffer.Length && + stylesheetBuffer[nextCharacterIndex] != ';') + { + nextCharacterIndex++; + } + selectorStart = nextCharacterIndex + 1; + } + nextCharacterIndex++; + } + + if (nextCharacterIndex < stylesheetBuffer.Length) + { + // Extract definition + var definitionStart = nextCharacterIndex; + while (nextCharacterIndex < stylesheetBuffer.Length && stylesheetBuffer[nextCharacterIndex] != '}') + { + nextCharacterIndex++; + } + + // Define a style + if (nextCharacterIndex - definitionStart > 2) + { + AddStyleDefinition( + stylesheetBuffer.ToString(selectorStart, definitionStart - selectorStart), + stylesheetBuffer.ToString(definitionStart + 1, nextCharacterIndex - definitionStart - 2)); + } + + // Skip closing brace + if (nextCharacterIndex < stylesheetBuffer.Length) + { + Debug.Assert(stylesheetBuffer[nextCharacterIndex] == '}'); + nextCharacterIndex++; + } + } + } + } + + // Returns a string with all c-style comments replaced by spaces + private string RemoveComments(string text) + { + var commentStart = text.IndexOf("/*", StringComparison.Ordinal); + if (commentStart < 0) + { + return text; + } + + var commentEnd = text.IndexOf("*/", commentStart + 2, StringComparison.Ordinal); + if (commentEnd < 0) + { + return text.Substring(0, commentStart); + } + + return text.Substring(0, commentStart) + " " + RemoveComments(text.Substring(commentEnd + 2)); + } + + public void AddStyleDefinition(string selector, string definition) + { + // Notrmalize parameter values + selector = selector.Trim().ToLower(); + definition = definition.Trim().ToLower(); + if (selector.Length == 0 || definition.Length == 0) + { + return; + } + + if (_styleDefinitions == null) + { + _styleDefinitions = new List(); + } + + var simpleSelectors = selector.Split(','); + + foreach (string t in simpleSelectors) + { + var simpleSelector = t.Trim(); + if (simpleSelector.Length > 0) + { + _styleDefinitions.Add(new StyleDefinition(simpleSelector, definition)); + } + } + } + + public string GetStyle(string elementName, List sourceContext) + { + Debug.Assert(sourceContext.Count > 0); + Debug.Assert(elementName == sourceContext[sourceContext.Count - 1].LocalName); + + // Add id processing for style selectors + if (_styleDefinitions != null) + { + for (var i = _styleDefinitions.Count - 1; i >= 0; i--) + { + var selector = _styleDefinitions[i].Selector; + + var selectorLevels = selector.Split(' '); + + var indexInSelector = selectorLevels.Length - 1; + var indexInContext = sourceContext.Count - 1; + var selectorLevel = selectorLevels[indexInSelector].Trim(); + + if (MatchSelectorLevel(selectorLevel, sourceContext[sourceContext.Count - 1])) + { + return _styleDefinitions[i].Definition; + } + } + } + + return null; + } + + private bool MatchSelectorLevel(string selectorLevel, XmlElement xmlElement) + { + if (selectorLevel.Length == 0) + { + return false; + } + + var indexOfDot = selectorLevel.IndexOf('.'); + var indexOfPound = selectorLevel.IndexOf('#'); + + string selectorClass = null; + string selectorId = null; + string selectorTag = null; + if (indexOfDot >= 0) + { + if (indexOfDot > 0) + { + selectorTag = selectorLevel.Substring(0, indexOfDot); + } + selectorClass = selectorLevel.Substring(indexOfDot + 1); + } + else if (indexOfPound >= 0) + { + if (indexOfPound > 0) + { + selectorTag = selectorLevel.Substring(0, indexOfPound); + } + selectorId = selectorLevel.Substring(indexOfPound + 1); + } + else + { + selectorTag = selectorLevel; + } + + if (selectorTag != null && selectorTag != xmlElement.LocalName) + { + return false; + } + + if (selectorId != null && HtmlToXamlConverter.GetAttribute(xmlElement, "id") != selectorId) + { + return false; + } + + if (selectorClass != null && HtmlToXamlConverter.GetAttribute(xmlElement, "class") != selectorClass) + { + return false; + } + + return true; + } + + private class StyleDefinition + { + public readonly string Definition; + public readonly string Selector; + + public StyleDefinition(string selector, string definition) + { + Selector = selector; + Definition = definition; + } + } + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Converters/HtmlCSSParser.cs b/JRCookbookBusiness/Converters/HtmlCSSParser.cs new file mode 100644 index 0000000..ef278bc --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlCSSParser.cs @@ -0,0 +1,844 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Xml; + +namespace HtmlToXamlDemo +{ + // DependencyProperty + + // TextElement + + internal static class HtmlCssParser + { + private static readonly string[] Colors = + { + "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", + "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", + "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", + "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", + "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", "deeppink", + "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", + "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", "indianred", + "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", + "lightcoral", + "lightcyan", "lightgoldenrodyellow", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", + "lightskyblue", "lightslategray", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", + "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", + "mediumslateblue", + "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", + "moccasin", + "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", + "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", + "powderblue", + "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", + "sienna", "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", "teal", + "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen" + }; + + private static readonly string[] SystemColors = + { + "activeborder", "activecaption", "appworkspace", "background", "buttonface", "buttonhighlight", + "buttonshadow", + "buttontext", "captiontext", "graytext", "highlight", "highlighttext", "inactiveborder", "inactivecaption", + "inactivecaptiontext", "infobackground", "infotext", "menu", "menutext", "scrollbar", "threeddarkshadow", + "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "window", "windowframe", "windowtext" + }; + + // ................................................................. + // + // Pasring CSS font Property + // + // ................................................................. + + // CSS has five font properties: font-family, font-style, font-variant, font-weight, font-size. + // An aggregated "font" property lets you specify in one action all the five in combination + // with additional line-height property. + // + // font-family: [,]* [ | ] + // generic-family: serif | sans-serif | monospace | cursive | fantasy + // The list of families sets priorities to choose fonts; + // Quotes not allowed around generic-family names + // font-style: normal | italic | oblique + // font-variant: normal | small-caps + // font-weight: normal | bold | bolder | lighter | 100 ... 900 | + // Default is "normal", normal==400 + // font-size: | | | + // absolute-size: xx-small | x-small | small | medium | large | x-large | xx-large + // relative-size: larger | smaller + // length: | | | | | | | + // Default: medium + // font: [ || || [ / ]? + + private static readonly string[] FontGenericFamilies = + { + "serif", "sans-serif", "monospace", "cursive", "fantasy" + }; + + private static readonly string[] FontStyles = {"normal", "italic", "oblique"}; + private static readonly string[] FontVariants = {"normal", "small-caps"}; + + private static readonly string[] FontWeights = + { + "normal", "bold", "bolder", "lighter", "100", "200", "300", + "400", "500", "600", "700", "800", "900" + }; + + private static readonly string[] FontAbsoluteSizes = + { + "xx-small", "x-small", "small", "medium", "large", + "x-large", "xx-large" + }; + + private static readonly string[] FontRelativeSizes = {"larger", "smaller"}; + + private static readonly string[] FontSizeUnits = {"px", "mm", "cm", "in", "pt", "pc", "em", "ex", "%"}; + + // ................................................................. + // + // Pasring CSS list-style Property + // + // ................................................................. + + // list-style: [ || || ] + + private static readonly string[] ListStyleTypes = + { + "disc", "circle", "square", "decimal", "lower-roman", + "upper-roman", "lower-alpha", "upper-alpha", "none" + }; + + private static readonly string[] ListStylePositions = {"inside", "outside"}; + // ................................................................. + // + // Pasring CSS text-decorations Property + // + // ................................................................. + + private static readonly string[] TextDecorations = {"none", "underline", "overline", "line-through", "blink"}; + + // ................................................................. + // + // Pasring CSS text-transform Property + // + // ................................................................. + + private static readonly string[] TextTransforms = {"none", "capitalize", "uppercase", "lowercase"}; + // ................................................................. + // + // Pasring CSS text-align Property + // + // ................................................................. + + private static readonly string[] TextAligns = {"left", "right", "center", "justify"}; + // ................................................................. + // + // Pasring CSS vertical-align Property + // + // ................................................................. + + private static readonly string[] VerticalAligns = + { + "baseline", "sub", "super", "top", "text-top", "middle", + "bottom", "text-bottom" + }; + + // ................................................................. + // + // Pasring CSS float Property + // + // ................................................................. + + private static readonly string[] Floats = {"left", "right", "none"}; + // ................................................................. + // + // Pasring CSS clear Property + // + // ................................................................. + + private static readonly string[] Clears = {"none", "left", "right", "both"}; + // ................................................................. + // + // Pasring CSS border-style Propertie + // + // ................................................................. + + private static readonly string[] BorderStyles = + { + "none", "dotted", "dashed", "solid", "double", "groove", + "ridge", "inset", "outset" + }; + + // ................................................................. + // + // What are these definitions doing here: + // + // ................................................................. + + private static string[] _blocks = {"block", "inline", "list-item", "none"}; + // ................................................................. + // + // Processing CSS Attributes + // + // ................................................................. + + internal static void GetElementPropertiesFromCssAttributes(XmlElement htmlElement, string elementName, + CssStylesheet stylesheet, Hashtable localProperties, List sourceContext) + { + var styleFromStylesheet = stylesheet.GetStyle(elementName, sourceContext); + + var styleInline = HtmlToXamlConverter.GetAttribute(htmlElement, "style"); + + // Combine styles from stylesheet and from inline attribute. + // The order is important - the latter styles will override the former. + var style = styleFromStylesheet ?? null; + if (styleInline != null) + { + style = style == null ? styleInline : (style + ";" + styleInline); + } + + // Apply local style to current formatting properties + if (style != null) + { + var styleValues = style.Split(';'); + foreach (string t in styleValues) + { + string[] styleNameValue; + + styleNameValue = t.Split(':'); + if (styleNameValue.Length == 2) + { + var styleName = styleNameValue[0].Trim().ToLower(); + var styleValue = HtmlToXamlConverter.UnQuote(styleNameValue[1].Trim()).ToLower(); + var nextIndex = 0; + + switch (styleName) + { + case "font": + ParseCssFont(styleValue, localProperties); + break; + case "font-family": + ParseCssFontFamily(styleValue, ref nextIndex, localProperties); + break; + case "font-size": + ParseCssSize(styleValue, ref nextIndex, localProperties, "font-size", + /*mustBeNonNegative:*/true); + break; + case "font-style": + ParseCssFontStyle(styleValue, ref nextIndex, localProperties); + break; + case "font-weight": + ParseCssFontWeight(styleValue, ref nextIndex, localProperties); + break; + case "font-variant": + ParseCssFontVariant(styleValue, ref nextIndex, localProperties); + break; + case "line-height": + ParseCssSize(styleValue, ref nextIndex, localProperties, "line-height", + /*mustBeNonNegative:*/true); + break; + case "word-spacing": + // Implement word-spacing conversion + break; + case "letter-spacing": + // Implement letter-spacing conversion + break; + case "color": + ParseCssColor(styleValue, ref nextIndex, localProperties, "color"); + break; + + case "text-decoration": + ParseCssTextDecoration(styleValue, ref nextIndex, localProperties); + break; + + case "text-transform": + ParseCssTextTransform(styleValue, ref nextIndex, localProperties); + break; + + case "background-color": + ParseCssColor(styleValue, ref nextIndex, localProperties, "background-color"); + break; + case "background": + // TODO: need to parse composite background property + ParseCssBackground(styleValue, ref nextIndex, localProperties); + break; + + case "text-align": + ParseCssTextAlign(styleValue, ref nextIndex, localProperties); + break; + case "vertical-align": + ParseCssVerticalAlign(styleValue, ref nextIndex, localProperties); + break; + case "text-indent": + ParseCssSize(styleValue, ref nextIndex, localProperties, "text-indent", + /*mustBeNonNegative:*/false); + break; + + case "width": + case "height": + ParseCssSize(styleValue, ref nextIndex, localProperties, styleName, + /*mustBeNonNegative:*/true); + break; + + case "margin": // top/right/bottom/left + ParseCssRectangleProperty(styleValue, ref nextIndex, localProperties, styleName); + break; + case "margin-top": + case "margin-right": + case "margin-bottom": + case "margin-left": + ParseCssSize(styleValue, ref nextIndex, localProperties, styleName, + /*mustBeNonNegative:*/true); + break; + + case "padding": + ParseCssRectangleProperty(styleValue, ref nextIndex, localProperties, styleName); + break; + case "padding-top": + case "padding-right": + case "padding-bottom": + case "padding-left": + ParseCssSize(styleValue, ref nextIndex, localProperties, styleName, + /*mustBeNonNegative:*/true); + break; + + case "border": + ParseCssBorder(styleValue, ref nextIndex, localProperties); + break; + case "border-style": + case "border-width": + case "border-color": + ParseCssRectangleProperty(styleValue, ref nextIndex, localProperties, styleName); + break; + case "border-top": + case "border-right": + case "border-left": + case "border-bottom": + // Parse css border style + break; + + // NOTE: css names for elementary border styles have side indications in the middle (top/bottom/left/right) + // In our internal notation we intentionally put them at the end - to unify processing in ParseCssRectangleProperty method + case "border-top-style": + case "border-right-style": + case "border-left-style": + case "border-bottom-style": + case "border-top-color": + case "border-right-color": + case "border-left-color": + case "border-bottom-color": + case "border-top-width": + case "border-right-width": + case "border-left-width": + case "border-bottom-width": + // Parse css border style + break; + + case "display": + // Implement display style conversion + break; + + case "float": + ParseCssFloat(styleValue, ref nextIndex, localProperties); + break; + case "clear": + ParseCssClear(styleValue, ref nextIndex, localProperties); + break; + + default: + break; + } + } + } + } + } + + // ................................................................. + // + // Parsing CSS - Lexical Helpers + // + // ................................................................. + + // Skips whitespaces in style values + private static void ParseWhiteSpace(string styleValue, ref int nextIndex) + { + while (nextIndex < styleValue.Length && char.IsWhiteSpace(styleValue[nextIndex])) + { + nextIndex++; + } + } + + // Checks if the following character matches to a given word and advances nextIndex + // by the word's length in case of success. + // Otherwise leaves nextIndex in place (except for possible whitespaces). + // Returns true or false depending on success or failure of matching. + private static bool ParseWord(string word, string styleValue, ref int nextIndex) + { + ParseWhiteSpace(styleValue, ref nextIndex); + + for (var i = 0; i < word.Length; i++) + { + if (!(nextIndex + i < styleValue.Length && word[i] == styleValue[nextIndex + i])) + { + return false; + } + } + + if (nextIndex + word.Length < styleValue.Length && char.IsLetterOrDigit(styleValue[nextIndex + word.Length])) + { + return false; + } + + nextIndex += word.Length; + return true; + } + + // CHecks whether the following character sequence matches to one of the given words, + // and advances the nextIndex to matched word length. + // Returns null in case if there is no match or the word matched. + private static string ParseWordEnumeration(string[] words, string styleValue, ref int nextIndex) + { + foreach (string t in words) + { + if (ParseWord(t, styleValue, ref nextIndex)) + { + return t; + } + } + + return null; + } + + private static void ParseWordEnumeration(string[] words, string styleValue, ref int nextIndex, + Hashtable localProperties, string attributeName) + { + var attributeValue = ParseWordEnumeration(words, styleValue, ref nextIndex); + if (attributeValue != null) + { + localProperties[attributeName] = attributeValue; + } + } + + private static string ParseCssSize(string styleValue, ref int nextIndex, bool mustBeNonNegative) + { + ParseWhiteSpace(styleValue, ref nextIndex); + + var startIndex = nextIndex; + + // Parse optional munis sign + if (nextIndex < styleValue.Length && styleValue[nextIndex] == '-') + { + nextIndex++; + } + + if (nextIndex < styleValue.Length && char.IsDigit(styleValue[nextIndex])) + { + while (nextIndex < styleValue.Length && + (char.IsDigit(styleValue[nextIndex]) || styleValue[nextIndex] == '.')) + { + nextIndex++; + } + + var number = styleValue.Substring(startIndex, nextIndex - startIndex); + + var unit = ParseWordEnumeration(FontSizeUnits, styleValue, ref nextIndex) ?? "px"; + + if (mustBeNonNegative && styleValue[startIndex] == '-') + { + return "0"; + } + return number + unit; + } + + return null; + } + + private static void ParseCssSize(string styleValue, ref int nextIndex, Hashtable localValues, + string propertyName, + bool mustBeNonNegative) + { + var length = ParseCssSize(styleValue, ref nextIndex, mustBeNonNegative); + if (length != null) + { + localValues[propertyName] = length; + } + } + + private static string ParseCssColor(string styleValue, ref int nextIndex) + { + // Implement color parsing + // rgb(100%,53.5%,10%) + // rgb(255,91,26) + // #FF5B1A + // black | silver | gray | ... | aqua + // transparent - for background-color + ParseWhiteSpace(styleValue, ref nextIndex); + + string color = null; + + if (nextIndex < styleValue.Length) + { + var startIndex = nextIndex; + var character = styleValue[nextIndex]; + + if (character == '#') + { + nextIndex++; + while (nextIndex < styleValue.Length) + { + character = char.ToUpper(styleValue[nextIndex]); + if (!('0' <= character && character <= '9' || 'A' <= character && character <= 'F')) + { + break; + } + nextIndex++; + } + if (nextIndex > startIndex + 1) + { + color = styleValue.Substring(startIndex, nextIndex - startIndex); + } + } + else if (styleValue.Substring(nextIndex, 3).ToLower() == "rbg") + { + // Implement real rgb() color parsing + while (nextIndex < styleValue.Length && styleValue[nextIndex] != ')') + { + nextIndex++; + } + if (nextIndex < styleValue.Length) + { + nextIndex++; // to skip ')' + } + color = "gray"; // return bogus color + } + else if (char.IsLetter(character)) + { + color = ParseWordEnumeration(Colors, styleValue, ref nextIndex); + if (color == null) + { + color = ParseWordEnumeration(SystemColors, styleValue, ref nextIndex); + if (color != null) + { + // Implement smarter system color converions into real colors + color = "black"; + } + } + } + } + + return color; + } + + private static void ParseCssColor(string styleValue, ref int nextIndex, Hashtable localValues, + string propertyName) + { + var color = ParseCssColor(styleValue, ref nextIndex); + if (color != null) + { + localValues[propertyName] = color; + } + } + + // Parses CSS string fontStyle representing a value for css font attribute + private static void ParseCssFont(string styleValue, Hashtable localProperties) + { + var nextIndex = 0; + + ParseCssFontStyle(styleValue, ref nextIndex, localProperties); + ParseCssFontVariant(styleValue, ref nextIndex, localProperties); + ParseCssFontWeight(styleValue, ref nextIndex, localProperties); + + ParseCssSize(styleValue, ref nextIndex, localProperties, "font-size", /*mustBeNonNegative:*/true); + + ParseWhiteSpace(styleValue, ref nextIndex); + if (nextIndex < styleValue.Length && styleValue[nextIndex] == '/') + { + nextIndex++; + ParseCssSize(styleValue, ref nextIndex, localProperties, "line-height", /*mustBeNonNegative:*/true); + } + + ParseCssFontFamily(styleValue, ref nextIndex, localProperties); + } + + private static void ParseCssFontStyle(string styleValue, ref int nextIndex, Hashtable localProperties) + { + ParseWordEnumeration(FontStyles, styleValue, ref nextIndex, localProperties, "font-style"); + } + + private static void ParseCssFontVariant(string styleValue, ref int nextIndex, Hashtable localProperties) + { + ParseWordEnumeration(FontVariants, styleValue, ref nextIndex, localProperties, "font-variant"); + } + + private static void ParseCssFontWeight(string styleValue, ref int nextIndex, Hashtable localProperties) + { + ParseWordEnumeration(FontWeights, styleValue, ref nextIndex, localProperties, "font-weight"); + } + + private static void ParseCssFontFamily(string styleValue, ref int nextIndex, Hashtable localProperties) + { + string fontFamilyList = null; + + while (nextIndex < styleValue.Length) + { + // Try generic-family + var fontFamily = ParseWordEnumeration(FontGenericFamilies, styleValue, ref nextIndex); + + if (fontFamily == null) + { + // Try quoted font family name + if (nextIndex < styleValue.Length && (styleValue[nextIndex] == '"' || styleValue[nextIndex] == '\'')) + { + var quote = styleValue[nextIndex]; + + nextIndex++; + + var startIndex = nextIndex; + + while (nextIndex < styleValue.Length && styleValue[nextIndex] != quote) + { + nextIndex++; + } + + fontFamily = '"' + styleValue.Substring(startIndex, nextIndex - startIndex) + '"'; + } + + if (fontFamily == null) + { + // Try unquoted font family name + var startIndex = nextIndex; + while (nextIndex < styleValue.Length && styleValue[nextIndex] != ',' && + styleValue[nextIndex] != ';') + { + nextIndex++; + } + + if (nextIndex > startIndex) + { + fontFamily = styleValue.Substring(startIndex, nextIndex - startIndex).Trim(); + if (fontFamily.Length == 0) + { + fontFamily = null; + } + } + } + } + + ParseWhiteSpace(styleValue, ref nextIndex); + if (nextIndex < styleValue.Length && styleValue[nextIndex] == ',') + { + nextIndex++; + } + + if (fontFamily != null) + { + // css font-family can contein a list of names. We only consider the first name from the list. Need a decision what to do with remaining names + // fontFamilyList = (fontFamilyList == null) ? fontFamily : fontFamilyList + "," + fontFamily; + if (fontFamilyList == null && fontFamily.Length > 0) + { + if (fontFamily[0] == '"' || fontFamily[0] == '\'') + { + // Unquote the font family name + fontFamily = fontFamily.Substring(1, fontFamily.Length - 2); + } + fontFamilyList = fontFamily; + } + } + else + { + break; + } + } + + if (fontFamilyList != null) + { + localProperties["font-family"] = fontFamilyList; + } + } + + private static void ParseCssListStyle(string styleValue, Hashtable localProperties) + { + var nextIndex = 0; + + while (nextIndex < styleValue.Length) + { + var listStyleType = ParseCssListStyleType(styleValue, ref nextIndex); + if (listStyleType != null) + { + localProperties["list-style-type"] = listStyleType; + } + else + { + var listStylePosition = ParseCssListStylePosition(styleValue, ref nextIndex); + if (listStylePosition != null) + { + localProperties["list-style-position"] = listStylePosition; + } + else + { + var listStyleImage = ParseCssListStyleImage(styleValue, ref nextIndex); + if (listStyleImage != null) + { + localProperties["list-style-image"] = listStyleImage; + } + else + { + // TODO: Process unrecognized list style value + break; + } + } + } + } + } + + private static string ParseCssListStyleType(string styleValue, ref int nextIndex) => ParseWordEnumeration(ListStyleTypes, styleValue, ref nextIndex); + + private static string ParseCssListStylePosition(string styleValue, ref int nextIndex) => ParseWordEnumeration(ListStylePositions, styleValue, ref nextIndex); + + private static string ParseCssListStyleImage(string styleValue, ref int nextIndex) => null; + + private static void ParseCssTextDecoration(string styleValue, ref int nextIndex, Hashtable localProperties) + { + // Set default text-decorations:none; + for (var i = 1; i < TextDecorations.Length; i++) + { + localProperties["text-decoration-" + TextDecorations[i]] = "false"; + } + + // Parse list of decorations values + while (nextIndex < styleValue.Length) + { + var decoration = ParseWordEnumeration(TextDecorations, styleValue, ref nextIndex); + if (decoration == null || decoration == "none") + { + break; + } + localProperties["text-decoration-" + decoration] = "true"; + } + } + + private static void ParseCssTextTransform(string styleValue, ref int nextIndex, Hashtable localProperties) + { + ParseWordEnumeration(TextTransforms, styleValue, ref nextIndex, localProperties, "text-transform"); + } + + private static void ParseCssTextAlign(string styleValue, ref int nextIndex, Hashtable localProperties) + { + ParseWordEnumeration(TextAligns, styleValue, ref nextIndex, localProperties, "text-align"); + } + + private static void ParseCssVerticalAlign(string styleValue, ref int nextIndex, Hashtable localProperties) + { + // Parse percentage value for vertical-align style + ParseWordEnumeration(VerticalAligns, styleValue, ref nextIndex, localProperties, "vertical-align"); + } + + private static void ParseCssFloat(string styleValue, ref int nextIndex, Hashtable localProperties) + { + ParseWordEnumeration(Floats, styleValue, ref nextIndex, localProperties, "float"); + } + + private static void ParseCssClear(string styleValue, ref int nextIndex, Hashtable localProperties) + { + ParseWordEnumeration(Clears, styleValue, ref nextIndex, localProperties, "clear"); + } + + // ................................................................. + // + // Pasring CSS margin and padding Properties + // + // ................................................................. + + // Generic method for parsing any of four-values properties, such as margin, padding, border-width, border-style, border-color + private static bool ParseCssRectangleProperty(string styleValue, ref int nextIndex, Hashtable localProperties, + string propertyName) + { + // CSS Spec: + // If only one value is set, then the value applies to all four sides; + // If two or three values are set, then missinng value(s) are taken fromm the opposite side(s). + // The order they are applied is: top/right/bottom/left + + Debug.Assert(propertyName == "margin" || propertyName == "padding" || propertyName == "border-width" || + propertyName == "border-style" || propertyName == "border-color"); + + var value = propertyName == "border-color" + ? ParseCssColor(styleValue, ref nextIndex) + : propertyName == "border-style" + ? ParseCssBorderStyle(styleValue, ref nextIndex) + : ParseCssSize(styleValue, ref nextIndex, /*mustBeNonNegative:*/true); + if (value != null) + { + localProperties[propertyName + "-top"] = value; + localProperties[propertyName + "-bottom"] = value; + localProperties[propertyName + "-right"] = value; + localProperties[propertyName + "-left"] = value; + value = propertyName == "border-color" + ? ParseCssColor(styleValue, ref nextIndex) + : propertyName == "border-style" + ? ParseCssBorderStyle(styleValue, ref nextIndex) + : ParseCssSize(styleValue, ref nextIndex, /*mustBeNonNegative:*/true); + if (value != null) + { + localProperties[propertyName + "-right"] = value; + localProperties[propertyName + "-left"] = value; + value = propertyName == "border-color" + ? ParseCssColor(styleValue, ref nextIndex) + : propertyName == "border-style" + ? ParseCssBorderStyle(styleValue, ref nextIndex) + : ParseCssSize(styleValue, ref nextIndex, /*mustBeNonNegative:*/true); + if (value != null) + { + localProperties[propertyName + "-bottom"] = value; + value = propertyName == "border-color" + ? ParseCssColor(styleValue, ref nextIndex) + : propertyName == "border-style" + ? ParseCssBorderStyle(styleValue, ref nextIndex) + : ParseCssSize(styleValue, ref nextIndex, /*mustBeNonNegative:*/true); + if (value != null) + { + localProperties[propertyName + "-left"] = value; + } + } + } + + return true; + } + + return false; + } + + // ................................................................. + // + // Pasring CSS border Properties + // + // ................................................................. + + // border: [ || || ] + + private static void ParseCssBorder(string styleValue, ref int nextIndex, Hashtable localProperties) + { + while ( + ParseCssRectangleProperty(styleValue, ref nextIndex, localProperties, "border-width") || + ParseCssRectangleProperty(styleValue, ref nextIndex, localProperties, "border-style") || + ParseCssRectangleProperty(styleValue, ref nextIndex, localProperties, "border-color")) + { + } + } + + private static string ParseCssBorderStyle(string styleValue, ref int nextIndex) => ParseWordEnumeration(BorderStyles, styleValue, ref nextIndex); + + // ................................................................. + // + // Pasring CSS Background Properties + // + // ................................................................. + + private static void ParseCssBackground(string styleValue, ref int nextIndex, Hashtable localValues) + { + // Implement parsing background attribute + } + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Converters/HtmlEncodedTextWriter.cs b/JRCookbookBusiness/Converters/HtmlEncodedTextWriter.cs new file mode 100644 index 0000000..a459967 --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlEncodedTextWriter.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Xml; + +namespace HtmlToXamlDemo +{ + public class HtmlEncodedTextWriter : XmlTextWriter + { + public HtmlEncodedTextWriter(TextWriter w) : base(w) { } + + #region Overrides of XmlTextWriter + + /// + public override void WriteString(string text) + { + text = WebUtility.HtmlEncode(text); + WriteRaw(text); + } + + #endregion + } +} diff --git a/JRCookbookBusiness/Converters/HtmlFromXamlConverter.cs b/JRCookbookBusiness/Converters/HtmlFromXamlConverter.cs new file mode 100644 index 0000000..3bf23d6 --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlFromXamlConverter.cs @@ -0,0 +1,577 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Text; +using System.Xml; + +namespace HtmlToXamlDemo +{ + /// + /// HtmlToXamlConverter is a static class that takes an HTML string + /// and converts it into XAML + /// + internal static class HtmlFromXamlConverter + { + // --------------------------------------------------------------------- + // + // Internal Methods + // + // --------------------------------------------------------------------- + + #region Internal Methods + + /// + /// Main entry point for Xaml-to-Html converter. + /// Converts a xaml string into html string. + /// + /// + /// Xaml strinng to convert. + /// + /// + /// Html string produced from a source xaml. + /// + internal static string ConvertXamlToHtml(string xamlString) + { + XmlTextReader xamlReader; + StringBuilder htmlStringBuilder; + XmlTextWriter htmlWriter; + + xamlReader = new XmlTextReader(new StringReader(xamlString)); + + htmlStringBuilder = new StringBuilder(100); + htmlWriter = new HtmlEncodedTextWriter(new StringWriter(htmlStringBuilder)); + + if (!WriteFlowDocument(xamlReader, htmlWriter)) + { + return ""; + } + + var htmlString = htmlStringBuilder.ToString(); + + return htmlString; + } + + #endregion Internal Methods + + // --------------------------------------------------------------------- + // + // Private Methods + // + // --------------------------------------------------------------------- + + #region Private Methods + + /// + /// Processes a root level element of XAML (normally it's FlowDocument element). + /// + /// + /// XmlTextReader for a source xaml. + /// + /// + /// XmlTextWriter producing resulting html + /// + private static bool WriteFlowDocument(XmlTextReader xamlReader, XmlTextWriter htmlWriter) + { + if (!ReadNextToken(xamlReader)) + { + // Xaml content is empty - nothing to convert + return false; + } + + if (xamlReader.NodeType != XmlNodeType.Element || xamlReader.Name != "FlowDocument") + { + // Root FlowDocument elemet is missing + return false; + } + + // Create a buffer StringBuilder for collecting css properties for inline STYLE attributes + // on every element level (it will be re-initialized on every level). + var inlineStyle = new StringBuilder(); + + htmlWriter.WriteStartElement("html"); + htmlWriter.WriteStartElement("body"); + + WriteFormattingProperties(xamlReader, htmlWriter, inlineStyle); + + WriteElementContent(xamlReader, htmlWriter, inlineStyle); + + htmlWriter.WriteEndElement(); + htmlWriter.WriteEndElement(); + + return true; + } + + /// + /// Reads attributes of the current xaml element and converts + /// them into appropriate html attributes or css styles. + /// + /// + /// XmlTextReader which is expected to be at XmlNodeType.Element + /// (opening element tag) position. + /// The reader will remain at the same level after function complete. + /// + /// + /// XmlTextWriter for output html, which is expected to be in + /// after WriteStartElement state. + /// + /// + /// String builder for collecting css properties for inline STYLE attribute. + /// + private static void WriteFormattingProperties(XmlTextReader xamlReader, XmlTextWriter htmlWriter, + StringBuilder inlineStyle) + { + Debug.Assert(xamlReader.NodeType == XmlNodeType.Element); + + // Clear string builder for the inline style + inlineStyle.Remove(0, inlineStyle.Length); + + if (!xamlReader.HasAttributes) + { + return; + } + + var borderSet = false; + + while (xamlReader.MoveToNextAttribute()) + { + string css = null; + + switch (xamlReader.Name) + { + // Character fomatting properties + // ------------------------------ + case "Background": + css = "background-color:" + ParseXamlColor(xamlReader.Value) + ";"; + break; + case "FontFamily": + css = "font-family:" + xamlReader.Value + ";"; + break; + case "FontStyle": + css = "font-style:" + xamlReader.Value.ToLower() + ";"; + break; + case "FontWeight": + css = "font-weight:" + xamlReader.Value.ToLower() + ";"; + break; + case "FontStretch": + break; + case "FontSize": + css = "font-size:" + xamlReader.Value + ";"; + break; + case "Foreground": + css = "color:" + ParseXamlColor(xamlReader.Value) + ";"; + break; + case "TextDecorations": + css = "text-decoration:underline;"; + break; + case "TextEffects": + break; + case "Emphasis": + break; + case "StandardLigatures": + break; + case "Variants": + break; + case "Capitals": + break; + case "Fraction": + break; + + // Paragraph formatting properties + // ------------------------------- + case "Padding": + css = "padding:" + ParseXamlThickness(xamlReader.Value) + ";"; + break; + case "Margin": + css = "margin:" + ParseXamlThickness(xamlReader.Value) + ";"; + break; + case "BorderThickness": + css = "border-width:" + ParseXamlThickness(xamlReader.Value) + ";"; + borderSet = true; + break; + case "BorderBrush": + css = "border-color:" + ParseXamlColor(xamlReader.Value) + ";"; + borderSet = true; + break; + case "LineHeight": + break; + case "TextIndent": + css = "text-indent:" + xamlReader.Value + ";"; + break; + case "TextAlignment": + css = "text-align:" + xamlReader.Value + ";"; + break; + case "IsKeptTogether": + break; + case "IsKeptWithNext": + break; + case "ColumnBreakBefore": + break; + case "PageBreakBefore": + break; + case "FlowDirection": + break; + + // Table attributes + // ---------------- + case "Width": + css = "width:" + xamlReader.Value + ";"; + break; + case "ColumnSpan": + htmlWriter.WriteAttributeString("colspan", xamlReader.Value); + break; + case "RowSpan": + htmlWriter.WriteAttributeString("rowspan", xamlReader.Value); + break; + } + + if (css != null) + { + inlineStyle.Append(css); + } + } + + if (borderSet) + { + inlineStyle.Append("border-style:solid;mso-element:para-border-div;"); + } + + // Return the xamlReader back to element level + xamlReader.MoveToElement(); + Debug.Assert(xamlReader.NodeType == XmlNodeType.Element); + } + + private static string ParseXamlColor(string color) + { + if (color.StartsWith("#")) + { + // Remove transparancy value + color = "#" + color.Substring(3); + } + return color; + } + + private static string ParseXamlThickness(string thickness) + { + var values = thickness.Split(','); + + for (var i = 0; i < values.Length; i++) + { + if (double.TryParse(values[i], NumberStyles.Any, CultureInfo.InvariantCulture, out double value)) + { + values[i] = Math.Ceiling(value).ToString(CultureInfo.InvariantCulture); + } + else + { + values[i] = "1"; + } + } + + string cssThickness; + switch (values.Length) + { + case 1: + cssThickness = thickness; + break; + case 2: + cssThickness = values[1] + " " + values[0]; + break; + case 4: + cssThickness = values[1] + " " + values[2] + " " + values[3] + " " + values[0]; + break; + default: + cssThickness = values[0]; + break; + } + + return cssThickness; + } + + /// + /// Reads a content of current xaml element, converts it + /// + /// + /// XmlTextReader which is expected to be at XmlNodeType.Element + /// (opening element tag) position. + /// + /// + /// May be null, in which case we are skipping the xaml element; + /// witout producing any output to html. + /// + /// + /// StringBuilder used for collecting css properties for inline STYLE attribute. + /// + private static void WriteElementContent(XmlTextReader xamlReader, XmlTextWriter htmlWriter, + StringBuilder inlineStyle) + { + Debug.Assert(xamlReader.NodeType == XmlNodeType.Element); + + var elementContentStarted = false; + + if (xamlReader.IsEmptyElement) + { + if (htmlWriter != null && !elementContentStarted && inlineStyle.Length > 0) + { + // Output STYLE attribute and clear inlineStyle buffer. + htmlWriter.WriteAttributeString("STYLE", inlineStyle.ToString()); + inlineStyle.Remove(0, inlineStyle.Length); + } + elementContentStarted = true; + } + else + { + while (ReadNextToken(xamlReader) && xamlReader.NodeType != XmlNodeType.EndElement) + { + switch (xamlReader.NodeType) + { + case XmlNodeType.Element: + if (xamlReader.Name.Contains(".")) + { + AddComplexProperty(xamlReader, inlineStyle); + } + else + { + if (htmlWriter != null && !elementContentStarted && inlineStyle.Length > 0) + { + // Output STYLE attribute and clear inlineStyle buffer. + htmlWriter.WriteAttributeString("style", inlineStyle.ToString()); + inlineStyle.Remove(0, inlineStyle.Length); + } + elementContentStarted = true; + WriteElement(xamlReader, htmlWriter, inlineStyle); + } + Debug.Assert(xamlReader.NodeType == XmlNodeType.EndElement || + xamlReader.NodeType == XmlNodeType.Element && xamlReader.IsEmptyElement); + break; + case XmlNodeType.Comment: + if (htmlWriter != null) + { + if (!elementContentStarted && inlineStyle.Length > 0) + { + htmlWriter.WriteAttributeString("style", inlineStyle.ToString()); + } + htmlWriter.WriteComment(xamlReader.Value); + } + elementContentStarted = true; + break; + case XmlNodeType.CDATA: + case XmlNodeType.Text: + case XmlNodeType.SignificantWhitespace: + if (htmlWriter != null) + { + if (!elementContentStarted && inlineStyle.Length > 0) + { + htmlWriter.WriteAttributeString("style", inlineStyle.ToString()); + } + htmlWriter.WriteString(xamlReader.Value); + } + elementContentStarted = true; + break; + } + } + + Debug.Assert(xamlReader.NodeType == XmlNodeType.EndElement); + } + } + + /// + /// Conberts an element notation of complex property into + /// + /// + /// On entry this XmlTextReader must be on Element start tag; + /// on exit - on EndElement tag. + /// + /// + /// StringBuilder containing a value for STYLE attribute. + /// + private static void AddComplexProperty(XmlTextReader xamlReader, StringBuilder inlineStyle) + { + Debug.Assert(xamlReader.NodeType == XmlNodeType.Element); + + if (inlineStyle != null && xamlReader.Name.EndsWith(".TextDecorations")) + { + inlineStyle.Append("text-decoration:underline;"); + } + + // Skip the element representing the complex property + WriteElementContent(xamlReader, /*htmlWriter:*/null, /*inlineStyle:*/null); + } + + /// + /// Converts a xaml element into an appropriate html element. + /// + /// + /// On entry this XmlTextReader must be on Element start tag; + /// on exit - on EndElement tag. + /// + /// + /// May be null, in which case we are skipping xaml content + /// without producing any html output + /// + /// + /// StringBuilder used for collecting css properties for inline STYLE attributes on every level. + /// + private static void WriteElement(XmlTextReader xamlReader, XmlTextWriter htmlWriter, StringBuilder inlineStyle) + { + Debug.Assert(xamlReader.NodeType == XmlNodeType.Element); + + if (htmlWriter == null) + { + // Skipping mode; recurse into the xaml element without any output + WriteElementContent(xamlReader, /*htmlWriter:*/null, null); + } + else + { + string htmlElementName = null; + + switch (xamlReader.Name) + { + case "Run": + case "Span": + htmlElementName = "span"; + break; + case "InlineUIContainer": + htmlElementName = "span"; + break; + case "Bold": + htmlElementName = "b"; + break; + case "Italic": + htmlElementName = "i"; + break; + case "Paragraph": + htmlElementName = "p"; + break; + case "BlockUIContainer": + htmlElementName = "div"; + break; + case "Section": + htmlElementName = "div"; + break; + case "Table": + htmlElementName = "table"; + break; + case "TableColumn": + htmlElementName = "col"; + break; + case "TableRowGroup": + htmlElementName = "tbody"; + break; + case "TableRow": + htmlElementName = "tr"; + break; + case "TableCell": + htmlElementName = "td"; + break; + case "List": + var marker = xamlReader.GetAttribute("MarkerStyle"); + if (marker == null || marker == "None" || marker == "Disc" || marker == "Circle" || + marker == "Square" || + marker == "Box") + { + htmlElementName = "ul"; + } + else + { + htmlElementName = "ol"; + } + break; + case "ListItem": + htmlElementName = "li"; + break; + default: + htmlElementName = null; // Ignore the element + break; + } + + if (htmlWriter != null && htmlElementName != null) + { + htmlWriter.WriteStartElement(htmlElementName); + + WriteFormattingProperties(xamlReader, htmlWriter, inlineStyle); + + WriteElementContent(xamlReader, htmlWriter, inlineStyle); + + htmlWriter.WriteEndElement(); + } + else + { + // Skip this unrecognized xaml element + WriteElementContent(xamlReader, /*htmlWriter:*/null, null); + } + } + } + + // Reader advance helpers + // ---------------------- + + /// + /// Reads several items from xamlReader skipping all non-significant stuff. + /// + /// + /// XmlTextReader from tokens are being read. + /// + /// + /// True if new token is available; false if end of stream reached. + /// + private static bool ReadNextToken(XmlReader xamlReader) + { + while (xamlReader.Read()) + { + Debug.Assert(xamlReader.ReadState == ReadState.Interactive, + "Reader is expected to be in Interactive state (" + xamlReader.ReadState + ")"); + switch (xamlReader.NodeType) + { + case XmlNodeType.Element: + case XmlNodeType.EndElement: + case XmlNodeType.None: + case XmlNodeType.CDATA: + case XmlNodeType.Text: + case XmlNodeType.SignificantWhitespace: + return true; + + case XmlNodeType.Whitespace: + if (xamlReader.XmlSpace == XmlSpace.Preserve) + { + return true; + } + // ignore insignificant whitespace + break; + + case XmlNodeType.EndEntity: + case XmlNodeType.EntityReference: + // Implement entity reading + //xamlReader.ResolveEntity(); + //xamlReader.Read(); + //ReadChildNodes( parent, parentBaseUri, xamlReader, positionInfo); + break; // for now we ignore entities as insignificant stuff + + case XmlNodeType.Comment: + return true; + case XmlNodeType.ProcessingInstruction: + case XmlNodeType.DocumentType: + case XmlNodeType.XmlDeclaration: + default: + // Ignorable stuff + break; + } + } + return false; + } + + #endregion Private Methods + + // --------------------------------------------------------------------- + // + // Private Fields + // + // --------------------------------------------------------------------- + + #region Private Fields + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Converters/HtmlLexicalAnalyzer.cs b/JRCookbookBusiness/Converters/HtmlLexicalAnalyzer.cs new file mode 100644 index 0000000..05cddba --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlLexicalAnalyzer.cs @@ -0,0 +1,745 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace HtmlToXamlDemo +{ + /// + /// lexical analyzer class + /// recognizes tokens as groups of characters separated by arbitrary amounts of whitespace + /// also classifies tokens according to type + /// + internal class HtmlLexicalAnalyzer + { + // --------------------------------------------------------------------- + // + // Constructors + // + // --------------------------------------------------------------------- + + #region Constructors + + /// + /// initializes the _inputStringReader member with the string to be read + /// also sets initial values for _nextCharacterCode and _nextTokenType + /// + /// + /// text string to be parsed for xml content + /// + internal HtmlLexicalAnalyzer(string inputTextString) + { + _inputStringReader = new StringReader(inputTextString); + _nextCharacterCode = 0; + NextCharacter = ' '; + _lookAheadCharacterCode = _inputStringReader.Read(); + _lookAheadCharacter = (char) _lookAheadCharacterCode; + _previousCharacter = ' '; + _ignoreNextWhitespace = true; + _nextToken = new StringBuilder(100); + NextTokenType = HtmlTokenType.Text; + // read the first character so we have some value for the NextCharacter property + GetNextCharacter(); + } + + #endregion Constructors + + // --------------------------------------------------------------------- + // + // Internal methods + // + // --------------------------------------------------------------------- + + #region Internal Methods + + /// + /// retrieves next recognizable token from input string + /// and identifies its type + /// if no valid token is found, the output parameters are set to null + /// if end of stream is reached without matching any token, token type + /// paramter is set to EOF + /// + internal void GetNextContentToken() + { + Debug.Assert(NextTokenType != HtmlTokenType.Eof); + _nextToken.Length = 0; + if (IsAtEndOfStream) + { + NextTokenType = HtmlTokenType.Eof; + return; + } + + if (IsAtTagStart) + { + GetNextCharacter(); + + if (NextCharacter == '/') + { + _nextToken.Append(" + /// Unconditionally returns a token which is one of: TagEnd, EmptyTagEnd, Name, Atom or EndOfStream + /// Does not guarantee token reader advancing. + /// + internal void GetNextTagToken() + { + _nextToken.Length = 0; + if (IsAtEndOfStream) + { + NextTokenType = HtmlTokenType.Eof; + return; + } + + SkipWhiteSpace(); + + if (NextCharacter == '>' && !IsNextCharacterEntity) + { + // > should not end a tag, so make sure it's not an entity + NextTokenType = HtmlTokenType.TagEnd; + _nextToken.Append('>'); + GetNextCharacter(); + // Note: _ignoreNextWhitespace must be set appropriately on tag start processing + } + else if (NextCharacter == '/' && _lookAheadCharacter == '>') + { + // could be start of closing of empty tag + NextTokenType = HtmlTokenType.EmptyTagEnd; + _nextToken.Append("/>"); + GetNextCharacter(); + GetNextCharacter(); + _ignoreNextWhitespace = false; // Whitespace after no-scope tags are sifnificant + } + else if (IsGoodForNameStart(NextCharacter)) + { + NextTokenType = HtmlTokenType.Name; + + // starts a name + // we allow character entities here + // we do not throw exceptions here if end of stream is encountered + // just stop and return whatever is in the token + // if the parser is not expecting end of file after this it will call + // the get next token function and throw an exception + while (IsGoodForName(NextCharacter) && !IsAtEndOfStream) + { + _nextToken.Append(NextCharacter); + GetNextCharacter(); + } + } + else + { + // Unexpected type of token for a tag. Reprot one character as Atom, expecting that HtmlParser will ignore it. + NextTokenType = HtmlTokenType.Atom; + _nextToken.Append(NextCharacter); + GetNextCharacter(); + } + } + + /// + /// Unconditionally returns equal sign token. Even if there is no + /// real equal sign in the stream, it behaves as if it were there. + /// Does not guarantee token reader advancing. + /// + internal void GetNextEqualSignToken() + { + Debug.Assert(NextTokenType != HtmlTokenType.Eof); + _nextToken.Length = 0; + + _nextToken.Append('='); + NextTokenType = HtmlTokenType.EqualSign; + + SkipWhiteSpace(); + + if (NextCharacter == '=') + { + // '=' is not in the list of entities, so no need to check for entities here + GetNextCharacter(); + } + } + + /// + /// Unconditionally returns an atomic value for an attribute + /// Even if there is no appropriate token it returns Atom value + /// Does not guarantee token reader advancing. + /// + internal void GetNextAtomToken() + { + Debug.Assert(NextTokenType != HtmlTokenType.Eof); + _nextToken.Length = 0; + + SkipWhiteSpace(); + + NextTokenType = HtmlTokenType.Atom; + + if ((NextCharacter == '\'' || NextCharacter == '"') && !IsNextCharacterEntity) + { + var startingQuote = NextCharacter; + GetNextCharacter(); + + // Consume all characters between quotes + while (!(NextCharacter == startingQuote && !IsNextCharacterEntity) && !IsAtEndOfStream) + { + _nextToken.Append(NextCharacter); + GetNextCharacter(); + } + if (NextCharacter == startingQuote) + { + GetNextCharacter(); + } + + // complete the quoted value + // NOTE: our recovery here is different from IE's + // IE keeps reading until it finds a closing quote or end of file + // if end of file, it treats current value as text + // if it finds a closing quote at any point within the text, it eats everything between the quotes + // TODO: Suggestion: + // however, we could stop when we encounter end of file or an angle bracket of any kind + // and assume there was a quote there + // so the attribute value may be meaningless but it is never treated as text + } + else + { + while (!IsAtEndOfStream && !char.IsWhiteSpace(NextCharacter) && NextCharacter != '>') + { + _nextToken.Append(NextCharacter); + GetNextCharacter(); + } + } + } + + #endregion Internal Methods + + // --------------------------------------------------------------------- + // + // Internal Properties + // + // --------------------------------------------------------------------- + + #region Internal Properties + + internal HtmlTokenType NextTokenType { get; private set; } + + internal string NextToken => _nextToken.ToString(); + + #endregion Internal Properties + + // --------------------------------------------------------------------- + // + // Private methods + // + // --------------------------------------------------------------------- + + #region Private Methods + + /// + /// Advances a reading position by one character code + /// and reads the next availbale character from a stream. + /// This character becomes available as NextCharacter property. + /// + /// + /// Throws InvalidOperationException if attempted to be called on EndOfStream + /// condition. + /// + private void GetNextCharacter() + { + if (_nextCharacterCode == -1) + { + throw new InvalidOperationException("GetNextCharacter method called at the end of a stream"); + } + + _previousCharacter = NextCharacter; + + NextCharacter = _lookAheadCharacter; + _nextCharacterCode = _lookAheadCharacterCode; + // next character not an entity as of now + IsNextCharacterEntity = false; + + ReadLookAheadCharacter(); + + if (NextCharacter == '&') + { + if (_lookAheadCharacter == '#') + { + // numeric entity - parse digits - &#DDDDD; + int entityCode; + entityCode = 0; + ReadLookAheadCharacter(); + + // largest numeric entity is 7 characters + for (var i = 0; i < 7 && char.IsDigit(_lookAheadCharacter); i++) + { + entityCode = 10*entityCode + (_lookAheadCharacterCode - '0'); + ReadLookAheadCharacter(); + } + if (_lookAheadCharacter == ';') + { + // correct format - advance + ReadLookAheadCharacter(); + _nextCharacterCode = entityCode; + + // if this is out of range it will set the character to '?' + NextCharacter = (char) _nextCharacterCode; + + // as far as we are concerned, this is an entity + IsNextCharacterEntity = true; + } + else + { + // not an entity, set next character to the current lookahread character + // we would have eaten up some digits + NextCharacter = _lookAheadCharacter; + _nextCharacterCode = _lookAheadCharacterCode; + ReadLookAheadCharacter(); + IsNextCharacterEntity = false; + } + } + else if (char.IsLetter(_lookAheadCharacter)) + { + // entity is written as a string + var entity = ""; + + // maximum length of string entities is 10 characters + for (var i = 0; + i < 10 && (char.IsLetter(_lookAheadCharacter) || char.IsDigit(_lookAheadCharacter)); + i++) + { + entity += _lookAheadCharacter; + ReadLookAheadCharacter(); + } + if (_lookAheadCharacter == ';') + { + // advance + ReadLookAheadCharacter(); + + if (HtmlSchema.IsEntity(entity)) + { + NextCharacter = HtmlSchema.EntityCharacterValue(entity); + _nextCharacterCode = NextCharacter; + IsNextCharacterEntity = true; + } + else + { + // just skip the whole thing - invalid entity + // move on to the next character + NextCharacter = _lookAheadCharacter; + _nextCharacterCode = _lookAheadCharacterCode; + ReadLookAheadCharacter(); + + // not an entity + IsNextCharacterEntity = false; + } + } + else + { + // skip whatever we read after the ampersand + // set next character and move on + NextCharacter = _lookAheadCharacter; + ReadLookAheadCharacter(); + IsNextCharacterEntity = false; + } + } + } + } + + private void ReadLookAheadCharacter() + { + if (_lookAheadCharacterCode != -1) + { + _lookAheadCharacterCode = _inputStringReader.Read(); + _lookAheadCharacter = (char) _lookAheadCharacterCode; + } + } + + /// + /// skips whitespace in the input string + /// leaves the first non-whitespace character available in the NextCharacter property + /// this may be the end-of-file character, it performs no checking + /// + private void SkipWhiteSpace() + { + // TODO: handle character entities while processing comments, cdata, and directives + // TODO: SUGGESTION: we could check if lookahead and previous characters are entities also + while (true) + { + if (NextCharacter == '<' && (_lookAheadCharacter == '?' || _lookAheadCharacter == '!')) + { + GetNextCharacter(); + + if (_lookAheadCharacter == '[') + { + // Skip CDATA block and DTDs(?) + while (!IsAtEndOfStream && + !(_previousCharacter == ']' && NextCharacter == ']' && _lookAheadCharacter == '>')) + { + GetNextCharacter(); + } + if (NextCharacter == '>') + { + GetNextCharacter(); + } + } + else + { + // Skip processing instruction, comments + while (!IsAtEndOfStream && NextCharacter != '>') + { + GetNextCharacter(); + } + if (NextCharacter == '>') + { + GetNextCharacter(); + } + } + } + + + if (!char.IsWhiteSpace(NextCharacter)) + { + break; + } + + GetNextCharacter(); + } + } + + /// + /// checks if a character can be used to start a name + /// if this check is true then the rest of the name can be read + /// + /// + /// character value to be checked + /// + /// + /// true if the character can be the first character in a name + /// false otherwise + /// + private bool IsGoodForNameStart(char character) => character == '_' || char.IsLetter(character); + + /// + /// checks if a character can be used as a non-starting character in a name + /// uses the IsExtender and IsCombiningCharacter predicates to see + /// if a character is an extender or a combining character + /// + /// + /// character to be checked for validity in a name + /// + /// + /// true if the character can be a valid part of a name + /// + private bool IsGoodForName(char character) => IsGoodForNameStart(character) || + character == '.' || + character == '-' || + character == ':' || + char.IsDigit(character) || + IsCombiningCharacter(character) || + IsExtender(character); + + /// + /// identifies a character as being a combining character, permitted in a name + /// TODO: only a placeholder for now but later to be replaced with comparisons against + /// the list of combining characters in the XML documentation + /// + /// + /// character to be checked + /// + /// + /// true if the character is a combining character, false otherwise + /// + private bool IsCombiningCharacter(char character) => false; + + /// + /// identifies a character as being an extender, permitted in a name + /// TODO: only a placeholder for now but later to be replaced with comparisons against + /// the list of extenders in the XML documentation + /// + /// + /// character to be checked + /// + /// + /// true if the character is an extender, false otherwise + /// + private bool IsExtender(char character) => false; + + /// + /// skips dynamic content starting with '' + /// + private void ReadDynamicContent() + { + // verify that we are at dynamic content, which may include CDATA + Debug.Assert(_previousCharacter == '<' && NextCharacter == '!' && _lookAheadCharacter == '['); + + // Let's treat this as empty text + NextTokenType = HtmlTokenType.Text; + _nextToken.Length = 0; + + // advance twice, once to get the lookahead character and then to reach the start of the cdata + GetNextCharacter(); + GetNextCharacter(); + + // NOTE: 10/12/2004: modified this function to check when called if's reading CDATA or something else + // some directives may start with a + // this function is modified to stop at the sequence ]> and not ]]> + // this means that CDATA and anything else expressed in their own set of [] within the + // directive cannot contain a ]> sequence. However it is doubtful that cdata could contain such + // sequence anyway, it probably stops at the first ] + while (!(NextCharacter == ']' && _lookAheadCharacter == '>') && !IsAtEndOfStream) + { + // advance + GetNextCharacter(); + } + + if (!IsAtEndOfStream) + { + // advance, first to the last > + GetNextCharacter(); + + // then advance past it to the next character after processing directive + GetNextCharacter(); + } + } + + /// + /// skips comments starting with '' + /// NOTE: 10/06/2004: processing changed, will now skip anything starting with + /// the "" or "->", because in practice many html pages do not + /// use the full comment specifying conventions + /// + private void ReadComment() + { + // verify that we are at a comment + Debug.Assert(_previousCharacter == '<' && NextCharacter == '!' && _lookAheadCharacter == '-'); + + // Initialize a token + NextTokenType = HtmlTokenType.Comment; + _nextToken.Length = 0; + + // advance to the next character, so that to be at the start of comment value + GetNextCharacter(); // get first '-' + GetNextCharacter(); // get second '-' + GetNextCharacter(); // get first character of comment content + + while (true) + { + // Read text until end of comment + // Note that in many actual html pages comments end with "!>" (while xml standard is "-->") + while (!IsAtEndOfStream && + !(NextCharacter == '-' && _lookAheadCharacter == '-' || + NextCharacter == '!' && _lookAheadCharacter == '>')) + { + _nextToken.Append(NextCharacter); + GetNextCharacter(); + } + + // Finish comment reading + GetNextCharacter(); + if (_previousCharacter == '-' && NextCharacter == '-' && _lookAheadCharacter == '>') + { + // Standard comment end. Eat it and exit the loop + GetNextCharacter(); // get '>' + break; + } + if (_previousCharacter == '!' && NextCharacter == '>') + { + // Nonstandard but possible comment end - '!>'. Exit the loop + break; + } + // Not an end. Save character and continue continue reading + _nextToken.Append(_previousCharacter); + } + + // Read end of comment combination + if (NextCharacter == '>') + { + GetNextCharacter(); + } + } + + /// + /// skips past unknown directives that start with "" + /// character + /// applies to directives such as DOCTYPE, etc that we do not presently support + /// + private void ReadUnknownDirective() + { + // verify that we are at an unknown directive + Debug.Assert(_previousCharacter == '<' && NextCharacter == '!' && + !(_lookAheadCharacter == '-' || _lookAheadCharacter == '[')); + + // Let's treat this as empty text + NextTokenType = HtmlTokenType.Text; + _nextToken.Length = 0; + + // advance to the next character + GetNextCharacter(); + + // skip to the first tag end we find + while (!(NextCharacter == '>' && !IsNextCharacterEntity) && !IsAtEndOfStream) + { + GetNextCharacter(); + } + + if (!IsAtEndOfStream) + { + // advance past the tag end + GetNextCharacter(); + } + } + + /// + /// skips processing directives starting with the characters '' + /// NOTE: 10/14/2004: IE also ends processing directives with a />, so this function is + /// being modified to recognize that condition as well + /// + private void SkipProcessingDirective() + { + // verify that we are at a processing directive + Debug.Assert(NextCharacter == '<' && _lookAheadCharacter == '?'); + + // advance twice, once to get the lookahead character and then to reach the start of the drective + GetNextCharacter(); + GetNextCharacter(); + + while (!((NextCharacter == '?' || NextCharacter == '/') && _lookAheadCharacter == '>') && !IsAtEndOfStream) + { + // advance + // we don't need to check for entities here because '?' is not an entity + // and even though > is an entity there is no entity processing when reading lookahead character + GetNextCharacter(); + } + + if (!IsAtEndOfStream) + { + // advance, first to the last > + GetNextCharacter(); + + // then advance past it to the next character after processing directive + GetNextCharacter(); + } + } + + #endregion Private Methods + + // --------------------------------------------------------------------- + // + // Private Properties + // + // --------------------------------------------------------------------- + + #region Private Properties + + private char NextCharacter { get; set; } + + private bool IsAtEndOfStream => _nextCharacterCode == -1; + + private bool IsAtTagStart + => NextCharacter == '<' && (_lookAheadCharacter == '/' || IsGoodForNameStart(_lookAheadCharacter)) && + !IsNextCharacterEntity; + + private bool IsAtTagEnd => (NextCharacter == '>' || (NextCharacter == '/' && _lookAheadCharacter == '>')) && + !IsNextCharacterEntity; + + private bool IsAtDirectiveStart + => (NextCharacter == '<' && _lookAheadCharacter == '!' && !IsNextCharacterEntity); + + private bool IsNextCharacterEntity { // check if next character is an entity + get; set; } + + #endregion Private Properties + + // --------------------------------------------------------------------- + // + // Private Fields + // + // --------------------------------------------------------------------- + + #region Private Fields + + // string reader which will move over input text + private readonly StringReader _inputStringReader; + // next character code read from input that is not yet part of any token + // and the character it represents + private int _nextCharacterCode; + private int _lookAheadCharacterCode; + private char _lookAheadCharacter; + private char _previousCharacter; + private bool _ignoreNextWhitespace; + + // store token and type in local variables before copying them to output parameters + private readonly StringBuilder _nextToken; + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Converters/HtmlParser.cs b/JRCookbookBusiness/Converters/HtmlParser.cs new file mode 100644 index 0000000..ae30106 --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlParser.cs @@ -0,0 +1,539 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Xml; + +// StringBuilder + +// important TODOS: +// TODO 1. Start tags: The ParseXmlElement function has been modified to be called after both the +// angle bracket < and element name have been read, instead of just the < bracket and some valid name character, +// previously the case. This change was made so that elements with optional closing tags could read a new +// element's start tag and decide whether they were required to close. However, there is a question of whether to +// handle this in the parser or lexical analyzer. It is currently handled in the parser - the lexical analyzer still +// recognizes a start tag opener as a '<' + valid name start char; it is the parser that reads the actual name. +// this is correct behavior assuming that the name is a valid html name, because the lexical analyzer should not know anything +// about optional closing tags, etc. UPDATED: 10/13/2004: I am updating this to read the whole start tag of something +// that is not an HTML, treat it as empty, and add it to the tree. That way the converter will know it's there, but +// it will hvae no content. We could also partially recover by trying to look up and match names if they are similar +// TODO 2. Invalid element names: However, it might make sense to give the lexical analyzer the ability to identify +// a valid html element name and not return something as a start tag otherwise. For example, if we type , should +// the lexical analyzer return that it has found the start of an element when this is not the case in HTML? But this will +// require implementing a lookahead token in the lexical analyzer so that it can treat an invalid element name as text. One +// character of lookahead will not be enough. +// TODO 3. Attributes: The attribute recovery is poor when reading attribute values in quotes - if no closing quotes are found, +// the lexical analyzer just keeps reading and if it eventually reaches the end of file, it would have just skipped everything. +// There are a couple of ways to deal with this: 1) stop reading attributes when we encounter a '>' character - this doesn't allow +// the '>' character to be used in attribute values, but it can still be used as an entity. 2) Maintain a HTML-specific list +// of attributes and their values that each html element can take, and if we find correct attribute namesand values for an +// element we use them regardless of the quotes, this way we could just ignore something invalid. One more option: 3) Read ahead +// in the quoted value and if we find an end of file, we can return to where we were and process as text. However this requires +// a lot of lookahead and a resettable reader. +// TODO 4: elements with optional closing tags: For elements with optional closing tags, we always close the element if we find +// that one of it's ancestors has closed. This condition may be too broad and we should develop a better heuristic. We should also +// improve the heuristics for closing certain elements when the next element starts +// TODO 5. Nesting: Support for unbalanced nesting, e.g. : this is not presently supported. To support it we may need +// to maintain two xml elements, one the element that represents what has already been read and another represents what we are presently reading. +// Then if we encounter an unbalanced nesting tag we could close the element that was supposed to close, save the current element +// and store it in the list of already-read content, and then open a new element to which all tags that are currently open +// can be applied. Is there a better way to do this? Should we do it at all? +// TODO 6. Elements with optional starting tags: there are 4 such elements in the HTML 4 specification - html, tbody, body and head. +// The current recovery doesn;t do anything for any of these elements except the html element, because it's not critical - head +// and body elementscan be contained within html element, and tbody is contained within table. To extend this for XHTML +// extensions, and to recover in case other elements are missing start tags, we would need to insert an extra recursive call +// to ParseXmlElement for the missing start tag. It is suggested to do this by giving ParseXmlElement an argument that specifies +// a name to use. If this argument is null, it assumes its name is the next token from the lexical analyzer and continues +// exactly as it does now. However, if the argument contains a valid html element name then it takes that value as its name +// and continues as before. This way, if the next token is the element that should actually be its child, it will see +// the name in the next step and initiate a recursive call. We would also need to add some logic in the loop for when a start tag +// is found - if the start tag is not compatible with current context and indicates that a start tag has been missed, then we +// can initiate the extra recursive call and give it the name of the missed start tag. The issues are when to insert this logic, +// and if we want to support it over multiple missing start tags. If we insert it at the time a start tag is read in element +// text, then we can support only one missing start tag, since the extra call will read the next start tag and make a recursive +// call without checking the context. This is a conceptual problem, and the check should be made just before a recursive call, +// with the choice being whether we should supply an element name as argument, or leave it as NULL and read from the input +// TODO 7: Context: Is it appropriate to keep track of context here? For example, should we only expect td, tr elements when +// reading a table and ignore them otherwise? This may be too much of a load on the parser, I think it's better if the converter +// deals with it + +namespace HtmlToXamlDemo +{ + /// + /// HtmlParser class accepts a string of possibly badly formed Html, parses it and returns a string + /// of well-formed Html that is as close to the original string in content as possible + /// + internal class HtmlParser + { + // --------------------------------------------------------------------- + // + // Constructors + // + // --------------------------------------------------------------------- + + #region Constructors + + /// + /// Constructor. Initializes the _htmlLexicalAnalayzer element with the given input string + /// + /// + /// string to parsed into well-formed Html + /// + private HtmlParser(string inputString) + { + // Create an output xml document + _document = new XmlDocument(); + + // initialize open tag stack + _openedElements = new Stack(); + + _pendingInlineElements = new Stack(); + + // initialize lexical analyzer + _htmlLexicalAnalyzer = new HtmlLexicalAnalyzer(inputString); + + // get first token from input, expecting text + _htmlLexicalAnalyzer.GetNextContentToken(); + } + + #endregion Constructors + + // --------------------------------------------------------------------- + // + // Internal Methods + // + // --------------------------------------------------------------------- + + #region Internal Methods + + /// + /// Instantiates an HtmlParser element and calls the parsing function on the given input string + /// + /// + /// Input string of pssibly badly-formed Html to be parsed into well-formed Html + /// + /// + /// XmlElement rep + /// + internal static XmlElement ParseHtml(string htmlString) + { + var htmlParser = new HtmlParser(htmlString); + + var htmlRootElement = htmlParser.ParseHtmlContent(); + + return htmlRootElement; + } + + // ..................................................................... + // + // Html Header on Clipboard + // + // ..................................................................... + + // Html header structure. + // Version:1.0 + // StartHTML:000000000 + // EndHTML:000000000 + // StartFragment:000000000 + // EndFragment:000000000 + // StartSelection:000000000 + // EndSelection:000000000 + internal const string HtmlHeader = + "Version:1.0\r\nStartHTML:{0:D10}\r\nEndHTML:{1:D10}\r\nStartFragment:{2:D10}\r\nEndFragment:{3:D10}\r\nStartSelection:{4:D10}\r\nEndSelection:{5:D10}\r\n"; + + internal const string HtmlStartFragmentComment = ""; + internal const string HtmlEndFragmentComment = ""; + + /// + /// Extracts Html string from clipboard data by parsing header information in htmlDataString + /// + /// + /// String representing Html clipboard data. This includes Html header + /// + /// + /// String containing only the Html data part of htmlDataString, without header + /// + internal static string ExtractHtmlFromClipboardData(string htmlDataString) + { + var startHtmlIndex = htmlDataString.IndexOf("StartHTML:", StringComparison.Ordinal); + if (startHtmlIndex < 0) + { + return "ERROR: Urecognized html header"; + } + // TODO: We assume that indices represented by strictly 10 zeros ("0123456789".Length), + // which could be wrong assumption. We need to implement more flrxible parsing here + startHtmlIndex = + int.Parse(htmlDataString.Substring(startHtmlIndex + "StartHTML:".Length, "0123456789".Length)); + if (startHtmlIndex < 0 || startHtmlIndex > htmlDataString.Length) + { + return "ERROR: Urecognized html header"; + } + + var endHtmlIndex = htmlDataString.IndexOf("EndHTML:", StringComparison.Ordinal); + if (endHtmlIndex < 0) + { + return "ERROR: Urecognized html header"; + } + // TODO: We assume that indices represented by strictly 10 zeros ("0123456789".Length), + // which could be wrong assumption. We need to implement more flrxible parsing here + endHtmlIndex = int.Parse(htmlDataString.Substring(endHtmlIndex + "EndHTML:".Length, "0123456789".Length)); + if (endHtmlIndex > htmlDataString.Length) + { + endHtmlIndex = htmlDataString.Length; + } + + return htmlDataString.Substring(startHtmlIndex, endHtmlIndex - startHtmlIndex); + } + + /// + /// Adds Xhtml header information to Html data string so that it can be placed on clipboard + /// + /// + /// Html string to be placed on clipboard with appropriate header + /// + /// + /// String wrapping htmlString with appropriate Html header + /// + internal static string AddHtmlClipboardHeader(string htmlString) + { + var stringBuilder = new StringBuilder(); + + // each of 6 numbers is represented by "{0:D10}" in the format string + // must actually occupy 10 digit positions ("0123456789") + var startHtml = HtmlHeader.Length + 6*("0123456789".Length - "{0:D10}".Length); + var endHtml = startHtml + htmlString.Length; + var startFragment = htmlString.IndexOf(HtmlStartFragmentComment, 0, StringComparison.Ordinal); + if (startFragment >= 0) + { + startFragment = startHtml + startFragment + HtmlStartFragmentComment.Length; + } + else + { + startFragment = startHtml; + } + var endFragment = htmlString.IndexOf(HtmlEndFragmentComment, 0, StringComparison.Ordinal); + if (endFragment >= 0) + { + endFragment = startHtml + endFragment; + } + else + { + endFragment = endHtml; + } + + // Create HTML clipboard header string + stringBuilder.AppendFormat(HtmlHeader, startHtml, endHtml, startFragment, endFragment, startFragment, + endFragment); + + // Append HTML body. + stringBuilder.Append(htmlString); + + return stringBuilder.ToString(); + } + + #endregion Internal Methods + + // --------------------------------------------------------------------- + // + // Private methods + // + // --------------------------------------------------------------------- + + #region Private Methods + + private void InvariantAssert(bool condition, string message) + { + if (!condition) + { + throw new Exception("Assertion error: " + message); + } + } + + /// + /// Parses the stream of html tokens starting + /// from the name of top-level element. + /// Returns XmlElement representing the top-level + /// html element + /// + private XmlElement ParseHtmlContent() + { + // Create artificial root elelemt to be able to group multiple top-level elements + // We create "html" element which may be a duplicate of real HTML element, which is ok, as HtmlConverter will swallow it painlessly.. + var htmlRootElement = _document.CreateElement("html", XhtmlNamespace); + OpenStructuringElement(htmlRootElement); + + while (_htmlLexicalAnalyzer.NextTokenType != HtmlTokenType.Eof) + { + if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.OpeningTagStart) + { + _htmlLexicalAnalyzer.GetNextTagToken(); + if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.Name) + { + var htmlElementName = _htmlLexicalAnalyzer.NextToken.ToLower(); + _htmlLexicalAnalyzer.GetNextTagToken(); + + // Create an element + var htmlElement = _document.CreateElement(htmlElementName, XhtmlNamespace); + + // Parse element attributes + ParseAttributes(htmlElement); + + if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.EmptyTagEnd || + HtmlSchema.IsEmptyElement(htmlElementName)) + { + // It is an element without content (because of explicit slash or based on implicit knowledge aboout html) + AddEmptyElement(htmlElement); + } + else if (HtmlSchema.IsInlineElement(htmlElementName)) + { + // Elements known as formatting are pushed to some special + // pending stack, which allows them to be transferred + // over block tags - by doing this we convert + // overlapping tags into normal heirarchical element structure. + OpenInlineElement(htmlElement); + } + else if (HtmlSchema.IsBlockElement(htmlElementName) || + HtmlSchema.IsKnownOpenableElement(htmlElementName)) + { + // This includes no-scope elements + OpenStructuringElement(htmlElement); + } + } + } + else if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.ClosingTagStart) + { + _htmlLexicalAnalyzer.GetNextTagToken(); + if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.Name) + { + var htmlElementName = _htmlLexicalAnalyzer.NextToken.ToLower(); + + // Skip the name token. Assume that the following token is end of tag, + // but do not check this. If it is not true, we simply ignore one token + // - this is our recovery from bad xml in this case. + _htmlLexicalAnalyzer.GetNextTagToken(); + + CloseElement(htmlElementName); + } + } + else if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.Text) + { + AddTextContent(_htmlLexicalAnalyzer.NextToken); + } + else if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.Comment) + { + AddComment(_htmlLexicalAnalyzer.NextToken); + } + + _htmlLexicalAnalyzer.GetNextContentToken(); + } + + // Get rid of the artificial root element + if (htmlRootElement.FirstChild is XmlElement && + htmlRootElement.FirstChild == htmlRootElement.LastChild && + htmlRootElement.FirstChild.LocalName.ToLower() == "html") + { + htmlRootElement = (XmlElement) htmlRootElement.FirstChild; + } + + return htmlRootElement; + } + + private XmlElement CreateElementCopy(XmlElement htmlElement) + { + var htmlElementCopy = _document.CreateElement(htmlElement.LocalName, XhtmlNamespace); + for (var i = 0; i < htmlElement.Attributes.Count; i++) + { + var attribute = htmlElement.Attributes[i]; + htmlElementCopy.SetAttribute(attribute.Name, attribute.Value); + } + return htmlElementCopy; + } + + private void AddEmptyElement(XmlElement htmlEmptyElement) + { + InvariantAssert(_openedElements.Count > 0, + "AddEmptyElement: Stack of opened elements cannot be empty, as we have at least one artificial root element"); + var htmlParent = _openedElements.Peek(); + htmlParent.AppendChild(htmlEmptyElement); + } + + private void OpenInlineElement(XmlElement htmlInlineElement) + { + _pendingInlineElements.Push(htmlInlineElement); + } + + // Opens structurig element such as Div or Table etc. + private void OpenStructuringElement(XmlElement htmlElement) + { + // Close all pending inline elements + // All block elements are considered as delimiters for inline elements + // which forces all inline elements to be closed and re-opened in the following + // structural element (if any). + // By doing that we guarantee that all inline elements appear only within most nested blocks + if (HtmlSchema.IsBlockElement(htmlElement.LocalName)) + { + while (_openedElements.Count > 0 && HtmlSchema.IsInlineElement(_openedElements.Peek().LocalName)) + { + var htmlInlineElement = _openedElements.Pop(); + InvariantAssert(_openedElements.Count > 0, + "OpenStructuringElement: stack of opened elements cannot become empty here"); + + _pendingInlineElements.Push(CreateElementCopy(htmlInlineElement)); + } + } + + // Add this block element to its parent + if (_openedElements.Count > 0) + { + var htmlParent = _openedElements.Peek(); + + // Check some known block elements for auto-closing (LI and P) + if (HtmlSchema.ClosesOnNextElementStart(htmlParent.LocalName, htmlElement.LocalName)) + { + _openedElements.Pop(); + htmlParent = _openedElements.Count > 0 ? _openedElements.Peek() : null; + } + + // NOTE: + // Actually we never expect null - it would mean two top-level P or LI (without a parent). + // In such weird case we will loose all paragraphs except the first one... + htmlParent?.AppendChild(htmlElement); + } + + // Push it onto a stack + _openedElements.Push(htmlElement); + } + + private bool IsElementOpened(string htmlElementName) => _openedElements.Any(openedElement => openedElement.LocalName == htmlElementName); + + private void CloseElement(string htmlElementName) + { + // Check if the element is opened and already added to the parent + InvariantAssert(_openedElements.Count > 0, + "CloseElement: Stack of opened elements cannot be empty, as we have at least one artificial root element"); + + // Check if the element is opened and still waiting to be added to the parent + if (_pendingInlineElements.Count > 0 && _pendingInlineElements.Peek().LocalName == htmlElementName) + { + // Closing an empty inline element. + // Note that HtmlConverter will skip empty inlines, but for completeness we keep them here on parser level. + var htmlInlineElement = _pendingInlineElements.Pop(); + InvariantAssert(_openedElements.Count > 0, + "CloseElement: Stack of opened elements cannot be empty, as we have at least one artificial root element"); + var htmlParent = _openedElements.Peek(); + htmlParent.AppendChild(htmlInlineElement); + } + else if (IsElementOpened(htmlElementName)) + { + while (_openedElements.Count > 1) // we never pop the last element - the artificial root + { + // Close all unbalanced elements. + var htmlOpenedElement = _openedElements.Pop(); + + if (htmlOpenedElement.LocalName == htmlElementName) + { + return; + } + + if (HtmlSchema.IsInlineElement(htmlOpenedElement.LocalName)) + { + // Unbalances Inlines will be transfered to the next element content + _pendingInlineElements.Push(CreateElementCopy(htmlOpenedElement)); + } + } + } + + // If element was not opened, we simply ignore the unbalanced closing tag + } + + private void AddTextContent(string textContent) + { + OpenPendingInlineElements(); + + InvariantAssert(_openedElements.Count > 0, + "AddTextContent: Stack of opened elements cannot be empty, as we have at least one artificial root element"); + + var htmlParent = _openedElements.Peek(); + var textNode = _document.CreateTextNode(textContent); + htmlParent.AppendChild(textNode); + } + + private void AddComment(string comment) + { + OpenPendingInlineElements(); + + InvariantAssert(_openedElements.Count > 0, + "AddComment: Stack of opened elements cannot be empty, as we have at least one artificial root element"); + + var htmlParent = _openedElements.Peek(); + var xmlComment = _document.CreateComment(comment); + htmlParent.AppendChild(xmlComment); + } + + // Moves all inline elements pending for opening to actual document + // and adds them to current open stack. + private void OpenPendingInlineElements() + { + if (_pendingInlineElements.Count > 0) + { + var htmlInlineElement = _pendingInlineElements.Pop(); + + OpenPendingInlineElements(); + + InvariantAssert(_openedElements.Count > 0, + "OpenPendingInlineElements: Stack of opened elements cannot be empty, as we have at least one artificial root element"); + + var htmlParent = _openedElements.Peek(); + htmlParent.AppendChild(htmlInlineElement); + _openedElements.Push(htmlInlineElement); + } + } + + private void ParseAttributes(XmlElement xmlElement) + { + while (_htmlLexicalAnalyzer.NextTokenType != HtmlTokenType.Eof && // + _htmlLexicalAnalyzer.NextTokenType != HtmlTokenType.TagEnd && // + _htmlLexicalAnalyzer.NextTokenType != HtmlTokenType.EmptyTagEnd) + { + // read next attribute (name=value) + if (_htmlLexicalAnalyzer.NextTokenType == HtmlTokenType.Name) + { + var attributeName = _htmlLexicalAnalyzer.NextToken; + _htmlLexicalAnalyzer.GetNextEqualSignToken(); + + _htmlLexicalAnalyzer.GetNextAtomToken(); + + var attributeValue = _htmlLexicalAnalyzer.NextToken; + xmlElement.SetAttribute(attributeName, attributeValue); + } + _htmlLexicalAnalyzer.GetNextTagToken(); + } + } + + #endregion Private Methods + + // --------------------------------------------------------------------- + // + // Private Fields + // + // --------------------------------------------------------------------- + + #region Private Fields + + internal const string XhtmlNamespace = "http://www.w3.org/1999/xhtml"; + + private readonly HtmlLexicalAnalyzer _htmlLexicalAnalyzer; + + // document from which all elements are created + private readonly XmlDocument _document; + + // stack for open elements + private readonly Stack _openedElements; + private readonly Stack _pendingInlineElements; + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Converters/HtmlSchema.cs b/JRCookbookBusiness/Converters/HtmlSchema.cs new file mode 100644 index 0000000..b698dde --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlSchema.cs @@ -0,0 +1,733 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections; +using System.Diagnostics; + +namespace HtmlToXamlDemo +{ + /// + /// HtmlSchema class + /// maintains static information about HTML structure + /// can be used by HtmlParser to check conditions under which an element starts or ends, etc. + /// + internal class HtmlSchema + { + // --------------------------------------------------------------------- + // + // Constructors + // + // --------------------------------------------------------------------- + + #region Constructors + + /// + /// static constructor, initializes the ArrayLists + /// that hold the elements in various sub-components of the schema + /// e.g _htmlEmptyElements, etc. + /// + static HtmlSchema() + { + // initializes the list of all html elements + InitializeInlineElements(); + + InitializeBlockElements(); + + InitializeOtherOpenableElements(); + + // initialize empty elements list + InitializeEmptyElements(); + + // initialize list of elements closing on the outer element end + InitializeElementsClosingOnParentElementEnd(); + + // initalize list of elements that close when a new element starts + InitializeElementsClosingOnNewElementStart(); + + // Initialize character entities + InitializeHtmlCharacterEntities(); + } + + #endregion Constructors; + + // --------------------------------------------------------------------- + // + // Internal Methods + // + // --------------------------------------------------------------------- + + #region Internal Methods + + /// + /// returns true when xmlElementName corresponds to empty element + /// + /// + /// string representing name to test + /// + internal static bool IsEmptyElement(string xmlElementName) => _htmlEmptyElements.Contains(xmlElementName.ToLower()); + + /// + /// returns true if xmlElementName represents a block formattinng element. + /// It used in an algorithm of transferring inline elements over block elements + /// in HtmlParser + /// + /// + /// + internal static bool IsBlockElement(string xmlElementName) => _htmlBlockElements.Contains(xmlElementName); + + /// + /// returns true if the xmlElementName represents an inline formatting element + /// + /// + /// + internal static bool IsInlineElement(string xmlElementName) => _htmlInlineElements.Contains(xmlElementName); + + /// + /// It is a list of known html elements which we + /// want to allow to produce bt HTML parser, + /// but don'tt want to act as inline, block or no-scope. + /// Presence in this list will allow to open + /// elements during html parsing, and adding the + /// to a tree produced by html parser. + /// + internal static bool IsKnownOpenableElement(string xmlElementName) => _htmlOtherOpenableElements.Contains(xmlElementName); + + /// + /// returns true when xmlElementName closes when the outer element closes + /// this is true of elements with optional start tags + /// + /// + /// string representing name to test + /// + internal static bool ClosesOnParentElementEnd(string xmlElementName) => _htmlElementsClosingOnParentElementEnd.Contains(xmlElementName.ToLower()); + + /// + /// returns true if the current element closes when the new element, whose name has just been read, starts + /// + /// + /// string representing current element name + /// + /// + /// string representing name of the next element that will start + internal static bool ClosesOnNextElementStart(string currentElementName, string nextElementName) + { + Debug.Assert(currentElementName == currentElementName.ToLower()); + switch (currentElementName) + { + case "colgroup": + return _htmlElementsClosingColgroup.Contains(nextElementName) && IsBlockElement(nextElementName); + case "dd": + return _htmlElementsClosingDd.Contains(nextElementName) && IsBlockElement(nextElementName); + case "dt": + return _htmlElementsClosingDt.Contains(nextElementName) && IsBlockElement(nextElementName); + case "li": + return _htmlElementsClosingLi.Contains(nextElementName); + case "p": + return IsBlockElement(nextElementName); + case "tbody": + return _htmlElementsClosingTbody.Contains(nextElementName); + case "tfoot": + return _htmlElementsClosingTfoot.Contains(nextElementName); + case "thead": + return _htmlElementsClosingThead.Contains(nextElementName); + case "tr": + return _htmlElementsClosingTr.Contains(nextElementName); + case "td": + return _htmlElementsClosingTd.Contains(nextElementName); + case "th": + return _htmlElementsClosingTh.Contains(nextElementName); + } + return false; + } + + /// + /// returns true if the string passed as argument is an Html entity name + /// + /// + /// string to be tested for Html entity name + /// + internal static bool IsEntity(string entityName) + { + // we do not convert entity strings to lowercase because these names are case-sensitive + if (_htmlCharacterEntities.Contains(entityName)) + { + return true; + } + return false; + } + + /// + /// returns the character represented by the entity name string which is passed as an argument, if the string is an + /// entity name + /// as specified in _htmlCharacterEntities, returns the character value of 0 otherwise + /// + /// + /// string representing entity name whose character value is desired + /// + internal static char EntityCharacterValue(string entityName) + { + if (_htmlCharacterEntities.Contains(entityName)) + { + return (char) _htmlCharacterEntities[entityName]; + } + return (char) 0; + } + + #endregion Internal Methods + + // --------------------------------------------------------------------- + // + // Internal Properties + // + // --------------------------------------------------------------------- + + #region Internal Properties + + #endregion Internal Indexers + + // --------------------------------------------------------------------- + // + // Private Methods + // + // --------------------------------------------------------------------- + + #region Private Methods + + private static void InitializeInlineElements() + { + _htmlInlineElements = new ArrayList + { + "a", + "abbr", + "acronym", + "address", + "b", + "bdo", + "big", + "button", + "code", + "del", + "dfn", + "em", + "font", + "i", + "ins", + "kbd", + "label", + "legend", + "q", + "s", + "samp", + "small", + "span", + "strike", + "strong", + "sub", + "sup", + "u", + "var" + }; + // ??? + // deleted text + // inserted text + // text to entered by a user + // ??? + // short inline quotation + // strike-through text style + // Specifies a code sample + // indicates an instance of a program variable + } + + private static void InitializeBlockElements() + { + _htmlBlockElements = new ArrayList + { + "blockquote", + "body", + "caption", + "center", + "cite", + "dd", + "dir", + "div", + "dl", + "dt", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "html", + "li", + "menu", + "ol", + "p", + "pre", + "table", + "tbody", + "td", + "textarea", + "tfoot", + "th", + "thead", + "tr", + "tt", + "ul" + }; + + // treat as UL element + // Not a block according to XHTML spec + // treat as UL element + // Renders text in a fixed-width font + } + + /// + /// initializes _htmlEmptyElements with empty elements in HTML 4 spec at + /// http://www.w3.org/TR/REC-html40/index/elements.html + /// + private static void InitializeEmptyElements() + { + // Build a list of empty (no-scope) elements + // (element not requiring closing tags, and not accepting any content) + _htmlEmptyElements = new ArrayList + { + "area", + "base", + "basefont", + "br", + "col", + "frame", + "hr", + "img", + "input", + "isindex", + "link", + "meta", + "param" + }; + } + + private static void InitializeOtherOpenableElements() + { + // It is a list of known html elements which we + // want to allow to produce bt HTML parser, + // but don'tt want to act as inline, block or no-scope. + // Presence in this list will allow to open + // elements during html parsing, and adding the + // to a tree produced by html parser. + _htmlOtherOpenableElements = new ArrayList + { + "applet", + "base", + "basefont", + "colgroup", + "fieldset", + "frameset", + "head", + "iframe", + "map", + "noframes", + "noscript", + "object", + "optgroup", + "option", + "script", + "select", + "style", + "title" + }; + //_htmlOtherOpenableElements.Add("form"); --> treated as block + } + + /// + /// initializes _htmlElementsClosingOnParentElementEnd with the list of HTML 4 elements for which closing tags are + /// optional + /// we assume that for any element for which closing tags are optional, the element closes when it's outer element + /// (in which it is nested) does + /// + private static void InitializeElementsClosingOnParentElementEnd() + { + _htmlElementsClosingOnParentElementEnd = new ArrayList + { + "body", + "colgroup", + "dd", + "dt", + "head", + "html", + "li", + "p", + "tbody", + "td", + "tfoot", + "thead", + "th", + "tr" + }; + } + + private static void InitializeElementsClosingOnNewElementStart() + { + _htmlElementsClosingColgroup = new ArrayList {"colgroup", "tr", "thead", "tfoot", "tbody"}; + + _htmlElementsClosingDd = new ArrayList {"dd", "dt"}; + // TODO: dd may end in other cases as well - if a new "p" starts, etc. + // TODO: these are the basic "legal" cases but there may be more recovery + + _htmlElementsClosingDt = new ArrayList(); + _htmlElementsClosingDd.Add("dd"); + _htmlElementsClosingDd.Add("dt"); + // TODO: dd may end in other cases as well - if a new "p" starts, etc. + // TODO: these are the basic "legal" cases but there may be more recovery + + _htmlElementsClosingLi = new ArrayList {"li"}; + // TODO: more complex recovery + + _htmlElementsClosingTbody = new ArrayList {"tbody", "thead", "tfoot"}; + // TODO: more complex recovery + + _htmlElementsClosingTr = new ArrayList {"thead", "tfoot", "tbody", "tr"}; + // NOTE: tr should not really close on a new thead + // because if there are rows before a thead, it is assumed to be in tbody, whose start tag is optional + // and thead can't come after tbody + // however, if we do encounter this, it's probably best to end the row and ignore the thead or treat + // it as part of the table + // TODO: more complex recovery + + _htmlElementsClosingTd = new ArrayList {"td", "th", "tr", "tbody", "tfoot", "thead"}; + // TODO: more complex recovery + + _htmlElementsClosingTh = new ArrayList {"td", "th", "tr", "tbody", "tfoot", "thead"}; + // TODO: more complex recovery + + _htmlElementsClosingThead = new ArrayList {"tbody", "tfoot"}; + // TODO: more complex recovery + + _htmlElementsClosingTfoot = new ArrayList {"tbody", "thead"}; + // although thead comes before tfoot, we add it because if it is found the tfoot should close + // and some recovery processing be done on the thead + // TODO: more complex recovery + } + + /// + /// initializes _htmlCharacterEntities hashtable with the character corresponding to entity names + /// + private static void InitializeHtmlCharacterEntities() + { + _htmlCharacterEntities = new Hashtable + { + ["Aacute"] = (char) 193, + ["aacute"] = (char) 225, + ["Acirc"] = (char) 194, + ["acirc"] = (char) 226, + ["acute"] = (char) 180, + ["AElig"] = (char) 198, + ["aelig"] = (char) 230, + ["Agrave"] = (char) 192, + ["agrave"] = (char) 224, + ["alefsym"] = (char) 8501, + ["Alpha"] = (char) 913, + ["alpha"] = (char) 945, + ["amp"] = (char) 38, + ["and"] = (char) 8743, + ["ang"] = (char) 8736, + ["Aring"] = (char) 197, + ["aring"] = (char) 229, + ["asymp"] = (char) 8776, + ["Atilde"] = (char) 195, + ["atilde"] = (char) 227, + ["Auml"] = (char) 196, + ["auml"] = (char) 228, + ["bdquo"] = (char) 8222, + ["Beta"] = (char) 914, + ["beta"] = (char) 946, + ["brvbar"] = (char) 166, + ["bull"] = (char) 8226, + ["cap"] = (char) 8745, + ["Ccedil"] = (char) 199, + ["ccedil"] = (char) 231, + ["cent"] = (char) 162, + ["Chi"] = (char) 935, + ["chi"] = (char) 967, + ["circ"] = (char) 710, + ["clubs"] = (char) 9827, + ["cong"] = (char) 8773, + ["copy"] = (char) 169, + ["crarr"] = (char) 8629, + ["cup"] = (char) 8746, + ["curren"] = (char) 164, + ["dagger"] = (char) 8224, + ["Dagger"] = (char) 8225, + ["darr"] = (char) 8595, + ["dArr"] = (char) 8659, + ["deg"] = (char) 176, + ["Delta"] = (char) 916, + ["delta"] = (char) 948, + ["diams"] = (char) 9830, + ["divide"] = (char) 247, + ["Eacute"] = (char) 201, + ["eacute"] = (char) 233, + ["Ecirc"] = (char) 202, + ["ecirc"] = (char) 234, + ["Egrave"] = (char) 200, + ["egrave"] = (char) 232, + ["empty"] = (char) 8709, + ["emsp"] = (char) 8195, + ["ensp"] = (char) 8194, + ["Epsilon"] = (char) 917, + ["epsilon"] = (char) 949, + ["equiv"] = (char) 8801, + ["Eta"] = (char) 919, + ["eta"] = (char) 951, + ["ETH"] = (char) 208, + ["eth"] = (char) 240, + ["Euml"] = (char) 203, + ["euml"] = (char) 235, + ["euro"] = (char) 8364, + ["exist"] = (char) 8707, + ["fnof"] = (char) 402, + ["forall"] = (char) 8704, + ["frac12"] = (char) 189, + ["frac14"] = (char) 188, + ["frac34"] = (char) 190, + ["frasl"] = (char) 8260, + ["Gamma"] = (char) 915, + ["gamma"] = (char) 947, + ["ge"] = (char) 8805, + ["gt"] = (char) 62, + ["harr"] = (char) 8596, + ["hArr"] = (char) 8660, + ["hearts"] = (char) 9829, + ["hellip"] = (char) 8230, + ["Iacute"] = (char) 205, + ["iacute"] = (char) 237, + ["Icirc"] = (char) 206, + ["icirc"] = (char) 238, + ["iexcl"] = (char) 161, + ["Igrave"] = (char) 204, + ["igrave"] = (char) 236, + ["image"] = (char) 8465, + ["infin"] = (char) 8734, + ["int"] = (char) 8747, + ["Iota"] = (char) 921, + ["iota"] = (char) 953, + ["iquest"] = (char) 191, + ["isin"] = (char) 8712, + ["Iuml"] = (char) 207, + ["iuml"] = (char) 239, + ["Kappa"] = (char) 922, + ["kappa"] = (char) 954, + ["Lambda"] = (char) 923, + ["lambda"] = (char) 955, + ["lang"] = (char) 9001, + ["laquo"] = (char) 171, + ["larr"] = (char) 8592, + ["lArr"] = (char) 8656, + ["lceil"] = (char) 8968, + ["ldquo"] = (char) 8220, + ["le"] = (char) 8804, + ["lfloor"] = (char) 8970, + ["lowast"] = (char) 8727, + ["loz"] = (char) 9674, + ["lrm"] = (char) 8206, + ["lsaquo"] = (char) 8249, + ["lsquo"] = (char) 8216, + ["lt"] = (char) 60, + ["macr"] = (char) 175, + ["mdash"] = (char) 8212, + ["micro"] = (char) 181, + ["middot"] = (char) 183, + ["minus"] = (char) 8722, + ["Mu"] = (char) 924, + ["mu"] = (char) 956, + ["nabla"] = (char) 8711, + ["nbsp"] = (char) 160, + ["ndash"] = (char) 8211, + ["ne"] = (char) 8800, + ["ni"] = (char) 8715, + ["not"] = (char) 172, + ["notin"] = (char) 8713, + ["nsub"] = (char) 8836, + ["Ntilde"] = (char) 209, + ["ntilde"] = (char) 241, + ["Nu"] = (char) 925, + ["nu"] = (char) 957, + ["Oacute"] = (char) 211, + ["ocirc"] = (char) 244, + ["OElig"] = (char) 338, + ["oelig"] = (char) 339, + ["Ograve"] = (char) 210, + ["ograve"] = (char) 242, + ["oline"] = (char) 8254, + ["Omega"] = (char) 937, + ["omega"] = (char) 969, + ["Omicron"] = (char) 927, + ["omicron"] = (char) 959, + ["oplus"] = (char) 8853, + ["or"] = (char) 8744, + ["ordf"] = (char) 170, + ["ordm"] = (char) 186, + ["Oslash"] = (char) 216, + ["oslash"] = (char) 248, + ["Otilde"] = (char) 213, + ["otilde"] = (char) 245, + ["otimes"] = (char) 8855, + ["Ouml"] = (char) 214, + ["ouml"] = (char) 246, + ["para"] = (char) 182, + ["part"] = (char) 8706, + ["permil"] = (char) 8240, + ["perp"] = (char) 8869, + ["Phi"] = (char) 934, + ["phi"] = (char) 966, + ["pi"] = (char) 960, + ["piv"] = (char) 982, + ["plusmn"] = (char) 177, + ["pound"] = (char) 163, + ["prime"] = (char) 8242, + ["Prime"] = (char) 8243, + ["prod"] = (char) 8719, + ["prop"] = (char) 8733, + ["Psi"] = (char) 936, + ["psi"] = (char) 968, + ["quot"] = (char) 34, + ["radic"] = (char) 8730, + ["rang"] = (char) 9002, + ["raquo"] = (char) 187, + ["rarr"] = (char) 8594, + ["rArr"] = (char) 8658, + ["rceil"] = (char) 8969, + ["rdquo"] = (char) 8221, + ["real"] = (char) 8476, + ["reg"] = (char) 174, + ["rfloor"] = (char) 8971, + ["Rho"] = (char) 929, + ["rho"] = (char) 961, + ["rlm"] = (char) 8207, + ["rsaquo"] = (char) 8250, + ["rsquo"] = (char) 8217, + ["sbquo"] = (char) 8218, + ["Scaron"] = (char) 352, + ["scaron"] = (char) 353, + ["sdot"] = (char) 8901, + ["sect"] = (char) 167, + ["shy"] = (char) 173, + ["Sigma"] = (char) 931, + ["sigma"] = (char) 963, + ["sigmaf"] = (char) 962, + ["sim"] = (char) 8764, + ["spades"] = (char) 9824, + ["sub"] = (char) 8834, + ["sube"] = (char) 8838, + ["sum"] = (char) 8721, + ["sup"] = (char) 8835, + ["sup1"] = (char) 185, + ["sup2"] = (char) 178, + ["sup3"] = (char) 179, + ["supe"] = (char) 8839, + ["szlig"] = (char) 223, + ["Tau"] = (char) 932, + ["tau"] = (char) 964, + ["there4"] = (char) 8756, + ["Theta"] = (char) 920, + ["theta"] = (char) 952, + ["thetasym"] = (char) 977, + ["thinsp"] = (char) 8201, + ["THORN"] = (char) 222, + ["thorn"] = (char) 254, + ["tilde"] = (char) 732, + ["times"] = (char) 215, + ["trade"] = (char) 8482, + ["Uacute"] = (char) 218, + ["uacute"] = (char) 250, + ["uarr"] = (char) 8593, + ["uArr"] = (char) 8657, + ["Ucirc"] = (char) 219, + ["ucirc"] = (char) 251, + ["Ugrave"] = (char) 217, + ["ugrave"] = (char) 249, + ["uml"] = (char) 168, + ["upsih"] = (char) 978, + ["Upsilon"] = (char) 933, + ["upsilon"] = (char) 965, + ["Uuml"] = (char) 220, + ["uuml"] = (char) 252, + ["weierp"] = (char) 8472, + ["Xi"] = (char) 926, + ["xi"] = (char) 958, + ["Yacute"] = (char) 221, + ["yacute"] = (char) 253, + ["yen"] = (char) 165, + ["Yuml"] = (char) 376, + ["yuml"] = (char) 255, + ["Zeta"] = (char) 918, + ["zeta"] = (char) 950, + ["zwj"] = (char) 8205, + ["zwnj"] = (char) 8204 + }; + } + + #endregion Private Methods + + // --------------------------------------------------------------------- + // + // Private Fields + // + // --------------------------------------------------------------------- + + #region Private Fields + + // html element names + // this is an array list now, but we may want to make it a hashtable later for better performance + private static ArrayList _htmlInlineElements; + + private static ArrayList _htmlBlockElements; + + private static ArrayList _htmlOtherOpenableElements; + + // list of html empty element names + private static ArrayList _htmlEmptyElements; + + // names of html elements for which closing tags are optional, and close when the outer nested element closes + private static ArrayList _htmlElementsClosingOnParentElementEnd; + + // names of elements that close certain optional closing tag elements when they start + + // names of elements closing the colgroup element + private static ArrayList _htmlElementsClosingColgroup; + + // names of elements closing the dd element + private static ArrayList _htmlElementsClosingDd; + + // names of elements closing the dt element + private static ArrayList _htmlElementsClosingDt; + + // names of elements closing the li element + private static ArrayList _htmlElementsClosingLi; + + // names of elements closing the tbody element + private static ArrayList _htmlElementsClosingTbody; + + // names of elements closing the td element + private static ArrayList _htmlElementsClosingTd; + + // names of elements closing the tfoot element + private static ArrayList _htmlElementsClosingTfoot; + + // names of elements closing the thead element + private static ArrayList _htmlElementsClosingThead; + + // names of elements closing the th element + private static ArrayList _htmlElementsClosingTh; + + // names of elements closing the tr element + private static ArrayList _htmlElementsClosingTr; + + // html character entities hashtable + private static Hashtable _htmlCharacterEntities; + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Converters/HtmlToXamlConverter.cs b/JRCookbookBusiness/Converters/HtmlToXamlConverter.cs new file mode 100644 index 0000000..11535b8 --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlToXamlConverter.cs @@ -0,0 +1,2765 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.Windows; +using System.Windows.Documents; +using System.Xml; + +namespace HtmlToXamlDemo +{ + // DependencyProperty + + // TextElement + + /// + /// HtmlToXamlConverter is a static class that takes an HTML string + /// and converts it into XAML + /// + public static class HtmlToXamlConverter + { + // ---------------------------------------------------------------- + // + // Internal Constants + // + // ---------------------------------------------------------------- + + // The constants reprtesent all Xaml names used in a conversion + public const string XamlFlowDocument = "FlowDocument"; + public const string XamlRun = "Run"; + public const string XamlSpan = "Span"; + public const string XamlHyperlink = "Hyperlink"; + public const string XamlHyperlinkNavigateUri = "NavigateUri"; + public const string XamlHyperlinkTargetName = "TargetName"; + public const string XamlSection = "Section"; + public const string XamlList = "List"; + public const string XamlListMarkerStyle = "MarkerStyle"; + public const string XamlListMarkerStyleNone = "None"; + public const string XamlListMarkerStyleDecimal = "Decimal"; + public const string XamlListMarkerStyleDisc = "Disc"; + public const string XamlListMarkerStyleCircle = "Circle"; + public const string XamlListMarkerStyleSquare = "Square"; + public const string XamlListMarkerStyleBox = "Box"; + public const string XamlListMarkerStyleLowerLatin = "LowerLatin"; + public const string XamlListMarkerStyleUpperLatin = "UpperLatin"; + public const string XamlListMarkerStyleLowerRoman = "LowerRoman"; + public const string XamlListMarkerStyleUpperRoman = "UpperRoman"; + public const string XamlListItem = "ListItem"; + public const string XamlLineBreak = "LineBreak"; + public const string XamlParagraph = "Paragraph"; + public const string XamlMargin = "Margin"; + public const string XamlPadding = "Padding"; + public const string XamlBorderBrush = "BorderBrush"; + public const string XamlBorderThickness = "BorderThickness"; + public const string XamlTable = "Table"; + // flowdocument table requires this element, take Table prefix because XMLReader cannot resolve the namespace of this element + public const string XamlTableColumnGroup = "Table.Columns"; + public const string XamlTableColumn = "TableColumn"; + public const string XamlTableRowGroup = "TableRowGroup"; + public const string XamlTableRow = "TableRow"; + public const string XamlTableCell = "TableCell"; + public const string XamlTableCellBorderThickness = "BorderThickness"; + public const string XamlTableCellBorderBrush = "BorderBrush"; + public const string XamlTableCellColumnSpan = "ColumnSpan"; + public const string XamlTableCellRowSpan = "RowSpan"; + public const string XamlWidth = "Width"; + public const string XamlBrushesBlack = "Black"; + public const string XamlFontFamily = "FontFamily"; + public const string XamlFontSize = "FontSize"; + public const string XamlFontSizeXxLarge = "22pt"; // "XXLarge"; + public const string XamlFontSizeXLarge = "20pt"; // "XLarge"; + public const string XamlFontSizeLarge = "18pt"; // "Large"; + public const string XamlFontSizeMedium = "16pt"; // "Medium"; + public const string XamlFontSizeSmall = "12pt"; // "Small"; + public const string XamlFontSizeXSmall = "10pt"; // "XSmall"; + public const string XamlFontSizeXxSmall = "8pt"; // "XXSmall"; + public const string XamlFontWeight = "FontWeight"; + public const string XamlFontWeightBold = "Bold"; + public const string XamlFontStyle = "FontStyle"; + public const string XamlForeground = "Foreground"; + public const string XamlBackground = "Background"; + public const string XamlTextDecorations = "TextDecorations"; + public const string XamlTextDecorationsUnderline = "Underline"; + public const string XamlTextIndent = "TextIndent"; + public const string XamlTextAlignment = "TextAlignment"; + // --------------------------------------------------------------------- + // + // Private Fields + // + // --------------------------------------------------------------------- + + #region Private Fields + + private static readonly string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; + + #endregion Private Fields + + // --------------------------------------------------------------------- + // + // Internal Methods + // + // --------------------------------------------------------------------- + + #region Internal Methods + + /// + /// Converts an html string into xaml string. + /// + /// + /// Input html which may be badly formated xml. + /// + /// + /// true indicates that we need a FlowDocument as a root element; + /// false means that Section or Span elements will be used + /// dependeing on StartFragment/EndFragment comments locations. + /// + /// + /// Well-formed xml representing XAML equivalent for the input html string. + /// + public static string ConvertHtmlToXaml(string htmlString, bool asFlowDocument) + { + // Create well-formed Xml from Html string + var htmlElement = HtmlParser.ParseHtml(htmlString); + + // Decide what name to use as a root + var rootElementName = asFlowDocument ? XamlFlowDocument : XamlSection; + + // Create an XmlDocument for generated xaml + var xamlTree = new XmlDocument(); + var xamlFlowDocumentElement = xamlTree.CreateElement(null, rootElementName, XamlNamespace); + + // Extract style definitions from all STYLE elements in the document + var stylesheet = new CssStylesheet(htmlElement); + + // Source context is a stack of all elements - ancestors of a parentElement + var sourceContext = new List(10); + + // Clear fragment parent + _inlineFragmentParentElement = null; + + // convert root html element + AddBlock(xamlFlowDocumentElement, htmlElement, new Hashtable(), stylesheet, sourceContext); + + // In case if the selected fragment is inline, extract it into a separate Span wrapper + if (!asFlowDocument) + { + xamlFlowDocumentElement = ExtractInlineFragment(xamlFlowDocumentElement); + } + + // Return a string representing resulting Xaml + xamlFlowDocumentElement.SetAttribute("xml:space", "preserve"); + var xaml = xamlFlowDocumentElement.OuterXml; + + return xaml; + } + + /// + /// Returns a value for an attribute by its name (ignoring casing) + /// + /// + /// XmlElement in which we are trying to find the specified attribute + /// + /// + /// String representing the attribute name to be searched for + /// + /// + public static string GetAttribute(XmlElement element, string attributeName) + { + attributeName = attributeName.ToLower(); + + for (var i = 0; i < element.Attributes.Count; i++) + { + if (element.Attributes[i].Name.ToLower() == attributeName) + { + return element.Attributes[i].Value; + } + } + + return null; + } + + /// + /// Returns string extracted from quotation marks + /// + /// + /// String representing value enclosed in quotation marks + /// + internal static string UnQuote(string value) + { + if (value.StartsWith("\"") && value.EndsWith("\"") || value.StartsWith("'") && value.EndsWith("'")) + { + value = value.Substring(1, value.Length - 2).Trim(); + } + return value; + } + + #endregion Internal Methods + + // --------------------------------------------------------------------- + // + // Private Methods + // + // --------------------------------------------------------------------- + + #region Private Methods + + /// + /// Analyzes the given htmlElement expecting it to be converted + /// into some of xaml Block elements and adds the converted block + /// to the children collection of xamlParentElement. + /// Analyzes the given XmlElement htmlElement, recognizes it as some HTML element + /// and adds it as a child to a xamlParentElement. + /// In some cases several following siblings of the given htmlElement + /// will be consumed too (e.g. LIs encountered without wrapping UL/OL, + /// which must be collected together and wrapped into one implicit List element). + /// + /// + /// Parent xaml element, to which new converted element will be added + /// + /// + /// Source html element subject to convert to xaml. + /// + /// + /// Properties inherited from an outer context. + /// + /// + /// + /// + /// Last processed html node. Normally it should be the same htmlElement + /// as was passed as a paramater, but in some irregular cases + /// it could one of its following siblings. + /// The caller must use this node to get to next sibling from it. + /// + private static XmlNode AddBlock(XmlElement xamlParentElement, XmlNode htmlNode, Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + if (htmlNode is XmlComment) + { + DefineInlineFragmentParent((XmlComment) htmlNode, /*xamlParentElement:*/null); + } + else if (htmlNode is XmlText) + { + htmlNode = AddImplicitParagraph(xamlParentElement, htmlNode, inheritedProperties, stylesheet, + sourceContext); + } + else if (htmlNode is XmlElement) + { + // Identify element name + var htmlElement = (XmlElement) htmlNode; + + var htmlElementName = htmlElement.LocalName; // Keep the name case-sensitive to check xml names + var htmlElementNamespace = htmlElement.NamespaceURI; + + if (htmlElementNamespace != HtmlParser.XhtmlNamespace) + { + // Non-html element. skip it + // Isn't it too agressive? What if this is just an error in html tag name? + // TODO: Consider skipping just a wparrer in recursing into the element tree, + // which may produce some garbage though coming from xml fragments. + return htmlElement; + } + + // Put source element to the stack + sourceContext.Add(htmlElement); + + // Convert the name to lowercase, because html elements are case-insensitive + htmlElementName = htmlElementName.ToLower(); + + // Switch to an appropriate kind of processing depending on html element name + switch (htmlElementName) + { + // Sections: + case "html": + case "body": + case "div": + case "form": // not a block according to xhtml spec + case "pre": // Renders text in a fixed-width font + case "blockquote": + case "caption": + case "center": + case "cite": + AddSection(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + break; + + // Paragraphs: + case "p": + case "h1": + case "h2": + case "h3": + case "h4": + case "h5": + case "h6": + case "nsrtitle": + case "textarea": + case "dd": // ??? + case "dl": // ??? + case "dt": // ??? + case "tt": // ??? + AddParagraph(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + break; + + case "ol": + case "ul": + case "dir": // treat as UL element + case "menu": // treat as UL element + // List element conversion + AddList(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + break; + case "li": + // LI outside of OL/UL + // Collect all sibling LIs, wrap them into a List and then proceed with the element following the last of LIs + htmlNode = AddOrphanListItems(xamlParentElement, htmlElement, inheritedProperties, stylesheet, + sourceContext); + break; + + case "img": + // TODO: Add image processing + AddImage(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + break; + + case "table": + // hand off to table parsing function which will perform special table syntax checks + AddTable(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + break; + + case "tbody": + case "tfoot": + case "thead": + case "tr": + case "td": + case "th": + // Table stuff without table wrapper + // TODO: add special-case processing here for elements that should be within tables when the + // parent element is NOT a table. If the parent element is a table they can be processed normally. + // we need to compare against the parent element here, we can't just break on a switch + goto default; // Thus we will skip this element as unknown, but still recurse into it. + + case "style": // We already pre-processed all style elements. Ignore it now + case "meta": + case "head": + case "title": + case "script": + // Ignore these elements + break; + + default: + // Wrap a sequence of inlines into an implicit paragraph + htmlNode = AddImplicitParagraph(xamlParentElement, htmlElement, inheritedProperties, stylesheet, + sourceContext); + break; + } + + // Remove the element from the stack + Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlElement); + sourceContext.RemoveAt(sourceContext.Count - 1); + } + + // Return last processed node + return htmlNode; + } + + // ............................................................. + // + // Line Breaks + // + // ............................................................. + + private static void AddBreak(XmlElement xamlParentElement, string htmlElementName) + { + // Create new xaml element corresponding to this html element + var xamlLineBreak = xamlParentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/XamlLineBreak, XamlNamespace); + xamlParentElement.AppendChild(xamlLineBreak); + if (htmlElementName == "hr") + { + var xamlHorizontalLine = xamlParentElement.OwnerDocument.CreateTextNode("----------------------"); + xamlParentElement.AppendChild(xamlHorizontalLine); + xamlLineBreak = xamlParentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/XamlLineBreak, XamlNamespace); + xamlParentElement.AppendChild(xamlLineBreak); + } + } + + // ............................................................. + // + // Text Flow Elements + // + // ............................................................. + + /// + /// Generates Section or Paragraph element from DIV depending whether it contains any block elements or not + /// + /// + /// XmlElement representing Xaml parent to which the converted element should be added + /// + /// + /// XmlElement representing Html element to be converted + /// + /// + /// properties inherited from parent context + /// + /// + /// + /// true indicates that a content added by this call contains at least one block element + /// + private static void AddSection(XmlElement xamlParentElement, XmlElement htmlElement, + Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + // Analyze the content of htmlElement to decide what xaml element to choose - Section or Paragraph. + // If this Div has at least one block child then we need to use Section, otherwise use Paragraph + var htmlElementContainsBlocks = false; + for (var htmlChildNode = htmlElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + if (htmlChildNode is XmlElement) + { + var htmlChildName = ((XmlElement) htmlChildNode).LocalName.ToLower(); + if (HtmlSchema.IsBlockElement(htmlChildName)) + { + htmlElementContainsBlocks = true; + break; + } + } + } + + if (!htmlElementContainsBlocks) + { + // The Div does not contain any block elements, so we can treat it as a Paragraph + AddParagraph(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + } + else + { + // The Div has some nested blocks, so we treat it as a Section + + // Create currentProperties as a compilation of local and inheritedProperties, set localProperties + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, + stylesheet, + sourceContext); + + // Create a XAML element corresponding to this html element + var xamlElement = xamlParentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/XamlSection, XamlNamespace); + ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/true); + + // Decide whether we can unwrap this element as not having any formatting significance. + if (!xamlElement.HasAttributes) + { + // This elements is a group of block elements whitout any additional formatting. + // We can add blocks directly to xamlParentElement and avoid + // creating unnecessary Sections nesting. + xamlElement = xamlParentElement; + } + + // Recurse into element subtree + for (var htmlChildNode = htmlElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode?.NextSibling) + { + htmlChildNode = AddBlock(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); + } + + // Add the new element to the parent. + if (xamlElement != xamlParentElement) + { + xamlParentElement.AppendChild(xamlElement); + } + } + } + + /// + /// Generates Paragraph element from P, H1-H7, Center etc. + /// + /// + /// XmlElement representing Xaml parent to which the converted element should be added + /// + /// + /// XmlElement representing Html element to be converted + /// + /// + /// properties inherited from parent context + /// + /// + /// + /// true indicates that a content added by this call contains at least one block element + /// + private static void AddParagraph(XmlElement xamlParentElement, XmlElement htmlElement, + Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + // Create currentProperties as a compilation of local and inheritedProperties, set localProperties + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, + stylesheet, + sourceContext); + + // Create a XAML element corresponding to this html element + var xamlElement = xamlParentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/XamlParagraph, XamlNamespace); + ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/true); + + // Recurse into element subtree + for (var htmlChildNode = htmlElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + AddInline(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); + } + + // Add the new element to the parent. + xamlParentElement.AppendChild(xamlElement); + } + + /// + /// Creates a Paragraph element and adds all nodes starting from htmlNode + /// converted to appropriate Inlines. + /// + /// + /// XmlElement representing Xaml parent to which the converted element should be added + /// + /// + /// XmlNode starting a collection of implicitly wrapped inlines. + /// + /// + /// properties inherited from parent context + /// + /// + /// + /// true indicates that a content added by this call contains at least one block element + /// + /// + /// The last htmlNode added to the implicit paragraph + /// + private static XmlNode AddImplicitParagraph(XmlElement xamlParentElement, XmlNode htmlNode, + Hashtable inheritedProperties, CssStylesheet stylesheet, List sourceContext) + { + // Collect all non-block elements and wrap them into implicit Paragraph + var xamlParagraph = xamlParentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/XamlParagraph, XamlNamespace); + XmlNode lastNodeProcessed = null; + while (htmlNode != null) + { + if (htmlNode is XmlComment) + { + DefineInlineFragmentParent((XmlComment) htmlNode, /*xamlParentElement:*/null); + } + else if (htmlNode is XmlText) + { + if (htmlNode.Value.Trim().Length > 0) + { + AddTextRun(xamlParagraph, htmlNode.Value); + } + } + else if (htmlNode is XmlElement) + { + var htmlChildName = ((XmlElement) htmlNode).LocalName.ToLower(); + if (HtmlSchema.IsBlockElement(htmlChildName)) + { + // The sequence of non-blocked inlines ended. Stop implicit loop here. + break; + } + AddInline(xamlParagraph, (XmlElement) htmlNode, inheritedProperties, stylesheet, sourceContext); + } + + // Store last processed node to return it at the end + lastNodeProcessed = htmlNode; + htmlNode = htmlNode.NextSibling; + } + + // Add the Paragraph to the parent + // If only whitespaces and commens have been encountered, + // then we have nothing to add in implicit paragraph; forget it. + if (xamlParagraph.FirstChild != null) + { + xamlParentElement.AppendChild(xamlParagraph); + } + + // Need to return last processed node + return lastNodeProcessed; + } + + // ............................................................. + // + // Inline Elements + // + // ............................................................. + + private static void AddInline(XmlElement xamlParentElement, XmlNode htmlNode, Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + if (htmlNode is XmlComment) + { + DefineInlineFragmentParent((XmlComment) htmlNode, xamlParentElement); + } + else if (htmlNode is XmlText) + { + AddTextRun(xamlParentElement, htmlNode.Value); + } + else if (htmlNode is XmlElement) + { + var htmlElement = (XmlElement) htmlNode; + + // Check whether this is an html element + if (htmlElement.NamespaceURI != HtmlParser.XhtmlNamespace) + { + return; // Skip non-html elements + } + + // Identify element name + var htmlElementName = htmlElement.LocalName.ToLower(); + + // Put source element to the stack + sourceContext.Add(htmlElement); + + switch (htmlElementName) + { + case "a": + AddHyperlink(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + break; + case "img": + AddImage(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + break; + case "br": + case "hr": + AddBreak(xamlParentElement, htmlElementName); + break; + default: + if (HtmlSchema.IsInlineElement(htmlElementName) || HtmlSchema.IsBlockElement(htmlElementName)) + { + // Note: actually we do not expect block elements here, + // but if it happens to be here, we will treat it as a Span. + + AddSpanOrRun(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + } + break; + } + // Ignore all other elements non-(block/inline/image) + + // Remove the element from the stack + Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlElement); + sourceContext.RemoveAt(sourceContext.Count - 1); + } + } + + private static void AddSpanOrRun(XmlElement xamlParentElement, XmlElement htmlElement, + Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + // Decide what XAML element to use for this inline element. + // Check whether it contains any nested inlines + var elementHasChildren = false; + for (var htmlNode = htmlElement.FirstChild; htmlNode != null; htmlNode = htmlNode.NextSibling) + { + if (htmlNode is XmlElement) + { + var htmlChildName = ((XmlElement) htmlNode).LocalName.ToLower(); + if (HtmlSchema.IsInlineElement(htmlChildName) || HtmlSchema.IsBlockElement(htmlChildName) || + htmlChildName == "img" || htmlChildName == "br" || htmlChildName == "hr") + { + elementHasChildren = true; + break; + } + } + } + + var xamlElementName = elementHasChildren ? XamlSpan : XamlRun; + + // Create currentProperties as a compilation of local and inheritedProperties, set localProperties + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, + stylesheet, + sourceContext); + + // Create a XAML element corresponding to this html element + var xamlElement = xamlParentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/xamlElementName, XamlNamespace); + ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/false); + + // Recurse into element subtree + for (var htmlChildNode = htmlElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + AddInline(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); + } + + // Add the new element to the parent. + xamlParentElement.AppendChild(xamlElement); + } + + // Adds a text run to a xaml tree + private static void AddTextRun(XmlElement xamlElement, string textData) + { + // Remove control characters + for (var i = 0; i < textData.Length; i++) + { + if (char.IsControl(textData[i])) + { + textData = textData.Remove(i--, 1); // decrement i to compensate for character removal + } + } + + // Replace No-Breaks by spaces (160 is a code of   entity in html) + // This is a work around since WPF/XAML does not support  . + textData = textData.Replace((char) 160, ' '); + + if (textData.Length > 0) + { + xamlElement.AppendChild(xamlElement.OwnerDocument.CreateTextNode(textData)); + } + } + + private static void AddHyperlink(XmlElement xamlParentElement, XmlElement htmlElement, + Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + // Convert href attribute into NavigateUri and TargetName + var href = GetAttribute(htmlElement, "href"); + if (href == null) + { + // When href attribute is missing - ignore the hyperlink + AddSpanOrRun(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); + } + else + { + // Create currentProperties as a compilation of local and inheritedProperties, set localProperties + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, + stylesheet, + sourceContext); + + // Create a XAML element corresponding to this html element + var xamlElement = xamlParentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/XamlHyperlink, XamlNamespace); + ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/false); + + var hrefParts = href.Split('#'); + if (hrefParts.Length > 0 && hrefParts[0].Trim().Length > 0) + { + xamlElement.SetAttribute(XamlHyperlinkNavigateUri, hrefParts[0].Trim()); + } + if (hrefParts.Length == 2 && hrefParts[1].Trim().Length > 0) + { + xamlElement.SetAttribute(XamlHyperlinkTargetName, hrefParts[1].Trim()); + } + + // Recurse into element subtree + for (var htmlChildNode = htmlElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + AddInline(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); + } + + // Add the new element to the parent. + xamlParentElement.AppendChild(xamlElement); + } + } + + // Stores a parent xaml element for the case when selected fragment is inline. + private static XmlElement _inlineFragmentParentElement; + + // Called when html comment is encountered to store a parent element + // for the case when the fragment is inline - to extract it to a separate + // Span wrapper after the conversion. + private static void DefineInlineFragmentParent(XmlComment htmlComment, XmlElement xamlParentElement) + { + if (htmlComment.Value == "StartFragment") + { + _inlineFragmentParentElement = xamlParentElement; + } + else if (htmlComment.Value == "EndFragment") + { + if (_inlineFragmentParentElement == null && xamlParentElement != null) + { + // Normally this cannot happen if comments produced by correct copying code + // in Word or IE, but when it is produced manually then fragment boundary + // markers can be inconsistent. In this case StartFragment takes precedence, + // but if it is not set, then we get the value from EndFragment marker. + _inlineFragmentParentElement = xamlParentElement; + } + } + } + + // Extracts a content of an element stored as InlineFragmentParentElement + // into a separate Span wrapper. + // Note: when selected content does not cross paragraph boundaries, + // the fragment is marked within + private static XmlElement ExtractInlineFragment(XmlElement xamlFlowDocumentElement) + { + if (_inlineFragmentParentElement != null) + { + if (_inlineFragmentParentElement.LocalName == XamlSpan) + { + xamlFlowDocumentElement = _inlineFragmentParentElement; + } + else + { + xamlFlowDocumentElement = xamlFlowDocumentElement.OwnerDocument.CreateElement( /*prefix:*/ + null, /*localName:*/XamlSpan, XamlNamespace); + while (_inlineFragmentParentElement.FirstChild != null) + { + var copyNode = _inlineFragmentParentElement.FirstChild; + _inlineFragmentParentElement.RemoveChild(copyNode); + xamlFlowDocumentElement.AppendChild(copyNode); + } + } + } + + return xamlFlowDocumentElement; + } + + // ............................................................. + // + // Images + // + // ............................................................. + + private static void AddImage(XmlElement xamlParentElement, XmlElement htmlElement, Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + // Implement images + } + + // ............................................................. + // + // Lists + // + // ............................................................. + + /// + /// Converts Html ul or ol element into Xaml list element. During conversion if the ul/ol element has any children + /// that are not li elements, they are ignored and not added to the list element + /// + /// + /// XmlElement representing Xaml parent to which the converted element should be added + /// + /// + /// XmlElement representing Html ul/ol element to be converted + /// + /// + /// properties inherited from parent context + /// + /// + /// + private static void AddList(XmlElement xamlParentElement, XmlElement htmlListElement, + Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + var htmlListElementName = htmlListElement.LocalName.ToLower(); + + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlListElement, inheritedProperties, out localProperties, + stylesheet, sourceContext); + + // Create Xaml List element + var xamlListElement = xamlParentElement.OwnerDocument.CreateElement(null, XamlList, XamlNamespace); + + // Set default list markers + xamlListElement.SetAttribute(XamlListMarkerStyle, + htmlListElementName == "ol" ? XamlListMarkerStyleDecimal : XamlListMarkerStyleDisc); + + // Apply local properties to list to set marker attribute if specified + // TODO: Should we have separate list attribute processing function? + ApplyLocalProperties(xamlListElement, localProperties, /*isBlock:*/true); + + // Recurse into list subtree + for (var htmlChildNode = htmlListElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + if (htmlChildNode is XmlElement && htmlChildNode.LocalName.ToLower() == "li") + { + sourceContext.Add((XmlElement) htmlChildNode); + AddListItem(xamlListElement, (XmlElement) htmlChildNode, currentProperties, stylesheet, + sourceContext); + Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); + sourceContext.RemoveAt(sourceContext.Count - 1); + } + } + + // Add the List element to xaml tree - if it is not empty + if (xamlListElement.HasChildNodes) + { + xamlParentElement.AppendChild(xamlListElement); + } + } + + /// + /// If li items are found without a parent ul/ol element in Html string, creates xamlListElement as their parent and + /// adds + /// them to it. If the previously added node to the same xamlParentElement was a List, adds the elements to that list. + /// Otherwise, we create a new xamlListElement and add them to it. Elements are added as long as li elements appear + /// sequentially. + /// The first non-li or text node stops the addition. + /// + /// + /// Parent element for the list + /// + /// + /// Start Html li element without parent list + /// + /// + /// Properties inherited from parent context + /// + /// + /// XmlNode representing the first non-li node in the input after one or more li's have been processed. + /// + private static XmlElement AddOrphanListItems(XmlElement xamlParentElement, XmlElement htmlLiElement, + Hashtable inheritedProperties, CssStylesheet stylesheet, List sourceContext) + { + Debug.Assert(htmlLiElement.LocalName.ToLower() == "li"); + + XmlElement lastProcessedListItemElement = null; + + // Find out the last element attached to the xamlParentElement, which is the previous sibling of this node + var xamlListItemElementPreviousSibling = xamlParentElement.LastChild; + XmlElement xamlListElement; + if (xamlListItemElementPreviousSibling != null && xamlListItemElementPreviousSibling.LocalName == XamlList) + { + // Previously added Xaml element was a list. We will add the new li to it + xamlListElement = (XmlElement) xamlListItemElementPreviousSibling; + } + else + { + // No list element near. Create our own. + xamlListElement = xamlParentElement.OwnerDocument.CreateElement(null, XamlList, XamlNamespace); + xamlParentElement.AppendChild(xamlListElement); + } + + XmlNode htmlChildNode = htmlLiElement; + var htmlChildNodeName = htmlChildNode == null ? null : htmlChildNode.LocalName.ToLower(); + + // Current element properties missed here. + //currentProperties = GetElementProperties(htmlLIElement, inheritedProperties, out localProperties, stylesheet); + + // Add li elements to the parent xamlListElement we created as long as they appear sequentially + // Use properties inherited from xamlParentElement for context + while (htmlChildNode != null && htmlChildNodeName == "li") + { + AddListItem(xamlListElement, (XmlElement) htmlChildNode, inheritedProperties, stylesheet, sourceContext); + lastProcessedListItemElement = (XmlElement) htmlChildNode; + htmlChildNode = htmlChildNode.NextSibling; + htmlChildNodeName = htmlChildNode?.LocalName.ToLower(); + } + + return lastProcessedListItemElement; + } + + /// + /// Converts htmlLIElement into Xaml ListItem element, and appends it to the parent xamlListElement + /// + /// + /// XmlElement representing Xaml List element to which the converted td/th should be added + /// + /// + /// XmlElement representing Html li element to be converted + /// + /// + /// Properties inherited from parent context + /// + private static void AddListItem(XmlElement xamlListElement, XmlElement htmlLiElement, + Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + // Parameter validation + Debug.Assert(xamlListElement != null); + Debug.Assert(xamlListElement.LocalName == XamlList); + Debug.Assert(htmlLiElement != null); + Debug.Assert(htmlLiElement.LocalName.ToLower() == "li"); + Debug.Assert(inheritedProperties != null); + + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlLiElement, inheritedProperties, out localProperties, + stylesheet, sourceContext); + + var xamlListItemElement = xamlListElement.OwnerDocument.CreateElement(null, XamlListItem, + XamlNamespace); + + // TODO: process local properties for li element + + // Process children of the ListItem + for (var htmlChildNode = htmlLiElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode?.NextSibling) + { + htmlChildNode = AddBlock(xamlListItemElement, htmlChildNode, currentProperties, stylesheet, + sourceContext); + } + + // Add resulting ListBoxItem to a xaml parent + xamlListElement.AppendChild(xamlListItemElement); + } + + // ............................................................. + // + // Tables + // + // ............................................................. + + /// + /// Converts htmlTableElement to a Xaml Table element. Adds tbody elements if they are missing so + /// that a resulting Xaml Table element is properly formed. + /// + /// + /// Parent xaml element to which a converted table must be added. + /// + /// + /// XmlElement reprsenting the Html table element to be converted + /// + /// + /// Hashtable representing properties inherited from parent context. + /// + private static void AddTable(XmlElement xamlParentElement, XmlElement htmlTableElement, + Hashtable inheritedProperties, + CssStylesheet stylesheet, List sourceContext) + { + // Parameter validation + Debug.Assert(htmlTableElement.LocalName.ToLower() == "table"); + Debug.Assert(xamlParentElement != null); + Debug.Assert(inheritedProperties != null); + + // Create current properties to be used by children as inherited properties, set local properties + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlTableElement, inheritedProperties, + out localProperties, + stylesheet, sourceContext); + + // TODO: process localProperties for tables to override defaults, decide cell spacing defaults + + // Check if the table contains only one cell - we want to take only its content + var singleCell = GetCellFromSingleCellTable(htmlTableElement); + + if (singleCell != null) + { + // Need to push skipped table elements onto sourceContext + sourceContext.Add(singleCell); + + // Add the cell's content directly to parent + for (var htmlChildNode = singleCell.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode?.NextSibling) + { + htmlChildNode = AddBlock(xamlParentElement, htmlChildNode, currentProperties, stylesheet, + sourceContext); + } + + Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == singleCell); + sourceContext.RemoveAt(sourceContext.Count - 1); + } + else + { + // Create xamlTableElement + var xamlTableElement = xamlParentElement.OwnerDocument.CreateElement(null, XamlTable, + XamlNamespace); + + // Analyze table structure for column widths and rowspan attributes + var columnStarts = AnalyzeTableStructure(htmlTableElement, stylesheet); + + // Process COLGROUP & COL elements + AddColumnInformation(htmlTableElement, xamlTableElement, columnStarts, currentProperties, stylesheet, + sourceContext); + + // Process table body - TBODY and TR elements + var htmlChildNode = htmlTableElement.FirstChild; + + while (htmlChildNode != null) + { + var htmlChildName = htmlChildNode.LocalName.ToLower(); + + // Process the element + if (htmlChildName == "tbody" || htmlChildName == "thead" || htmlChildName == "tfoot") + { + // Add more special processing for TableHeader and TableFooter + var xamlTableBodyElement = xamlTableElement.OwnerDocument.CreateElement(null, + XamlTableRowGroup, + XamlNamespace); + xamlTableElement.AppendChild(xamlTableBodyElement); + + sourceContext.Add((XmlElement) htmlChildNode); + + // Get properties of Html tbody element + Hashtable tbodyElementLocalProperties; + var tbodyElementCurrentProperties = GetElementProperties((XmlElement) htmlChildNode, + currentProperties, + out tbodyElementLocalProperties, stylesheet, sourceContext); + // TODO: apply local properties for tbody + + // Process children of htmlChildNode, which is tbody, for tr elements + AddTableRowsToTableBody(xamlTableBodyElement, htmlChildNode.FirstChild, + tbodyElementCurrentProperties, + columnStarts, stylesheet, sourceContext); + if (xamlTableBodyElement.HasChildNodes) + { + xamlTableElement.AppendChild(xamlTableBodyElement); + // else: if there is no TRs in this TBody, we simply ignore it + } + + Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); + sourceContext.RemoveAt(sourceContext.Count - 1); + + htmlChildNode = htmlChildNode.NextSibling; + } + else if (htmlChildName == "tr") + { + // Tbody is not present, but tr element is present. Tr is wrapped in tbody + var xamlTableBodyElement = xamlTableElement.OwnerDocument.CreateElement(null, + XamlTableRowGroup, + XamlNamespace); + + // We use currentProperties of xamlTableElement when adding rows since the tbody element is artificially created and has + // no properties of its own + + htmlChildNode = AddTableRowsToTableBody(xamlTableBodyElement, htmlChildNode, currentProperties, + columnStarts, + stylesheet, sourceContext); + if (xamlTableBodyElement.HasChildNodes) + { + xamlTableElement.AppendChild(xamlTableBodyElement); + } + } + else + { + // Element is not tbody or tr. Ignore it. + // TODO: add processing for thead, tfoot elements and recovery for td elements + htmlChildNode = htmlChildNode.NextSibling; + } + } + + if (xamlTableElement.HasChildNodes) + { + xamlParentElement.AppendChild(xamlTableElement); + } + } + } + + private static XmlElement GetCellFromSingleCellTable(XmlElement htmlTableElement) + { + XmlElement singleCell = null; + + for (var tableChild = htmlTableElement.FirstChild; + tableChild != null; + tableChild = tableChild.NextSibling) + { + var elementName = tableChild.LocalName.ToLower(); + if (elementName == "tbody" || elementName == "thead" || elementName == "tfoot") + { + if (singleCell != null) + { + return null; + } + for (var tbodyChild = tableChild.FirstChild; + tbodyChild != null; + tbodyChild = tbodyChild.NextSibling) + { + if (tbodyChild.LocalName.ToLower() == "tr") + { + if (singleCell != null) + { + return null; + } + for (var trChild = tbodyChild.FirstChild; + trChild != null; + trChild = trChild.NextSibling) + { + var cellName = trChild.LocalName.ToLower(); + if (cellName == "td" || cellName == "th") + { + if (singleCell != null) + { + return null; + } + singleCell = (XmlElement) trChild; + } + } + } + } + } + else if (tableChild.LocalName.ToLower() == "tr") + { + if (singleCell != null) + { + return null; + } + for (var trChild = tableChild.FirstChild; trChild != null; trChild = trChild.NextSibling) + { + var cellName = trChild.LocalName.ToLower(); + if (cellName == "td" || cellName == "th") + { + if (singleCell != null) + { + return null; + } + singleCell = (XmlElement) trChild; + } + } + } + } + + return singleCell; + } + + /// + /// Processes the information about table columns - COLGROUP and COL html elements. + /// + /// + /// XmlElement representing a source html table. + /// + /// + /// XmlElement repesenting a resulting xaml table. + /// + /// + /// Array of doubles - column start coordinates. + /// Can be null, which means that column size information is not available + /// and we must use source colgroup/col information. + /// In case wneh it's not null, we will ignore source colgroup/col information. + /// + /// + /// + /// + private static void AddColumnInformation(XmlElement htmlTableElement, XmlElement xamlTableElement, + ArrayList columnStartsAllRows, Hashtable currentProperties, CssStylesheet stylesheet, + List sourceContext) + { + // Flow document table requires element to include element as + // defined in https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/how-to-define-a-table-with-xaml + // Notic: CreateElement("Table", "Columns", XamlNamespace) would add xmlns attribute to and lead to XMLReader crash. + XmlElement xamlTableColumnGroupElement = xamlTableElement.OwnerDocument.CreateElement(null, XamlTableColumnGroup, XamlNamespace); + // Add column information + if (columnStartsAllRows != null) + { + // We have consistent information derived from table cells; use it + // The last element in columnStarts represents the end of the table + for (var columnIndex = 0; columnIndex < columnStartsAllRows.Count - 1; columnIndex++) + { + XmlElement xamlColumnElement; + + xamlColumnElement = xamlTableColumnGroupElement.OwnerDocument.CreateElement(null, XamlTableColumn, + XamlNamespace); + xamlColumnElement.SetAttribute(XamlWidth, + ((double) columnStartsAllRows[columnIndex + 1] - (double) columnStartsAllRows[columnIndex]) + .ToString(CultureInfo.InvariantCulture)); + xamlTableColumnGroupElement.AppendChild(xamlColumnElement); + } + } + else + { + // We do not have consistent information from table cells; + // Translate blindly colgroups from html. + for (var htmlChildNode = htmlTableElement.FirstChild; + htmlChildNode != null; + htmlChildNode = htmlChildNode.NextSibling) + { + if (htmlChildNode.LocalName.ToLower() == "colgroup") + { + // TODO: add column width information to this function as a parameter and process it + AddTableColumnGroup(xamlTableColumnGroupElement, (XmlElement) htmlChildNode, currentProperties, stylesheet, + sourceContext); + } + else if (htmlChildNode.LocalName.ToLower() == "col") + { + AddTableColumn(xamlTableColumnGroupElement, (XmlElement) htmlChildNode, currentProperties, stylesheet, + sourceContext); + } + else if (htmlChildNode is XmlElement) + { + // Some element which belongs to table body. Stop column loop. + break; + } + } + } + if (xamlTableColumnGroupElement.HasChildNodes) + { + xamlTableElement.AppendChild(xamlTableColumnGroupElement); + } + } + + /// + /// Converts htmlColgroupElement into Xaml TableColumnGroup element, and appends it to the parent + /// xamlTableElement + /// + /// + /// XmlElement representing Xaml Table element to which the converted column group should be added + /// + /// + /// XmlElement representing Html colgroup element to be converted + /// + /// Properties inherited from parent context + /// + private static void AddTableColumnGroup(XmlElement xamlTableColumnGroupElement, XmlElement htmlColgroupElement, + Hashtable inheritedProperties, CssStylesheet stylesheet, List sourceContext) + { + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlColgroupElement, inheritedProperties, + out localProperties, + stylesheet, sourceContext); + + // TODO: process local properties for colgroup + + // Process children of colgroup. Colgroup may contain only col elements. + for (var htmlNode = htmlColgroupElement.FirstChild; htmlNode != null; htmlNode = htmlNode.NextSibling) + { + if (htmlNode is XmlElement && htmlNode.LocalName.ToLower() == "col") + { + AddTableColumn(xamlTableColumnGroupElement, (XmlElement) htmlNode, currentProperties, stylesheet, sourceContext); + } + } + } + + /// + /// Converts htmlColElement into Xaml TableColumn element, and appends it to the parent + /// xamlTableColumnGroupElement + /// + /// + /// + /// XmlElement representing Html col element to be converted + /// + /// + /// properties inherited from parent context + /// + /// + /// + private static void AddTableColumn(XmlElement xamlTableColumnGroupElement, XmlElement htmlColElement, + Hashtable inheritedProperties, CssStylesheet stylesheet, List sourceContext) + { + Hashtable localProperties; + var currentProperties = GetElementProperties(htmlColElement, inheritedProperties, out localProperties, + stylesheet, sourceContext); + + var xamlTableColumnElement = xamlTableColumnGroupElement.OwnerDocument.CreateElement(null, XamlTableColumn, + XamlNamespace); + + // TODO: process local properties for TableColumn element + + // Col is an empty element, with no subtree + xamlTableColumnGroupElement.AppendChild(xamlTableColumnElement); + } + + /// + /// Adds TableRow elements to xamlTableBodyElement. The rows are converted from Html tr elements that + /// may be the children of an Html tbody element or an Html table element with tbody missing + /// + /// + /// XmlElement representing Xaml TableRowGroup element to which the converted rows should be added + /// + /// + /// XmlElement representing the first tr child of the tbody element to be read + /// + /// + /// Hashtable representing current properties of the tbody element that are generated and applied in the + /// AddTable function; to be used as inheritedProperties when adding tr elements + /// + /// + /// + /// + /// + /// XmlNode representing the current position of the iterator among tr elements + /// + private static XmlNode AddTableRowsToTableBody(XmlElement xamlTableBodyElement, XmlNode htmlTrStartNode, + Hashtable currentProperties, ArrayList columnStarts, CssStylesheet stylesheet, + List sourceContext) + { + // Parameter validation + Debug.Assert(xamlTableBodyElement.LocalName == XamlTableRowGroup); + Debug.Assert(currentProperties != null); + + // Initialize child node for iteratimg through children to the first tr element + var htmlChildNode = htmlTrStartNode; + ArrayList activeRowSpans = null; + if (columnStarts != null) + { + activeRowSpans = new ArrayList(); + InitializeActiveRowSpans(activeRowSpans, columnStarts.Count); + } + + while (htmlChildNode != null && htmlChildNode.LocalName.ToLower() != "tbody") + { + if (htmlChildNode.LocalName.ToLower() == "tr") + { + var xamlTableRowElement = xamlTableBodyElement.OwnerDocument.CreateElement(null, + XamlTableRow, + XamlNamespace); + + sourceContext.Add((XmlElement) htmlChildNode); + + // Get tr element properties + Hashtable trElementLocalProperties; + var trElementCurrentProperties = GetElementProperties((XmlElement) htmlChildNode, + currentProperties, + out trElementLocalProperties, stylesheet, sourceContext); + // TODO: apply local properties to tr element + + AddTableCellsToTableRow(xamlTableRowElement, htmlChildNode.FirstChild, trElementCurrentProperties, + columnStarts, + activeRowSpans, stylesheet, sourceContext); + if (xamlTableRowElement.HasChildNodes) + { + xamlTableBodyElement.AppendChild(xamlTableRowElement); + } + + Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); + sourceContext.RemoveAt(sourceContext.Count - 1); + + // Advance + htmlChildNode = htmlChildNode.NextSibling; + } + else if (htmlChildNode.LocalName.ToLower() == "td") + { + // Tr element is not present. We create one and add td elements to it + var xamlTableRowElement = xamlTableBodyElement.OwnerDocument.CreateElement(null, + XamlTableRow, + XamlNamespace); + + // This is incorrect formatting and the column starts should not be set in this case + Debug.Assert(columnStarts == null); + + htmlChildNode = AddTableCellsToTableRow(xamlTableRowElement, htmlChildNode, currentProperties, + columnStarts, + activeRowSpans, stylesheet, sourceContext); + if (xamlTableRowElement.HasChildNodes) + { + xamlTableBodyElement.AppendChild(xamlTableRowElement); + } + } + else + { + // Not a tr or td element. Ignore it. + // TODO: consider better recovery here + htmlChildNode = htmlChildNode.NextSibling; + } + } + return htmlChildNode; + } + + /// + /// Adds TableCell elements to xamlTableRowElement. + /// + /// + /// XmlElement representing Xaml TableRow element to which the converted cells should be added + /// + /// + /// XmlElement representing the child of tr or tbody element from which we should start adding td elements + /// + /// + /// properties of the current html tr element to which cells are to be added + /// + /// + /// XmlElement representing the current position of the iterator among the children of the parent Html tbody/tr element + /// + private static XmlNode AddTableCellsToTableRow(XmlElement xamlTableRowElement, XmlNode htmlTdStartNode, + Hashtable currentProperties, ArrayList columnStarts, ArrayList activeRowSpans, CssStylesheet stylesheet, + List sourceContext) + { + // parameter validation + Debug.Assert(xamlTableRowElement.LocalName == XamlTableRow); + Debug.Assert(currentProperties != null); + if (columnStarts != null) + { + Debug.Assert(activeRowSpans.Count == columnStarts.Count); + } + + var htmlChildNode = htmlTdStartNode; + double columnStart = 0; + double columnWidth = 0; + var columnIndex = 0; + var columnSpan = 0; + + while (htmlChildNode != null && htmlChildNode.LocalName.ToLower() != "tr" && + htmlChildNode.LocalName.ToLower() != "tbody" && htmlChildNode.LocalName.ToLower() != "thead" && + htmlChildNode.LocalName.ToLower() != "tfoot") + { + if (htmlChildNode.LocalName.ToLower() == "td" || htmlChildNode.LocalName.ToLower() == "th") + { + var xamlTableCellElement = xamlTableRowElement.OwnerDocument.CreateElement(null, + XamlTableCell, + XamlNamespace); + + sourceContext.Add((XmlElement) htmlChildNode); + + Hashtable tdElementLocalProperties; + var tdElementCurrentProperties = GetElementProperties((XmlElement) htmlChildNode, + currentProperties, + out tdElementLocalProperties, stylesheet, sourceContext); + + // TODO: determine if localProperties can be used instead of htmlChildNode in this call, and if they can, + // make necessary changes and use them instead. + ApplyPropertiesToTableCellElement((XmlElement) htmlChildNode, xamlTableCellElement); + + if (columnStarts != null) + { + Debug.Assert(columnIndex < columnStarts.Count - 1); + while (columnIndex < activeRowSpans.Count && (int) activeRowSpans[columnIndex] > 0) + { + activeRowSpans[columnIndex] = (int) activeRowSpans[columnIndex] - 1; + Debug.Assert((int) activeRowSpans[columnIndex] >= 0); + columnIndex++; + } + Debug.Assert(columnIndex < columnStarts.Count - 1); + columnStart = (double) columnStarts[columnIndex]; + columnWidth = GetColumnWidth((XmlElement) htmlChildNode); + columnSpan = CalculateColumnSpan(columnIndex, columnWidth, columnStarts); + var rowSpan = GetRowSpan((XmlElement) htmlChildNode); + + // Column cannot have no span + Debug.Assert(columnSpan > 0); + Debug.Assert(columnIndex + columnSpan < columnStarts.Count); + + xamlTableCellElement.SetAttribute(XamlTableCellColumnSpan, columnSpan.ToString()); + + // Apply row span + for (var spannedColumnIndex = columnIndex; + spannedColumnIndex < columnIndex + columnSpan; + spannedColumnIndex++) + { + Debug.Assert(spannedColumnIndex < activeRowSpans.Count); + activeRowSpans[spannedColumnIndex] = (rowSpan - 1); + Debug.Assert((int) activeRowSpans[spannedColumnIndex] >= 0); + } + + columnIndex = columnIndex + columnSpan; + } + + AddDataToTableCell(xamlTableCellElement, htmlChildNode.FirstChild, tdElementCurrentProperties, + stylesheet, + sourceContext); + if (xamlTableCellElement.HasChildNodes) + { + xamlTableRowElement.AppendChild(xamlTableCellElement); + } + + Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); + sourceContext.RemoveAt(sourceContext.Count - 1); + + htmlChildNode = htmlChildNode.NextSibling; + } + else + { + // Not td element. Ignore it. + // TODO: Consider better recovery + htmlChildNode = htmlChildNode.NextSibling; + } + } + return htmlChildNode; + } + + /// + /// adds table cell data to xamlTableCellElement + /// + /// + /// XmlElement representing Xaml TableCell element to which the converted data should be added + /// + /// + /// XmlElement representing the start element of data to be added to xamlTableCellElement + /// + /// + /// Current properties for the html td/th element corresponding to xamlTableCellElement + /// + private static void AddDataToTableCell(XmlElement xamlTableCellElement, XmlNode htmlDataStartNode, + Hashtable currentProperties, CssStylesheet stylesheet, List sourceContext) + { + // Parameter validation + Debug.Assert(xamlTableCellElement.LocalName == XamlTableCell); + Debug.Assert(currentProperties != null); + + for (var htmlChildNode = htmlDataStartNode; + htmlChildNode != null; + htmlChildNode = htmlChildNode?.NextSibling) + { + // Process a new html element and add it to the td element + htmlChildNode = AddBlock(xamlTableCellElement, htmlChildNode, currentProperties, stylesheet, + sourceContext); + } + } + + /// + /// Performs a parsing pass over a table to read information about column width and rowspan attributes. This + /// information + /// is used to determine the starting point of each column. + /// + /// + /// XmlElement representing Html table whose structure is to be analyzed + /// + /// + /// ArrayList of type double which contains the function output. If analysis is successful, this ArrayList contains + /// all the points which are the starting position of any column in the table, ordered from left to right. + /// In case if analisys was impossible we return null. + /// + private static ArrayList AnalyzeTableStructure(XmlElement htmlTableElement, CssStylesheet stylesheet) + { + // Parameter validation + Debug.Assert(htmlTableElement.LocalName.ToLower() == "table"); + if (!htmlTableElement.HasChildNodes) + { + return null; + } + + var columnWidthsAvailable = true; + + var columnStarts = new ArrayList(); + var activeRowSpans = new ArrayList(); + Debug.Assert(columnStarts.Count == activeRowSpans.Count); + + var htmlChildNode = htmlTableElement.FirstChild; + double tableWidth = 0; // Keep track of table width which is the width of its widest row + + // Analyze tbody and tr elements + while (htmlChildNode != null && columnWidthsAvailable) + { + Debug.Assert(columnStarts.Count == activeRowSpans.Count); + + switch (htmlChildNode.LocalName.ToLower()) + { + case "tbody": + // Tbody element, we should analyze its children for trows + var tbodyWidth = AnalyzeTbodyStructure((XmlElement) htmlChildNode, columnStarts, + activeRowSpans, tableWidth, + stylesheet); + if (tbodyWidth > tableWidth) + { + // Table width must be increased to supported newly added wide row + tableWidth = tbodyWidth; + } + else if (tbodyWidth == 0) + { + // Tbody analysis may return 0, probably due to unprocessable format. + // We should also fail. + columnWidthsAvailable = false; // interrupt the analisys + } + break; + case "tr": + // Table row. Analyze column structure within row directly + var trWidth = AnalyzeTrStructure((XmlElement) htmlChildNode, columnStarts, activeRowSpans, + tableWidth, + stylesheet); + if (trWidth > tableWidth) + { + tableWidth = trWidth; + } + else if (trWidth == 0) + { + columnWidthsAvailable = false; // interrupt the analisys + } + break; + case "td": + // Incorrect formatting, too deep to analyze at this level. Return null. + // TODO: implement analysis at this level, possibly by creating a new tr + columnWidthsAvailable = false; // interrupt the analisys + break; + default: + // Element should not occur directly in table. Ignore it. + break; + } + + htmlChildNode = htmlChildNode.NextSibling; + } + + if (columnWidthsAvailable) + { + // Add an item for whole table width + columnStarts.Add(tableWidth); + VerifyColumnStartsAscendingOrder(columnStarts); + } + else + { + columnStarts = null; + } + + return columnStarts; + } + + /// + /// Performs a parsing pass over a tbody to read information about column width and rowspan attributes. Information + /// read about width + /// attributes is stored in the reference ArrayList parameter columnStarts, which contains a list of all starting + /// positions of all columns in the table, ordered from left to right. Row spans are taken into consideration when + /// computing column starts + /// + /// + /// XmlElement representing Html tbody whose structure is to be analyzed + /// + /// + /// ArrayList of type double which contains the function output. If analysis fails, this parameter is set to null + /// + /// + /// Current width of the table. This is used to determine if a new column when added to the end of table should + /// come after the last column in the table or is actually splitting the last column in two. If it is only splitting + /// the last column it should inherit row span for that column + /// + /// + /// Calculated width of a tbody. + /// In case of non-analizable column width structure return 0; + /// + private static double AnalyzeTbodyStructure(XmlElement htmlTbodyElement, ArrayList columnStarts, + ArrayList activeRowSpans, double tableWidth, CssStylesheet stylesheet) + { + // Parameter validation + Debug.Assert(htmlTbodyElement.LocalName.ToLower() == "tbody"); + Debug.Assert(columnStarts != null); + + double tbodyWidth = 0; + var columnWidthsAvailable = true; + + if (!htmlTbodyElement.HasChildNodes) + { + return tbodyWidth; + } + + // Set active row spans to 0 - thus ignoring row spans crossing tbody boundaries + ClearActiveRowSpans(activeRowSpans); + + var htmlChildNode = htmlTbodyElement.FirstChild; + + // Analyze tr elements + while (htmlChildNode != null && columnWidthsAvailable) + { + switch (htmlChildNode.LocalName.ToLower()) + { + case "tr": + var trWidth = AnalyzeTrStructure((XmlElement) htmlChildNode, columnStarts, activeRowSpans, + tbodyWidth, + stylesheet); + if (trWidth > tbodyWidth) + { + tbodyWidth = trWidth; + } + break; + case "td": + columnWidthsAvailable = false; // interrupt the analisys + break; + default: + break; + } + htmlChildNode = htmlChildNode.NextSibling; + } + + // Set active row spans to 0 - thus ignoring row spans crossing tbody boundaries + ClearActiveRowSpans(activeRowSpans); + + return columnWidthsAvailable ? tbodyWidth : 0; + } + + /// + /// Performs a parsing pass over a tr element to read information about column width and rowspan attributes. + /// + /// + /// XmlElement representing Html tr element whose structure is to be analyzed + /// + /// + /// ArrayList of type double which contains the function output. If analysis is successful, this ArrayList contains + /// all the points which are the starting position of any column in the tr, ordered from left to right. If analysis + /// fails, + /// the ArrayList is set to null + /// + /// + /// ArrayList representing all columns currently spanned by an earlier row span attribute. These columns should + /// not be used for data in this row. The ArrayList actually contains notation for all columns in the table, if the + /// active row span is set to 0 that column is not presently spanned but if it is > 0 the column is presently spanned + /// + /// + /// Double value representing the current width of the table. + /// Return 0 if analisys was insuccessful. + /// + private static double AnalyzeTrStructure(XmlElement htmlTrElement, ArrayList columnStarts, + ArrayList activeRowSpans, + double tableWidth, CssStylesheet stylesheet) + { + double columnWidth; + + // Parameter validation + Debug.Assert(htmlTrElement.LocalName.ToLower() == "tr"); + Debug.Assert(columnStarts != null); + Debug.Assert(activeRowSpans != null); + Debug.Assert(columnStarts.Count == activeRowSpans.Count); + + if (!htmlTrElement.HasChildNodes) + { + return 0; + } + + var columnWidthsAvailable = true; + + double columnStart = 0; // starting position of current column + var htmlChildNode = htmlTrElement.FirstChild; + var columnIndex = 0; + double trWidth = 0; + + // Skip spanned columns to get to real column start + if (columnIndex < activeRowSpans.Count) + { + Debug.Assert((double) columnStarts[columnIndex] >= columnStart); + if ((double) columnStarts[columnIndex] == columnStart) + { + // The new column may be in a spanned area + while (columnIndex < activeRowSpans.Count && (int) activeRowSpans[columnIndex] > 0) + { + activeRowSpans[columnIndex] = (int) activeRowSpans[columnIndex] - 1; + Debug.Assert((int) activeRowSpans[columnIndex] >= 0); + columnIndex++; + columnStart = (double) columnStarts[columnIndex]; + } + } + } + + while (htmlChildNode != null && columnWidthsAvailable) + { + Debug.Assert(columnStarts.Count == activeRowSpans.Count); + + VerifyColumnStartsAscendingOrder(columnStarts); + + switch (htmlChildNode.LocalName.ToLower()) + { + case "td": + Debug.Assert(columnIndex <= columnStarts.Count); + if (columnIndex < columnStarts.Count) + { + Debug.Assert(columnStart <= (double) columnStarts[columnIndex]); + if (columnStart < (double) columnStarts[columnIndex]) + { + columnStarts.Insert(columnIndex, columnStart); + // There can be no row spans now - the column data will appear here + // Row spans may appear only during the column analysis + activeRowSpans.Insert(columnIndex, 0); + } + } + else + { + // Column start is greater than all previous starts. Row span must still be 0 because + // we are either adding after another column of the same row, in which case it should not inherit + // the previous column's span. Otherwise we are adding after the last column of some previous + // row, and assuming the table widths line up, we should not be spanned by it. If there is + // an incorrect tbale structure where a columns starts in the middle of a row span, we do not + // guarantee correct output + columnStarts.Add(columnStart); + activeRowSpans.Add(0); + } + columnWidth = GetColumnWidth((XmlElement) htmlChildNode); + if (columnWidth != -1) + { + int nextColumnIndex; + var rowSpan = GetRowSpan((XmlElement) htmlChildNode); + + nextColumnIndex = GetNextColumnIndex(columnIndex, columnWidth, columnStarts, activeRowSpans); + if (nextColumnIndex != -1) + { + // Entire column width can be processed without hitting conflicting row span. This means that + // column widths line up and we can process them + Debug.Assert(nextColumnIndex <= columnStarts.Count); + + // Apply row span to affected columns + for (var spannedColumnIndex = columnIndex; + spannedColumnIndex < nextColumnIndex; + spannedColumnIndex++) + { + activeRowSpans[spannedColumnIndex] = rowSpan - 1; + Debug.Assert((int) activeRowSpans[spannedColumnIndex] >= 0); + } + + columnIndex = nextColumnIndex; + + // Calculate columnsStart for the next cell + columnStart = columnStart + columnWidth; + + if (columnIndex < activeRowSpans.Count) + { + Debug.Assert((double) columnStarts[columnIndex] >= columnStart); + if ((double) columnStarts[columnIndex] == columnStart) + { + // The new column may be in a spanned area + while (columnIndex < activeRowSpans.Count && + (int) activeRowSpans[columnIndex] > 0) + { + activeRowSpans[columnIndex] = (int) activeRowSpans[columnIndex] - 1; + Debug.Assert((int) activeRowSpans[columnIndex] >= 0); + columnIndex++; + columnStart = (double) columnStarts[columnIndex]; + } + } + // else: the new column does not start at the same time as a pre existing column + // so we don't have to check it for active row spans, it starts in the middle + // of another column which has been checked already by the GetNextColumnIndex function + } + } + else + { + // Full column width cannot be processed without a pre existing row span. + // We cannot analyze widths + columnWidthsAvailable = false; + } + } + else + { + // Incorrect column width, stop processing + columnWidthsAvailable = false; + } + break; + default: + break; + } + + htmlChildNode = htmlChildNode.NextSibling; + } + + // The width of the tr element is the position at which it's last td element ends, which is calculated in + // the columnStart value after each td element is processed + trWidth = columnWidthsAvailable ? columnStart : 0; + + return trWidth; + } + + /// + /// Gets row span attribute from htmlTDElement. Returns an integer representing the value of the rowspan attribute. + /// Default value if attribute is not specified or if it is invalid is 1 + /// + /// + /// Html td element to be searched for rowspan attribute + /// + private static int GetRowSpan(XmlElement htmlTdElement) + { + string rowSpanAsString; + int rowSpan; + + rowSpanAsString = GetAttribute(htmlTdElement, "rowspan"); + if (rowSpanAsString != null) + { + if (!int.TryParse(rowSpanAsString, out rowSpan)) + { + // Ignore invalid value of rowspan; treat it as 1 + rowSpan = 1; + } + } + else + { + // No row span, default is 1 + rowSpan = 1; + } + return rowSpan; + } + + /// + /// Gets index at which a column should be inseerted into the columnStarts ArrayList. This is + /// decided by the value columnStart. The columnStarts ArrayList is ordered in ascending order. + /// Returns an integer representing the index at which the column should be inserted + /// + /// + /// Array list representing starting coordinates of all columns in the table + /// + /// + /// Starting coordinate of column we wish to insert into columnStart + /// + /// + /// Int representing the current column index. This acts as a clue while finding the insertion index. + /// If the value of columnStarts at columnIndex is the same as columnStart, then this position alrady exists + /// in the array and we can jsut return columnIndex. + /// + /// + private static int GetNextColumnIndex(int columnIndex, double columnWidth, ArrayList columnStarts, + ArrayList activeRowSpans) + { + double columnStart; + int spannedColumnIndex; + + // Parameter validation + Debug.Assert(columnStarts != null); + Debug.Assert(0 <= columnIndex && columnIndex <= columnStarts.Count); + Debug.Assert(columnWidth > 0); + + columnStart = (double) columnStarts[columnIndex]; + spannedColumnIndex = columnIndex + 1; + + while (spannedColumnIndex < columnStarts.Count && + (double) columnStarts[spannedColumnIndex] < columnStart + columnWidth && spannedColumnIndex != -1) + { + if ((int) activeRowSpans[spannedColumnIndex] > 0) + { + // The current column should span this area, but something else is already spanning it + // Not analyzable + spannedColumnIndex = -1; + } + else + { + spannedColumnIndex++; + } + } + + return spannedColumnIndex; + } + + + /// + /// Used for clearing activeRowSpans array in the beginning/end of each tbody + /// + /// + /// ArrayList representing currently active row spans + /// + private static void ClearActiveRowSpans(ArrayList activeRowSpans) + { + for (var columnIndex = 0; columnIndex < activeRowSpans.Count; columnIndex++) + { + activeRowSpans[columnIndex] = 0; + } + } + + /// + /// Used for initializing activeRowSpans array in the before adding rows to tbody element + /// + /// + /// ArrayList representing currently active row spans + /// + /// + /// Size to be give to array list + /// + private static void InitializeActiveRowSpans(ArrayList activeRowSpans, int count) + { + for (var columnIndex = 0; columnIndex < count; columnIndex++) + { + activeRowSpans.Add(0); + } + } + + + /// + /// Calculates width of next TD element based on starting position of current element and it's width, which + /// is calculated byt he function + /// + /// + /// XmlElement representing Html td element whose width is to be read + /// + /// + /// Starting position of current column + /// + private static double GetNextColumnStart(XmlElement htmlTdElement, double columnStart) + { + double columnWidth; + double nextColumnStart; + + // Parameter validation + Debug.Assert(htmlTdElement.LocalName.ToLower() == "td" || htmlTdElement.LocalName.ToLower() == "th"); + Debug.Assert(columnStart >= 0); + + nextColumnStart = -1; // -1 indicates inability to calculate columnStart width + + columnWidth = GetColumnWidth(htmlTdElement); + + if (columnWidth == -1) + { + nextColumnStart = -1; + } + else + { + nextColumnStart = columnStart + columnWidth; + } + + return nextColumnStart; + } + + + private static double GetColumnWidth(XmlElement htmlTdElement) + { + string columnWidthAsString; + double columnWidth; + + columnWidthAsString = null; + columnWidth = -1; + + // Get string valkue for the width + columnWidthAsString = GetAttribute(htmlTdElement, "width") ?? + GetCssAttribute(GetAttribute(htmlTdElement, "style"), "width"); + + // We do not allow column width to be 0, if specified as 0 we will fail to record it + if (!TryGetLengthValue(columnWidthAsString, out columnWidth) || columnWidth == 0) + { + columnWidth = -1; + } + return columnWidth; + } + + /// + /// Calculates column span based the column width and the widths of all other columns. Returns an integer representing + /// the column span + /// + /// + /// Index of the current column + /// + /// + /// Width of the current column + /// + /// + /// ArrayList repsenting starting coordinates of all columns + /// + private static int CalculateColumnSpan(int columnIndex, double columnWidth, ArrayList columnStarts) + { + // Current status of column width. Indicates the amount of width that has been scanned already + double columnSpanningValue; + int columnSpanningIndex; + int columnSpan; + double subColumnWidth; // Width of the smallest-grain columns in the table + + Debug.Assert(columnStarts != null); + Debug.Assert(columnIndex < columnStarts.Count - 1); + Debug.Assert((double) columnStarts[columnIndex] >= 0); + Debug.Assert(columnWidth > 0); + + columnSpanningIndex = columnIndex; + columnSpanningValue = 0; + columnSpan = 0; + subColumnWidth = 0; + + while (columnSpanningValue < columnWidth && columnSpanningIndex < columnStarts.Count - 1) + { + subColumnWidth = (double) columnStarts[columnSpanningIndex + 1] - + (double) columnStarts[columnSpanningIndex]; + Debug.Assert(subColumnWidth > 0); + columnSpanningValue += subColumnWidth; + columnSpanningIndex++; + } + + // Now, we have either covered the width we needed to cover or reached the end of the table, in which + // case the column spans all the columns until the end + columnSpan = columnSpanningIndex - columnIndex; + Debug.Assert(columnSpan > 0); + + return columnSpan; + } + + /// + /// Verifies that values in columnStart, which represent starting coordinates of all columns, are arranged + /// in ascending order + /// + /// + /// ArrayList representing starting coordinates of all columns + /// + private static void VerifyColumnStartsAscendingOrder(ArrayList columnStarts) + { + Debug.Assert(columnStarts != null); + + double columnStart; + + columnStart = -0.01; + + foreach (object t in columnStarts) + { + Debug.Assert(columnStart < (double) t); + columnStart = (double) t; + } + } + + // ............................................................. + // + // Attributes and Properties + // + // ............................................................. + + /// + /// Analyzes local properties of Html element, converts them into Xaml equivalents, and applies them to xamlElement + /// + /// + /// XmlElement representing Xaml element to which properties are to be applied + /// + /// + /// Hashtable representing local properties of Html element that is converted into xamlElement + /// + private static void ApplyLocalProperties(XmlElement xamlElement, Hashtable localProperties, bool isBlock) + { + var marginSet = false; + var marginTop = "0"; + var marginBottom = "0"; + var marginLeft = "0"; + var marginRight = "0"; + + var paddingSet = false; + var paddingTop = "0"; + var paddingBottom = "0"; + var paddingLeft = "0"; + var paddingRight = "0"; + + string borderColor = null; + + var borderThicknessSet = false; + var borderThicknessTop = "0"; + var borderThicknessBottom = "0"; + var borderThicknessLeft = "0"; + var borderThicknessRight = "0"; + + var propertyEnumerator = localProperties.GetEnumerator(); + while (propertyEnumerator.MoveNext()) + { + switch ((string) propertyEnumerator.Key) + { + case "font-family": + // Convert from font-family value list into xaml FontFamily value + xamlElement.SetAttribute(XamlFontFamily, (string) propertyEnumerator.Value); + break; + case "font-style": + xamlElement.SetAttribute(XamlFontStyle, (string) propertyEnumerator.Value); + break; + case "font-variant": + // Convert from font-variant into xaml property + break; + case "font-weight": + xamlElement.SetAttribute(XamlFontWeight, (string) propertyEnumerator.Value); + break; + case "font-size": + // Convert from css size into FontSize + xamlElement.SetAttribute(XamlFontSize, (string) propertyEnumerator.Value); + break; + case "color": + SetPropertyValue(xamlElement, TextElement.ForegroundProperty, (string) propertyEnumerator.Value); + break; + case "background-color": + SetPropertyValue(xamlElement, TextElement.BackgroundProperty, (string) propertyEnumerator.Value); + break; + case "text-decoration-underline": + if (!isBlock) + { + if ((string) propertyEnumerator.Value == "true") + { + xamlElement.SetAttribute(XamlTextDecorations, XamlTextDecorationsUnderline); + } + } + break; + case "text-decoration-none": + case "text-decoration-overline": + case "text-decoration-line-through": + case "text-decoration-blink": + // Convert from all other text-decorations values + if (!isBlock) + { + } + break; + case "text-transform": + // Convert from text-transform into xaml property + break; + + case "text-indent": + if (isBlock) + { + xamlElement.SetAttribute(XamlTextIndent, (string) propertyEnumerator.Value); + } + break; + + case "text-align": + if (isBlock) + { + xamlElement.SetAttribute(XamlTextAlignment, (string) propertyEnumerator.Value); + } + break; + + case "width": + case "height": + // Decide what to do with width and height propeties + break; + + case "margin-top": + marginSet = true; + marginTop = (string) propertyEnumerator.Value; + break; + case "margin-right": + marginSet = true; + marginRight = (string) propertyEnumerator.Value; + break; + case "margin-bottom": + marginSet = true; + marginBottom = (string) propertyEnumerator.Value; + break; + case "margin-left": + marginSet = true; + marginLeft = (string) propertyEnumerator.Value; + break; + + case "padding-top": + paddingSet = true; + paddingTop = (string) propertyEnumerator.Value; + break; + case "padding-right": + paddingSet = true; + paddingRight = (string) propertyEnumerator.Value; + break; + case "padding-bottom": + paddingSet = true; + paddingBottom = (string) propertyEnumerator.Value; + break; + case "padding-left": + paddingSet = true; + paddingLeft = (string) propertyEnumerator.Value; + break; + + // NOTE: css names for elementary border styles have side indications in the middle (top/bottom/left/right) + // In our internal notation we intentionally put them at the end - to unify processing in ParseCssRectangleProperty method + case "border-color-top": + borderColor = (string) propertyEnumerator.Value; + break; + case "border-color-right": + borderColor = (string) propertyEnumerator.Value; + break; + case "border-color-bottom": + borderColor = (string) propertyEnumerator.Value; + break; + case "border-color-left": + borderColor = (string) propertyEnumerator.Value; + break; + case "border-style-top": + case "border-style-right": + case "border-style-bottom": + case "border-style-left": + // Implement conversion from border style + break; + case "border-width-top": + borderThicknessSet = true; + borderThicknessTop = (string) propertyEnumerator.Value; + break; + case "border-width-right": + borderThicknessSet = true; + borderThicknessRight = (string) propertyEnumerator.Value; + break; + case "border-width-bottom": + borderThicknessSet = true; + borderThicknessBottom = (string) propertyEnumerator.Value; + break; + case "border-width-left": + borderThicknessSet = true; + borderThicknessLeft = (string) propertyEnumerator.Value; + break; + + case "list-style-type": + if (xamlElement.LocalName == XamlList) + { + string markerStyle; + switch (((string) propertyEnumerator.Value).ToLower()) + { + case "disc": + markerStyle = XamlListMarkerStyleDisc; + break; + case "circle": + markerStyle = XamlListMarkerStyleCircle; + break; + case "none": + markerStyle = XamlListMarkerStyleNone; + break; + case "square": + markerStyle = XamlListMarkerStyleSquare; + break; + case "box": + markerStyle = XamlListMarkerStyleBox; + break; + case "lower-latin": + markerStyle = XamlListMarkerStyleLowerLatin; + break; + case "upper-latin": + markerStyle = XamlListMarkerStyleUpperLatin; + break; + case "lower-roman": + markerStyle = XamlListMarkerStyleLowerRoman; + break; + case "upper-roman": + markerStyle = XamlListMarkerStyleUpperRoman; + break; + case "decimal": + markerStyle = XamlListMarkerStyleDecimal; + break; + default: + markerStyle = XamlListMarkerStyleDisc; + break; + } + xamlElement.SetAttribute(XamlListMarkerStyle, markerStyle); + } + break; + + case "float": + case "clear": + if (isBlock) + { + // Convert float and clear properties + } + break; + + case "display": + break; + } + } + + if (isBlock) + { + if (marginSet) + { + ComposeThicknessProperty(xamlElement, XamlMargin, marginLeft, marginRight, marginTop, marginBottom); + } + + if (paddingSet) + { + ComposeThicknessProperty(xamlElement, XamlPadding, paddingLeft, paddingRight, paddingTop, + paddingBottom); + } + + if (borderColor != null) + { + // We currently ignore possible difference in brush colors on different border sides. Use the last colored side mentioned + xamlElement.SetAttribute(XamlBorderBrush, borderColor); + } + + if (borderThicknessSet) + { + ComposeThicknessProperty(xamlElement, XamlBorderThickness, borderThicknessLeft, + borderThicknessRight, + borderThicknessTop, borderThicknessBottom); + } + } + } + + // Create syntactically optimized four-value Thickness + private static void ComposeThicknessProperty(XmlElement xamlElement, string propertyName, string left, + string right, + string top, string bottom) + { + // Xaml syntax: + // We have a reasonable interpreation for one value (all four edges), two values (horizontal, vertical), + // and four values (left, top, right, bottom). + // switch (i) { + // case 1: return new Thickness(lengths[0]); + // case 2: return new Thickness(lengths[0], lengths[1], lengths[0], lengths[1]); + // case 4: return new Thickness(lengths[0], lengths[1], lengths[2], lengths[3]); + // } + string thickness; + + // We do not accept negative margins + if (left[0] == '0' || left[0] == '-') left = "0"; + if (right[0] == '0' || right[0] == '-') right = "0"; + if (top[0] == '0' || top[0] == '-') top = "0"; + if (bottom[0] == '0' || bottom[0] == '-') bottom = "0"; + + if (left == right && top == bottom) + { + if (left == top) + { + thickness = left; + } + else + { + thickness = left + "," + top; + } + } + else + { + thickness = left + "," + top + "," + right + "," + bottom; + } + + // Need safer processing for a thickness value + xamlElement.SetAttribute(propertyName, thickness); + } + + private static void SetPropertyValue(XmlElement xamlElement, DependencyProperty property, string stringValue) + { + var typeConverter = + TypeDescriptor.GetConverter(property.PropertyType); + try + { + var convertedValue = typeConverter.ConvertFromInvariantString(stringValue); + if (convertedValue != null) + { + xamlElement.SetAttribute(property.Name, stringValue); + } + } + catch (Exception) + { + } + } + + /// + /// Analyzes the tag of the htmlElement and infers its associated formatted properties. + /// After that parses style attribute and adds all inline css styles. + /// The resulting style attributes are collected in output parameter localProperties. + /// + /// + /// + /// + /// set of properties inherited from ancestor elements. Currently not used in the code. Reserved for the future + /// development. + /// + /// + /// returns all formatting properties defined by this element - implied by its tag, its attributes, or its css inline + /// style + /// + /// + /// + /// + /// returns a combination of previous context with local set of properties. + /// This value is not used in the current code - inntended for the future development. + /// + private static Hashtable GetElementProperties(XmlElement htmlElement, Hashtable inheritedProperties, + out Hashtable localProperties, CssStylesheet stylesheet, List sourceContext) + { + // Start with context formatting properties + var currentProperties = new Hashtable(); + var propertyEnumerator = inheritedProperties.GetEnumerator(); + while (propertyEnumerator.MoveNext()) + { + currentProperties[propertyEnumerator.Key] = propertyEnumerator.Value; + } + + // Identify element name + var elementName = htmlElement.LocalName.ToLower(); + var elementNamespace = htmlElement.NamespaceURI; + + // update current formatting properties depending on element tag + + localProperties = new Hashtable(); + switch (elementName) + { + // Character formatting + case "i": + case "italic": + case "em": + localProperties["font-style"] = "italic"; + break; + case "b": + case "bold": + case "strong": + case "dfn": + localProperties["font-weight"] = "bold"; + break; + case "u": + case "underline": + localProperties["text-decoration-underline"] = "true"; + break; + case "font": + var attributeValue = GetAttribute(htmlElement, "face"); + if (attributeValue != null) + { + localProperties["font-family"] = attributeValue; + } + attributeValue = GetAttribute(htmlElement, "size"); + if (attributeValue != null) + { + var fontSize = double.Parse(attributeValue)*(12.0/3.0); + if (fontSize < 1.0) + { + fontSize = 1.0; + } + else if (fontSize > 1000.0) + { + fontSize = 1000.0; + } + localProperties["font-size"] = fontSize.ToString(CultureInfo.InvariantCulture); + } + attributeValue = GetAttribute(htmlElement, "color"); + if (attributeValue != null) + { + localProperties["color"] = attributeValue; + } + break; + case "samp": + localProperties["font-family"] = "Courier New"; // code sample + localProperties["font-size"] = XamlFontSizeXxSmall; + localProperties["text-align"] = "Left"; + break; + case "sub": + break; + case "sup": + break; + + // Hyperlinks + case "a": // href, hreflang, urn, methods, rel, rev, title + // Set default hyperlink properties + break; + case "acronym": + break; + + // Paragraph formatting: + case "p": + // Set default paragraph properties + break; + case "div": + // Set default div properties + break; + case "pre": + localProperties["font-family"] = "Courier New"; // renders text in a fixed-width font + localProperties["font-size"] = XamlFontSizeXxSmall; + localProperties["text-align"] = "Left"; + break; + case "blockquote": + localProperties["margin-left"] = "16"; + break; + + case "h1": + localProperties["font-size"] = XamlFontSizeXxLarge; + break; + case "h2": + localProperties["font-size"] = XamlFontSizeXLarge; + break; + case "h3": + localProperties["font-size"] = XamlFontSizeLarge; + break; + case "h4": + localProperties["font-size"] = XamlFontSizeMedium; + break; + case "h5": + localProperties["font-size"] = XamlFontSizeSmall; + break; + case "h6": + localProperties["font-size"] = XamlFontSizeXSmall; + break; + // List properties + case "ul": + localProperties["list-style-type"] = "disc"; + break; + case "ol": + localProperties["list-style-type"] = "decimal"; + break; + + case "table": + case "body": + case "html": + break; + } + + // Override html defaults by css attributes - from stylesheets and inline settings + HtmlCssParser.GetElementPropertiesFromCssAttributes(htmlElement, elementName, stylesheet, localProperties, + sourceContext); + + // Combine local properties with context to create new current properties + propertyEnumerator = localProperties.GetEnumerator(); + while (propertyEnumerator.MoveNext()) + { + currentProperties[propertyEnumerator.Key] = propertyEnumerator.Value; + } + + return currentProperties; + } + + /// + /// Extracts a value of css attribute from css style definition. + /// + /// + /// Source csll style definition + /// + /// + /// A name of css attribute to extract + /// + /// + /// A string rrepresentation of an attribute value if found; + /// null if there is no such attribute in a given string. + /// + private static string GetCssAttribute(string cssStyle, string attributeName) + { + // This is poor man's attribute parsing. Replace it by real css parsing + if (cssStyle != null) + { + string[] styleValues; + + attributeName = attributeName.ToLower(); + + // Check for width specification in style string + styleValues = cssStyle.Split(';'); + + foreach (string t in styleValues) + { + string[] styleNameValue; + + styleNameValue = t.Split(':'); + if (styleNameValue.Length == 2) + { + if (styleNameValue[0].Trim().ToLower() == attributeName) + { + return styleNameValue[1].Trim(); + } + } + } + } + + return null; + } + + /// + /// Converts a length value from string representation to a double. + /// + /// + /// Source string value of a length. + /// + /// + /// + private static bool TryGetLengthValue(string lengthAsString, out double length) + { + length = double.NaN; + + if (lengthAsString != null) + { + lengthAsString = lengthAsString.Trim().ToLower(); + + // We try to convert currentColumnWidthAsString into a double. This will eliminate widths of type "50%", etc. + if (lengthAsString.EndsWith("pt")) + { + lengthAsString = lengthAsString.Substring(0, lengthAsString.Length - 2); + if (double.TryParse(lengthAsString, out length)) + { + length = (length*96.0)/72.0; // convert from points to pixels + } + else + { + length = double.NaN; + } + } + else if (lengthAsString.EndsWith("px")) + { + lengthAsString = lengthAsString.Substring(0, lengthAsString.Length - 2); + if (!double.TryParse(lengthAsString, out length)) + { + length = double.NaN; + } + } + else + { + if (!double.TryParse(lengthAsString, out length)) // Assuming pixels + { + length = double.NaN; + } + } + } + + return !double.IsNaN(length); + } + + // ................................................................. + // + // Pasring Color Attribute + // + // ................................................................. + + private static string GetColorValue(string colorValue) => colorValue; + + /// + /// Applies properties to xamlTableCellElement based on the html td element it is converted from. + /// + /// + /// Html td/th element to be converted to xaml + /// + /// + /// XmlElement representing Xaml element for which properties are to be processed + /// + /// + /// TODO: Use the processed properties for htmlChildNode instead of using the node itself + /// + private static void ApplyPropertiesToTableCellElement(XmlElement htmlChildNode, XmlElement xamlTableCellElement) + { + // Parameter validation + Debug.Assert(htmlChildNode.LocalName.ToLower() == "td" || htmlChildNode.LocalName.ToLower() == "th"); + Debug.Assert(xamlTableCellElement.LocalName == XamlTableCell); + + // set default border thickness for xamlTableCellElement to enable gridlines + xamlTableCellElement.SetAttribute(XamlTableCellBorderThickness, "1,1,1,1"); + xamlTableCellElement.SetAttribute(XamlTableCellBorderBrush, XamlBrushesBlack); + var rowSpanString = GetAttribute(htmlChildNode, "rowspan"); + if (rowSpanString != null) + { + xamlTableCellElement.SetAttribute(XamlTableCellRowSpan, rowSpanString); + } + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Converters/HtmlTokenType.cs b/JRCookbookBusiness/Converters/HtmlTokenType.cs new file mode 100644 index 0000000..ba78f18 --- /dev/null +++ b/JRCookbookBusiness/Converters/HtmlTokenType.cs @@ -0,0 +1,22 @@ +// // Copyright (c) Microsoft. All rights reserved. +// // Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace HtmlToXamlDemo +{ + /// + /// types of lexical tokens for html-to-xaml converter + /// + internal enum HtmlTokenType + { + OpeningTagStart, + ClosingTagStart, + TagEnd, + EmptyTagEnd, + EqualSign, + Name, + Atom, // any attribute value not in quotes + Text, //text content when accepting text + Comment, + Eof + } +} \ No newline at end of file diff --git a/JRCookbookBusiness/Cookbook.cs b/JRCookbookBusiness/Cookbook.cs new file mode 100644 index 0000000..7d20d90 --- /dev/null +++ b/JRCookbookBusiness/Cookbook.cs @@ -0,0 +1,586 @@ +using Microsoft.AspNetCore.Html; +using Microsoft.Office.Interop.Word; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace JRCookbookBusiness +{ + public class Cookbook + { + public Guid? cookbookID = null; + public String author = String.Empty; + public String copyright = String.Empty; + public String name = String.Empty; + public String comments = String.Empty; + + public List cookbookChapters = new List(); + public List recipeHighlights = new List(); + + private int mNumberRecipiesRendered = 0; + private int mTotalNumberRecipiesToRender = 0; + + public event EventHandler LongRunningStatusUpdatedEvent; + + + public Cookbook() + { + } + + public Cookbook(Guid cookbookID) + { + PopulateByID(cookbookID); + } + + public void Save() + { + if (this.cookbookID == null) + { + this.cookbookID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDCookbook(); + clsDatabaseLayer.GetDatabaseLayer().InsertCookbook(this); + } + else + { + clsDatabaseLayer.GetDatabaseLayer().UpdateCookbook(this); + } + } + + public void Delete() + { + foreach(var cookbookChapter in cookbookChapters) + { + cookbookChapter.Delete(); + } + foreach (var recipe in recipeHighlights) + { + recipe.Delete(); + } + clsDatabaseLayer.GetDatabaseLayer().DeleteCookbookByID(cookbookID.Value); + } + + + public static Cookbook GetCookbookByID(Guid cookbookID) + { + return new Cookbook(cookbookID); + } + + public static Cookbook GetCookbookByDataRow(DataRow row) + { + var newCookbook = new Cookbook(); + newCookbook.PopulateFromDataRow(row); + return newCookbook; + } + + public static List GetAllCookbooks() + { + DataSet recordSet; + var returnValue = new List(); + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetAllCookbooks(); + + if (recordSet.Tables[0].Rows.Count > 0) + { + foreach (DataRow ldbrwRow in recordSet.Tables[0].Rows) + { + var newCookbook = new Cookbook(); + newCookbook.PopulateFromDataRow(ldbrwRow); + returnValue.Add(newCookbook); + } + } + return returnValue; + } + + + private void PopulateByID(Guid cookbookID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetCookbookByID(cookbookID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("cookbookID")) + cookbookID = null; + else + cookbookID = (Guid)dataRow["cookbookID"]; + + if (dataRow.IsNull("author")) + author = String.Empty; + else + author = (String)dataRow["author"]; + + if (dataRow.IsNull("copyright")) + copyright = String.Empty; + else + copyright = (String)dataRow["copyright"]; + + if (dataRow.IsNull("name")) + name = String.Empty; + else + name = (String)dataRow["name"]; + + if (dataRow.IsNull("comments")) + comments = String.Empty; + else + comments = (String)dataRow["comments"]; + + LoadChapters(); + LoadRecipeHighlights(); + } + + private void InitializeAllFields() + { + cookbookID = null; + author = String.Empty; + copyright = String.Empty; + name = String.Empty; + comments = String.Empty; + + cookbookChapters = new List(); + recipeHighlights = new List(); + } + + private void LoadChapters() + { + //Populate child objects + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetCookbookChaptersByParentChapter(this.cookbookID.Value, null); + + foreach (DataRow childDataRow in recordSet.Tables[0].Rows) + { + var newChapter = CookbookChapter.GetCookbookChapterByDataRow(childDataRow); + cookbookChapters.Add(newChapter); + } + + } + + private void LoadRecipeHighlights() + { + //Populate child objects + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeHighlightsByParentChapter(this.cookbookID.Value, null); + + foreach (DataRow childDataRow in recordSet.Tables[0].Rows) + { + var newRecipeHighlights = RecipeHighlights.GetRecipeHighlightsByDataRow(childDataRow); + recipeHighlights.Add(newRecipeHighlights); + } + + } + + public void GenerateWebPages(String folderToSaveTo) + { + var recipePageDictionary = new Dictionary(); + var pagesAlreadyAdded = new SortedSet(); + var recipesAlpha = new SortedList(); + + + //var strCookbookPage = SharedRoutines.RemoveSpecialCharactersFromFileName(this.name); + var strCookbookPage = SharedRoutines.RemoveSpecialCharactersFromFileName("index"); + var strCookbookPageWithExtension = strCookbookPage + ".htm"; + + while (pagesAlreadyAdded.Contains(strCookbookPageWithExtension.ToUpper())) + { + strCookbookPage += "1"; + strCookbookPageWithExtension = strCookbookPage + ".htm"; + } + pagesAlreadyAdded.Add(strCookbookPageWithExtension.ToUpper()); + + + var builderCookbookIndex = new HtmlContentBuilder(); + + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendFormat("{0}" + Constants.CRLF, this.name); + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtml(HTMLAddCookbookName()); + + List trackbackList = new List(); + + Trackback thisTrackback = new Trackback(); + thisTrackback.TrackbackURL = strCookbookPageWithExtension; + thisTrackback.TrackbackText = this.name; + + trackbackList.Add(thisTrackback); + + + foreach (var cookbookChapter in cookbookChapters) + { + cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; + var chapterURLAdded = cookbookChapter.GenerateWebPagesToFolder(folderToSaveTo, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, trackbackList); + + builderCookbookIndex.AppendHtml(HTMLAddSubChapterToIndex(cookbookChapter, chapterURLAdded)); + cookbookChapter.RecipeRenderedEvent -= HandleRecipeRendered; + } + + foreach (var recipeHighlight in recipeHighlights) + { + var recipe = Recipe.GetRecipeByID(recipeHighlight.recipeID.Value); + + recipe.RecipeRenderedEvent += HandleRecipeRendered; + recipe.GenerateWebPageToFolder(folderToSaveTo, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, trackbackList); + builderCookbookIndex.AppendHtml(HTMLAddRecipeToIndex(recipe, recipePageDictionary)); + + recipe.RecipeRenderedEvent -= HandleRecipeRendered; + } + + + + var allRecipesURLAdded = GenerateCookbookAllRecipesWebPageIndex(folderToSaveTo, strCookbookPage, recipePageDictionary, recipesAlpha, pagesAlreadyAdded); + + builderCookbookIndex.AppendHtml(HTMLAddAllRecipesItemToIndex(allRecipesURLAdded)); + + var strIndexPath = folderToSaveTo; + if (strIndexPath.EndsWith("\\") == false) + { + strIndexPath += "\\"; + } + + builderCookbookIndex.AppendHtmlLine("
"); + + builderCookbookIndex.AppendHtmlLine(""); + builderCookbookIndex.AppendHtmlLine(""); + + strIndexPath += strCookbookPageWithExtension; + using (var writer = new System.IO.StreamWriter(strIndexPath, false)) + { + builderCookbookIndex.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + } + } + + private String HTMLAddSubChapterToIndex(CookbookChapter chapter, String chapterURL) + { + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("", chapterURL); + builder.AppendFormat("{0}", chapter.name); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String GenerateCookbookAllRecipesWebPageIndex(String folderToSaveTo, String cookbookPageName, Dictionary recipePageDictionary, SortedList recipesAlpha, SortedSet pagesAlreadyAdded) + { + var builderAllRecipeIndex = new HtmlContentBuilder(); + var builderChapterIndex = new HtmlContentBuilder(); + + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendFormat("{0}" + Constants.CRLF, this.name); + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtml(HTMLAddCookbookName()); + + foreach (var recipe in recipesAlpha.Values) + { + builderAllRecipeIndex.AppendHtml(HTMLAddRecipeToIndex(recipe, recipePageDictionary)); + } + + builderAllRecipeIndex.AppendHtmlLine("
"); + + builderAllRecipeIndex.AppendHtmlLine(""); + builderAllRecipeIndex.AppendHtmlLine(""); + + var strIndexPath = folderToSaveTo; + if (strIndexPath.EndsWith("\\") == false) + { + strIndexPath += "\\"; + } + + var strPageName = cookbookPageName + "-allrecipes"; + var strPageNameWithExtension = strPageName + ".htm"; + + while (pagesAlreadyAdded.Contains(strPageNameWithExtension.ToUpper())) + { + strPageName += "1"; + strPageNameWithExtension = strPageName + ".htm"; + } + + pagesAlreadyAdded.Add(strPageNameWithExtension.ToUpper()); + + strIndexPath += strPageNameWithExtension; + using (var writer = new System.IO.StreamWriter(strIndexPath, false)) + { + builderAllRecipeIndex.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + } + + return strPageNameWithExtension; + + } + + private String HTMLAddCookbookName() + { + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", this.name); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddRecipeToIndex(Recipe recipe, Dictionary recipePageDictionary) + { + var recipePageURL = recipePageDictionary.GetValueOrDefault(recipe.recipeID.Value, String.Empty); + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("", recipePageURL); + builder.AppendFormat("{0}", recipe.recipename); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddAllRecipesItemToIndex(String allRecipesURL) + { + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("", allRecipesURL); + builder.AppendFormat("{0}", "All Recipes"); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + public void GenerateWordDoc(String fileToSaveTo) + { + try + { + var recipePageDictionary = new Dictionary(); + var pagesAlreadyAdded = new SortedSet(); + var recipesAlpha = new SortedList(); + + mTotalNumberRecipiesToRender = this.GetTotalRecipeCount(); + mNumberRecipiesRendered = 0; + + clsWord.ResetWord(); + + clsWord.WordApplication.Documents.Add(); + + clsWord.WordApplication.ActiveDocument.PageSetup.LeftMargin = clsWord.WordApplication.InchesToPoints(0.5F); + clsWord.WordApplication.ActiveDocument.PageSetup.RightMargin = clsWord.WordApplication.InchesToPoints(0.5F); + clsWord.WordApplication.ActiveDocument.PageSetup.TopMargin = clsWord.WordApplication.InchesToPoints(0.5F); + clsWord.WordApplication.ActiveDocument.PageSetup.BottomMargin = clsWord.WordApplication.InchesToPoints(0.5F); + clsWord.WordApplication.Selection.ParagraphFormat.SpaceBefore = 0; + clsWord.WordApplication.Selection.ParagraphFormat.SpaceAfter = 0; + clsWord.WordApplication.Selection.ParagraphFormat.SpaceAfterAuto = 0; + clsWord.WordApplication.Selection.ParagraphFormat.LineUnitBefore = 0; + clsWord.WordApplication.Selection.ParagraphFormat.LineUnitAfter = 0; + + //clsWord.WordApplication.ActiveDocument.Styles["Heading 1"].Font.Size = clsWord.WORD_CHAPTER_NAME_FONT_SIZE; + //clsWord.WordApplication.ActiveDocument.Styles["Heading 2"].Font.Size = clsWord.WORD_RECIPE_NAME_FONT_SIZE; + + var baseFontName = clsWord.WordApplication.Selection.Font.Name; + + var heading1Style = clsWord.WordApplication.ActiveDocument.Styles["Heading 1"]; + heading1Style.Font.Name = baseFontName; + heading1Style.Font.Size = clsWord.WORD_CHAPTER_NAME_FONT_SIZE; + heading1Style.Font.Bold = 1; + heading1Style.Font.Italic = 0; + heading1Style.Font.Underline = WdUnderline.wdUnderlineNone; + heading1Style.AutomaticallyUpdate = true; + heading1Style.set_BaseStyle("Normal"); + heading1Style.set_NextParagraphStyle("Normal"); + + var heading2Style = clsWord.WordApplication.ActiveDocument.Styles["Heading 2"]; + heading2Style.Font.Name = baseFontName; + heading2Style.Font.Size = clsWord.WORD_RECIPE_NAME_FONT_SIZE; + heading2Style.Font.Bold = 1; + heading2Style.Font.Italic = 0; + heading2Style.Font.Underline = WdUnderline.wdUnderlineNone; + heading2Style.AutomaticallyUpdate = true; + heading2Style.set_BaseStyle("Normal"); + heading2Style.set_NextParagraphStyle("Normal"); + + + var toc1Style = clsWord.WordApplication.ActiveDocument.Styles["TOC 1"]; + toc1Style.AutomaticallyUpdate = true; + toc1Style.set_BaseStyle("Normal"); + toc1Style.set_NextParagraphStyle("Normal"); + toc1Style.Font.Name = baseFontName; + toc1Style.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + toc1Style.ParagraphFormat.SpaceBefore = 0F; + toc1Style.ParagraphFormat.SpaceBeforeAuto = 0; + toc1Style.ParagraphFormat.SpaceAfter = 0F; + toc1Style.ParagraphFormat.SpaceAfterAuto = 0; + toc1Style.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle; + + var toc2Style = clsWord.WordApplication.ActiveDocument.Styles["TOC 2"]; + toc2Style.AutomaticallyUpdate = true; + toc2Style.set_BaseStyle("Normal"); + toc2Style.set_NextParagraphStyle("Normal"); + toc2Style.Font.Name = baseFontName; + toc2Style.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + toc2Style.ParagraphFormat.SpaceBefore = 0F; + toc2Style.ParagraphFormat.SpaceBeforeAuto = 0; + toc2Style.ParagraphFormat.SpaceAfter = 0F; + toc2Style.ParagraphFormat.SpaceAfterAuto = 0; + toc2Style.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle; + + + clsWord.WordApplication.Selection.Font.Size = clsWord.WORD_RECIPE_SECTION_HEADING_FONT_SIZE; + clsWord.WordApplication.Selection.Font.Bold = 1; + + clsWord.WordApplication.Selection.TypeText(this.name); + clsWord.WordApplication.Selection.TypeParagraph(); + + clsWord.WordApplication.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + clsWord.WordApplication.Selection.Font.Bold = 0; + + clsWord.WordApplication.Selection.InsertNewPage(); + clsWord.WordApplication.Selection.Bookmarks.Add("TableOfContents"); + + bool isFirstPageOfContent = true; + + foreach (var cookbookChapter in cookbookChapters) + { + cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; + + cookbookChapter.AddToWordDoc(clsWord.WordApplication, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, ref isFirstPageOfContent); + + cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; + } + + if (recipeHighlights.Count > 0) + { + clsWord.WordApplication.Selection.InsertBreak(WdBreakType.wdSectionBreakNextPage); + clsWord.Insert_HeaderText(String.Empty); + clsWord.Insert_PageNumberFooter(ref isFirstPageOfContent); + } + + foreach (var recipeHighlight in recipeHighlights) + { + var recipe = Recipe.GetRecipeByID(recipeHighlight.recipeID.Value); + recipe.RecipeRenderedEvent += HandleRecipeRendered; + recipe.AddToWordDoc(clsWord.WordApplication, recipePageDictionary, recipesAlpha, pagesAlreadyAdded); + recipe.RecipeRenderedEvent -= HandleRecipeRendered; + } + + clsWord.WordApplication.Selection.InsertBreak(WdBreakType.wdSectionBreakNextPage); + clsWord.Insert_HeaderText(String.Empty); + clsWord.Insert_PageNumberFooter(ref isFirstPageOfContent); + + clsWord.WordApplication.ActiveDocument.Indexes.Add(clsWord.WordApplication.Selection.Range, Microsoft.Office.Interop.Word.WdHeadingSeparator.wdHeadingSeparatorNone, 1, NumberOfColumns: 2, IndexLanguage: Microsoft.Office.Interop.Word.WdLanguageID.wdEnglishUS); + clsWord.WordApplication.ActiveDocument.Indexes[1].TabLeader = Microsoft.Office.Interop.Word.WdTabLeader.wdTabLeaderDots; + + if (clsWord.WordApplication.ActiveDocument.Bookmarks.Exists("TableOfContents")) + { + clsWord.WordApplication.Selection.GoTo(Microsoft.Office.Interop.Word.WdGoToItem.wdGoToBookmark, Name: "TableOfContents"); + clsWord.WordApplication.ActiveDocument.TablesOfContents.Add(clsWord.WordApplication.Selection.Range, RightAlignPageNumbers: true, IncludePageNumbers: true); + clsWord.WordApplication.ActiveDocument.TablesOfContents[1].Update(); + } + + clsWord.WordApplication.ActiveDocument.SaveAs2(fileToSaveTo); + clsWord.WordApplication.ActiveDocument.Close(); + + } + catch(Exception ex) + { + MessageBox.Show("Error creating document " + ex.ToString()); + } + finally + { + clsWord.ShutDownWord(); + } + + } + + private void HandleRecipeRendered(object sender, System.EventArgs e) + { + mNumberRecipiesRendered += 1; + + if (LongRunningStatusUpdatedEvent != null) + { + LongRunningStatusUpdatedEvent.Invoke(this, new LongRunningStatusUpdatedEventArgs("Rendered " + mNumberRecipiesRendered.ToString() + " of " + mTotalNumberRecipiesToRender.ToString(), mNumberRecipiesRendered, mTotalNumberRecipiesToRender)); + } + + } + + public int GetTotalRecipeCount() + { + int returnValue = 0; + foreach (var cookbookChapter in cookbookChapters) + { + returnValue += cookbookChapter.GetTotalRecipeCount(); + } + + returnValue += recipeHighlights.Count; + + return returnValue; + } + } +} diff --git a/JRCookbookBusiness/CookbookChapter.cs b/JRCookbookBusiness/CookbookChapter.cs new file mode 100644 index 0000000..72e92b7 --- /dev/null +++ b/JRCookbookBusiness/CookbookChapter.cs @@ -0,0 +1,410 @@ +using Microsoft.AspNetCore.Html; +using Microsoft.Office.Interop.Word; +using System; +using System.CodeDom; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class CookbookChapter + { + public Guid? cookbookChapterID = null; + public Guid? parentChapterID = null; + public Guid? cookbookID = null; + public String name = String.Empty; + public String comments = String.Empty; + + public List cookbookChapters = new List(); + public List recipeHighlights = new List(); + + public event EventHandler RecipeRenderedEvent; + + public CookbookChapter() + { + } + + public CookbookChapter(Guid cookbookID, Guid cookbookChapterID) + { + PopulateByID(cookbookID, cookbookChapterID); + } + + public void Save() + { + if (this.cookbookChapterID == null) + { + this.cookbookChapterID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDCookbookChapter(); + clsDatabaseLayer.GetDatabaseLayer().InsertCookbookChapter(this); + } + else + { + clsDatabaseLayer.GetDatabaseLayer().UpdateCookbookChapter(this); + } + } + + public void Delete() + { + foreach (var cookbookChapter in cookbookChapters) + { + cookbookChapter.Delete(); + } + foreach (var recipe in recipeHighlights) + { + recipe.Delete(); + } + clsDatabaseLayer.GetDatabaseLayer().DeleteCookbookChapterByID(cookbookID.Value, cookbookChapterID.Value); + } + + internal String GenerateWebPagesToFolder(String folderToSaveTo, Dictionary recipePageDictionary, SortedList recipesAlpha, SortedSet pagesAlreadyAdded, List trackbackListForThisChapter) + { + String pageNameToUse = SharedRoutines.RemoveSpecialCharactersFromFileName(this.name); + String pageNameToUseWithExtension = pageNameToUse + ".htm"; + + while (pagesAlreadyAdded.Contains(pageNameToUseWithExtension.ToUpper())) + { + pageNameToUse += "1"; + pageNameToUseWithExtension = pageNameToUse + ".htm"; + } + + pagesAlreadyAdded.Add(pageNameToUseWithExtension.ToUpper()); + + + var builderChapterIndex = new HtmlContentBuilder(); + + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendFormat("{0}" + Constants.CRLF, this.name); + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendHtmlLine(""); + + if ((trackbackListForThisChapter?.Count() ?? 0) > 0) + { + builderChapterIndex.AppendHtmlLine(" "); + builderChapterIndex.AppendHtmlLine(" "); + builderChapterIndex.AppendHtmlLine(" "); + } + + builderChapterIndex.AppendHtml(HTMLAddChapterName()); + + Trackback thisTrackback = new Trackback(); + thisTrackback.TrackbackURL = pageNameToUseWithExtension; + thisTrackback.TrackbackText = this.name; + + List trackbackListForChildren = new List(); + trackbackListForChildren.AddRange(trackbackListForThisChapter); + trackbackListForChildren.Add(thisTrackback); + + foreach (var cookbookChapter in cookbookChapters) + { + var chapterURLAdded = cookbookChapter.GenerateWebPagesToFolder(folderToSaveTo, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, trackbackListForChildren); + + cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; + builderChapterIndex.AppendHtml(HTMLAddSubChapterToIndex(cookbookChapter, chapterURLAdded)); + cookbookChapter.RecipeRenderedEvent -= HandleRecipeRendered; + } + foreach (var recipeHighlight in recipeHighlights) + { + var recipe = Recipe.GetRecipeByID(recipeHighlight.recipeID.Value); + recipe.GenerateWebPageToFolder(folderToSaveTo, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, trackbackListForChildren); + + builderChapterIndex.AppendHtml(HTMLAddRecipeToIndex(recipe, recipePageDictionary)); + + if (RecipeRenderedEvent != null) + { + RecipeRenderedEvent.Invoke(recipe, new EventArgs()); + } + + } + + builderChapterIndex.AppendHtmlLine("
"); + builderChapterIndex.AppendHtml(" "); + builderChapterIndex.AppendHtmlLine("
"); + builderChapterIndex.AppendHtmlLine(""); + builderChapterIndex.AppendHtmlLine(""); + + + var strChapterPath = folderToSaveTo; + if (strChapterPath.EndsWith("\\") == false) + { + strChapterPath += "\\"; + } + + strChapterPath += pageNameToUseWithExtension; + + using (var writer = new System.IO.StreamWriter(strChapterPath, false)) + { + builderChapterIndex.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + } + + + + return pageNameToUseWithExtension; + } + + private String HTMLAddChapterName() + { + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", this.name); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddSubChapterToIndex(CookbookChapter chapter, String chapterURL) + { + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("", chapterURL); + builder.AppendFormat("{0}", chapter.name); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddRecipeToIndex(Recipe recipe, Dictionary recipePageDictionary) + { + var recipePageURL = recipePageDictionary.GetValueOrDefault(recipe.recipeID.Value, String.Empty); + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("", recipePageURL); + builder.AppendFormat("{0}", recipe.recipename); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + + internal void AddToWordDoc(Microsoft.Office.Interop.Word.Application objWord, Dictionary recipePageDictionary, SortedList recipesAlpha, SortedSet pagesAlreadyAdded, ref bool isFirstPageOfContent) + { + String pageNameToUse = SharedRoutines.RemoveSpecialCharactersFromFileName(this.name); + String pageNameToUseWithExtension = pageNameToUse; + + while (pagesAlreadyAdded.Contains(pageNameToUseWithExtension.ToUpper())) + { + pageNameToUse += "1"; + pageNameToUseWithExtension = pageNameToUse; + } + + pagesAlreadyAdded.Add(pageNameToUseWithExtension.ToUpper()); + + clsWord.WordApplication.Selection.InsertBreak(WdBreakType.wdSectionBreakNextPage); + clsWord.Insert_HeaderText(this.name); + clsWord.Insert_PageNumberFooter(ref isFirstPageOfContent); + + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 1, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + objWord.Selection.Cells[1].LeftPadding = 0; + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineWidth = WdLineWidth.wdLineWidth050pt; + //objWord.Selection.Font.Bold = 1; + //objWord.Selection.Font.Size = clsWord.WORD_CHAPTER_NAME_FONT_SIZE; + //objWord.Selection.TypeText(this.name); + //objWord.Selection.Font.Bold = 0; + + objWord.Selection.set_Style(objWord.ActiveDocument.Styles["Heading 1"]); + objWord.Selection.TypeText(this.name); + + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + clsWord.AddHalfSpaceLineAtEndOfDocument(); + objWord.Selection.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle; + objWord.Selection.ParagraphFormat.SpaceAfter = 0F; + + foreach (var cookbookChapter in cookbookChapters) + { + cookbookChapter.RecipeRenderedEvent += HandleRecipeRendered; + cookbookChapter.AddToWordDoc(objWord, recipePageDictionary, recipesAlpha, pagesAlreadyAdded, ref isFirstPageOfContent); + cookbookChapter.RecipeRenderedEvent -= HandleRecipeRendered; + } + foreach (var recipeHighlight in recipeHighlights) + { + var recipe = Recipe.GetRecipeByID(recipeHighlight.recipeID.Value); + recipe.AddToWordDoc(objWord, recipePageDictionary, recipesAlpha, pagesAlreadyAdded); + + if (RecipeRenderedEvent != null) + { + RecipeRenderedEvent.Invoke(recipe, new EventArgs()); + } + + //builderChapterIndex.AppendHtml(HTMLAddRecipeToIndex(recipe, recipePageDictionary)); + } + } + + private void HandleRecipeRendered(object sender, System.EventArgs e) + { + if (RecipeRenderedEvent != null) + { + RecipeRenderedEvent.Invoke(sender, new EventArgs()); + } + } + + public static CookbookChapter GetCookbookByID(Guid cookbookID, Guid cookbookChapterID) + { + return new CookbookChapter(cookbookID, cookbookChapterID); + } + + public static CookbookChapter GetCookbookChapterByDataRow(DataRow row) + { + var newChapter = new CookbookChapter(); + newChapter.PopulateFromDataRow(row); + return newChapter; + } + + private void PopulateByID(Guid cookbookID, Guid cookbookChapterID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetCookbookChapterByID(cookbookID, cookbookChapterID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("cookbookChapterID")) + cookbookChapterID = null; + else + cookbookChapterID = (Guid)dataRow["cookbookChapterID"]; + + if (dataRow.IsNull("cookbookID")) + cookbookID = null; + else + cookbookID = (Guid)dataRow["cookbookID"]; + + if (dataRow.IsNull("parentChapterID")) + parentChapterID = null; + else + parentChapterID = (Guid)dataRow["parentChapterID"]; + + if (dataRow.IsNull("name")) + name = String.Empty; + else + name = (String)dataRow["name"]; + + if (dataRow.IsNull("comments")) + comments = String.Empty; + else + comments = (String)dataRow["comments"]; + + LoadChapters(); + LoadRecipeHighlights(); + } + + private void InitializeAllFields() + { + cookbookChapterID = null; + parentChapterID = null; + cookbookID = null; + name = String.Empty; + comments = String.Empty; + + cookbookChapters = new List(); + recipeHighlights = new List(); + } + + private void LoadChapters() + { + //Populate child objects + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetCookbookChaptersByParentChapter(this.cookbookID.Value, this.cookbookChapterID); + + foreach (DataRow childDataRow in recordSet.Tables[0].Rows) + { + var newChapter = CookbookChapter.GetCookbookChapterByDataRow(childDataRow); + cookbookChapters.Add(newChapter); + } + + } + + private void LoadRecipeHighlights() + { + //Populate child objects + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeHighlightsByParentChapter(this.cookbookID.Value, this.cookbookChapterID); + + foreach (DataRow childDataRow in recordSet.Tables[0].Rows) + { + var newRecipeHighlights = RecipeHighlights.GetRecipeHighlightsByDataRow(childDataRow); + recipeHighlights.Add(newRecipeHighlights); + } + + } + + public int GetTotalRecipeCount() + { + int returnValue = 0; + foreach (var cookbookChapter in cookbookChapters) + { + returnValue += cookbookChapter.GetTotalRecipeCount(); + } + + returnValue += recipeHighlights.Count; + + return returnValue; + } + + } +} diff --git a/JRCookbookBusiness/Ingredient.cs b/JRCookbookBusiness/Ingredient.cs new file mode 100644 index 0000000..e875ad0 --- /dev/null +++ b/JRCookbookBusiness/Ingredient.cs @@ -0,0 +1,1310 @@ +using Microsoft.AspNetCore.Html; +using System; +using System.Net; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Office.Interop.Word; +using System.Text.RegularExpressions; + +namespace JRCookbookBusiness +{ + public class Ingredient + { + public Guid? ingredientID = null; + private String _name = String.Empty; + public String source = String.Empty; + public Guid ingredientfolderID = Guid.Empty; + public String comments = String.Empty; + public Single water = 0; + public Single calories = 0; + public Single caloriesfromfat = 0; + public Single percentcaloriesfromfat = 0; + public Single energy = 0; + public Single protein = 0; + public Single totalfat = 0; + public Single sugar = 0; + public Single totalcarbohydrate = 0; + public Single fiber = 0; + public Single calcium = 0; + public Single phosphorus = 0; + public Single iron = 0; + public Single sodium = 0; + public Single potassium = 0; + public Single magnesium = 0; + public Single zinc = 0; + public Single copper = 0; + public Single manganese = 0; + public Single selenium = 0; + public Single vitamina = 0; + public Single vitamine = 0; + public Single thiamin = 0; + public Single riboflavin = 0; + public Single niacin = 0; + public Single pantothenicacid = 0; + public Single vitaminb6 = 0; + public Single folate = 0; + public Single vitaminb12 = 0; + public Single vitaminc = 0; + public Single saturatedfat = 0; + public Single monounsaturatedfat = 0; + public Single polyunsaturatedfat = 0; + public Single cholesterol = 0; + public Single alcohol = 0; + public Single caffeine = 0; + public Int16 selectedweight = 0; + public String usdaingredient = String.Empty; + public String useringredient = String.Empty; + public Guid? selectedmeasureid = null; + public Single biotin = 0; + public String commonname = String.Empty; + public Single energyfromfat = 0; + public String nutritionsource = String.Empty; + public Double servingsize = 0; + public Guid? servingsizemeasureid = null; + public Single sugaralcohols = 0; + public Single transfattyacids = 0; + public Single vitamind = 0; + public Single caloriesfromalcohol = 0; + public Single caloriesfromcarbs = 0; + public Single caloriesfromprotein = 0; + public Single energyfromalcohol = 0; + public Single energyfromcarbs = 0; + public Single energyfromprotein = 0; + public Single percentcaloriesfromalcohol = 0; + public Single percentcaloriesfromcarbs = 0; + public Single percentcaloriesfromprotein = 0; + public Single alanine = 0; + public Single alcoholfactor = 0; + public Single alphacarotene = 0; + public Single alphalinolenicacid = 0; + public Single arachidonicacid = 0; + public Single arginine = 0; + public Single ash = 0; + public Single asparticacid = 0; + public Single betacarotene = 0; + public Single betacryptoxanthin = 0; + public Single betasitosterol = 0; + public Single betatocopherol = 0; + public Single campesterol = 0; + public Single carbohydratefactor = 0; + public Single chloride = 0; + public Single choline = 0; + public Single chromium = 0; + public Single cystine = 0; + public Single deltatocopherol = 0; + public Single dihomogammalinolenicacid = 0; + public Single docosahexaenoicacid = 0; + public Single docosapentaenoicacid = 0; + public Single eicosadienoicacid = 0; + public Single eicosapentaenoicacid = 0; + public Single fatfactor = 0; + public Single fluoride = 0; + public Single fructose = 0; + public Single galactose = 0; + public Single gammalinolenicacid = 0; + public Single gammatocopherol = 0; + public Single glucose = 0; + public Single glutamicacid = 0; + public Single glycine = 0; + public Single histidine = 0; + public Single hydroxyproline = 0; + public Single iodine = 0; + public Single isoleucine = 0; + public Single lactose = 0; + public Single leucine = 0; + public Single linoleicacid = 0; + public Single lycopene = 0; + public Single lysine = 0; + public Single maltose = 0; + public Single methionine = 0; + public Single molybdenum = 0; + public Single monounsaturatedfattyacid_14_1 = 0; + public Single monounsaturatedfattyacid_15_1 = 0; + public Single monounsaturatedfattyacid_16_1 = 0; + public Single monounsaturatedfattyacid_17_1 = 0; + public Single monounsaturatedfattyacid_18_1 = 0; + public Single monounsaturatedfattyacid_20_1 = 0; + public Single monounsaturatedfattyacid_22_1 = 0; + public Single monounsaturatedfattyacid_24_1 = 0; + public Single netcarbohydrates = 0; + public String nutritioncalculationmode = String.Empty; + public Single omega3fattyacids = 0; + public Single omega6fattyacids = 0; + public Single phenylalanine = 0; + public Single phytosterols = 0; + public Single polyunsaturatedfattyacid_18_2 = 0; + public Single polyunsaturatedfattyacid_18_3 = 0; + public Single polyunsaturatedfattyacid_18_4 = 0; + public Single polyunsaturatedfattyacid_20_3 = 0; + public Single polyunsaturatedfattyacid_20_4 = 0; + public Single polyunsaturatedfattyacid_21_5 = 0; + public Single polyunsaturatedfattyacid_22_4 = 0; + public Single proline = 0; + public Single proteinfactor = 0; + public Single refuse = 0; + public Single retinol = 0; + public Single saturatedfattyacid_10_0 = 0; + public Single saturatedfattyacid_12_0 = 0; + public Single saturatedfattyacid_13_0 = 0; + public Single saturatedfattyacid_14_0 = 0; + public Single saturatedfattyacid_15_0 = 0; + public Single saturatedfattyacid_16_0 = 0; + public Single saturatedfattyacid_17_0 = 0; + public Single saturatedfattyacid_18_0 = 0; + public Single saturatedfattyacid_20_0 = 0; + public Single saturatedfattyacid_22_0 = 0; + public Single saturatedfattyacid_24_0 = 0; + public Single saturatedfattyacid_4_0 = 0; + public Single saturatedfattyacid_6_0 = 0; + public Single saturatedfattyacid_8_0 = 0; + public Single serine = 0; + public Single starch = 0; + public Single stigmasterol = 0; + public Single sucrose = 0; + public Single theobromine = 0; + public Single threonine = 0; + public Single transmonoenoicfattyacids = 0; + public Single transpolyenoicfattyacids = 0; + public Single tryptophan = 0; + public Single tyrosine = 0; + public Single valine = 0; + public Single vitamink = 0; + public Single volume = 0; + + private String _normalizedIngredientName = String.Empty; + + public Dictionary ingredientMeasureDictionary = new Dictionary(); + + private static List _allIngredients = null; + + public Ingredient() + { + } + + public Ingredient(Guid ingredientID) + { + PopulateByID(ingredientID); + } + + public string? name + { + get => _name; + set + { + _name = value; + _normalizedIngredientName = RecipeIngredient.NormalizeRecipeIngredientName(value); + } + } + + public string? normalizedIngredientName + { + get + { + return _normalizedIngredientName; + } + } + + //public void Delete() + //{ + // clsDatabaseLayer.GetDatabaseLayer().DeleteIngredientByID(ingredientID); + //} + + public static Ingredient GetIngredientByID(Guid ingredientID) + { + return new Ingredient(ingredientID); + } + + public static Ingredient GetIngredientByDataRow(DataRow dataRow) + { + var newIngredient = new Ingredient(); + newIngredient.PopulateFromDataRow(dataRow); + + return newIngredient; + } + + public static List GetAllIngredients() + { + if (_allIngredients == null) + { + _allIngredients = new List(); + + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetAllIngredients(); + + foreach (DataRow dataRow in recordSet.Tables[0].Rows) + { + var newIngredient = GetIngredientByDataRow(dataRow); + _allIngredients.Add(newIngredient); + } + + } + return _allIngredients; + + } + public static List GetIngredientsBySearchString(String searchString) + { + var returnValue = new List(); + + //var searchRegEx = new Regex(@"\A" + new Regex(@"\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\").Replace(searchString, ch => @"\" + ch).Replace('_', '.').Replace("%", ".*") + @"\z", RegexOptions.Singleline); + var searchRegEx = new Regex(new Regex(@"\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\").Replace(searchString, ch => @"\" + ch).Replace('_', '.').Replace("%", ".*"), RegexOptions.Singleline); + foreach (var item in GetAllIngredients()) + { + if (searchRegEx.IsMatch(item.normalizedIngredientName)) + { + returnValue.Add(item); + } + } + //DataSet recordSet; + //recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientsBySearchString(searchString); + + //foreach (DataRow dataRow in recordSet.Tables[0].Rows) + //{ + // var newIngredient = GetIngredientByDataRow(dataRow); + // returnValue.Add(newIngredient); + //} + + return returnValue; + + } + + //public static void DeleteByID(Guid ingredientID) + //{ + // var ingredient = new Ingredient(ingredientID); + // ingredient.Delete(); + //} + + + private void PopulateByID(Guid ingredientID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientByID(ingredientID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("ingredientid")) + ingredientID = null; + else + ingredientID = (Guid)dataRow["ingredientid"]; + + if (dataRow.IsNull("name")) + name = String.Empty; + else + name = (String)dataRow["name"]; + + if (dataRow.IsNull("source")) + source = String.Empty; + else + source = (String)dataRow["source"]; + + if (dataRow.IsNull("ingredientfolderid")) + ingredientfolderID = Guid.Empty; + else + ingredientfolderID = (Guid)dataRow["ingredientfolderid"]; + + if (dataRow.IsNull("comments")) + comments = String.Empty; + else + comments = (String)dataRow["comments"]; + + if (dataRow.IsNull("water")) + water = 0; + else + water = (Single)dataRow["water"]; + + if (dataRow.IsNull("calories")) + calories = 0; + else + calories = (Single)dataRow["calories"]; + + if (dataRow.IsNull("caloriesfromfat")) + caloriesfromfat = 0; + else + caloriesfromfat = (Single)dataRow["caloriesfromfat"]; + + if (dataRow.IsNull("percentcaloriesfromfat")) + percentcaloriesfromfat = 0; + else + percentcaloriesfromfat = (Single)dataRow["percentcaloriesfromfat"]; + + if (dataRow.IsNull("energy")) + energy = 0; + else + energy = (Single)dataRow["energy"]; + + if (dataRow.IsNull("protein")) + protein = 0; + else + protein = (Single)dataRow["protein"]; + + if (dataRow.IsNull("totalfat")) + totalfat = 0; + else + totalfat = (Single)dataRow["totalfat"]; + + if (dataRow.IsNull("sugar")) + sugar = 0; + else + sugar = (Single)dataRow["sugar"]; + + if (dataRow.IsNull("totalcarbohydrate")) + totalcarbohydrate = 0; + else + totalcarbohydrate = (Single)dataRow["totalcarbohydrate"]; + + if (dataRow.IsNull("fiber")) + fiber = 0; + else + fiber = (Single)dataRow["fiber"]; + + if (dataRow.IsNull("calcium")) + calcium = 0; + else + calcium = (Single)dataRow["calcium"]; + + if (dataRow.IsNull("phosphorus")) + phosphorus = 0; + else + phosphorus = (Single)dataRow["phosphorus"]; + + if (dataRow.IsNull("iron")) + iron = 0; + else + iron = (Single)dataRow["iron"]; + + if (dataRow.IsNull("sodium")) + sodium = 0; + else + sodium = (Single)dataRow["sodium"]; + + if (dataRow.IsNull("potassium")) + potassium = 0; + else + potassium = (Single)dataRow["potassium"]; + + if (dataRow.IsNull("magnesium")) + magnesium = 0; + else + magnesium = (Single)dataRow["magnesium"]; + + if (dataRow.IsNull("zinc")) + zinc = 0; + else + zinc = (Single)dataRow["zinc"]; + + if (dataRow.IsNull("copper")) + copper = 0; + else + copper = (Single)dataRow["copper"]; + + if (dataRow.IsNull("manganese")) + manganese = 0; + else + manganese = (Single)dataRow["manganese"]; + + if (dataRow.IsNull("selenium")) + selenium = 0; + else + selenium = (Single)dataRow["selenium"]; + + if (dataRow.IsNull("vitamina")) + vitamina = 0; + else + vitamina = (Single)dataRow["vitamina"]; + + if (dataRow.IsNull("vitamine")) + vitamine = 0; + else + vitamine = (Single)dataRow["vitamine"]; + + if (dataRow.IsNull("thiamin")) + thiamin = 0; + else + thiamin = (Single)dataRow["thiamin"]; + + if (dataRow.IsNull("riboflavin")) + riboflavin = 0; + else + riboflavin = (Single)dataRow["riboflavin"]; + + if (dataRow.IsNull("niacin")) + niacin = 0; + else + niacin = (Single)dataRow["niacin"]; + + if (dataRow.IsNull("pantothenicacid")) + pantothenicacid = 0; + else + pantothenicacid = (Single)dataRow["pantothenicacid"]; + + if (dataRow.IsNull("vitaminb6")) + vitaminb6 = 0; + else + vitaminb6 = (Single)dataRow["vitaminb6"]; + + if (dataRow.IsNull("folate")) + folate = 0; + else + folate = (Single)dataRow["folate"]; + + if (dataRow.IsNull("vitaminb12")) + vitaminb12 = 0; + else + vitaminb12 = (Single)dataRow["vitaminb12"]; + + if (dataRow.IsNull("vitaminc")) + vitaminc = 0; + else + vitaminc = (Single)dataRow["vitaminc"]; + + if (dataRow.IsNull("saturatedfat")) + saturatedfat = 0; + else + saturatedfat = (Single)dataRow["saturatedfat"]; + + if (dataRow.IsNull("monounsaturatedfat")) + monounsaturatedfat = 0; + else + monounsaturatedfat = (Single)dataRow["monounsaturatedfat"]; + + if (dataRow.IsNull("polyunsaturatedfat")) + polyunsaturatedfat = 0; + else + polyunsaturatedfat = (Single)dataRow["polyunsaturatedfat"]; + + if (dataRow.IsNull("cholesterol")) + cholesterol = 0; + else + cholesterol = (Single)dataRow["cholesterol"]; + + if (dataRow.IsNull("alcohol")) + alcohol = 0; + else + alcohol = (Single)dataRow["alcohol"]; + + if (dataRow.IsNull("caffeine")) + caffeine = 0; + else + caffeine = (Single)dataRow["caffeine"]; + + if (dataRow.IsNull("selectedweight")) + selectedweight = 0; + else + selectedweight = (Int16)dataRow["selectedweight"]; + + if (dataRow.IsNull("usdaingredient")) + usdaingredient = String.Empty; + else + usdaingredient = (String)dataRow["usdaingredient"]; + + if (dataRow.IsNull("useringredient")) + useringredient = String.Empty; + else + useringredient = (String)dataRow["useringredient"]; + + if (dataRow.IsNull("selectedmeasureid")) + selectedmeasureid = null; + else + selectedmeasureid = (Guid)dataRow["selectedmeasureid"]; + + if (dataRow.IsNull("biotin")) + biotin = 0; + else + biotin = (Single)dataRow["biotin"]; + + if (dataRow.IsNull("commonname")) + commonname = String.Empty; + else + commonname = (String)dataRow["commonname"]; + + if (dataRow.IsNull("energyfromfat")) + energyfromfat = 0; + else + energyfromfat = (Single)dataRow["energyfromfat"]; + + if (dataRow.IsNull("nutritionsource")) + nutritionsource = String.Empty; + else + nutritionsource = (String)dataRow["nutritionsource"]; + + if (dataRow.IsNull("servingsize")) + servingsize = 0; + else + servingsize = (Double)dataRow["servingsize"]; + + if (dataRow.IsNull("servingsizemeasureid")) + servingsizemeasureid = null; + else + servingsizemeasureid = (Guid)dataRow["servingsizemeasureid"]; + + if (dataRow.IsNull("sugaralcohols")) + sugaralcohols = 0; + else + sugaralcohols = (Single)dataRow["sugaralcohols"]; + + if (dataRow.IsNull("transfattyacids")) + transfattyacids = 0; + else + transfattyacids = (Single)dataRow["transfattyacids"]; + + if (dataRow.IsNull("vitamind")) + vitamind = 0; + else + vitamind = (Single)dataRow["vitamind"]; + + if (dataRow.IsNull("caloriesfromalcohol")) + caloriesfromalcohol = 0; + else + caloriesfromalcohol = (Single)dataRow["caloriesfromalcohol"]; + + if (dataRow.IsNull("caloriesfromcarbs")) + caloriesfromcarbs = 0; + else + caloriesfromcarbs = (Single)dataRow["caloriesfromcarbs"]; + + if (dataRow.IsNull("caloriesfromprotein")) + caloriesfromprotein = 0; + else + caloriesfromprotein = (Single)dataRow["caloriesfromprotein"]; + + if (dataRow.IsNull("energyfromalcohol")) + energyfromalcohol = 0; + else + energyfromalcohol = (Single)dataRow["energyfromalcohol"]; + + if (dataRow.IsNull("energyfromcarbs")) + energyfromcarbs = 0; + else + energyfromcarbs = (Single)dataRow["energyfromcarbs"]; + + if (dataRow.IsNull("energyfromprotein")) + energyfromprotein = 0; + else + energyfromprotein = (Single)dataRow["energyfromprotein"]; + + if (dataRow.IsNull("percentcaloriesfromalcohol")) + percentcaloriesfromalcohol = 0; + else + percentcaloriesfromalcohol = (Single)dataRow["percentcaloriesfromalcohol"]; + + if (dataRow.IsNull("percentcaloriesfromcarbs")) + percentcaloriesfromcarbs = 0; + else + percentcaloriesfromcarbs = (Single)dataRow["percentcaloriesfromcarbs"]; + + if (dataRow.IsNull("percentcaloriesfromprotein")) + percentcaloriesfromprotein = 0; + else + percentcaloriesfromprotein = (Single)dataRow["percentcaloriesfromprotein"]; + + if (dataRow.IsNull("alanine")) + alanine = 0; + else + alanine = (Single)dataRow["alanine"]; + + if (dataRow.IsNull("alcoholfactor")) + alcoholfactor = 0; + else + alcoholfactor = (Single)dataRow["alcoholfactor"]; + + if (dataRow.IsNull("alphacarotene")) + alphacarotene = 0; + else + alphacarotene = (Single)dataRow["alphacarotene"]; + + if (dataRow.IsNull("alphalinolenicacid")) + alphalinolenicacid = 0; + else + alphalinolenicacid = (Single)dataRow["alphalinolenicacid"]; + + if (dataRow.IsNull("arachidonicacid")) + arachidonicacid = 0; + else + arachidonicacid = (Single)dataRow["arachidonicacid"]; + + if (dataRow.IsNull("arginine")) + arginine = 0; + else + arginine = (Single)dataRow["arginine"]; + + if (dataRow.IsNull("ash")) + ash = 0; + else + ash = (Single)dataRow["ash"]; + + if (dataRow.IsNull("asparticacid")) + asparticacid = 0; + else + asparticacid = (Single)dataRow["asparticacid"]; + + if (dataRow.IsNull("betacarotene")) + betacarotene = 0; + else + betacarotene = (Single)dataRow["betacarotene"]; + + if (dataRow.IsNull("betacryptoxanthin")) + betacryptoxanthin = 0; + else + betacryptoxanthin = (Single)dataRow["betacryptoxanthin"]; + + if (dataRow.IsNull("betasitosterol")) + betasitosterol = 0; + else + betasitosterol = (Single)dataRow["betasitosterol"]; + + if (dataRow.IsNull("betatocopherol")) + betatocopherol = 0; + else + betatocopherol = (Single)dataRow["betatocopherol"]; + + if (dataRow.IsNull("campesterol")) + campesterol = 0; + else + campesterol = (Single)dataRow["campesterol"]; + + if (dataRow.IsNull("carbohydratefactor")) + carbohydratefactor = 0; + else + carbohydratefactor = (Single)dataRow["carbohydratefactor"]; + + if (dataRow.IsNull("chloride")) + chloride = 0; + else + chloride = (Single)dataRow["chloride"]; + + if (dataRow.IsNull("choline")) + choline = 0; + else + choline = (Single)dataRow["choline"]; + + if (dataRow.IsNull("chromium")) + chromium = 0; + else + chromium = (Single)dataRow["chromium"]; + + if (dataRow.IsNull("cystine")) + cystine = 0; + else + cystine = (Single)dataRow["cystine"]; + + if (dataRow.IsNull("deltatocopherol")) + deltatocopherol = 0; + else + deltatocopherol = (Single)dataRow["deltatocopherol"]; + + if (dataRow.IsNull("dihomogammalinolenicacid")) + dihomogammalinolenicacid = 0; + else + dihomogammalinolenicacid = (Single)dataRow["dihomogammalinolenicacid"]; + + if (dataRow.IsNull("docosahexaenoicacid")) + docosahexaenoicacid = 0; + else + docosahexaenoicacid = (Single)dataRow["docosahexaenoicacid"]; + + if (dataRow.IsNull("docosapentaenoicacid")) + docosapentaenoicacid = 0; + else + docosapentaenoicacid = (Single)dataRow["docosapentaenoicacid"]; + + if (dataRow.IsNull("eicosadienoicacid")) + eicosadienoicacid = 0; + else + eicosadienoicacid = (Single)dataRow["eicosadienoicacid"]; + + if (dataRow.IsNull("eicosapentaenoicacid")) + eicosapentaenoicacid = 0; + else + eicosapentaenoicacid = (Single)dataRow["eicosapentaenoicacid"]; + + if (dataRow.IsNull("fatfactor")) + fatfactor = 0; + else + fatfactor = (Single)dataRow["fatfactor"]; + + if (dataRow.IsNull("fluoride")) + fluoride = 0; + else + fluoride = (Single)dataRow["fluoride"]; + + if (dataRow.IsNull("fructose")) + fructose = 0; + else + fructose = (Single)dataRow["fructose"]; + + if (dataRow.IsNull("galactose")) + galactose = 0; + else + galactose = (Single)dataRow["galactose"]; + + if (dataRow.IsNull("gammalinolenicacid")) + gammalinolenicacid = 0; + else + gammalinolenicacid = (Single)dataRow["gammalinolenicacid"]; + + if (dataRow.IsNull("gammatocopherol")) + gammatocopherol = 0; + else + gammatocopherol = (Single)dataRow["gammatocopherol"]; + + if (dataRow.IsNull("glucose")) + glucose = 0; + else + glucose = (Single)dataRow["glucose"]; + + if (dataRow.IsNull("glutamicacid")) + glutamicacid = 0; + else + glutamicacid = (Single)dataRow["glutamicacid"]; + + if (dataRow.IsNull("glycine")) + glycine = 0; + else + glycine = (Single)dataRow["glycine"]; + + if (dataRow.IsNull("histidine")) + histidine = 0; + else + histidine = (Single)dataRow["histidine"]; + + if (dataRow.IsNull("hydroxyproline")) + hydroxyproline = 0; + else + hydroxyproline = (Single)dataRow["hydroxyproline"]; + + if (dataRow.IsNull("iodine")) + iodine = 0; + else + iodine = (Single)dataRow["iodine"]; + + if (dataRow.IsNull("isoleucine")) + isoleucine = 0; + else + isoleucine = (Single)dataRow["isoleucine"]; + + if (dataRow.IsNull("lactose")) + lactose = 0; + else + lactose = (Single)dataRow["lactose"]; + + if (dataRow.IsNull("leucine")) + leucine = 0; + else + leucine = (Single)dataRow["leucine"]; + + if (dataRow.IsNull("linoleicacid")) + linoleicacid = 0; + else + linoleicacid = (Single)dataRow["linoleicacid"]; + + if (dataRow.IsNull("lycopene")) + lycopene = 0; + else + lycopene = (Single)dataRow["lycopene"]; + + if (dataRow.IsNull("lysine")) + lysine = 0; + else + lysine = (Single)dataRow["lysine"]; + + if (dataRow.IsNull("maltose")) + maltose = 0; + else + maltose = (Single)dataRow["maltose"]; + + if (dataRow.IsNull("methionine")) + methionine = 0; + else + methionine = (Single)dataRow["methionine"]; + + if (dataRow.IsNull("molybdenum")) + molybdenum = 0; + else + molybdenum = (Single)dataRow["molybdenum"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_14_1")) + monounsaturatedfattyacid_14_1 = 0; + else + monounsaturatedfattyacid_14_1 = (Single)dataRow["monounsaturatedfattyacid_14_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_15_1")) + monounsaturatedfattyacid_15_1 = 0; + else + monounsaturatedfattyacid_15_1 = (Single)dataRow["monounsaturatedfattyacid_15_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_16_1")) + monounsaturatedfattyacid_16_1 = 0; + else + monounsaturatedfattyacid_16_1 = (Single)dataRow["monounsaturatedfattyacid_16_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_17_1")) + monounsaturatedfattyacid_17_1 = 0; + else + monounsaturatedfattyacid_17_1 = (Single)dataRow["monounsaturatedfattyacid_17_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_18_1")) + monounsaturatedfattyacid_18_1 = 0; + else + monounsaturatedfattyacid_18_1 = (Single)dataRow["monounsaturatedfattyacid_18_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_20_1")) + monounsaturatedfattyacid_20_1 = 0; + else + monounsaturatedfattyacid_20_1 = (Single)dataRow["monounsaturatedfattyacid_20_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_22_1")) + monounsaturatedfattyacid_22_1 = 0; + else + monounsaturatedfattyacid_22_1 = (Single)dataRow["monounsaturatedfattyacid_22_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_24_1")) + monounsaturatedfattyacid_24_1 = 0; + else + monounsaturatedfattyacid_24_1 = (Single)dataRow["monounsaturatedfattyacid_24_1"]; + + if (dataRow.IsNull("netcarbohydrates")) + netcarbohydrates = 0; + else + netcarbohydrates = (Single)dataRow["netcarbohydrates"]; + + if (dataRow.IsNull("nutritioncalculationmode")) + nutritioncalculationmode = String.Empty; + else + nutritioncalculationmode = (string)dataRow["nutritioncalculationmode"]; + + if (dataRow.IsNull("omega3fattyacids")) + omega3fattyacids = 0; + else + omega3fattyacids = (Single)dataRow["omega3fattyacids"]; + + if (dataRow.IsNull("omega6fattyacids")) + omega6fattyacids = 0; + else + omega6fattyacids = (Single)dataRow["omega6fattyacids"]; + + if (dataRow.IsNull("phenylalanine")) + phenylalanine = 0; + else + phenylalanine = (Single)dataRow["phenylalanine"]; + + if (dataRow.IsNull("phytosterols")) + phytosterols = 0; + else + phytosterols = (Single)dataRow["phytosterols"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_18_2")) + polyunsaturatedfattyacid_18_2 = 0; + else + polyunsaturatedfattyacid_18_2 = (Single)dataRow["polyunsaturatedfattyacid_18_2"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_18_3")) + polyunsaturatedfattyacid_18_3 = 0; + else + polyunsaturatedfattyacid_18_3 = (Single)dataRow["polyunsaturatedfattyacid_18_3"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_18_4")) + polyunsaturatedfattyacid_18_4 = 0; + else + polyunsaturatedfattyacid_18_4 = (Single)dataRow["polyunsaturatedfattyacid_18_4"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_20_3")) + polyunsaturatedfattyacid_20_3 = 0; + else + polyunsaturatedfattyacid_20_3 = (Single)dataRow["polyunsaturatedfattyacid_20_3"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_20_4")) + polyunsaturatedfattyacid_20_4 = 0; + else + polyunsaturatedfattyacid_20_4 = (Single)dataRow["polyunsaturatedfattyacid_20_4"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_21_5")) + polyunsaturatedfattyacid_21_5 = 0; + else + polyunsaturatedfattyacid_21_5 = (Single)dataRow["polyunsaturatedfattyacid_21_5"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_22_4")) + polyunsaturatedfattyacid_22_4 = 0; + else + polyunsaturatedfattyacid_22_4 = (Single)dataRow["polyunsaturatedfattyacid_22_4"]; + + if (dataRow.IsNull("proline")) + proline = 0; + else + proline = (Single)dataRow["proline"]; + + if (dataRow.IsNull("proteinfactor")) + proteinfactor = 0; + else + proteinfactor = (Single)dataRow["proteinfactor"]; + + if (dataRow.IsNull("refuse")) + refuse = 0; + else + refuse = (Single)dataRow["refuse"]; + + if (dataRow.IsNull("retinol")) + retinol = 0; + else + retinol = (Single)dataRow["retinol"]; + + if (dataRow.IsNull("saturatedfattyacid_10_0")) + saturatedfattyacid_10_0 = 0; + else + saturatedfattyacid_10_0 = (Single)dataRow["saturatedfattyacid_10_0"]; + + if (dataRow.IsNull("saturatedfattyacid_12_0")) + saturatedfattyacid_12_0 = 0; + else + saturatedfattyacid_12_0 = (Single)dataRow["saturatedfattyacid_12_0"]; + + if (dataRow.IsNull("saturatedfattyacid_13_0")) + saturatedfattyacid_13_0 = 0; + else + saturatedfattyacid_13_0 = (Single)dataRow["saturatedfattyacid_13_0"]; + + if (dataRow.IsNull("saturatedfattyacid_14_0")) + saturatedfattyacid_14_0 = 0; + else + saturatedfattyacid_14_0 = (Single)dataRow["saturatedfattyacid_14_0"]; + + if (dataRow.IsNull("saturatedfattyacid_15_0")) + saturatedfattyacid_15_0 = 0; + else + saturatedfattyacid_15_0 = (Single)dataRow["saturatedfattyacid_15_0"]; + + if (dataRow.IsNull("saturatedfattyacid_16_0")) + saturatedfattyacid_16_0 = 0; + else + saturatedfattyacid_16_0 = (Single)dataRow["saturatedfattyacid_16_0"]; + + if (dataRow.IsNull("saturatedfattyacid_17_0")) + saturatedfattyacid_17_0 = 0; + else + saturatedfattyacid_17_0 = (Single)dataRow["saturatedfattyacid_17_0"]; + + if (dataRow.IsNull("saturatedfattyacid_18_0")) + saturatedfattyacid_18_0 = 0; + else + saturatedfattyacid_18_0 = (Single)dataRow["saturatedfattyacid_18_0"]; + + if (dataRow.IsNull("saturatedfattyacid_20_0")) + saturatedfattyacid_20_0 = 0; + else + saturatedfattyacid_20_0 = (Single)dataRow["saturatedfattyacid_20_0"]; + + if (dataRow.IsNull("saturatedfattyacid_22_0")) + saturatedfattyacid_22_0 = 0; + else + saturatedfattyacid_22_0 = (Single)dataRow["saturatedfattyacid_22_0"]; + + if (dataRow.IsNull("saturatedfattyacid_24_0")) + saturatedfattyacid_24_0 = 0; + else + saturatedfattyacid_24_0 = (Single)dataRow["saturatedfattyacid_24_0"]; + + if (dataRow.IsNull("saturatedfattyacid_4_0")) + saturatedfattyacid_4_0 = 0; + else + saturatedfattyacid_4_0 = (Single)dataRow["saturatedfattyacid_4_0"]; + + if (dataRow.IsNull("saturatedfattyacid_6_0")) + saturatedfattyacid_6_0 = 0; + else + saturatedfattyacid_6_0 = (Single)dataRow["saturatedfattyacid_6_0"]; + + if (dataRow.IsNull("saturatedfattyacid_8_0")) + saturatedfattyacid_8_0 = 0; + else + saturatedfattyacid_8_0 = (Single)dataRow["saturatedfattyacid_8_0"]; + + if (dataRow.IsNull("serine")) + serine = 0; + else + serine = (Single)dataRow["serine"]; + + if (dataRow.IsNull("starch")) + starch = 0; + else + starch = (Single)dataRow["starch"]; + + if (dataRow.IsNull("stigmasterol")) + stigmasterol = 0; + else + stigmasterol = (Single)dataRow["stigmasterol"]; + + if (dataRow.IsNull("sucrose")) + sucrose = 0; + else + sucrose = (Single)dataRow["sucrose"]; + + if (dataRow.IsNull("theobromine")) + theobromine = 0; + else + theobromine = (Single)dataRow["theobromine"]; + + if (dataRow.IsNull("threonine")) + threonine = 0; + else + threonine = (Single)dataRow["threonine"]; + + if (dataRow.IsNull("transmonoenoicfattyacids")) + transmonoenoicfattyacids = 0; + else + transmonoenoicfattyacids = (Single)dataRow["transmonoenoicfattyacids"]; + + if (dataRow.IsNull("transpolyenoicfattyacids")) + transpolyenoicfattyacids = 0; + else + transpolyenoicfattyacids = (Single)dataRow["transpolyenoicfattyacids"]; + + if (dataRow.IsNull("tryptophan")) + tryptophan = 0; + else + tryptophan = (Single)dataRow["tryptophan"]; + + if (dataRow.IsNull("tyrosine")) + tyrosine = 0; + else + tyrosine = (Single)dataRow["tyrosine"]; + + if (dataRow.IsNull("valine")) + valine = 0; + else + valine = (Single)dataRow["valine"]; + + if (dataRow.IsNull("vitamink")) + vitamink = 0; + else + vitamink = (Single)dataRow["vitamink"]; + + if (dataRow.IsNull("volume")) + volume = 0; + else + volume = (Single)dataRow["volume"]; + + _normalizedIngredientName = RecipeIngredient.NormalizeRecipeIngredientName(name); + + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientMeasureByIngredientID(ingredientID.Value); + + if (recordSet.Tables[0].Rows.Count > 0) + { + foreach (DataRow ldbrwRow in recordSet.Tables[0].Rows) + { + var ingredientMeasure = IngredientMeasure.GetIngredientMeasureByDataRow(ldbrwRow); + + ingredientMeasureDictionary.Add(ingredientMeasure.measureID.Value, ingredientMeasure); + } + + } + + } + + private void InitializeAllFields() + { + ingredientID = null; + name = String.Empty; + source = String.Empty; + ingredientfolderID = Guid.Empty; + comments = String.Empty; + water = 0; + calories = 0; + caloriesfromfat = 0; + percentcaloriesfromfat = 0; + energy = 0; + protein = 0; + totalfat = 0; + sugar = 0; + totalcarbohydrate = 0; + fiber = 0; + calcium = 0; + phosphorus = 0; + iron = 0; + sodium = 0; + potassium = 0; + magnesium = 0; + zinc = 0; + copper = 0; + manganese = 0; + selenium = 0; + vitamina = 0; + vitamine = 0; + thiamin = 0; + riboflavin = 0; + niacin = 0; + pantothenicacid = 0; + vitaminb6 = 0; + folate = 0; + vitaminb12 = 0; + vitaminc = 0; + saturatedfat = 0; + monounsaturatedfat = 0; + polyunsaturatedfat = 0; + cholesterol = 0; + alcohol = 0; + caffeine = 0; + selectedweight = 0; + usdaingredient = String.Empty; + useringredient = String.Empty; + selectedmeasureid = null; + biotin = 0; + commonname = String.Empty; + energyfromfat = 0; + nutritionsource = String.Empty; + servingsize = 0; + servingsizemeasureid = null; + sugaralcohols = 0; + transfattyacids = 0; + vitamind = 0; + caloriesfromalcohol = 0; + caloriesfromcarbs = 0; + caloriesfromprotein = 0; + energyfromalcohol = 0; + energyfromcarbs = 0; + energyfromprotein = 0; + percentcaloriesfromalcohol = 0; + percentcaloriesfromcarbs = 0; + percentcaloriesfromprotein = 0; + alanine = 0; + alcoholfactor = 0; + alphacarotene = 0; + alphalinolenicacid = 0; + arachidonicacid = 0; + arginine = 0; + ash = 0; + asparticacid = 0; + betacarotene = 0; + betacryptoxanthin = 0; + betasitosterol = 0; + betatocopherol = 0; + campesterol = 0; + carbohydratefactor = 0; + chloride = 0; + choline = 0; + chromium = 0; + cystine = 0; + deltatocopherol = 0; + dihomogammalinolenicacid = 0; + docosahexaenoicacid = 0; + docosapentaenoicacid = 0; + eicosadienoicacid = 0; + eicosapentaenoicacid = 0; + fatfactor = 0; + fluoride = 0; + fructose = 0; + galactose = 0; + gammalinolenicacid = 0; + gammatocopherol = 0; + glucose = 0; + glutamicacid = 0; + glycine = 0; + histidine = 0; + hydroxyproline = 0; + iodine = 0; + isoleucine = 0; + lactose = 0; + leucine = 0; + linoleicacid = 0; + lycopene = 0; + lysine = 0; + maltose = 0; + methionine = 0; + molybdenum = 0; + monounsaturatedfattyacid_14_1 = 0; + monounsaturatedfattyacid_15_1 = 0; + monounsaturatedfattyacid_16_1 = 0; + monounsaturatedfattyacid_17_1 = 0; + monounsaturatedfattyacid_18_1 = 0; + monounsaturatedfattyacid_20_1 = 0; + monounsaturatedfattyacid_22_1 = 0; + monounsaturatedfattyacid_24_1 = 0; + netcarbohydrates = 0; + nutritioncalculationmode = String.Empty; + omega3fattyacids = 0; + omega6fattyacids = 0; + phenylalanine = 0; + phytosterols = 0; + polyunsaturatedfattyacid_18_2 = 0; + polyunsaturatedfattyacid_18_3 = 0; + polyunsaturatedfattyacid_18_4 = 0; + polyunsaturatedfattyacid_20_3 = 0; + polyunsaturatedfattyacid_20_4 = 0; + polyunsaturatedfattyacid_21_5 = 0; + polyunsaturatedfattyacid_22_4 = 0; + proline = 0; + proteinfactor = 0; + refuse = 0; + retinol = 0; + saturatedfattyacid_10_0 = 0; + saturatedfattyacid_12_0 = 0; + saturatedfattyacid_13_0 = 0; + saturatedfattyacid_14_0 = 0; + saturatedfattyacid_15_0 = 0; + saturatedfattyacid_16_0 = 0; + saturatedfattyacid_17_0 = 0; + saturatedfattyacid_18_0 = 0; + saturatedfattyacid_20_0 = 0; + saturatedfattyacid_22_0 = 0; + saturatedfattyacid_24_0 = 0; + saturatedfattyacid_4_0 = 0; + saturatedfattyacid_6_0 = 0; + saturatedfattyacid_8_0 = 0; + serine = 0; + starch = 0; + stigmasterol = 0; + sucrose = 0; + theobromine = 0; + threonine = 0; + transmonoenoicfattyacids = 0; + transpolyenoicfattyacids = 0; + tryptophan = 0; + tyrosine = 0; + valine = 0; + vitamink = 0; + volume = 0; + + ingredientMeasureDictionary = new Dictionary(); + + } + + public Single GramWeightByMeasureID(Guid measureID) + { + IngredientMeasure ingredientMeasure; + if (ingredientMeasureDictionary.TryGetValue(measureID, out ingredientMeasure)) + { + return ingredientMeasure.gramWeight; + } + else + { + return 0F; + } + + } + + public override string ToString() + { + return this.name; + } + + + + + + } +} diff --git a/JRCookbookBusiness/IngredientMeasure.cs b/JRCookbookBusiness/IngredientMeasure.cs new file mode 100644 index 0000000..4eab658 --- /dev/null +++ b/JRCookbookBusiness/IngredientMeasure.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace JRCookbookBusiness +{ + public class IngredientMeasure + { + public Guid? ingredientID = null; + public Guid? measureID = null; + public Single gramWeight = 0; + + + public IngredientMeasure() + { + } + + public IngredientMeasure(Guid ingredientID, Guid measureID) + { + PopulateByID(ingredientID, measureID); + } + + public static IngredientMeasure GetIngredientMeasureByID(Guid ingredientID, Guid measureID) + { + return new IngredientMeasure(ingredientID, measureID); + } + + private void PopulateByID(Guid ingredientID, Guid measureID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientMeasureByID(ingredientID, measureID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + public static IngredientMeasure GetIngredientMeasureByDataRow(DataRow row) + { + var newIngredientMeasure = new IngredientMeasure(); + newIngredientMeasure.PopulateFromDataRow(row); + return newIngredientMeasure; + } + + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("ingredientID")) + ingredientID = null; + else + ingredientID = (Guid)dataRow["ingredientID"]; + + if (dataRow.IsNull("measureID")) + measureID = null; + else + measureID = (Guid)dataRow["measureID"]; + + if (dataRow.IsNull("gramweight")) + gramWeight = 0; + else + gramWeight = (Single)dataRow["gramweight"]; + + + } + + private void InitializeAllFields() + { + ingredientID = null; + measureID = null; + gramWeight = 0; + } + + } +} diff --git a/JRCookbookBusiness/IngredientSkipSearchWord.cs b/JRCookbookBusiness/IngredientSkipSearchWord.cs new file mode 100644 index 0000000..70a1e07 --- /dev/null +++ b/JRCookbookBusiness/IngredientSkipSearchWord.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class IngredientSkipSearchWord + { + public Guid? wordID = null; + public String word = String.Empty; + + public IngredientSkipSearchWord() + { + } + + public IngredientSkipSearchWord(Guid wordID) + { + PopulateByID(wordID); + } + + + public static IngredientSkipSearchWord GetIngredientSkipSearchWordByID(Guid wordID) + { + return new IngredientSkipSearchWord(wordID); + } + + public static List GetAllIngredientSkipSearchWords() + { + DataSet recordSet; + var returnValue = new List(); + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetAllIngredientSkipSearchWords(); + + if (recordSet.Tables[0].Rows.Count > 0) + { + foreach (DataRow ldbrwRow in recordSet.Tables[0].Rows) + { + var newIngredientSkipSearchWord = new IngredientSkipSearchWord(); + newIngredientSkipSearchWord.PopulateFromDataRow(ldbrwRow); + returnValue.Add(newIngredientSkipSearchWord); + } + } + return returnValue; + } + + public static IngredientSkipSearchWord GetIngredientSkipSearchWordByDataRow(DataRow row) + { + var newIngredientSkipSearchWord = new IngredientSkipSearchWord(); + newIngredientSkipSearchWord.PopulateFromDataRow(row); + return newIngredientSkipSearchWord; + } + + private void PopulateByID(Guid wordID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientSkipSearchWordByID(wordID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("wordID")) + wordID = null; + else + wordID = (Guid)dataRow["wordID"]; + + if (dataRow.IsNull("word")) + word = null; + else + word= (String)dataRow["word"]; + } + + private void InitializeAllFields() + { + wordID = null; + word = String.Empty; + } + + + } +} diff --git a/JRCookbookBusiness/IngredientUsage.cs b/JRCookbookBusiness/IngredientUsage.cs new file mode 100644 index 0000000..53cad4a --- /dev/null +++ b/JRCookbookBusiness/IngredientUsage.cs @@ -0,0 +1,269 @@ +using Microsoft.Office.Interop.Word; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace JRCookbookBusiness +{ + public class IngredientUsage + { + public Guid? ingredientUsageID = null; + public string normalizedIngredientName = string.Empty; + public Guid? ingredientID = null; + public Int32 usageCount = 0; + private string retrievedIngredientName = string.Empty; + + private static List _allIngredientUsage = null; + + public IngredientUsage() + { + } + + public IngredientUsage(Guid ingredientUsageID) + { + PopulateByID(ingredientUsageID); + } + + public IngredientUsage(DataRow dataRow) + { + PopulateFromDataRow(dataRow); + } + + public IngredientUsage(string normalizedIngredientName, Guid ingredientID) + { + PopulateByNameAndIngredientID(normalizedIngredientName, ingredientID); + } + + public static IngredientUsage GetIngredientUsageByID(Guid ingredientUsageID) + { + return new IngredientUsage(ingredientUsageID); + } + + public static IngredientUsage GetIngredientUsageByNameAndIngredientID(string normalizedIngredientName, Guid ingredientID) + { + return new IngredientUsage(normalizedIngredientName, ingredientID); + } + + private void PopulateByID(Guid ingredientUsageID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientUsageByID(ingredientUsageID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + private void PopulateByNameAndIngredientID(string normalizedIngredientName, Guid ingredientID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientUsageByNameAndIngredientID(normalizedIngredientName, ingredientID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + public static Int32 GetIngredientUsageCount(Ingredient ingredient) + { + var getUsage = GetIngredientUsageAll(); + + Int32 totalUsageCount = 0; + + foreach(var ingredientUsage in getUsage) + { + if (ingredientUsage.ingredientID == ingredient.ingredientID) + { + totalUsageCount += ingredientUsage.usageCount; + } + } + + return totalUsageCount; + } + + public static List GetIngredientUsageAll() + { + if (_allIngredientUsage == null) + { + _allIngredientUsage = new List(); + + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetIngredientUsageAll(); + + foreach (DataRow dataRow in recordSet.Tables[0].Rows) + { + var ingredientUsage = new IngredientUsage(dataRow); + _allIngredientUsage.Add(ingredientUsage); + } + } + + _allIngredientUsage.Sort(CompareIngredientByUsage); + return _allIngredientUsage; + } + + private static int CompareIngredientByUsage(IngredientUsage x, IngredientUsage y) + { + if (x == null) + { + if (y == null) + { + // If x is null and y is null, they're + // equal. + return 0; + } + else + { + // If x is null and y is not null, y + // is greater. + return -1; + } + } + else + { + // If x is not null... + // + if (y == null) + // ...and y is null, x is greater. + { + return 1; + } + else + { + // ...and y is not null, compare the usage count + // + int retval = -1 * x.usageCount.CompareTo(y.usageCount); + + if (retval != 0) + { + // If the usageCounts are different, + // return that the higher count should be first + // + return retval; + } + else + { + // If the usageCounts are the same, + // sort them with ordinary string comparison. + // + return x.retrievedIngredientName.CompareTo(y.retrievedIngredientName); + } + } + } + } + + + public static IngredientUsage GetIngredientUsageByDataRow(DataRow row) + { + var newIngredientUsage = new IngredientUsage(); + newIngredientUsage.PopulateFromDataRow(row); + return newIngredientUsage; + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("ingredientUsageID")) + ingredientUsageID = null; + else + ingredientUsageID = (Guid)dataRow["ingredientUsageID"]; + + if (dataRow.IsNull("normalizedIngredientName")) + normalizedIngredientName = null; + else + normalizedIngredientName = (String)dataRow["normalizedIngredientName"]; + + if (dataRow.IsNull("ingredientID")) + ingredientID = null; + else + ingredientID = (Guid)dataRow["ingredientID"]; + + if (dataRow.IsNull("usageCount")) + usageCount = 0; + else + usageCount = (Int32)dataRow["usageCount"]; + + if (ingredientID != null) + { + retrievedIngredientName = Ingredient.GetIngredientByID(ingredientID.Value).name; + } + } + + private void InitializeAllFields() + { + ingredientUsageID = null; + normalizedIngredientName = String.Empty; + ingredientID = null; + usageCount = 0; + } + + public void Save() + { + if (this.ingredientUsageID == null) + { + this.ingredientUsageID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDIngredientUsage(); + clsDatabaseLayer.GetDatabaseLayer().InsertIngredientUsage(this); + } + else + { + clsDatabaseLayer.GetDatabaseLayer().UpdateIngredientUsage(this); + } + } + + + public static void RebuildIngredientUsage() + { + clsDatabaseLayer.GetDatabaseLayer().DeleteIngredientUsageAll(); + List newList = new List(); + var allRecipeIngredients = RecipeIngredient.GetRecipeIngredientAll(); + foreach(RecipeIngredientItem recipeIngredient in allRecipeIngredients) + { + var normalizedIngredientName = RecipeIngredient.NormalizeRecipeIngredientName(recipeIngredient.ingredientText); + + bool foundMatch = false; + + foreach(var ingredientUsage in newList) + { + if (ingredientUsage.normalizedIngredientName == normalizedIngredientName && ingredientUsage.ingredientID == recipeIngredient.ingredientID) + { + foundMatch = true; + ingredientUsage.usageCount++; + } + } + + if (!foundMatch) + { + var newIngredientUsage = new IngredientUsage(); + newIngredientUsage.normalizedIngredientName = normalizedIngredientName; + newIngredientUsage.ingredientID = ((RecipeIngredientItem)recipeIngredient).ingredientID; + newIngredientUsage.usageCount = 1; + + newList.Add(newIngredientUsage); + } + } + + foreach(var ingredient in newList) + { + ingredient.Save(); + } + + } + } +} diff --git a/JRCookbookBusiness/JRCookbookBusiness.csproj b/JRCookbookBusiness/JRCookbookBusiness.csproj new file mode 100644 index 0000000..15307cf --- /dev/null +++ b/JRCookbookBusiness/JRCookbookBusiness.csproj @@ -0,0 +1,40 @@ + + + + net10.0-windows7.0 + true + JRCookbookStrongNameKey.snk + x86 + + + + x86 + + + + x86 + + + + + tlbimp + 7 + 8 + 00020905-0000-0000-c000-000000000046 + 0 + false + true + + + + + + + + + + + + + + diff --git a/JRCookbookBusiness/JRCookbookBusinessAppManagement.cs b/JRCookbookBusiness/JRCookbookBusinessAppManagement.cs new file mode 100644 index 0000000..d691e1e --- /dev/null +++ b/JRCookbookBusiness/JRCookbookBusinessAppManagement.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public static class JRCookbookBusinessAppManagement + { + public static void ShutDownApp() + { + clsDatabaseLayer.CloseSharedDatabaseConnection(); + } + + public static Int32 JRJRUpdateAdhoc(String strSQL) + { + return clsDatabaseLayer.GetDatabaseLayer().JRJRUpdateAdhoc(strSQL); + } + + public static DataSet JRJRSelectAdhoc(String strSQL) + { + return clsDatabaseLayer.GetDatabaseLayer().JRJRSelectAdhoc(strSQL); + } + } +} diff --git a/JRCookbookBusiness/JRCookbookStrongNameKey.snk b/JRCookbookBusiness/JRCookbookStrongNameKey.snk new file mode 100644 index 0000000..4ae9cf8 Binary files /dev/null and b/JRCookbookBusiness/JRCookbookStrongNameKey.snk differ diff --git a/JRCookbookBusiness/LongRunningStatusUpdatedEventArgs.cs b/JRCookbookBusiness/LongRunningStatusUpdatedEventArgs.cs new file mode 100644 index 0000000..5691df3 --- /dev/null +++ b/JRCookbookBusiness/LongRunningStatusUpdatedEventArgs.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class LongRunningStatusUpdatedEventArgs : EventArgs + { + public string Status { get; set; } + public int CompletedItemCount { get; set; } + public int TotalItemCount { get; set; } + + public LongRunningStatusUpdatedEventArgs(string status, int completedItemCount, int totalItemCount) + { + Status = Status; + CompletedItemCount = completedItemCount; + TotalItemCount = totalItemCount; + } + } +} diff --git a/JRCookbookBusiness/Measure.cs b/JRCookbookBusiness/Measure.cs new file mode 100644 index 0000000..871b51f --- /dev/null +++ b/JRCookbookBusiness/Measure.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace JRCookbookBusiness +{ + public enum MeasureType + { + Mass, + Volume, + Unit + } + public class Measure + { + public Guid? measureID = null; + public String description = String.Empty; + public MeasureType measureType = MeasureType.Mass; + + + public Measure() + { + } + + public Measure(Guid measureID) + { + PopulateByID(measureID); + } + + public static Measure GetMeasureByID(Guid measureID) + { + return new Measure(measureID); + } + + private void PopulateByID(Guid measureID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetMeasureByID(measureID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("measureID")) + measureID = null; + else + measureID = (Guid)dataRow["measureID"]; + + if (dataRow.IsNull("description")) + description = String.Empty; + else + description = (String)dataRow["description"]; + + if (dataRow.IsNull("Type")) + measureType = MeasureType.Mass; + else + measureType = MeasureTypeByString((String)dataRow["Type"]); + + } + + private void InitializeAllFields() + { + measureID = null; + description = String.Empty; + measureType = MeasureType.Mass; + } + + public static Measure GetMeasureByDataRow(DataRow dataRow) + { + var newMeasure = new Measure(); + newMeasure.PopulateFromDataRow(dataRow); + + return newMeasure; + } + + public static List GetMeasuresByIngredientID(Guid ingredientID) + { + var returnValue = new List(); + + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetMeasuresByIngredientID(ingredientID); + + foreach (DataRow dataRow in recordSet.Tables[0].Rows) + { + var newMeasure = Measure.GetMeasureByDataRow(dataRow); + returnValue.Add(newMeasure); + } + + return returnValue; + } + + + public static MeasureType MeasureTypeByString(String value) + { + switch (value) + { + case "Mass": return MeasureType.Mass; + case "Volume": return MeasureType.Volume; + case "Unit": return MeasureType.Unit; + default: + throw new ApplicationException("Invalid MeasureType"); + } + } + + public static String ConvertMeasureTypeToString(MeasureType value) + { + switch (value) + { + case MeasureType.Mass: return "Mass"; + case MeasureType.Volume: return "Volume"; + case MeasureType.Unit: return "Unit"; + default: + throw new ApplicationException("Invalid MeasureType"); + } + } + + public override string ToString() + { + return this.description; + } + + } +} diff --git a/JRCookbookBusiness/Recipe.cs b/JRCookbookBusiness/Recipe.cs new file mode 100644 index 0000000..3d0204c --- /dev/null +++ b/JRCookbookBusiness/Recipe.cs @@ -0,0 +1,3435 @@ +using Microsoft.AspNetCore.Html; +using System; +using System.Net; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Office.Interop.Word; +using static System.Net.WebRequestMethods; + +namespace JRCookbookBusiness +{ + public class Recipe : ICloneable + { + public Guid? recipeID = null; + public Guid? cookbookID = null; + public Guid? cookbookchapterID = null; + + public String recipename = String.Empty; + public String author = String.Empty; + public String source = String.Empty; + public String webpage = String.Empty; + public String comments = String.Empty; + public String copyright = String.Empty; + + public Single servings = 0; + public String nutritionservinglabel = String.Empty; + public String yield = String.Empty; + + public Int32 preparationtime = 0; + public Int32 cookingtime = 0; + public Int32 readyintime = 0; + public Int32 inactivetime = 0; + + public Int16 oventemperaturec = 0; + public Int16 oventemperaturef = 0; + + public Single percentcaloriesfromalcohol = 0; + public Single percentcaloriesfromcarbs = 0; + public Single percentcaloriesfromfat = 0; + public Single percentcaloriesfromprotein = 0; + + public Single alanine = 0; + public Single alcohol = 0; + public Single alcoholfactor = 0; + public Single alphacarotene = 0; + public Single alphalinolenicacid = 0; + public Single arachidonicacid = 0; + public Single arginine = 0; + public Single ash = 0; + public Single asparticacid = 0; + public Single betacarotene = 0; + public Single betacryptoxanthin = 0; + public Single betasitosterol = 0; + public Single betatocopherol = 0; + public Single biotin = 0; + public Single caffeine = 0; + public Single calcium = 0; + public Single calories = 0; + public Single caloriesfromalcohol = 0; + public Single caloriesfromcarbs = 0; + public Single caloriesfromfat = 0; + public Single caloriesfromprotein = 0; + public Single campesterol = 0; + public Single carbohydratefactor = 0; + public Single chloride = 0; + public Single cholesterol = 0; + public Single choline = 0; + public Single chromium = 0; + public Single copper = 0; + public Single cystine = 0; + public Single deltatocopherol = 0; + public Single dihomogammalinolenicacid = 0; + public Single docosahexaenoicacid = 0; + public Single docosapentaenoicacid = 0; + public Single eicosadienoicacid = 0; + public Single eicosapentaenoicacid = 0; + public Single energy = 0; + public Single energyfromalcohol = 0; + public Single energyfromcarbs = 0; + public Single energyfromfat = 0; + public Single energyfromprotein = 0; + public Single fatfactor = 0; + public Single fiber = 0; + public Single fluoride = 0; + public Single folate = 0; + public Single fructose = 0; + public Single galactose = 0; + public Single gammalinolenicacid = 0; + public Single gammatocopherol = 0; + public Single glucose = 0; + public Single glutamicacid = 0; + public Single glycine = 0; + public Single histidine = 0; + public Single hydroxyproline = 0; + public Single iodine = 0; + public Single iron = 0; + public Single isoleucine = 0; + public Single lactose = 0; + public Single leucine = 0; + public Single linoleicacid = 0; + public Single lycopene = 0; + public Single lysine = 0; + public Single magnesium = 0; + public Single maltose = 0; + public Single manganese = 0; + public Single mass = 0; + public Single methionine = 0; + public Single molybdenum = 0; + public Single monounsaturatedfat = 0; + public Single monounsaturatedfattyacid_14_1 = 0; + public Single monounsaturatedfattyacid_15_1 = 0; + public Single monounsaturatedfattyacid_16_1 = 0; + public Single monounsaturatedfattyacid_17_1 = 0; + public Single monounsaturatedfattyacid_18_1 = 0; + public Single monounsaturatedfattyacid_20_1 = 0; + public Single monounsaturatedfattyacid_22_1 = 0; + public Single monounsaturatedfattyacid_24_1 = 0; + public Single netcarbohydrates = 0; + public Single niacin = 0; + public Single omega3fattyacids = 0; + public Single omega6fattyacids = 0; + public Single pantothenicacid = 0; + public Single phenylalanine = 0; + public Single phosphorus = 0; + public Single phytosterols = 0; + public Single polyunsaturatedfat = 0; + public Single polyunsaturatedfattyacid_18_2 = 0; + public Single polyunsaturatedfattyacid_18_3 = 0; + public Single polyunsaturatedfattyacid_18_4 = 0; + public Single polyunsaturatedfattyacid_20_3 = 0; + public Single polyunsaturatedfattyacid_20_4 = 0; + public Single polyunsaturatedfattyacid_21_5 = 0; + public Single polyunsaturatedfattyacid_22_4 = 0; + public Single potassium = 0; + public Single proline = 0; + public Single protein = 0; + public Single proteinfactor = 0; + public Single refuse = 0; + public Single retinol = 0; + public Single riboflavin = 0; + public Single saturatedfat = 0; + public Single saturatedfattyacid_10_0 = 0; + public Single saturatedfattyacid_12_0 = 0; + public Single saturatedfattyacid_13_0 = 0; + public Single saturatedfattyacid_14_0 = 0; + public Single saturatedfattyacid_15_0 = 0; + public Single saturatedfattyacid_16_0 = 0; + public Single saturatedfattyacid_17_0 = 0; + public Single saturatedfattyacid_18_0 = 0; + public Single saturatedfattyacid_20_0 = 0; + public Single saturatedfattyacid_22_0 = 0; + public Single saturatedfattyacid_24_0 = 0; + public Single saturatedfattyacid_4_0 = 0; + public Single saturatedfattyacid_6_0 = 0; + public Single saturatedfattyacid_8_0 = 0; + public Single selenium = 0; + public Single serine = 0; + public Single sodium = 0; + public Single starch = 0; + public Single stigmasterol = 0; + public Single sucrose = 0; + public Single sugar = 0; + public Single sugaralcohols = 0; + public Single theobromine = 0; + public Single thiamin = 0; + public Single threonine = 0; + public Single totalcarbohydrate = 0; + public Single totalfat = 0; + public Single transfattyacids = 0; + public Single transmonoenoicfattyacids = 0; + public Single transpolyenoicfattyacids = 0; + public Single tryptophan = 0; + public Single tyrosine = 0; + public Single valine = 0; + public Single vitamina = 0; + public Single vitaminb12 = 0; + public Single vitaminb6 = 0; + public Single vitaminc = 0; + public Single vitamind = 0; + public Single vitamine = 0; + public Single vitamink = 0; + public Single volume = 0; + public Single water = 0; + public Single zinc = 0; + + public List recipeIngredients = new List(); + public List recipeProcedures = new List(); + public List recipeTips = new List(); + + public event EventHandler RecipeRenderedEvent; + + public Recipe() + { + } + + public Recipe(Guid recipeID) + { + PopulateByID(recipeID); + } + + public void PasteIntoChapter(Guid newCookbookID, Guid? newCookbookChapterID) + { + this.recipeID = null; + this.cookbookID = newCookbookID; + this.cookbookchapterID = newCookbookChapterID; + + foreach (var recipeIngredient in this.recipeIngredients) + { + recipeIngredient.recipeIngredientID = null; + } + + + foreach (var recipeProcedure in this.recipeProcedures) + { + recipeProcedure.recipeProcedureID = null; + } + + + foreach (var recipeTip in this.recipeTips) + { + recipeTip.recipeTipID = null; + } + + this.Save(); + } + + public void Save() + { + + this.CalcNutrition(); + + if (this.recipeID == null) + { + this.recipeID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDRecipe(); + clsDatabaseLayer.GetDatabaseLayer().InsertRecipe(this); + } + else + { + clsDatabaseLayer.GetDatabaseLayer().UpdateRecipe(this); + } + + + var recipeIngredientIndex = 0; + var procedureIndex = 0; + var tipIndex = 0; + + RecipeIngredient.DeleteAllByRecipeID(recipeID.Value); + + foreach (var recipeIngredient in this.recipeIngredients) + { + recipeIngredient.recipeIngredientID = null; + recipeIngredient.recipeID = this.recipeID; + + recipeIngredient.ingredientIndex = recipeIngredientIndex; + + recipeIngredient.Save(); + recipeIngredientIndex += 1; + } + + + RecipeProcedure.DeleteAllByRecipeID(recipeID.Value); + + foreach (var recipeProcedure in this.recipeProcedures) + { + recipeProcedure.recipeProcedureID = null; + recipeProcedure.recipeID = this.recipeID; + + recipeProcedure.procedureIndex = procedureIndex; + + recipeProcedure.Save(); + procedureIndex += 1; + } + + + RecipeTip.DeleteAllByRecipeID(recipeID.Value); + + foreach (var recipeTip in this.recipeTips) + { + recipeTip.recipeTipID = null; + recipeTip.recipeID = this.recipeID; + + recipeTip.tipIndex = tipIndex; + + recipeTip.Save(); + tipIndex += 1; + + } + } + + public void Delete() + { + RecipeIngredient.DeleteAllByRecipeID(recipeID.Value); + + RecipeProcedure.DeleteAllByRecipeID(recipeID.Value); + + RecipeTip.DeleteAllByRecipeID(recipeID.Value); + + clsDatabaseLayer.GetDatabaseLayer().DeleteRecipeByID(recipeID.Value); + } + + + internal void GenerateWebPageToFolder(String folderToSaveTo, Dictionary recipePageDictionary, SortedList recipesAlpha, SortedSet pagesAlreadyAdded, List trackbackList) + { + var recipeHTML = this.GetHTML(trackbackList); + + String pageNameToUse = SharedRoutines.RemoveSpecialCharactersFromFileName(this.recipename); + String pageNameToUseWithExtension = pageNameToUse + ".htm"; + + while(pagesAlreadyAdded.Contains(pageNameToUseWithExtension.ToUpper())) + { + pageNameToUse += "1"; + pageNameToUseWithExtension = pageNameToUse + ".htm"; + } + + + recipePageDictionary.Add(this.recipeID.Value, pageNameToUseWithExtension); + recipesAlpha.Add(this.recipename.ToUpper(), this); + pagesAlreadyAdded.Add(pageNameToUseWithExtension.ToUpper()); + + + var strRecipePath = folderToSaveTo; + if (strRecipePath.EndsWith("\\") == false) + { + strRecipePath += "\\"; + } + + strRecipePath += pageNameToUseWithExtension; + + using (var writer = new System.IO.StreamWriter(strRecipePath, false)) + { + writer.Write(recipeHTML); + } + + if (RecipeRenderedEvent != null) + { + RecipeRenderedEvent.Invoke(this, new EventArgs()); + } + } + + + public static Recipe GetRecipeByID(Guid recipeID) + { + return new Recipe(recipeID); + } + + public static void DeleteByID(Guid recipeID) + { + var recipe = new Recipe(recipeID); + recipe.Delete(); + } + + + private void PopulateByID(Guid recipeID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeByID(recipeID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("recipeID")) + recipeID = null; + else + recipeID = (Guid)dataRow["recipeID"]; + + if (dataRow.IsNull("cookbookID")) + cookbookID = null; + else + cookbookID = (Guid)dataRow["cookbookID"]; + + if (dataRow.IsNull("cookbookchapterID")) + cookbookchapterID = null; + else + cookbookchapterID = (Guid)dataRow["cookbookchapterID"]; + + if (dataRow.IsNull("recipename")) + recipename = String.Empty; + else + recipename = (String)dataRow["recipename"]; + + if (dataRow.IsNull("author")) + author = String.Empty; + else + author = (String)dataRow["author"]; + + if (dataRow.IsNull("source")) + source = String.Empty; + else + source = (String)dataRow["source"]; + + if (dataRow.IsNull("webpage")) + webpage = String.Empty; + else + webpage = (String)dataRow["webpage"]; + + if (dataRow.IsNull("comments")) + comments = String.Empty; + else + comments = (String)dataRow["comments"]; + + if (dataRow.IsNull("copyright")) + copyright = String.Empty; + else + copyright = (String)dataRow["copyright"]; + + if (dataRow.IsNull("servings")) + servings = 0; + else + servings = (Single)dataRow["servings"]; + + if (dataRow.IsNull("nutritionservinglabel")) + nutritionservinglabel = String.Empty; + else + nutritionservinglabel = (String)dataRow["nutritionservinglabel"]; + + if (dataRow.IsNull("yield")) + yield = String.Empty; + else + yield = (String)dataRow["yield"]; + + if (dataRow.IsNull("preparationtime")) + preparationtime = 0; + else + preparationtime = (Int32)dataRow["preparationtime"]; + + if (dataRow.IsNull("cookingtime")) + cookingtime = 0; + else + cookingtime = (Int32)dataRow["cookingtime"]; + + if (dataRow.IsNull("readyintime")) + readyintime = 0; + else + readyintime = (Int32)dataRow["readyintime"]; + + if (dataRow.IsNull("inactivetime")) + inactivetime = 0; + else + inactivetime = (Int32)dataRow["inactivetime"]; + + if (dataRow.IsNull("oventemperaturec")) + oventemperaturec = 0; + else + oventemperaturec = (Int16)dataRow["oventemperaturec"]; + + if (dataRow.IsNull("oventemperaturef")) + oventemperaturef = 0; + else + oventemperaturef = (Int16)dataRow["oventemperaturef"]; + + if (dataRow.IsNull("percentcaloriesfromalcohol")) + percentcaloriesfromalcohol = 0; + else + percentcaloriesfromalcohol = (Single)dataRow["percentcaloriesfromalcohol"]; + + if (dataRow.IsNull("percentcaloriesfromcarbs")) + percentcaloriesfromcarbs = 0; + else + percentcaloriesfromcarbs = (Single)dataRow["percentcaloriesfromcarbs"]; + + if (dataRow.IsNull("percentcaloriesfromfat")) + percentcaloriesfromfat = 0; + else + percentcaloriesfromfat = (Single)dataRow["percentcaloriesfromfat"]; + + if (dataRow.IsNull("percentcaloriesfromprotein")) + percentcaloriesfromprotein = 0; + else + percentcaloriesfromprotein = (Single)dataRow["percentcaloriesfromprotein"]; + + if (dataRow.IsNull("alanine")) + alanine = 0; + else + alanine = (Single)dataRow["alanine"]; + + if (dataRow.IsNull("alcohol")) + alcohol = 0; + else + alcohol = (Single)dataRow["alcohol"]; + + if (dataRow.IsNull("alcoholfactor")) + alcoholfactor = 0; + else + alcoholfactor = (Single)dataRow["alcoholfactor"]; + + if (dataRow.IsNull("alphacarotene")) + alphacarotene = 0; + else + alphacarotene = (Single)dataRow["alphacarotene"]; + + if (dataRow.IsNull("alphalinolenicacid")) + alphalinolenicacid = 0; + else + alphalinolenicacid = (Single)dataRow["alphalinolenicacid"]; + + if (dataRow.IsNull("arachidonicacid")) + arachidonicacid = 0; + else + arachidonicacid = (Single)dataRow["arachidonicacid"]; + + if (dataRow.IsNull("arginine")) + arginine = 0; + else + arginine = (Single)dataRow["arginine"]; + + if (dataRow.IsNull("ash")) + ash = 0; + else + ash = (Single)dataRow["ash"]; + + if (dataRow.IsNull("asparticacid")) + asparticacid = 0; + else + asparticacid = (Single)dataRow["asparticacid"]; + + if (dataRow.IsNull("betacarotene")) + betacarotene = 0; + else + betacarotene = (Single)dataRow["betacarotene"]; + + if (dataRow.IsNull("betacryptoxanthin")) + betacryptoxanthin = 0; + else + betacryptoxanthin = (Single)dataRow["betacryptoxanthin"]; + + if (dataRow.IsNull("betasitosterol")) + betasitosterol = 0; + else + betasitosterol = (Single)dataRow["betasitosterol"]; + + if (dataRow.IsNull("betatocopherol")) + betatocopherol = 0; + else + betatocopherol = (Single)dataRow["betatocopherol"]; + + if (dataRow.IsNull("biotin")) + biotin = 0; + else + biotin = (Single)dataRow["biotin"]; + + if (dataRow.IsNull("caffeine")) + caffeine = 0; + else + caffeine = (Single)dataRow["caffeine"]; + + if (dataRow.IsNull("calcium")) + calcium = 0; + else + calcium = (Single)dataRow["calcium"]; + + if (dataRow.IsNull("calories")) + calories = 0; + else + calories = (Single)dataRow["calories"]; + + if (dataRow.IsNull("caloriesfromalcohol")) + caloriesfromalcohol = 0; + else + caloriesfromalcohol = (Single)dataRow["caloriesfromalcohol"]; + + if (dataRow.IsNull("caloriesfromcarbs")) + caloriesfromcarbs = 0; + else + caloriesfromcarbs = (Single)dataRow["caloriesfromcarbs"]; + + if (dataRow.IsNull("caloriesfromfat")) + caloriesfromfat = 0; + else + caloriesfromfat = (Single)dataRow["caloriesfromfat"]; + + if (dataRow.IsNull("caloriesfromprotein")) + caloriesfromprotein = 0; + else + caloriesfromprotein = (Single)dataRow["caloriesfromprotein"]; + + if (dataRow.IsNull("campesterol")) + campesterol = 0; + else + campesterol = (Single)dataRow["campesterol"]; + + if (dataRow.IsNull("carbohydratefactor")) + carbohydratefactor = 0; + else + carbohydratefactor = (Single)dataRow["carbohydratefactor"]; + + if (dataRow.IsNull("chloride")) + chloride = 0; + else + chloride = (Single)dataRow["chloride"]; + + if (dataRow.IsNull("cholesterol")) + cholesterol = 0; + else + cholesterol = (Single)dataRow["cholesterol"]; + + if (dataRow.IsNull("choline")) + choline = 0; + else + choline = (Single)dataRow["choline"]; + + if (dataRow.IsNull("chromium")) + chromium = 0; + else + chromium = (Single)dataRow["chromium"]; + + if (dataRow.IsNull("copper")) + copper = 0; + else + copper = (Single)dataRow["copper"]; + + if (dataRow.IsNull("cystine")) + cystine = 0; + else + cystine = (Single)dataRow["cystine"]; + + if (dataRow.IsNull("deltatocopherol")) + deltatocopherol = 0; + else + deltatocopherol = (Single)dataRow["deltatocopherol"]; + + if (dataRow.IsNull("dihomogammalinolenicacid")) + dihomogammalinolenicacid = 0; + else + dihomogammalinolenicacid = (Single)dataRow["dihomogammalinolenicacid"]; + + if (dataRow.IsNull("docosahexaenoicacid")) + docosahexaenoicacid = 0; + else + docosahexaenoicacid = (Single)dataRow["docosahexaenoicacid"]; + + if (dataRow.IsNull("docosapentaenoicacid")) + docosapentaenoicacid = 0; + else + docosapentaenoicacid = (Single)dataRow["docosapentaenoicacid"]; + + if (dataRow.IsNull("eicosadienoicacid")) + eicosadienoicacid = 0; + else + eicosadienoicacid = (Single)dataRow["eicosadienoicacid"]; + + if (dataRow.IsNull("eicosapentaenoicacid")) + eicosapentaenoicacid = 0; + else + eicosapentaenoicacid = (Single)dataRow["eicosapentaenoicacid"]; + + if (dataRow.IsNull("energy")) + energy = 0; + else + energy = (Single)dataRow["energy"]; + + if (dataRow.IsNull("energyfromalcohol")) + energyfromalcohol = 0; + else + energyfromalcohol = (Single)dataRow["energyfromalcohol"]; + + if (dataRow.IsNull("energyfromcarbs")) + energyfromcarbs = 0; + else + energyfromcarbs = (Single)dataRow["energyfromcarbs"]; + + if (dataRow.IsNull("energyfromfat")) + energyfromfat = 0; + else + energyfromfat = (Single)dataRow["energyfromfat"]; + + if (dataRow.IsNull("energyfromprotein")) + energyfromprotein = 0; + else + energyfromprotein = (Single)dataRow["energyfromprotein"]; + + if (dataRow.IsNull("fatfactor")) + fatfactor = 0; + else + fatfactor = (Single)dataRow["fatfactor"]; + + if (dataRow.IsNull("fiber")) + fiber = 0; + else + fiber = (Single)dataRow["fiber"]; + + if (dataRow.IsNull("fluoride")) + fluoride = 0; + else + fluoride = (Single)dataRow["fluoride"]; + + if (dataRow.IsNull("folate")) + folate = 0; + else + folate = (Single)dataRow["folate"]; + + if (dataRow.IsNull("fructose")) + fructose = 0; + else + fructose = (Single)dataRow["fructose"]; + + if (dataRow.IsNull("galactose")) + galactose = 0; + else + galactose = (Single)dataRow["galactose"]; + + if (dataRow.IsNull("gammalinolenicacid")) + gammalinolenicacid = 0; + else + gammalinolenicacid = (Single)dataRow["gammalinolenicacid"]; + + if (dataRow.IsNull("gammatocopherol")) + gammatocopherol = 0; + else + gammatocopherol = (Single)dataRow["gammatocopherol"]; + + if (dataRow.IsNull("glucose")) + glucose = 0; + else + glucose = (Single)dataRow["glucose"]; + + if (dataRow.IsNull("glutamicacid")) + glutamicacid = 0; + else + glutamicacid = (Single)dataRow["glutamicacid"]; + + if (dataRow.IsNull("glycine")) + glycine = 0; + else + glycine = (Single)dataRow["glycine"]; + + if (dataRow.IsNull("histidine")) + histidine = 0; + else + histidine = (Single)dataRow["histidine"]; + + if (dataRow.IsNull("hydroxyproline")) + hydroxyproline = 0; + else + hydroxyproline = (Single)dataRow["hydroxyproline"]; + + if (dataRow.IsNull("iodine")) + iodine = 0; + else + iodine = (Single)dataRow["iodine"]; + + if (dataRow.IsNull("iron")) + iron = 0; + else + iron = (Single)dataRow["iron"]; + + if (dataRow.IsNull("isoleucine")) + isoleucine = 0; + else + isoleucine = (Single)dataRow["isoleucine"]; + + if (dataRow.IsNull("lactose")) + lactose = 0; + else + lactose = (Single)dataRow["lactose"]; + + if (dataRow.IsNull("leucine")) + leucine = 0; + else + leucine = (Single)dataRow["leucine"]; + + if (dataRow.IsNull("linoleicacid")) + linoleicacid = 0; + else + linoleicacid = (Single)dataRow["linoleicacid"]; + + if (dataRow.IsNull("lycopene")) + lycopene = 0; + else + lycopene = (Single)dataRow["lycopene"]; + + if (dataRow.IsNull("lysine")) + lysine = 0; + else + lysine = (Single)dataRow["lysine"]; + + if (dataRow.IsNull("magnesium")) + magnesium = 0; + else + magnesium = (Single)dataRow["magnesium"]; + + if (dataRow.IsNull("maltose")) + maltose = 0; + else + maltose = (Single)dataRow["maltose"]; + + if (dataRow.IsNull("manganese")) + manganese = 0; + else + manganese = (Single)dataRow["manganese"]; + + if (dataRow.IsNull("mass")) + mass = 0; + else + mass = (Single)dataRow["mass"]; + + if (dataRow.IsNull("methionine")) + methionine = 0; + else + methionine = (Single)dataRow["methionine"]; + + if (dataRow.IsNull("molybdenum")) + molybdenum = 0; + else + molybdenum = (Single)dataRow["molybdenum"]; + + if (dataRow.IsNull("monounsaturatedfat")) + monounsaturatedfat = 0; + else + monounsaturatedfat = (Single)dataRow["monounsaturatedfat"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_14_1")) + monounsaturatedfattyacid_14_1 = 0; + else + monounsaturatedfattyacid_14_1 = (Single)dataRow["monounsaturatedfattyacid_14_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_15_1")) + monounsaturatedfattyacid_15_1 = 0; + else + monounsaturatedfattyacid_15_1 = (Single)dataRow["monounsaturatedfattyacid_15_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_16_1")) + monounsaturatedfattyacid_16_1 = 0; + else + monounsaturatedfattyacid_16_1 = (Single)dataRow["monounsaturatedfattyacid_16_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_17_1")) + monounsaturatedfattyacid_17_1 = 0; + else + monounsaturatedfattyacid_17_1 = (Single)dataRow["monounsaturatedfattyacid_17_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_18_1")) + monounsaturatedfattyacid_18_1 = 0; + else + monounsaturatedfattyacid_18_1 = (Single)dataRow["monounsaturatedfattyacid_18_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_20_1")) + monounsaturatedfattyacid_20_1 = 0; + else + monounsaturatedfattyacid_20_1 = (Single)dataRow["monounsaturatedfattyacid_20_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_22_1")) + monounsaturatedfattyacid_22_1 = 0; + else + monounsaturatedfattyacid_22_1 = (Single)dataRow["monounsaturatedfattyacid_22_1"]; + + if (dataRow.IsNull("monounsaturatedfattyacid_24_1")) + monounsaturatedfattyacid_24_1 = 0; + else + monounsaturatedfattyacid_24_1 = (Single)dataRow["monounsaturatedfattyacid_24_1"]; + + if (dataRow.IsNull("netcarbohydrates")) + netcarbohydrates = 0; + else + netcarbohydrates = (Single)dataRow["netcarbohydrates"]; + + if (dataRow.IsNull("niacin")) + niacin = 0; + else + niacin = (Single)dataRow["niacin"]; + + if (dataRow.IsNull("omega3fattyacids")) + omega3fattyacids = 0; + else + omega3fattyacids = (Single)dataRow["omega3fattyacids"]; + + if (dataRow.IsNull("omega6fattyacids")) + omega6fattyacids = 0; + else + omega6fattyacids = (Single)dataRow["omega6fattyacids"]; + + if (dataRow.IsNull("pantothenicacid")) + pantothenicacid = 0; + else + pantothenicacid = (Single)dataRow["pantothenicacid"]; + + if (dataRow.IsNull("phenylalanine")) + phenylalanine = 0; + else + phenylalanine = (Single)dataRow["phenylalanine"]; + + if (dataRow.IsNull("phosphorus")) + phosphorus = 0; + else + phosphorus = (Single)dataRow["phosphorus"]; + + if (dataRow.IsNull("phytosterols")) + phytosterols = 0; + else + phytosterols = (Single)dataRow["phytosterols"]; + + if (dataRow.IsNull("polyunsaturatedfat")) + polyunsaturatedfat = 0; + else + polyunsaturatedfat = (Single)dataRow["polyunsaturatedfat"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_18_2")) + polyunsaturatedfattyacid_18_2 = 0; + else + polyunsaturatedfattyacid_18_2 = (Single)dataRow["polyunsaturatedfattyacid_18_2"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_18_3")) + polyunsaturatedfattyacid_18_3 = 0; + else + polyunsaturatedfattyacid_18_3 = (Single)dataRow["polyunsaturatedfattyacid_18_3"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_18_4")) + polyunsaturatedfattyacid_18_4 = 0; + else + polyunsaturatedfattyacid_18_4 = (Single)dataRow["polyunsaturatedfattyacid_18_4"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_20_3")) + polyunsaturatedfattyacid_20_3 = 0; + else + polyunsaturatedfattyacid_20_3 = (Single)dataRow["polyunsaturatedfattyacid_20_3"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_20_4")) + polyunsaturatedfattyacid_20_4 = 0; + else + polyunsaturatedfattyacid_20_4 = (Single)dataRow["polyunsaturatedfattyacid_20_4"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_21_5")) + polyunsaturatedfattyacid_21_5 = 0; + else + polyunsaturatedfattyacid_21_5 = (Single)dataRow["polyunsaturatedfattyacid_21_5"]; + + if (dataRow.IsNull("polyunsaturatedfattyacid_22_4")) + polyunsaturatedfattyacid_22_4 = 0; + else + polyunsaturatedfattyacid_22_4 = (Single)dataRow["polyunsaturatedfattyacid_22_4"]; + + if (dataRow.IsNull("potassium")) + potassium = 0; + else + potassium = (Single)dataRow["potassium"]; + + if (dataRow.IsNull("proline")) + proline = 0; + else + proline = (Single)dataRow["proline"]; + + if (dataRow.IsNull("protein")) + protein = 0; + else + protein = (Single)dataRow["protein"]; + + if (dataRow.IsNull("proteinfactor")) + proteinfactor = 0; + else + proteinfactor = (Single)dataRow["proteinfactor"]; + + if (dataRow.IsNull("refuse")) + refuse = 0; + else + refuse = (Single)dataRow["refuse"]; + + if (dataRow.IsNull("retinol")) + retinol = 0; + else + retinol = (Single)dataRow["retinol"]; + + if (dataRow.IsNull("riboflavin")) + riboflavin = 0; + else + riboflavin = (Single)dataRow["riboflavin"]; + + if (dataRow.IsNull("saturatedfat")) + saturatedfat = 0; + else + saturatedfat = (Single)dataRow["saturatedfat"]; + + if (dataRow.IsNull("saturatedfattyacid_10_0")) + saturatedfattyacid_10_0 = 0; + else + saturatedfattyacid_10_0 = (Single)dataRow["saturatedfattyacid_10_0"]; + + if (dataRow.IsNull("saturatedfattyacid_12_0")) + saturatedfattyacid_12_0 = 0; + else + saturatedfattyacid_12_0 = (Single)dataRow["saturatedfattyacid_12_0"]; + + if (dataRow.IsNull("saturatedfattyacid_13_0")) + saturatedfattyacid_13_0 = 0; + else + saturatedfattyacid_13_0 = (Single)dataRow["saturatedfattyacid_13_0"]; + + if (dataRow.IsNull("saturatedfattyacid_14_0")) + saturatedfattyacid_14_0 = 0; + else + saturatedfattyacid_14_0 = (Single)dataRow["saturatedfattyacid_14_0"]; + + if (dataRow.IsNull("saturatedfattyacid_15_0")) + saturatedfattyacid_15_0 = 0; + else + saturatedfattyacid_15_0 = (Single)dataRow["saturatedfattyacid_15_0"]; + + if (dataRow.IsNull("saturatedfattyacid_16_0")) + saturatedfattyacid_16_0 = 0; + else + saturatedfattyacid_16_0 = (Single)dataRow["saturatedfattyacid_16_0"]; + + if (dataRow.IsNull("saturatedfattyacid_17_0")) + saturatedfattyacid_17_0 = 0; + else + saturatedfattyacid_17_0 = (Single)dataRow["saturatedfattyacid_17_0"]; + + if (dataRow.IsNull("saturatedfattyacid_18_0")) + saturatedfattyacid_18_0 = 0; + else + saturatedfattyacid_18_0 = (Single)dataRow["saturatedfattyacid_18_0"]; + + if (dataRow.IsNull("saturatedfattyacid_20_0")) + saturatedfattyacid_20_0 = 0; + else + saturatedfattyacid_20_0 = (Single)dataRow["saturatedfattyacid_20_0"]; + + if (dataRow.IsNull("saturatedfattyacid_22_0")) + saturatedfattyacid_22_0 = 0; + else + saturatedfattyacid_22_0 = (Single)dataRow["saturatedfattyacid_22_0"]; + + if (dataRow.IsNull("saturatedfattyacid_24_0")) + saturatedfattyacid_24_0 = 0; + else + saturatedfattyacid_24_0 = (Single)dataRow["saturatedfattyacid_24_0"]; + + if (dataRow.IsNull("saturatedfattyacid_4_0")) + saturatedfattyacid_4_0 = 0; + else + saturatedfattyacid_4_0 = (Single)dataRow["saturatedfattyacid_4_0"]; + + if (dataRow.IsNull("saturatedfattyacid_6_0")) + saturatedfattyacid_6_0 = 0; + else + saturatedfattyacid_6_0 = (Single)dataRow["saturatedfattyacid_6_0"]; + + if (dataRow.IsNull("saturatedfattyacid_8_0")) + saturatedfattyacid_8_0 = 0; + else + saturatedfattyacid_8_0 = (Single)dataRow["saturatedfattyacid_8_0"]; + + if (dataRow.IsNull("selenium")) + selenium = 0; + else + selenium = (Single)dataRow["selenium"]; + + if (dataRow.IsNull("serine")) + serine = 0; + else + serine = (Single)dataRow["serine"]; + + if (dataRow.IsNull("sodium")) + sodium = 0; + else + sodium = (Single)dataRow["sodium"]; + + if (dataRow.IsNull("starch")) + starch = 0; + else + starch = (Single)dataRow["starch"]; + + if (dataRow.IsNull("stigmasterol")) + stigmasterol = 0; + else + stigmasterol = (Single)dataRow["stigmasterol"]; + + if (dataRow.IsNull("sucrose")) + sucrose = 0; + else + sucrose = (Single)dataRow["sucrose"]; + + if (dataRow.IsNull("sugar")) + sugar = 0; + else + sugar = (Single)dataRow["sugar"]; + + if (dataRow.IsNull("sugaralcohols")) + sugaralcohols = 0; + else + sugaralcohols = (Single)dataRow["sugaralcohols"]; + + if (dataRow.IsNull("theobromine")) + theobromine = 0; + else + theobromine = (Single)dataRow["theobromine"]; + + if (dataRow.IsNull("thiamin")) + thiamin = 0; + else + thiamin = (Single)dataRow["thiamin"]; + + if (dataRow.IsNull("threonine")) + threonine = 0; + else + threonine = (Single)dataRow["threonine"]; + + if (dataRow.IsNull("totalcarbohydrate")) + totalcarbohydrate = 0; + else + totalcarbohydrate = (Single)dataRow["totalcarbohydrate"]; + + if (dataRow.IsNull("totalfat")) + totalfat = 0; + else + totalfat = (Single)dataRow["totalfat"]; + + if (dataRow.IsNull("transfattyacids")) + transfattyacids = 0; + else + transfattyacids = (Single)dataRow["transfattyacids"]; + + if (dataRow.IsNull("transmonoenoicfattyacids")) + transmonoenoicfattyacids = 0; + else + transmonoenoicfattyacids = (Single)dataRow["transmonoenoicfattyacids"]; + + if (dataRow.IsNull("transpolyenoicfattyacids")) + transpolyenoicfattyacids = 0; + else + transpolyenoicfattyacids = (Single)dataRow["transpolyenoicfattyacids"]; + + if (dataRow.IsNull("tryptophan")) + tryptophan = 0; + else + tryptophan = (Single)dataRow["tryptophan"]; + + if (dataRow.IsNull("tyrosine")) + tyrosine = 0; + else + tyrosine = (Single)dataRow["tyrosine"]; + + if (dataRow.IsNull("valine")) + valine = 0; + else + valine = (Single)dataRow["valine"]; + + if (dataRow.IsNull("vitamina")) + vitamina = 0; + else + vitamina = (Single)dataRow["vitamina"]; + + if (dataRow.IsNull("vitaminb12")) + vitaminb12 = 0; + else + vitaminb12 = (Single)dataRow["vitaminb12"]; + + if (dataRow.IsNull("vitaminb6")) + vitaminb6 = 0; + else + vitaminb6 = (Single)dataRow["vitaminb6"]; + + if (dataRow.IsNull("vitaminc")) + vitaminc = 0; + else + vitaminc = (Single)dataRow["vitaminc"]; + + if (dataRow.IsNull("vitamind")) + vitamind = 0; + else + vitamind = (Single)dataRow["vitamind"]; + + if (dataRow.IsNull("vitamine")) + vitamine = 0; + else + vitamine = (Single)dataRow["vitamine"]; + + if (dataRow.IsNull("vitamink")) + vitamink = 0; + else + vitamink = (Single)dataRow["vitamink"]; + + if (dataRow.IsNull("volume")) + volume = 0; + else + volume = (Single)dataRow["volume"]; + + if (dataRow.IsNull("water")) + water = 0; + else + water = (Single)dataRow["water"]; + + if (dataRow.IsNull("zinc")) + zinc = 0; + else + zinc = (Single)dataRow["zinc"]; + + + //Populate child objects + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeIngredientsByRecipeID(recipeID.Value); + + foreach (DataRow childDataRow in recordSet.Tables[0].Rows) + { + var newIngredient = RecipeIngredient.GetRecipeIngredientByDataRow(childDataRow); + recipeIngredients.Add(newIngredient); + } + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeProceduresByRecipeID(recipeID.Value); + + foreach (DataRow childDataRow in recordSet.Tables[0].Rows) + { + var newProcedure = RecipeProcedure.GetRecipeProcedureByDataRow(childDataRow); + recipeProcedures.Add(newProcedure); + } + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeTipsByRecipeID(recipeID.Value); + + foreach (DataRow childDataRow in recordSet.Tables[0].Rows) + { + var newTip = RecipeTip.GetRecipeTipByDataRow(childDataRow); + recipeTips.Add(newTip); + } + + + + } + + private void InitializeAllFields() + { + recipeID = null; + cookbookID = null; + cookbookchapterID = null; + recipename = String.Empty; + author = String.Empty; + source = String.Empty; + webpage = String.Empty; + comments = String.Empty; + copyright = String.Empty; + servings = 0; + nutritionservinglabel = String.Empty; + yield = String.Empty; + preparationtime = 0; + cookingtime = 0; + readyintime = 0; + inactivetime = 0; + oventemperaturec = 0; + oventemperaturef = 0; + percentcaloriesfromalcohol = 0; + percentcaloriesfromcarbs = 0; + percentcaloriesfromfat = 0; + percentcaloriesfromprotein = 0; + alanine = 0; + alcohol = 0; + alcoholfactor = 0; + alphacarotene = 0; + alphalinolenicacid = 0; + arachidonicacid = 0; + arginine = 0; + ash = 0; + asparticacid = 0; + betacarotene = 0; + betacryptoxanthin = 0; + betasitosterol = 0; + betatocopherol = 0; + biotin = 0; + caffeine = 0; + calcium = 0; + calories = 0; + caloriesfromalcohol = 0; + caloriesfromcarbs = 0; + caloriesfromfat = 0; + caloriesfromprotein = 0; + campesterol = 0; + carbohydratefactor = 0; + chloride = 0; + cholesterol = 0; + choline = 0; + chromium = 0; + copper = 0; + cystine = 0; + deltatocopherol = 0; + dihomogammalinolenicacid = 0; + docosahexaenoicacid = 0; + docosapentaenoicacid = 0; + eicosadienoicacid = 0; + eicosapentaenoicacid = 0; + energy = 0; + energyfromalcohol = 0; + energyfromcarbs = 0; + energyfromfat = 0; + energyfromprotein = 0; + fatfactor = 0; + fiber = 0; + fluoride = 0; + folate = 0; + fructose = 0; + galactose = 0; + gammalinolenicacid = 0; + gammatocopherol = 0; + glucose = 0; + glutamicacid = 0; + glycine = 0; + histidine = 0; + hydroxyproline = 0; + iodine = 0; + iron = 0; + isoleucine = 0; + lactose = 0; + leucine = 0; + linoleicacid = 0; + lycopene = 0; + lysine = 0; + magnesium = 0; + maltose = 0; + manganese = 0; + mass = 0; + methionine = 0; + molybdenum = 0; + monounsaturatedfat = 0; + monounsaturatedfattyacid_14_1 = 0; + monounsaturatedfattyacid_15_1 = 0; + monounsaturatedfattyacid_16_1 = 0; + monounsaturatedfattyacid_17_1 = 0; + monounsaturatedfattyacid_18_1 = 0; + monounsaturatedfattyacid_20_1 = 0; + monounsaturatedfattyacid_22_1 = 0; + monounsaturatedfattyacid_24_1 = 0; + netcarbohydrates = 0; + niacin = 0; + omega3fattyacids = 0; + omega6fattyacids = 0; + pantothenicacid = 0; + phenylalanine = 0; + phosphorus = 0; + phytosterols = 0; + polyunsaturatedfat = 0; + polyunsaturatedfattyacid_18_2 = 0; + polyunsaturatedfattyacid_18_3 = 0; + polyunsaturatedfattyacid_18_4 = 0; + polyunsaturatedfattyacid_20_3 = 0; + polyunsaturatedfattyacid_20_4 = 0; + polyunsaturatedfattyacid_21_5 = 0; + polyunsaturatedfattyacid_22_4 = 0; + potassium = 0; + proline = 0; + protein = 0; + proteinfactor = 0; + refuse = 0; + retinol = 0; + riboflavin = 0; + saturatedfat = 0; + saturatedfattyacid_10_0 = 0; + saturatedfattyacid_12_0 = 0; + saturatedfattyacid_13_0 = 0; + saturatedfattyacid_14_0 = 0; + saturatedfattyacid_15_0 = 0; + saturatedfattyacid_16_0 = 0; + saturatedfattyacid_17_0 = 0; + saturatedfattyacid_18_0 = 0; + saturatedfattyacid_20_0 = 0; + saturatedfattyacid_22_0 = 0; + saturatedfattyacid_24_0 = 0; + saturatedfattyacid_4_0 = 0; + saturatedfattyacid_6_0 = 0; + saturatedfattyacid_8_0 = 0; + selenium = 0; + serine = 0; + sodium = 0; + starch = 0; + stigmasterol = 0; + sucrose = 0; + sugar = 0; + sugaralcohols = 0; + theobromine = 0; + thiamin = 0; + threonine = 0; + totalcarbohydrate = 0; + totalfat = 0; + transfattyacids = 0; + transmonoenoicfattyacids = 0; + transpolyenoicfattyacids = 0; + tryptophan = 0; + tyrosine = 0; + valine = 0; + vitamina = 0; + vitaminb12 = 0; + vitaminb6 = 0; + vitaminc = 0; + vitamind = 0; + vitamine = 0; + vitamink = 0; + volume = 0; + water = 0; + zinc = 0; + + recipeIngredients = new List(); + recipeProcedures = new List(); + recipeTips = new List(); + } + + public String GetHTML(List trackbackList) + { + var builder = new HtmlContentBuilder(); + + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(""); + builder.AppendFormat("{0}" + Constants.CRLF, this.recipename); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(HTMLAddTrackbackLinks(trackbackList)); + builder.AppendHtml(HTMLAddRecipeName()); + builder.AppendHtml(HTMLAddRecipeComments()); + builder.AppendHtml(HTMLAddAllIngredients()); + builder.AppendHtml(HTMLAddAllProcedures()); + builder.AppendHtml(HTMLAddServingsYieldNutrition()); + builder.AppendHtml(HTMLAddAllTips()); + builder.AppendHtml(HTMLAddSourceInfo()); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine(""); + builder.AppendHtmlLine(""); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + + } + + private String HTMLAddTrackbackLinks(List trackbackList) + { + if ((trackbackList?.Count() ?? 0) == 0) + { + return String.Empty; + } + + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + private String HTMLAddRecipeName() + { + var builder = new HtmlContentBuilder(); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", this.recipename); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddRecipeComments() + { + var builder = new HtmlContentBuilder(); + + if (!String.IsNullOrWhiteSpace(this.comments)) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", this.comments); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + } + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + private String HTMLAddAllIngredients() + { + var builder = new HtmlContentBuilder(); + + if (this.recipeIngredients.Count > 0) + { + //First build the two columns of ingredients + List ingredientsFirstColumn = new List(); + List ingredientsSecondColumn = new List(); + + for (int intIngredientIndex = 0; intIngredientIndex < this.recipeIngredients.Count; intIngredientIndex++) + { + if (intIngredientIndex < ((double)this.recipeIngredients.Count / 2D)) + { + ingredientsFirstColumn.Add(this.recipeIngredients[intIngredientIndex]); + } + else + { + ingredientsSecondColumn.Add(this.recipeIngredients[intIngredientIndex]); + } + } + + if (ingredientsFirstColumn.Count > 0 && ingredientsSecondColumn.Count > 0) + { + //Check for only two ingredients. If so, put both on first column + if (ingredientsFirstColumn.Count == 1 && ingredientsSecondColumn.Count == 1) + { + ingredientsFirstColumn.Add(ingredientsSecondColumn[0]); + ingredientsSecondColumn.RemoveAt(0); + } + else + { + + //Check for orphan header at end of first column. Move to second column if orphaned + if (ingredientsFirstColumn[ingredientsFirstColumn.Count - 1].isHeading && ingredientsSecondColumn[ingredientsSecondColumn.Count - 1].isHeading == false) + { + ingredientsSecondColumn.Insert(0, ingredientsFirstColumn[ingredientsFirstColumn.Count - 1]); + ingredientsFirstColumn.RemoveAt(ingredientsFirstColumn.Count - 1); + } + } + } + + + + + + //Now build the display for the two columns + StringBuilder ingredientsDisplayFirstColumn = new StringBuilder(); + StringBuilder ingredientsDisplaySecondColumn = new StringBuilder(); + + foreach(var ingredient in ingredientsFirstColumn) + { + ingredientsDisplayFirstColumn.Append(HTMLAddIngredient(ingredient)); + } + + foreach (var ingredient in ingredientsSecondColumn) + { + ingredientsDisplaySecondColumn.Append(HTMLAddIngredient(ingredient)); + } + + //Now put those two columns into the HTML + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + } + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddIngredient(RecipeIngredient ingredient) + { + var builder = new HtmlContentBuilder(); + + if (ingredient.isHeading) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + } + else + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + } + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddAllProcedures() + { + var builder = new HtmlContentBuilder(); + + if (this.recipeProcedures.Count > 0) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine(" "); + builder.AppendHtml(ingredientsDisplayFirstColumn.ToString()); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine(" "); + builder.AppendHtml(ingredientsDisplaySecondColumn.ToString()); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("
"); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", ingredient.ingredientText); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", ((RecipeIngredientItem)ingredient).quantityText); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", ((RecipeIngredientItem)ingredient).unitText); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", ingredient.ingredientText); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine(" "); + + int taskNumber = 1; + + foreach (var recipeProcedure in this.recipeProcedures) + { + if (recipeProcedure.isHeading) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + //reset task number + taskNumber = 1; + } + else + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + taskNumber += 1; + + } + } + + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + } + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddAllTips() + { + var builder = new HtmlContentBuilder(); + + if (this.recipeTips.Count > 0) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + } + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + private String HTMLAddServingsYieldNutrition() + { + var builder = new HtmlContentBuilder(); + + var needTopMargin = true; + var styleToUse = String.Empty; + + var servingsToUse = this.servings; + if (servingsToUse == 0) + { + servingsToUse = 1; + } + + if (this.servings > 0) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + if (!String.IsNullOrWhiteSpace(this.yield)) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + } + + + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine("
"); + builder.AppendHtml("

"); + builder.AppendFormat("{0}",recipeProcedure.procedureText); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", taskNumber.ToString()); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtml("

"); + builder.AppendFormat("{0}", recipeProcedure.procedureText); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("

Tips

"); + + foreach (var recipeTip in this.recipeTips) + { + if (recipeTip.isHeading) + { + builder.AppendHtml("

"); + } + else + { + builder.AppendHtml("

"); + } + builder.AppendFormat("{0}", recipeTip.tipText); + builder.AppendHtmlLine("

"); + } + + builder.AppendHtmlLine("
"); + if (needTopMargin) + { + styleToUse = "style=\"MARGIN-TOP: 0.11in; MARGIN-BOTTOM: 0in;\""; + needTopMargin = false; + } + else + { + styleToUse = "style=\"MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in;\""; + } + + builder.AppendHtml("

"); + builder.AppendFormat("{0}", "Servings: " + this.servings.ToString()); + builder.AppendHtmlLine("

"); + } + builder.AppendHtmlLine("
"); + if (needTopMargin) + { + styleToUse = "style=\"MARGIN-TOP: 0.11in; MARGIN-BOTTOM: 0in;\""; + needTopMargin = false; + } + else + { + styleToUse = "style=\"MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in;\""; + } + builder.AppendHtml("

"); + builder.AppendFormat("{0}", "Yield: " + this.yield); + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("

Nutrition Facts

"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + private String HTMLAddSourceInfo() + { + var builder = new HtmlContentBuilder(); + + var needTopMargin = true; + var styleToUse = String.Empty; + + if (!String.IsNullOrWhiteSpace(this.source) || !String.IsNullOrWhiteSpace(this.webpage) || !String.IsNullOrWhiteSpace(this.copyright)) + { + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine("
"); + if (servingsToUse == 1) + { + builder.AppendFormat("

Serving size: Entire recipe. ({0} g)", this.mass.ToString("F2")); + } + else + { + builder.AppendFormat("

Serving size: 1/{0} of a recipe. ({1} g)", servingsToUse.ToString(), this.mass.ToString("F2")); + } + builder.AppendHtmlLine("

"); + builder.AppendHtmlLine("

Percent daily values based on the Reference Daily Intake (RDI) for a 2000 calorie diet.

"); + builder.AppendHtmlLine("

Nutrition information calculated from recipe ingredients.

"); + + int totalIngredients = 0; + int totalIngredientsLinked = 0; + int totalIngredientsNotLinked = 0; + + foreach (var recipeIngredient in this.recipeIngredients) + { + if (recipeIngredient is RecipeIngredientItem) + { + totalIngredients += 1; + + var recipeIngredientItem = (RecipeIngredientItem)recipeIngredient; + if (recipeIngredientItem.ingredientID != null) + { + totalIngredientsLinked += 1; + } + else + { + totalIngredientsNotLinked += 1; + } + } + } + + if (totalIngredients > 0 && totalIngredientsNotLinked > 0) + { + if (totalIngredientsNotLinked == 1) + { + builder.AppendHtmlLine("

There is an ingredient not linked for nutrition

"); + } + else + { + builder.AppendFormat("

There are {0} ingredient(s) not linked for nutrition

" + Constants.CRLF, totalIngredientsNotLinked.ToString()); + } + } + + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine(" "); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("

Amount Per Serving

"); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("

Calories

"); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}

" + Constants.CRLF, this.calories.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Calories From Fat ({0}%)

" + Constants.CRLF, this.percentcaloriesfromfat.ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}

" + Constants.CRLF, this.caloriesfromfat.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("

% Daily Value

"); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Total Fat {0}g

" + Constants.CRLF,this.totalfat.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.totalfat * 100)/Constants.DAILY_VALUE_FAT).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Saturated Fat {0}g

" + Constants.CRLF,this.saturatedfat.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.saturatedfat * 100)/Constants.DAILY_VALUE_SATURATED_FAT).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Cholesterol {0}mg

" + Constants.CRLF,this.cholesterol.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.cholesterol * 100)/Constants.DAILY_VALUE_CHOLESTEROL).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Sodium {0}mg

" + Constants.CRLF,this.sodium.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.sodium * 100)/Constants.DAILY_VALUE_SODIUM).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Potassium {0}mg

" + Constants.CRLF,this.potassium.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.potassium * 100)/Constants.DAILY_VALUE_POTASSIUM).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Total Carbohydrates {0}g

" + Constants.CRLF,this.totalcarbohydrate.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.totalcarbohydrate * 100)/Constants.DAILY_VALUE_TOTAL_CARBOHYDRATE).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Fiber {0}g

" + Constants.CRLF,this.fiber.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.fiber * 100)/Constants.DAILY_VALUE_DIETARY_FIBER).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Sugar {0}g

" + Constants.CRLF,this.sugar.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("

 

"); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

Protein {0}g

" + Constants.CRLF,this.protein.ToString("F2")); + builder.AppendHtmlLine("
"); + builder.AppendFormat("

{0}%

" + Constants.CRLF,((this.protein * 100)/Constants.DAILY_VALUE_PROTEIN).ToString("F0")); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("
"); + builder.AppendHtmlLine("

Source

"); + + if (!String.IsNullOrWhiteSpace(this.source)) + { + if (needTopMargin) + { + styleToUse = "style=\"MARGIN-TOP: 0.11in; MARGIN-BOTTOM: 0in;\""; + needTopMargin = false; + } + else + { + styleToUse = "style=\"MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in;\""; + } + builder.AppendFormat("

{0}

" + Constants.CRLF,"Source: " + this.source); + } + + if (!String.IsNullOrWhiteSpace(this.webpage)) + { + if (needTopMargin) + { + styleToUse = "style=\"MARGIN-TOP: 0.11in; MARGIN-BOTTOM: 0in;\""; + needTopMargin = false; + } + else + { + styleToUse = "style=\"MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in;\""; + } + builder.AppendFormat("

{0}

" + Constants.CRLF, "Web Page: " + this.webpage); + } + if (!String.IsNullOrWhiteSpace(this.copyright)) + { + if (needTopMargin) + { + styleToUse = "style=\"MARGIN-TOP: 0.11in; MARGIN-BOTTOM: 0in;\""; + needTopMargin = false; + } + else + { + styleToUse = "style=\"MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in;\""; + } + builder.AppendFormat("

{0}

" + Constants.CRLF, "Copyright: " + this.copyright); + } + + } + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + + + public void CalcNutrition() + { + alanine = 0; + alcohol = 0; + alcoholfactor = 0; + alphacarotene = 0; + alphalinolenicacid = 0; + arachidonicacid = 0; + arginine = 0; + ash = 0; + asparticacid = 0; + betacarotene = 0; + betacryptoxanthin = 0; + betasitosterol = 0; + betatocopherol = 0; + biotin = 0; + caffeine = 0; + calcium = 0; + calories = 0; + caloriesfromalcohol = 0; + caloriesfromcarbs = 0; + caloriesfromfat = 0; + caloriesfromprotein = 0; + campesterol = 0; + carbohydratefactor = 0; + chloride = 0; + cholesterol = 0; + choline = 0; + chromium = 0; + copper = 0; + cystine = 0; + deltatocopherol = 0; + dihomogammalinolenicacid = 0; + docosahexaenoicacid = 0; + docosapentaenoicacid = 0; + eicosadienoicacid = 0; + eicosapentaenoicacid = 0; + energy = 0; + energyfromalcohol = 0; + energyfromcarbs = 0; + energyfromfat = 0; + energyfromprotein = 0; + fatfactor = 0; + fiber = 0; + fluoride = 0; + folate = 0; + fructose = 0; + galactose = 0; + gammalinolenicacid = 0; + gammatocopherol = 0; + glucose = 0; + glutamicacid = 0; + glycine = 0; + histidine = 0; + hydroxyproline = 0; + iodine = 0; + iron = 0; + isoleucine = 0; + lactose = 0; + leucine = 0; + linoleicacid = 0; + lycopene = 0; + lysine = 0; + magnesium = 0; + maltose = 0; + manganese = 0; + mass = 0; + methionine = 0; + molybdenum = 0; + monounsaturatedfat = 0; + monounsaturatedfattyacid_14_1 = 0; + monounsaturatedfattyacid_15_1 = 0; + monounsaturatedfattyacid_16_1 = 0; + monounsaturatedfattyacid_17_1 = 0; + monounsaturatedfattyacid_18_1 = 0; + monounsaturatedfattyacid_20_1 = 0; + monounsaturatedfattyacid_22_1 = 0; + monounsaturatedfattyacid_24_1 = 0; + netcarbohydrates = 0; + niacin = 0; + omega3fattyacids = 0; + omega6fattyacids = 0; + pantothenicacid = 0; + phenylalanine = 0; + phosphorus = 0; + phytosterols = 0; + polyunsaturatedfat = 0; + polyunsaturatedfattyacid_18_2 = 0; + polyunsaturatedfattyacid_18_3 = 0; + polyunsaturatedfattyacid_18_4 = 0; + polyunsaturatedfattyacid_20_3 = 0; + polyunsaturatedfattyacid_20_4 = 0; + polyunsaturatedfattyacid_21_5 = 0; + polyunsaturatedfattyacid_22_4 = 0; + potassium = 0; + proline = 0; + protein = 0; + proteinfactor = 0; + refuse = 0; + retinol = 0; + riboflavin = 0; + saturatedfat = 0; + saturatedfattyacid_10_0 = 0; + saturatedfattyacid_12_0 = 0; + saturatedfattyacid_13_0 = 0; + saturatedfattyacid_14_0 = 0; + saturatedfattyacid_15_0 = 0; + saturatedfattyacid_16_0 = 0; + saturatedfattyacid_17_0 = 0; + saturatedfattyacid_18_0 = 0; + saturatedfattyacid_20_0 = 0; + saturatedfattyacid_22_0 = 0; + saturatedfattyacid_24_0 = 0; + saturatedfattyacid_4_0 = 0; + saturatedfattyacid_6_0 = 0; + saturatedfattyacid_8_0 = 0; + selenium = 0; + serine = 0; + sodium = 0; + starch = 0; + stigmasterol = 0; + sucrose = 0; + sugar = 0; + sugaralcohols = 0; + theobromine = 0; + thiamin = 0; + threonine = 0; + totalcarbohydrate = 0; + totalfat = 0; + transfattyacids = 0; + transmonoenoicfattyacids = 0; + transpolyenoicfattyacids = 0; + tryptophan = 0; + tyrosine = 0; + valine = 0; + vitamina = 0; + vitaminb12 = 0; + vitaminb6 = 0; + vitaminc = 0; + vitamind = 0; + vitamine = 0; + vitamink = 0; + volume = 0; + water = 0; + zinc = 0; + + Single servingsToUse = this.servings; + if (servingsToUse == 0) + { + servingsToUse = 1; + } + + foreach (var recipeIngredient in this.recipeIngredients) + { + if (recipeIngredient is RecipeIngredientItem) + { + var recipeIngredientItem = (RecipeIngredientItem)recipeIngredient; + + + if (recipeIngredientItem.ingredientID != null && recipeIngredientItem.measureID != null) + { + var ingredient = new Ingredient(recipeIngredientItem.ingredientID.Value); + + var gramWeight = ingredient.GramWeightByMeasureID(recipeIngredientItem.measureID.Value); + + this.alanine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alanine); + this.alcohol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alcohol); + this.alphacarotene += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alphacarotene); + this.alphalinolenicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alphalinolenicacid); + this.arachidonicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.arachidonicacid); + this.arginine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.arginine); + this.ash += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.ash); + this.asparticacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.asparticacid); + this.betacarotene += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betacarotene); + this.betacryptoxanthin += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betacryptoxanthin); + this.betasitosterol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betasitosterol); + this.betatocopherol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.betatocopherol); + this.biotin += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.biotin); + this.caffeine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caffeine); + this.calcium += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.calcium); + this.calories += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.calories); + this.caloriesfromalcohol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromalcohol); + this.caloriesfromcarbs += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromcarbs); + this.caloriesfromfat += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromfat); + this.caloriesfromprotein += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.caloriesfromprotein); + this.campesterol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.campesterol); + this.chloride += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.chloride); + this.cholesterol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.cholesterol); + this.choline += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.choline); + this.chromium += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.chromium); + this.copper += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.copper); + this.cystine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.cystine); + this.deltatocopherol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.deltatocopherol); + this.dihomogammalinolenicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.dihomogammalinolenicacid); + this.docosahexaenoicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.docosahexaenoicacid); + this.docosapentaenoicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.docosapentaenoicacid); + this.eicosadienoicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.eicosadienoicacid); + this.eicosapentaenoicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.eicosapentaenoicacid); + this.energy += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energy); + this.energyfromalcohol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromalcohol); + this.energyfromcarbs += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromcarbs); + this.energyfromfat += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromfat); + this.energyfromprotein += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.energyfromprotein); + this.fiber += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fiber); + this.fluoride += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fluoride); + this.folate += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.folate); + this.fructose += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fructose); + this.galactose += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.galactose); + this.gammalinolenicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.gammalinolenicacid); + this.gammatocopherol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.gammatocopherol); + this.glucose += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.glucose); + this.glutamicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.glutamicacid); + this.glycine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.glycine); + this.histidine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.histidine); + this.hydroxyproline += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.hydroxyproline); + this.iodine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.iodine); + this.iron += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.iron); + this.isoleucine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.isoleucine); + this.lactose += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.lactose); + this.leucine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.leucine); + this.linoleicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.linoleicacid); + this.lycopene += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.lycopene); + this.lysine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.lysine); + this.magnesium += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.magnesium); + this.maltose += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.maltose); + this.manganese += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.manganese); + + //mass calculated differently, since it directly uses gramWeight of ingredient + this.mass += recipeIngredientItem.measureQuantity * gramWeight; + + this.methionine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.methionine); + this.molybdenum += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.molybdenum); + this.monounsaturatedfat += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfat); + this.monounsaturatedfattyacid_14_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_14_1); + this.monounsaturatedfattyacid_15_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_15_1); + this.monounsaturatedfattyacid_16_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_16_1); + this.monounsaturatedfattyacid_17_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_17_1); + this.monounsaturatedfattyacid_18_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_18_1); + this.monounsaturatedfattyacid_20_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_20_1); + this.monounsaturatedfattyacid_22_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_22_1); + this.monounsaturatedfattyacid_24_1 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.monounsaturatedfattyacid_24_1); + this.netcarbohydrates += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.netcarbohydrates); + this.niacin += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.niacin); + this.omega3fattyacids += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.omega3fattyacids); + this.omega6fattyacids += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.omega6fattyacids); + this.pantothenicacid += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.pantothenicacid); + this.phenylalanine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.phenylalanine); + this.phosphorus += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.phosphorus); + this.phytosterols += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.phytosterols); + this.polyunsaturatedfat += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfat); + this.polyunsaturatedfattyacid_18_2 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_18_2); + this.polyunsaturatedfattyacid_18_3 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_18_3); + this.polyunsaturatedfattyacid_18_4 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_18_4); + this.polyunsaturatedfattyacid_20_3 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_20_3); + this.polyunsaturatedfattyacid_20_4 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_20_4); + this.polyunsaturatedfattyacid_21_5 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_21_5); + this.polyunsaturatedfattyacid_22_4 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.polyunsaturatedfattyacid_22_4); + this.potassium += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.potassium); + this.proline += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.proline); + this.protein += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.protein); + this.refuse += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.refuse); + this.retinol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.retinol); + this.riboflavin += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.riboflavin); + this.saturatedfat += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfat); + this.saturatedfattyacid_10_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_10_0); + this.saturatedfattyacid_12_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_12_0); + this.saturatedfattyacid_13_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_13_0); + this.saturatedfattyacid_14_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_14_0); + this.saturatedfattyacid_15_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_15_0); + this.saturatedfattyacid_16_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_16_0); + this.saturatedfattyacid_17_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_17_0); + this.saturatedfattyacid_18_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_18_0); + this.saturatedfattyacid_20_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_20_0); + this.saturatedfattyacid_22_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_22_0); + this.saturatedfattyacid_24_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_24_0); + this.saturatedfattyacid_4_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_4_0); + this.saturatedfattyacid_6_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_6_0); + this.saturatedfattyacid_8_0 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.saturatedfattyacid_8_0); + this.selenium += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.selenium); + this.serine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.serine); + this.sodium += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sodium); + this.starch += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.starch); + this.stigmasterol += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.stigmasterol); + this.sucrose += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sucrose); + this.sugar += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sugar); + this.sugaralcohols += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.sugaralcohols); + this.theobromine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.theobromine); + this.thiamin += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.thiamin); + this.threonine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.threonine); + this.totalcarbohydrate += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.totalcarbohydrate); + this.totalfat += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.totalfat); + this.transfattyacids += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.transfattyacids); + this.transmonoenoicfattyacids += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.transmonoenoicfattyacids); + this.transpolyenoicfattyacids += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.transpolyenoicfattyacids); + this.tryptophan += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.tryptophan); + this.tyrosine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.tyrosine); + this.valine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.valine); + this.vitamina += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamina); + this.vitaminb12 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitaminb12); + this.vitaminb6 += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitaminb6); + this.vitaminc += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitaminc); + this.vitamind += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamind); + this.vitamine += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamine); + this.vitamink += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.vitamink); + this.volume += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.volume); + this.water += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.water); + this.zinc += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.zinc); + + this.alcoholfactor += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.alcoholfactor); + this.carbohydratefactor += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.carbohydratefactor); + this.fatfactor += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.fatfactor); + this.proteinfactor += GetNutrientItemAmount(recipeIngredientItem, gramWeight, ingredient.proteinfactor); + } + } + + } + + if (this.calories == 0) + { + this.percentcaloriesfromalcohol = 0; + this.percentcaloriesfromcarbs = 0; + this.percentcaloriesfromfat = 0; + this.percentcaloriesfromprotein = 0; + } + else + { + this.percentcaloriesfromalcohol = (100F * this.caloriesfromalcohol) / this.calories; + this.percentcaloriesfromcarbs = (100F * this.caloriesfromcarbs) / this.calories; + this.percentcaloriesfromfat = (100F * this.caloriesfromfat) / this.calories; + this.percentcaloriesfromprotein = (100F * this.caloriesfromprotein) / this.calories; + } + + this.netcarbohydrates = this.totalcarbohydrate - this.fiber - this.sugaralcohols; + + this.alanine = this.alanine / servingsToUse; + this.alcohol = this.alcohol / servingsToUse; + this.alcoholfactor = this.alcoholfactor / servingsToUse; + this.alphacarotene = this.alphacarotene / servingsToUse; + this.alphalinolenicacid = this.alphalinolenicacid / servingsToUse; + this.arachidonicacid = this.arachidonicacid / servingsToUse; + this.arginine = this.arginine / servingsToUse; + this.ash = this.ash / servingsToUse; + this.asparticacid = this.asparticacid / servingsToUse; + this.betacarotene = this.betacarotene / servingsToUse; + this.betacryptoxanthin = this.betacryptoxanthin / servingsToUse; + this.betasitosterol = this.betasitosterol / servingsToUse; + this.betatocopherol = this.betatocopherol / servingsToUse; + this.biotin = this.biotin / servingsToUse; + this.caffeine = this.caffeine / servingsToUse; + this.calcium = this.calcium / servingsToUse; + this.calories = this.calories / servingsToUse; + this.caloriesfromalcohol = this.caloriesfromalcohol / servingsToUse; + this.caloriesfromcarbs = this.caloriesfromcarbs / servingsToUse; + this.caloriesfromfat = this.caloriesfromfat / servingsToUse; + this.caloriesfromprotein = this.caloriesfromprotein / servingsToUse; + this.campesterol = this.campesterol / servingsToUse; + this.carbohydratefactor = this.carbohydratefactor / servingsToUse; + this.chloride = this.chloride / servingsToUse; + this.cholesterol = this.cholesterol / servingsToUse; + this.choline = this.choline / servingsToUse; + this.chromium = this.chromium / servingsToUse; + this.copper = this.copper / servingsToUse; + this.cystine = this.cystine / servingsToUse; + this.deltatocopherol = this.deltatocopherol / servingsToUse; + this.dihomogammalinolenicacid = this.dihomogammalinolenicacid / servingsToUse; + this.docosahexaenoicacid = this.docosahexaenoicacid / servingsToUse; + this.docosapentaenoicacid = this.docosapentaenoicacid / servingsToUse; + this.eicosadienoicacid = this.eicosadienoicacid / servingsToUse; + this.eicosapentaenoicacid = this.eicosapentaenoicacid / servingsToUse; + this.energy = this.energy / servingsToUse; + this.energyfromalcohol = this.energyfromalcohol / servingsToUse; + this.energyfromcarbs = this.energyfromcarbs / servingsToUse; + this.energyfromfat = this.energyfromfat / servingsToUse; + this.energyfromprotein = this.energyfromprotein / servingsToUse; + this.fatfactor = this.fatfactor / servingsToUse; + this.fiber = this.fiber / servingsToUse; + this.fluoride = this.fluoride / servingsToUse; + this.folate = this.folate / servingsToUse; + this.fructose = this.fructose / servingsToUse; + this.galactose = this.galactose / servingsToUse; + this.gammalinolenicacid = this.gammalinolenicacid / servingsToUse; + this.gammatocopherol = this.gammatocopherol / servingsToUse; + this.glucose = this.glucose / servingsToUse; + this.glutamicacid = this.glutamicacid / servingsToUse; + this.glycine = this.glycine / servingsToUse; + this.histidine = this.histidine / servingsToUse; + this.hydroxyproline = this.hydroxyproline / servingsToUse; + this.iodine = this.iodine / servingsToUse; + this.iron = this.iron / servingsToUse; + this.isoleucine = this.isoleucine / servingsToUse; + this.lactose = this.lactose / servingsToUse; + this.leucine = this.leucine / servingsToUse; + this.linoleicacid = this.linoleicacid / servingsToUse; + this.lycopene = this.lycopene / servingsToUse; + this.lysine = this.lysine / servingsToUse; + this.magnesium = this.magnesium / servingsToUse; + this.maltose = this.maltose / servingsToUse; + this.manganese = this.manganese / servingsToUse; + this.mass = this.mass / servingsToUse; + this.methionine = this.methionine / servingsToUse; + this.molybdenum = this.molybdenum / servingsToUse; + this.monounsaturatedfat = this.monounsaturatedfat / servingsToUse; + this.monounsaturatedfattyacid_14_1 = this.monounsaturatedfattyacid_14_1 / servingsToUse; + this.monounsaturatedfattyacid_15_1 = this.monounsaturatedfattyacid_15_1 / servingsToUse; + this.monounsaturatedfattyacid_16_1 = this.monounsaturatedfattyacid_16_1 / servingsToUse; + this.monounsaturatedfattyacid_17_1 = this.monounsaturatedfattyacid_17_1 / servingsToUse; + this.monounsaturatedfattyacid_18_1 = this.monounsaturatedfattyacid_18_1 / servingsToUse; + this.monounsaturatedfattyacid_20_1 = this.monounsaturatedfattyacid_20_1 / servingsToUse; + this.monounsaturatedfattyacid_22_1 = this.monounsaturatedfattyacid_22_1 / servingsToUse; + this.monounsaturatedfattyacid_24_1 = this.monounsaturatedfattyacid_24_1 / servingsToUse; + this.netcarbohydrates = this.netcarbohydrates / servingsToUse; + this.niacin = this.niacin / servingsToUse; + this.omega3fattyacids = this.omega3fattyacids / servingsToUse; + this.omega6fattyacids = this.omega6fattyacids / servingsToUse; + this.pantothenicacid = this.pantothenicacid / servingsToUse; + this.phenylalanine = this.phenylalanine / servingsToUse; + this.phosphorus = this.phosphorus / servingsToUse; + this.phytosterols = this.phytosterols / servingsToUse; + this.polyunsaturatedfat = this.polyunsaturatedfat / servingsToUse; + this.polyunsaturatedfattyacid_18_2 = this.polyunsaturatedfattyacid_18_2 / servingsToUse; + this.polyunsaturatedfattyacid_18_3 = this.polyunsaturatedfattyacid_18_3 / servingsToUse; + this.polyunsaturatedfattyacid_18_4 = this.polyunsaturatedfattyacid_18_4 / servingsToUse; + this.polyunsaturatedfattyacid_20_3 = this.polyunsaturatedfattyacid_20_3 / servingsToUse; + this.polyunsaturatedfattyacid_20_4 = this.polyunsaturatedfattyacid_20_4 / servingsToUse; + this.polyunsaturatedfattyacid_21_5 = this.polyunsaturatedfattyacid_21_5 / servingsToUse; + this.polyunsaturatedfattyacid_22_4 = this.polyunsaturatedfattyacid_22_4 / servingsToUse; + this.potassium = this.potassium / servingsToUse; + this.proline = this.proline / servingsToUse; + this.protein = this.protein / servingsToUse; + this.proteinfactor = this.proteinfactor / servingsToUse; + this.refuse = this.refuse / servingsToUse; + this.retinol = this.retinol / servingsToUse; + this.riboflavin = this.riboflavin / servingsToUse; + this.saturatedfat = this.saturatedfat / servingsToUse; + this.saturatedfattyacid_10_0 = this.saturatedfattyacid_10_0 / servingsToUse; + this.saturatedfattyacid_12_0 = this.saturatedfattyacid_12_0 / servingsToUse; + this.saturatedfattyacid_13_0 = this.saturatedfattyacid_13_0 / servingsToUse; + this.saturatedfattyacid_14_0 = this.saturatedfattyacid_14_0 / servingsToUse; + this.saturatedfattyacid_15_0 = this.saturatedfattyacid_15_0 / servingsToUse; + this.saturatedfattyacid_16_0 = this.saturatedfattyacid_16_0 / servingsToUse; + this.saturatedfattyacid_17_0 = this.saturatedfattyacid_17_0 / servingsToUse; + this.saturatedfattyacid_18_0 = this.saturatedfattyacid_18_0 / servingsToUse; + this.saturatedfattyacid_20_0 = this.saturatedfattyacid_20_0 / servingsToUse; + this.saturatedfattyacid_22_0 = this.saturatedfattyacid_22_0 / servingsToUse; + this.saturatedfattyacid_24_0 = this.saturatedfattyacid_24_0 / servingsToUse; + this.saturatedfattyacid_4_0 = this.saturatedfattyacid_4_0 / servingsToUse; + this.saturatedfattyacid_6_0 = this.saturatedfattyacid_6_0 / servingsToUse; + this.saturatedfattyacid_8_0 = this.saturatedfattyacid_8_0 / servingsToUse; + this.selenium = this.selenium / servingsToUse; + this.serine = this.serine / servingsToUse; + this.sodium = this.sodium / servingsToUse; + this.starch = this.starch / servingsToUse; + this.stigmasterol = this.stigmasterol / servingsToUse; + this.sucrose = this.sucrose / servingsToUse; + this.sugar = this.sugar / servingsToUse; + this.sugaralcohols = this.sugaralcohols / servingsToUse; + this.theobromine = this.theobromine / servingsToUse; + this.thiamin = this.thiamin / servingsToUse; + this.threonine = this.threonine / servingsToUse; + this.totalcarbohydrate = this.totalcarbohydrate / servingsToUse; + this.totalfat = this.totalfat / servingsToUse; + this.transfattyacids = this.transfattyacids / servingsToUse; + this.transmonoenoicfattyacids = this.transmonoenoicfattyacids / servingsToUse; + this.transpolyenoicfattyacids = this.transpolyenoicfattyacids / servingsToUse; + this.tryptophan = this.tryptophan / servingsToUse; + this.tyrosine = this.tyrosine / servingsToUse; + this.valine = this.valine / servingsToUse; + this.vitamina = this.vitamina / servingsToUse; + this.vitaminb12 = this.vitaminb12 / servingsToUse; + this.vitaminb6 = this.vitaminb6 / servingsToUse; + this.vitaminc = this.vitaminc / servingsToUse; + this.vitamind = this.vitamind / servingsToUse; + this.vitamine = this.vitamine / servingsToUse; + this.vitamink = this.vitamink / servingsToUse; + this.volume = this.volume / servingsToUse; + this.water = this.water / servingsToUse; + this.zinc = this.zinc / servingsToUse; + } + + public Single GetNutrientItemAmount(RecipeIngredientItem recipeIngredientItem, Single gramWeight, Single nutrientAmount) + { + return recipeIngredientItem.measureQuantity * nutrientAmount * (gramWeight / 100.0F); + } + + public void AddToWordDoc(Microsoft.Office.Interop.Word.Application objWord, Dictionary recipePageDictionary, SortedList recipesAlpha, SortedSet pagesAlreadyAdded) + { + + String pageNameToUse = SharedRoutines.RemoveSpecialCharactersFromFileName(this.recipename); + String pageNameToUseWithExtension = pageNameToUse; + + while (pagesAlreadyAdded.Contains(pageNameToUseWithExtension.ToUpper())) + { + pageNameToUse += "1"; + pageNameToUseWithExtension = pageNameToUse; + } + + + recipePageDictionary.Add(this.recipeID.Value, pageNameToUseWithExtension); + recipesAlpha.Add(this.recipename.ToUpper(), this); + pagesAlreadyAdded.Add(pageNameToUseWithExtension.ToUpper()); + + + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 1, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + objWord.Selection.Cells[1].LeftPadding = 0; + + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + + objWord.Selection.Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineWidth = WdLineWidth.wdLineWidth050pt; + + + //objWord.Selection.Font.Bold = 1; + //objWord.Selection.Font.Size = clsWord.WORD_RECIPE_NAME_FONT_SIZE; + //objWord.Selection.TypeText(this.recipename); + //objWord.Selection.Font.Bold = 0; + + objWord.Selection.set_Style(objWord.ActiveDocument.Styles["Heading 2"]); + objWord.Selection.TypeText(this.recipename); + + //objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + objWord.Selection.set_Style(objWord.ActiveDocument.Styles["Normal"]); + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.Selection.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle; + objWord.Selection.ParagraphFormat.SpaceAfter = 0F; + objWord.ActiveDocument.Indexes.MarkEntry(objWord.Selection.Range, this.recipename, this.recipename, String.Empty, String.Empty, String.Empty, 0, 0); + + clsWord.AddHalfSpaceLineAtEndOfDocument(); + + WordDocAddComments(objWord); + WordDocAddAllIngredients(objWord); + WordDocAddAllProcedures(objWord); + WordDocAddServingsYieldNutrition(objWord); + WordDocAddAllTips(objWord); + WordDocAddSourceInfo(objWord); + + if (RecipeRenderedEvent != null) + { + RecipeRenderedEvent.Invoke(this, new EventArgs()); + } + + } + + public void WordDocAddComments(Microsoft.Office.Interop.Word.Application objWord) + { + if (!String.IsNullOrWhiteSpace(this.comments)) + { + objWord.Selection.TypeText(this.comments); + objWord.Selection.TypeParagraph(); + clsWord.AddHalfSpaceLineAtEndOfDocument(); + } + } + + + private void WordDocAddAllIngredients(Microsoft.Office.Interop.Word.Application objWord) + { + if (this.recipeIngredients.Count > 0) + { + //First build the two columns + List ingredientsFirstColumn = new List(); + List ingredientsSecondColumn = new List(); + + for (int intIngredientIndex = 0; intIngredientIndex < this.recipeIngredients.Count; intIngredientIndex++) + { + if (intIngredientIndex < ((double)this.recipeIngredients.Count / 2D)) + { + ingredientsFirstColumn.Add(this.recipeIngredients[intIngredientIndex]); + } + else + { + ingredientsSecondColumn.Add(this.recipeIngredients[intIngredientIndex]); + } + } + + if (ingredientsFirstColumn.Count > 0 && ingredientsSecondColumn.Count > 0) + { + //Check for only two ingredients. If so, put both on first column + if (ingredientsFirstColumn.Count == 1 && ingredientsSecondColumn.Count == 1) + { + ingredientsFirstColumn.Add(ingredientsSecondColumn[0]); + ingredientsSecondColumn.RemoveAt(0); + } + else + { + + //Check for orphan header at end of first column. Move to second column if orphaned + if (ingredientsFirstColumn[ingredientsFirstColumn.Count - 1].isHeading && ingredientsSecondColumn[ingredientsSecondColumn.Count - 1].isHeading == false) + { + ingredientsSecondColumn.Insert(0, ingredientsFirstColumn[ingredientsFirstColumn.Count - 1]); + ingredientsFirstColumn.RemoveAt(ingredientsFirstColumn.Count - 1); + } + } + } + + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 7, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + objWord.Selection.Tables[1].Rows.AllowBreakAcrossPages = 0; + + + objWord.Selection.Cells[1].LeftPadding = 0; + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + objWord.Selection.Tables[1].Borders.InsideLineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + //objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + //objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + //objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + //objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + //objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + //objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + //objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + + //Now put those two columns into the table + for (int intIngredientIndex = 0; intIngredientIndex < ingredientsFirstColumn.Count || intIngredientIndex < ingredientsSecondColumn.Count; intIngredientIndex++) + { + if (intIngredientIndex > 0) + { + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + } + + if (intIngredientIndex <= ingredientsFirstColumn.Count - 1) + { + WordDocAddIngredient(objWord, ingredientsFirstColumn[intIngredientIndex]); + } + else + { + //make up for empty ingredient + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + } + + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + if (intIngredientIndex <= ingredientsSecondColumn.Count - 1) + { + WordDocAddIngredient(objWord, ingredientsSecondColumn[intIngredientIndex]); + } + } + + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + clsWord.AddHalfSpaceLineAtEndOfDocument(); + } + + } + + private void WordDocAddIngredient(Microsoft.Office.Interop.Word.Application objWord, RecipeIngredient ingredient) + { + if (ingredient.isHeading) + { + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText(ingredient.ingredientText); + } + else + { + objWord.Selection.TypeText(((RecipeIngredientItem)ingredient).quantityText); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(((RecipeIngredientItem)ingredient).unitText); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(ingredient.ingredientText); + } + } + + private void WordDocAddAllProcedures(Microsoft.Office.Interop.Word.Application objWord) + { + if (this.recipeProcedures.Count > 0) + { + int taskNumber = 1; + bool blnInTable = false; + + foreach (var recipeProcedure in this.recipeProcedures) + { + if (recipeProcedure.isHeading) + { + if (blnInTable) + { + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + blnInTable = false; + } + + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText(recipeProcedure.procedureText); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeParagraph(); + + //reset task number + taskNumber = 1; + } + else + { + if (blnInTable) + { + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + } + else + { + blnInTable = true; + + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 2, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + objWord.Selection.Tables[1].Rows.AllowBreakAcrossPages = 0; + + objWord.Selection.Tables[1].BottomPadding = objWord.InchesToPoints(0.07F); + + objWord.Selection.Cells[1].Column.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Cells[1].Column.PreferredWidth = 4F; + + objWord.Selection.Cells[1].LeftPadding = 0; + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + objWord.Selection.Tables[1].Borders.InsideLineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + objWord.Selection.Cells[1].Column.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Cells[1].Column.PreferredWidth = 96F; + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + } + objWord.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight; + objWord.Selection.TypeText(taskNumber.ToString()); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft; + objWord.Selection.TypeText(recipeProcedure.procedureText); + + taskNumber += 1; + + } + } + + if (blnInTable) + { + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + blnInTable = false; + } + clsWord.AddHalfSpaceLineAtEndOfDocument(); + } + + } + + private void WordDocAddServingsYieldNutrition(Microsoft.Office.Interop.Word.Application objWord) + { + var servingsToUse = this.servings; + if (servingsToUse == 0) + { + servingsToUse = 1; + } + + bool blnNeedSpaceBeforeNutrition = false; + + if (this.servings > 0) + { + objWord.Selection.TypeText("Servings: " + this.servings.ToString()); + objWord.Selection.TypeParagraph(); + blnNeedSpaceBeforeNutrition = true; + } + + if (!String.IsNullOrWhiteSpace(this.yield)) + { + objWord.Selection.TypeText("Yield: " + this.yield); + objWord.Selection.TypeParagraph(); + blnNeedSpaceBeforeNutrition = true; + } + + if (blnNeedSpaceBeforeNutrition) + { + clsWord.AddHalfSpaceLineAtEndOfDocument(); + } + + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 1, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + objWord.Selection.Cells[1].LeftPadding = 0; + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Tables[1].Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Tables[1].Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineWidth = WdLineWidth.wdLineWidth050pt; + + + objWord.Selection.Font.Bold = 1; + objWord.Selection.Font.Size = clsWord.WORD_RECIPE_SECTION_HEADING_FONT_SIZE; + objWord.Selection.TypeText("Nutrition Facts"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + clsWord.AddHalfSpaceLineAtEndOfDocument(); + + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 2, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + + objWord.Selection.Tables[1].Rows.AllowBreakAcrossPages = 0; + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + objWord.Selection.Tables[1].Borders.InsideLineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Cells[1].Column.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Cells[1].Column.PreferredWidth = 67F; + + objWord.Selection.Cells[1].LeftPadding = 0; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + objWord.Selection.Cells[1].Column.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Cells[1].Column.PreferredWidth = 33F; + + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderLeft].LineStyle = WdLineStyle.wdLineStyleNone; + //objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderRight].LineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + if (servingsToUse == 1) + { + objWord.Selection.TypeText(String.Format("Serving size: Entire recipe. ({0}g)", this.mass.ToString("F2"))); + } + else + { + objWord.Selection.TypeText(String.Format("Serving size: 1/{0} of a recipe. ({1}g)", servingsToUse.ToString(), this.mass.ToString("F2"))); + } + objWord.Selection.TypeParagraph(); + objWord.Selection.TypeText("Percent daily values based on the Reference Daily Intake (RDI) for a 2000 calorie diet."); + objWord.Selection.TypeParagraph(); + objWord.Selection.TypeText("Nutrition information calculated from recipe ingredients."); + + int totalIngredients = 0; + int totalIngredientsLinked = 0; + int totalIngredientsNotLinked = 0; + + foreach (var recipeIngredient in this.recipeIngredients) + { + if (recipeIngredient is RecipeIngredientItem) + { + totalIngredients += 1; + + var recipeIngredientItem = (RecipeIngredientItem)recipeIngredient; + if (recipeIngredientItem.ingredientID != null) + { + totalIngredientsLinked += 1; + } + else + { + totalIngredientsNotLinked += 1; + } + } + } + + if (totalIngredients > 0 && totalIngredientsNotLinked > 0) + { + objWord.Selection.TypeParagraph(); + + if (totalIngredientsNotLinked == 1) + { + objWord.Selection.TypeText("There is an ingredient not linked for nutrition"); + } + else + { + objWord.Selection.TypeText(String.Format("There are {0} ingredient(s) not linked for nutrition", totalIngredientsNotLinked.ToString())); + } + } + + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 2, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + objWord.Selection.Tables[1].Borders.InsideLineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Tables[1].AllowPageBreaks = false; + + objWord.Selection.Cells[1].Column.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Cells[1].Column.PreferredWidth = 60F; + + objWord.Selection.Cells[1].LeftPadding = 0; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineWidth = WdLineWidth.wdLineWidth300pt; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineWidth = WdLineWidth.wdLineWidth050pt; + + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + objWord.Selection.Cells[1].Column.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Cells[1].Column.PreferredWidth = 40F; + + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineWidth = WdLineWidth.wdLineWidth300pt; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineWidth = WdLineWidth.wdLineWidth050pt; + + objWord.Selection.MoveLeft(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + + objWord.Selection.Font.Size = clsWord.WORD_NUTRITION_FONT_SIZE; + objWord.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft; + objWord.Selection.TypeText("Amount Per Serving"); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight; + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Size = clsWord.WORD_NUTRITION_FONT_SIZE; + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText("Calories"); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Size = clsWord.WORD_NUTRITION_FONT_SIZE; + objWord.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight; + objWord.Selection.TypeText(this.calories.ToString("F2")); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" Calories From Fat ({0}%)", this.percentcaloriesfromfat.ToString("F0"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}", this.caloriesfromfat.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineWidth = WdLineWidth.wdLineWidth150pt; + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineWidth = WdLineWidth.wdLineWidth150pt; + objWord.Selection.TypeText("% Daily Value"); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineWidth = WdLineWidth.wdLineWidth050pt; + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText("Total Fat"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" {0}g", this.totalfat.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.totalfat * 100) / Constants.DAILY_VALUE_FAT).ToString("F0"))); + + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderTop].LineWidth = WdLineWidth.wdLineWidth050pt; + + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" Saturated Fat {0}g", this.saturatedfat.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.saturatedfat * 100) / Constants.DAILY_VALUE_SATURATED_FAT).ToString("F0"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText("Cholesterol"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" {0}mg", this.cholesterol.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.cholesterol * 100) / Constants.DAILY_VALUE_CHOLESTEROL).ToString("F0"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText("Sodium"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" {0}mg" , this.sodium.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.sodium * 100) / Constants.DAILY_VALUE_SODIUM).ToString("F0"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText("Potassium"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" {0}mg", this.potassium.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.potassium * 100) / Constants.DAILY_VALUE_POTASSIUM).ToString("F0"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText("Total Carbohydrates"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" {0}g", this.totalcarbohydrate.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.totalcarbohydrate * 100) / Constants.DAILY_VALUE_TOTAL_CARBOHYDRATE).ToString("F0"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" Fiber {0}g", this.fiber.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.fiber * 100) / Constants.DAILY_VALUE_DIETARY_FIBER).ToString("F0"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("Sugar {0}g", this.sugar.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.Font.Bold = 1; + objWord.Selection.TypeText("Protein"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.TypeText(String.Format(" {0}g", this.protein.ToString("F2"))); + objWord.Selection.MoveRight(Microsoft.Office.Interop.Word.WdUnits.wdCell, 1); + objWord.Selection.TypeText(String.Format("{0}%", ((this.protein * 100) / Constants.DAILY_VALUE_PROTEIN).ToString("F0"))); + + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + clsWord.AddHalfSpaceLineAtEndOfDocument(); + } + private void WordDocAddAllTips(Microsoft.Office.Interop.Word.Application objWord) + { + if (this.recipeTips.Count > 0) + { + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 1, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + + objWord.Selection.Cells[1].LeftPadding = 0; + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineWidth = WdLineWidth.wdLineWidth050pt; + + objWord.Selection.Font.Bold = 1; + objWord.Selection.Font.Size = clsWord.WORD_RECIPE_SECTION_HEADING_FONT_SIZE; + objWord.Selection.TypeText("Tips"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + + foreach (var recipeTip in this.recipeTips) + { + if (recipeTip.isHeading) + { + objWord.Selection.Font.Bold = 1; + } + else + { + objWord.Selection.Font.Bold = 0; + } + objWord.Selection.TypeText(recipeTip.tipText); + objWord.Selection.TypeParagraph(); + objWord.Selection.Font.Bold = 0; + } + + clsWord.AddHalfSpaceLineAtEndOfDocument(); + } + } + + private void WordDocAddSourceInfo(Microsoft.Office.Interop.Word.Application objWord) + { + if (!String.IsNullOrWhiteSpace(this.source) || !String.IsNullOrWhiteSpace(this.webpage) || !String.IsNullOrWhiteSpace(this.copyright)) + { + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.ActiveDocument.Tables.Add(objWord.Selection.Range, 1, 1, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent); + + objWord.Selection.Tables[1].PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent; + objWord.Selection.Tables[1].PreferredWidth = 100F; + + objWord.Selection.Cells[1].LeftPadding = 0; + + objWord.Selection.Tables[1].Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone; + + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineStyle = WdLineStyle.wdLineStyleSingle; + objWord.Selection.Borders[Microsoft.Office.Interop.Word.WdBorderType.wdBorderBottom].LineWidth = WdLineWidth.wdLineWidth050pt; + + objWord.Selection.Font.Bold = 1; + objWord.Selection.Font.Size = clsWord.WORD_RECIPE_SECTION_HEADING_FONT_SIZE; + objWord.Selection.TypeText("Source"); + objWord.Selection.Font.Bold = 0; + objWord.Selection.Font.Size = clsWord.WORD_NORMAL_FONT_SIZE; + objWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + + clsWord.AddHalfSpaceLineAtEndOfDocument(); + + if (!String.IsNullOrWhiteSpace(this.source)) + { + objWord.Selection.TypeText("Source: " + this.source); + objWord.Selection.TypeParagraph(); + } + + if (!String.IsNullOrWhiteSpace(this.webpage)) + { + objWord.Selection.TypeText("Web Page: " + this.webpage); + objWord.Selection.TypeParagraph(); + } + if (!String.IsNullOrWhiteSpace(this.copyright)) + { + objWord.Selection.TypeText("Copyright: " + this.copyright); + objWord.Selection.TypeParagraph(); + } + + clsWord.AddHalfSpaceLineAtEndOfDocument(); + } + } + + public void JRJRTestNutritionRecalc(ref String originalNutrition, ref String recalcNutrition) + { + Recipe recipeClone = (Recipe)this.Clone(); + + recipeClone.CalcNutrition(); + originalNutrition = this.JRJRTestDumpForCompare(); + recalcNutrition = recipeClone.JRJRTestDumpForCompare(); + } + + public string JRJRTestDumpForCompare() + { + StringBuilder strbResult = new StringBuilder(); + + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "---------------------------------------------------------------" + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "recipename" + Constants.TAB +this.recipename.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "recipeID" + Constants.TAB +this.recipeID.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "cookbookID" + Constants.TAB +this.cookbookID.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "cookbookchapterID" + Constants.TAB + (this.cookbookchapterID ?? Guid.Empty).ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "author" + Constants.TAB +this.author.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "source" + Constants.TAB +this.source.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "webpage" + Constants.TAB +this.webpage.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "comments" + Constants.TAB +this.comments.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "copyright" + Constants.TAB +this.copyright.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "servings" + Constants.TAB +this.servings.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "nutritionservinglabel" + Constants.TAB +this.nutritionservinglabel.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "yield" + Constants.TAB +this.yield.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "preparationtime" + Constants.TAB +this.preparationtime.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "cookingtime" + Constants.TAB +this.cookingtime.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "readyintime" + Constants.TAB +this.readyintime.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "inactivetime" + Constants.TAB +this.inactivetime.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "oventemperaturec" + Constants.TAB +this.oventemperaturec.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "oventemperaturef" + Constants.TAB +this.oventemperaturef.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "percentcaloriesfromalcohol" + Constants.TAB +this.percentcaloriesfromalcohol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "percentcaloriesfromcarbs" + Constants.TAB +this.percentcaloriesfromcarbs.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "percentcaloriesfromfat" + Constants.TAB +this.percentcaloriesfromfat.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "percentcaloriesfromprotein" + Constants.TAB +this.percentcaloriesfromprotein.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "alanine" + Constants.TAB +this.alanine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "alcohol" + Constants.TAB +this.alcohol.ToString() + Constants.CRLF); + //strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "alcoholfactor" + Constants.TAB +this.alcoholfactor.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "alphacarotene" + Constants.TAB +this.alphacarotene.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "alphalinolenicacid" + Constants.TAB +this.alphalinolenicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "arachidonicacid" + Constants.TAB +this.arachidonicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "arginine" + Constants.TAB +this.arginine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "ash" + Constants.TAB +this.ash.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "asparticacid" + Constants.TAB +this.asparticacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "betacarotene" + Constants.TAB +this.betacarotene.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "betacryptoxanthin" + Constants.TAB +this.betacryptoxanthin.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "betasitosterol" + Constants.TAB +this.betasitosterol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "betatocopherol" + Constants.TAB +this.betatocopherol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "biotin" + Constants.TAB +this.biotin.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "caffeine" + Constants.TAB +this.caffeine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "calcium" + Constants.TAB +this.calcium.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "calories" + Constants.TAB +this.calories.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "caloriesfromalcohol" + Constants.TAB +this.caloriesfromalcohol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "caloriesfromcarbs" + Constants.TAB +this.caloriesfromcarbs.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "caloriesfromfat" + Constants.TAB +this.caloriesfromfat.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "caloriesfromprotein" + Constants.TAB +this.caloriesfromprotein.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "campesterol" + Constants.TAB +this.campesterol.ToString() + Constants.CRLF); + //strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "carbohydratefactor" + Constants.TAB +this.carbohydratefactor.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "chloride" + Constants.TAB +this.chloride.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "cholesterol" + Constants.TAB +this.cholesterol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "choline" + Constants.TAB +this.choline.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "chromium" + Constants.TAB +this.chromium.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "copper" + Constants.TAB +this.copper.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "cystine" + Constants.TAB +this.cystine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "deltatocopherol" + Constants.TAB +this.deltatocopherol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "dihomogammalinolenicacid" + Constants.TAB +this.dihomogammalinolenicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "docosahexaenoicacid" + Constants.TAB +this.docosahexaenoicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "docosapentaenoicacid" + Constants.TAB +this.docosapentaenoicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "eicosadienoicacid" + Constants.TAB +this.eicosadienoicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "eicosapentaenoicacid" + Constants.TAB +this.eicosapentaenoicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "energy" + Constants.TAB +this.energy.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "energyfromalcohol" + Constants.TAB +this.energyfromalcohol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "energyfromcarbs" + Constants.TAB +this.energyfromcarbs.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "energyfromfat" + Constants.TAB +this.energyfromfat.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "energyfromprotein" + Constants.TAB +this.energyfromprotein.ToString() + Constants.CRLF); + //strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "fatfactor" + Constants.TAB +this.fatfactor.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "fiber" + Constants.TAB +this.fiber.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "fluoride" + Constants.TAB +this.fluoride.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "folate" + Constants.TAB +this.folate.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "fructose" + Constants.TAB +this.fructose.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "galactose" + Constants.TAB +this.galactose.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "gammalinolenicacid" + Constants.TAB +this.gammalinolenicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "gammatocopherol" + Constants.TAB +this.gammatocopherol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "glucose" + Constants.TAB +this.glucose.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "glutamicacid" + Constants.TAB +this.glutamicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "glycine" + Constants.TAB +this.glycine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "histidine" + Constants.TAB +this.histidine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "hydroxyproline" + Constants.TAB +this.hydroxyproline.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "iodine" + Constants.TAB +this.iodine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "iron" + Constants.TAB +this.iron.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "isoleucine" + Constants.TAB +this.isoleucine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "lactose" + Constants.TAB +this.lactose.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "leucine" + Constants.TAB +this.leucine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "linoleicacid" + Constants.TAB +this.linoleicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "lycopene" + Constants.TAB +this.lycopene.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "lysine" + Constants.TAB +this.lysine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "magnesium" + Constants.TAB +this.magnesium.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "maltose" + Constants.TAB +this.maltose.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "manganese" + Constants.TAB +this.manganese.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "mass" + Constants.TAB +this.mass.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "methionine" + Constants.TAB +this.methionine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "molybdenum" + Constants.TAB +this.molybdenum.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfat" + Constants.TAB +this.monounsaturatedfat.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_14_1" + Constants.TAB +this.monounsaturatedfattyacid_14_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_15_1" + Constants.TAB +this.monounsaturatedfattyacid_15_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_16_1" + Constants.TAB +this.monounsaturatedfattyacid_16_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_17_1" + Constants.TAB +this.monounsaturatedfattyacid_17_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_18_1" + Constants.TAB +this.monounsaturatedfattyacid_18_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_20_1" + Constants.TAB +this.monounsaturatedfattyacid_20_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_22_1" + Constants.TAB +this.monounsaturatedfattyacid_22_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "monounsaturatedfattyacid_24_1" + Constants.TAB +this.monounsaturatedfattyacid_24_1.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "netcarbohydrates" + Constants.TAB +this.netcarbohydrates.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "niacin" + Constants.TAB +this.niacin.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "omega3fattyacids" + Constants.TAB +this.omega3fattyacids.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "omega6fattyacids" + Constants.TAB +this.omega6fattyacids.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "pantothenicacid" + Constants.TAB +this.pantothenicacid.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "phenylalanine" + Constants.TAB +this.phenylalanine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "phosphorus" + Constants.TAB +this.phosphorus.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "phytosterols" + Constants.TAB +this.phytosterols.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfat" + Constants.TAB +this.polyunsaturatedfat.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfattyacid_18_2" + Constants.TAB +this.polyunsaturatedfattyacid_18_2.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfattyacid_18_3" + Constants.TAB +this.polyunsaturatedfattyacid_18_3.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfattyacid_18_4" + Constants.TAB +this.polyunsaturatedfattyacid_18_4.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfattyacid_20_3" + Constants.TAB +this.polyunsaturatedfattyacid_20_3.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfattyacid_20_4" + Constants.TAB +this.polyunsaturatedfattyacid_20_4.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfattyacid_21_5" + Constants.TAB +this.polyunsaturatedfattyacid_21_5.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "polyunsaturatedfattyacid_22_4" + Constants.TAB +this.polyunsaturatedfattyacid_22_4.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "potassium" + Constants.TAB +this.potassium.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "proline" + Constants.TAB +this.proline.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "protein" + Constants.TAB +this.protein.ToString() + Constants.CRLF); + //strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "proteinfactor" + Constants.TAB +this.proteinfactor.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "refuse" + Constants.TAB +this.refuse.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "retinol" + Constants.TAB +this.retinol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "riboflavin" + Constants.TAB +this.riboflavin.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfat" + Constants.TAB +this.saturatedfat.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_10_0" + Constants.TAB +this.saturatedfattyacid_10_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_12_0" + Constants.TAB +this.saturatedfattyacid_12_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_13_0" + Constants.TAB +this.saturatedfattyacid_13_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_14_0" + Constants.TAB +this.saturatedfattyacid_14_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_15_0" + Constants.TAB +this.saturatedfattyacid_15_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_16_0" + Constants.TAB +this.saturatedfattyacid_16_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_17_0" + Constants.TAB +this.saturatedfattyacid_17_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_18_0" + Constants.TAB +this.saturatedfattyacid_18_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_20_0" + Constants.TAB +this.saturatedfattyacid_20_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_22_0" + Constants.TAB +this.saturatedfattyacid_22_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_24_0" + Constants.TAB +this.saturatedfattyacid_24_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_4_0" + Constants.TAB +this.saturatedfattyacid_4_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_6_0" + Constants.TAB +this.saturatedfattyacid_6_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "saturatedfattyacid_8_0" + Constants.TAB +this.saturatedfattyacid_8_0.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "selenium" + Constants.TAB +this.selenium.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "serine" + Constants.TAB +this.serine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "sodium" + Constants.TAB +this.sodium.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "starch" + Constants.TAB +this.starch.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "stigmasterol" + Constants.TAB +this.stigmasterol.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "sucrose" + Constants.TAB +this.sucrose.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "sugar" + Constants.TAB +this.sugar.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "sugaralcohols" + Constants.TAB +this.sugaralcohols.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "theobromine" + Constants.TAB +this.theobromine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "thiamin" + Constants.TAB +this.thiamin.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "threonine" + Constants.TAB +this.threonine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "totalcarbohydrate" + Constants.TAB +this.totalcarbohydrate.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "totalfat" + Constants.TAB +this.totalfat.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "transfattyacids" + Constants.TAB +this.transfattyacids.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "transmonoenoicfattyacids" + Constants.TAB +this.transmonoenoicfattyacids.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "transpolyenoicfattyacids" + Constants.TAB +this.transpolyenoicfattyacids.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "tryptophan" + Constants.TAB +this.tryptophan.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "tyrosine" + Constants.TAB +this.tyrosine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "valine" + Constants.TAB +this.valine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "vitamina" + Constants.TAB +this.vitamina.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "vitaminb12" + Constants.TAB +this.vitaminb12.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "vitaminb6" + Constants.TAB +this.vitaminb6.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "vitaminc" + Constants.TAB +this.vitaminc.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "vitamind" + Constants.TAB +this.vitamind.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "vitamine" + Constants.TAB +this.vitamine.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "vitamink" + Constants.TAB +this.vitamink.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "volume" + Constants.TAB +this.volume.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "water" + Constants.TAB +this.water.ToString() + Constants.CRLF); + strbResult.Append(this.cookbookID.ToString() + Constants.TAB + this.recipename + Constants.TAB + "zinc" + Constants.TAB +this.zinc.ToString() + Constants.CRLF); + + return strbResult.ToString(); + } + + public object Clone() + { + var copy = (Recipe)(this.MemberwiseClone()); + + var originalIngredient = copy.recipeIngredients; + + copy.recipeIngredients = new List(); + foreach (var ingredient in originalIngredient) + { + var newIngredient = (RecipeIngredient)(ingredient.Clone()); + copy.recipeIngredients.Add(newIngredient); + } + + var originalProcedures = copy.recipeProcedures; + + copy.recipeProcedures = new List(); + foreach (var procedure in originalProcedures) + { + var newProcedure = (RecipeProcedure)(procedure.Clone()); + copy.recipeProcedures.Add(newProcedure); + } + + var originalTips = copy.recipeTips; + + copy.recipeTips = new List(); + foreach(var tip in originalTips) + { + var newTip = (RecipeTip)(tip.Clone()); + copy.recipeTips.Add(newTip); + } + + return copy; + } + } +} diff --git a/JRCookbookBusiness/RecipeHighlights.cs b/JRCookbookBusiness/RecipeHighlights.cs new file mode 100644 index 0000000..e97ab4d --- /dev/null +++ b/JRCookbookBusiness/RecipeHighlights.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class RecipeHighlights + { + public Guid? recipeID = null; + public Guid? cookbookID = null; + public Guid? cookbookchapterID = null; + + public String recipename = String.Empty; + + public RecipeHighlights() + { + } + + public RecipeHighlights(Guid recipeID) + { + PopulateByID(recipeID); + } + + + + public void Delete() + { + Recipe.DeleteByID(recipeID.Value); + } + + public static RecipeHighlights GetRecipeByID(Guid recipeID) + { + return new RecipeHighlights(recipeID); + } + + public static List GetAllRecipes() + { + DataSet recordSet; + var returnValue = new List(); + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetAllRecipes(); + + if (recordSet.Tables[0].Rows.Count > 0) + { + foreach(DataRow ldbrwRow in recordSet.Tables[0].Rows) + { + var newRecipe = new RecipeHighlights(); + newRecipe.PopulateFromDataRow(ldbrwRow); + returnValue.Add(newRecipe); + } + } + return returnValue; + } + + public static RecipeHighlights GetRecipeHighlightsByDataRow(DataRow row) + { + var newRecipe = new RecipeHighlights(); + newRecipe.PopulateFromDataRow(row); + return newRecipe; + } + + private void PopulateByID(Guid recipeID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeByID(recipeID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("recipeID")) + recipeID = null; + else + recipeID = (Guid)dataRow["recipeID"]; + + if (dataRow.IsNull("cookbookID")) + cookbookID = null; + else + cookbookID = (Guid)dataRow["cookbookID"]; + + if (dataRow.IsNull("cookbookchapterID")) + cookbookchapterID = null; + else + cookbookchapterID = (Guid)dataRow["cookbookchapterID"]; + + if (dataRow.IsNull("recipename")) + recipename = String.Empty; + else + recipename = (String)dataRow["recipename"]; + + + } + + private void InitializeAllFields() + { + recipeID = null; + cookbookID = null; + cookbookchapterID = null; + recipename = String.Empty; + } + + } +} diff --git a/JRCookbookBusiness/RecipeIngredient.cs b/JRCookbookBusiness/RecipeIngredient.cs new file mode 100644 index 0000000..8c3c851 --- /dev/null +++ b/JRCookbookBusiness/RecipeIngredient.cs @@ -0,0 +1,295 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Net.Security; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public enum RecipeIngredientLinkType + { + Unlinked, + Ingredient, + NoLink + } + + public class RecipeIngredient: ICloneable + { + public Guid? recipeIngredientID = null; + public Guid? recipeID = null; + public Int32 ingredientIndex = 0; + public String ingredientText = String.Empty; + private bool _isHeading = false; + public RecipeIngredientLinkType linkType = RecipeIngredientLinkType.Unlinked; + + private static SortedList ingredientSkipWords = null; + + public bool isHeading + { + get + { + return (this is RecipeIngredientHeading); + } + } + + internal string linkTypeAsString + { + get + { + return Enum.GetName(typeof(RecipeIngredientLinkType), linkType); + } + } + + public RecipeIngredientHeading ConvertToHeading() + { + if (isHeading) + { + return (RecipeIngredientHeading)this; + } + else + { + RecipeIngredientHeading temp = new RecipeIngredientHeading(); + temp.recipeIngredientID = this.recipeIngredientID; + temp.recipeID = this.recipeID; + temp.ingredientIndex = this.ingredientIndex; + temp.ingredientText = this.ingredientText; + temp.linkType = RecipeIngredientLinkType.NoLink; + + return temp; + } + } + public RecipeIngredientItem ConvertToItem() + { + if (!isHeading) + { + return (RecipeIngredientItem)this; + } + else + { + RecipeIngredientItem temp = new RecipeIngredientItem(); + temp.recipeIngredientID = this.recipeIngredientID; + temp.recipeID = this.recipeID; + temp.ingredientIndex = this.ingredientIndex; + temp.ingredientText = this.ingredientText; + temp.linkType = RecipeIngredientLinkType.Unlinked; + temp.linkQuality = 0; + + return temp; + } + } + + //protected RecipeIngredient() + //{ + //} + + public void PasteIntoChapter(Guid newRecipeID) + { + this.recipeIngredientID = null; + this.recipeID = newRecipeID; + } + + public void Save() + { + if (this.recipeIngredientID == null) + { + this.recipeIngredientID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDRecipeIngredient(); + clsDatabaseLayer.GetDatabaseLayer().InsertRecipeIngredient(this); + } + else + { + clsDatabaseLayer.GetDatabaseLayer().UpdateRecipeIngredient(this); + } + } + + public void Delete() + { + clsDatabaseLayer.GetDatabaseLayer().DeleteRecipeIngredientByID(recipeIngredientID.Value); + } + + public static void DeleteAllByRecipeID(Guid recipeID) + { + clsDatabaseLayer.GetDatabaseLayer().DeleteRecipeIngredientsByRecipeID(recipeID); + } + + public static RecipeIngredient GetRecipeIngredientByID(Guid recipeIngredientID) + { + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeIngredientByID(recipeIngredientID); + + var row = recordSet.Tables[0].Rows[0]; + return GetRecipeIngredientByDataRow(row); + } + + internal static RecipeIngredient GetRecipeIngredientByDataRow(DataRow recipeIngredientDataRow) + { + if (recipeIngredientDataRow["Heading"].ToString() == "Y") + { + var recipeIngredientHeading = new RecipeIngredientHeading(); + recipeIngredientHeading.PopulateFromDataRow(recipeIngredientDataRow); + return recipeIngredientHeading; + } + else + { + var recipeIngredientItem = new RecipeIngredientItem(); + recipeIngredientItem.PopulateFromDataRow(recipeIngredientDataRow); + return recipeIngredientItem; + } + } + + internal virtual void PopulateFromDataRow(DataRow dataRow) + { + //initializing in child objects + + if (dataRow.IsNull("recipeIngredientID")) + recipeIngredientID = null; + else + recipeIngredientID = (Guid)dataRow["recipeIngredientID"]; + + if (dataRow.IsNull("recipeID")) + recipeID = null; + else + recipeID = (Guid)dataRow["recipeID"]; + + if (dataRow.IsNull("ingredientindex")) + ingredientIndex = 0; + else + ingredientIndex = (Int32)dataRow["ingredientindex"]; + + if (dataRow.IsNull("ingredientText")) + ingredientText = String.Empty; + else + ingredientText = (String)dataRow["ingredientText"]; + + if (dataRow.IsNull("Heading")) + _isHeading = false; + else + _isHeading = (((String)dataRow["Heading"]).ToUpper() == "Y"); + + + if (dataRow.IsNull("linkType")) + linkType = RecipeIngredientLinkType.Unlinked; + else + linkType = (RecipeIngredientLinkType)Enum.Parse(typeof(RecipeIngredientLinkType),(String)dataRow["linkType"]); + + //Convert back to string + //String t = Enum.GetName(typeof(Roles), roleValue); + + + } + + protected virtual void InitializeAllFields() + { + recipeIngredientID = null; + recipeID = null; + ingredientIndex = 0; + ingredientText = String.Empty; + _isHeading = false; + linkType = RecipeIngredientLinkType.Unlinked; + + + } + + public static String NormalizeRecipeIngredientName(String strInputRecipeIngredientName) + { + LoadSkipWords(); + + strInputRecipeIngredientName = clsDiacriticRemover.RemoveDiacritics(strInputRecipeIngredientName).ToLower(); + + StringBuilder thisWord = new StringBuilder(); + + SortedList allWords = new SortedList(); + + foreach (var thisChar in strInputRecipeIngredientName) + { + if (thisChar >= 'a' && thisChar <= 'z') + { + thisWord.Append(thisChar); + } + else + { + if (thisWord.Length > 0) + { + String fullWord = thisWord.ToString(); + + if (!allWords.ContainsKey(fullWord)) + { + allWords.Add(fullWord,fullWord); + + } + + thisWord.Clear(); + } + } + } + + if (thisWord.Length > 0) + { + String fullWord = thisWord.ToString(); + + if (!allWords.ContainsKey(fullWord)) + { + allWords.Add(fullWord, fullWord); + + } + + thisWord.Clear(); + } + + StringBuilder normalizedName = new StringBuilder(); + + foreach (var wordToAdd in allWords.Values) + { + if (!ingredientSkipWords.ContainsKey(wordToAdd)) + { + normalizedName.Append(wordToAdd); + normalizedName.Append(' '); + } + } + + return normalizedName.ToString().Trim(); + } + + private static void LoadSkipWords() + { + if (ingredientSkipWords == null) + { + var ingredientSkipWordsUnsorted = IngredientSkipSearchWord.GetAllIngredientSkipSearchWords(); + ingredientSkipWords = new SortedList(); + foreach (var loadVal in ingredientSkipWordsUnsorted) + { + ingredientSkipWords.Add(loadVal.word, loadVal); + } + } + } + + + public static List GetRecipeIngredientAll() + { + List allIngredients = new List(); + DataSet recordSet; + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeIngredientAll(); + + foreach (DataRow row in recordSet.Tables[0].Rows) + { + var recipeIngredient = GetRecipeIngredientByDataRow(row); + if (recipeIngredient.isHeading == false) + { + if (((RecipeIngredientItem)recipeIngredient).ingredientID != null) + { + allIngredients.Add(recipeIngredient); + } + } + } + + return allIngredients; + } + + + public object Clone() + { + return this.MemberwiseClone(); + } + } +} diff --git a/JRCookbookBusiness/RecipeIngredientHeading.cs b/JRCookbookBusiness/RecipeIngredientHeading.cs new file mode 100644 index 0000000..f50ce75 --- /dev/null +++ b/JRCookbookBusiness/RecipeIngredientHeading.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class RecipeIngredientHeading : RecipeIngredient + { + + public RecipeIngredientHeading() + { + } + + internal override void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + base.PopulateFromDataRow(dataRow); + + } + + protected override void InitializeAllFields() + { + base.InitializeAllFields(); + } + } +} diff --git a/JRCookbookBusiness/RecipeIngredientItem.cs b/JRCookbookBusiness/RecipeIngredientItem.cs new file mode 100644 index 0000000..43c92d7 --- /dev/null +++ b/JRCookbookBusiness/RecipeIngredientItem.cs @@ -0,0 +1,163 @@ +using System; +using System.Data; + +namespace JRCookbookBusiness +{ + public class RecipeIngredientItem: RecipeIngredient + { + public Guid? ingredientID = null; + public String quantityText = String.Empty; + public String unitText = String.Empty; + + public String measureName = String.Empty; + private Guid? _measureID = null; + private bool isMeasureLoaded = false; + private Measure _measure = null; + + public Single measureQuantity = 0; + public Int16 linkQuality = 1; + + public RecipeIngredientItem() + { + linkQuality = 0; + } + + public RecipeIngredientItem(Recipe parentRecipe) + { + recipeID = parentRecipe.recipeID; + linkQuality = 0; + } + + public Measure measure { + get { + if (_measureID == null) + { + return null; + } + if (!isMeasureLoaded) + { + Measure.GetMeasureByID(_measureID.Value); + isMeasureLoaded = true; + } + return _measure; + } + set + { + if (value == null) + { + measureName = String.Empty; + _measureID = null; + isMeasureLoaded = false; + _measure = null; + } + else + { + _measure = value; + measureName = _measure.description; + _measureID = _measure.measureID; + isMeasureLoaded = true; + } + } + } + + public Guid? measureID + { + get + { + return _measureID; + } + set + { + if (value == null) + { + measureName = String.Empty; + _measureID = null; + isMeasureLoaded = false; + _measure = null; + } + _measureID = value; + _measure = Measure.GetMeasureByID(_measureID.Value); + isMeasureLoaded = true; + measureName = _measure.description; + } + } + + + + + internal override void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + base.PopulateFromDataRow(dataRow); + + if (dataRow.IsNull("ingredientID")) + ingredientID = null; + else + ingredientID = (Guid)dataRow["ingredientID"]; + + if (dataRow.IsNull("quantityText")) + quantityText = String.Empty; + else + quantityText = (String)dataRow["quantityText"]; + + if (dataRow.IsNull("unitText")) + unitText = String.Empty; + else + unitText = (String)dataRow["unitText"]; + + if (dataRow.IsNull("measureQuantity")) + measureQuantity = 0; + else + measureQuantity = (Single)dataRow["measureQuantity"]; + + if (dataRow.IsNull("linkQuality")) + linkQuality = 0; + else + linkQuality = (Int16)dataRow["linkQuality"]; + + + + if (dataRow.IsNull("measureID")) + _measureID = null; + else + _measureID = (Guid)dataRow["measureID"]; + + measureName = String.Empty; + isMeasureLoaded = false; + _measure = null; + + if (dataRow.Table.Columns.Contains("measureName") && !dataRow.IsNull("measureName") && !String.IsNullOrEmpty(dataRow[measureName].ToString())) + { + measureName = (String)dataRow[measureName]; + } + else + { + if (_measureID != null) + { + measure = Measure.GetMeasureByID(_measureID.Value); + isMeasureLoaded = true; + measureName = measure.description; + } + } + } + + protected override void InitializeAllFields() + { + base.InitializeAllFields(); + + ingredientID = null; + quantityText = String.Empty; + unitText = String.Empty; + + measureName = String.Empty; + _measureID = null; + isMeasureLoaded = false; + _measure = null; + + measureQuantity = 0; + linkQuality = 0; + } + + } +} diff --git a/JRCookbookBusiness/RecipeProcedure.cs b/JRCookbookBusiness/RecipeProcedure.cs new file mode 100644 index 0000000..fe93df8 --- /dev/null +++ b/JRCookbookBusiness/RecipeProcedure.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class RecipeProcedure: ICloneable + { + public Guid? recipeProcedureID = null; + public Guid? recipeID = null; + public String procedureText = String.Empty; + public Int32 procedureIndex = 0; + public bool isHeading = false; + + public RecipeProcedure() + { + } + + public RecipeProcedure(Recipe parentRecipe) + { + recipeID = parentRecipe.recipeID; + } + + public RecipeProcedure(Guid recipeProcedureID) + { + PopulateByID(recipeProcedureID); + } + + + public void PasteIntoChapter(Guid newRecipeID) + { + this.recipeProcedureID = null; + this.recipeID = newRecipeID; + } + + public void Save() + { + if (this.recipeProcedureID == null) + { + this.recipeProcedureID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDRecipeProcedure(); + clsDatabaseLayer.GetDatabaseLayer().InsertRecipeProcedure(this); + } + else + { + clsDatabaseLayer.GetDatabaseLayer().UpdateRecipeProcedure(this); + } + } + + public void Delete() + { + clsDatabaseLayer.GetDatabaseLayer().DeleteRecipeProcedureByID(recipeProcedureID.Value); + } + + public static void DeleteAllByRecipeID(Guid recipeID) + { + clsDatabaseLayer.GetDatabaseLayer().DeleteRecipeProceduresByRecipeID(recipeID); + } + + public static RecipeProcedure GetRecipeProcedureByID(Guid recipeProcedureID) + { + return new RecipeProcedure(recipeProcedureID); + } + + public static RecipeProcedure GetRecipeProcedureByDataRow(DataRow row) + { + var newProcedure = new RecipeProcedure(); + newProcedure.PopulateFromDataRow(row); + return newProcedure; + } + + private void PopulateByID(Guid recipeProcedureID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeProcedureByID(recipeProcedureID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("recipeProcedureID")) + recipeProcedureID = null; + else + recipeProcedureID = (Guid)dataRow["recipeProcedureID"]; + + if (dataRow.IsNull("recipeID")) + recipeID = null; + else + recipeID = (Guid)dataRow["recipeID"]; + + if (dataRow.IsNull("procedureText")) + procedureText = String.Empty; + else + procedureText = (String)dataRow["procedureText"]; + + if (dataRow.IsNull("procedureIndex")) + procedureIndex = 0; + else + procedureIndex = (Int32)dataRow["procedureIndex"]; + + if (dataRow.IsNull("Heading")) + isHeading = false; + else + isHeading = (((String)dataRow["Heading"]).ToUpper() == "Y"); + } + + private void InitializeAllFields() + { + recipeProcedureID = null; + recipeID = null; + procedureText = String.Empty; + procedureIndex = 0; + isHeading = false; + } + + public object Clone() + { + return this.MemberwiseClone(); + } + + } +} diff --git a/JRCookbookBusiness/RecipeTip.cs b/JRCookbookBusiness/RecipeTip.cs new file mode 100644 index 0000000..efda281 --- /dev/null +++ b/JRCookbookBusiness/RecipeTip.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class RecipeTip: ICloneable + { + public Guid? recipeTipID = null; + public Guid? recipeID = null; + public String tipText = String.Empty; + public Int32 tipIndex = 0; + public bool isHeading = false; + + public RecipeTip() + { + } + + public RecipeTip(Recipe parentRecipe) + { + recipeID = parentRecipe.recipeID; + } + + public RecipeTip(Guid recipeTipID) + { + PopulateByID(recipeTipID); + } + + + public void PasteIntoChapter(Guid newRecipeID) + { + this.recipeTipID = null; + this.recipeID = newRecipeID; + } + + + public void Save() + { + if (this.recipeTipID == null) + { + this.recipeTipID = clsDatabaseLayer.GetDatabaseLayer().GetNewIDRecipeTip(); + clsDatabaseLayer.GetDatabaseLayer().InsertRecipeTip(this); + } + else + { + clsDatabaseLayer.GetDatabaseLayer().UpdateRecipeTip(this); + } + } + + public void Delete() + { + clsDatabaseLayer.GetDatabaseLayer().DeleteRecipeTipByID(recipeTipID.Value); + } + + public static void DeleteAllByRecipeID(Guid recipeID) + { + clsDatabaseLayer.GetDatabaseLayer().DeleteRecipeTipsByRecipeID(recipeID); + } + + public static RecipeTip GetRecipeTipByID(Guid recipeTipID) + { + return new RecipeTip(recipeTipID); + } + + public static RecipeTip GetRecipeTipByDataRow(DataRow row) + { + var newTip = new RecipeTip(); + newTip.PopulateFromDataRow(row); + return newTip; + } + + private void PopulateByID(Guid recipeTipID) + { + DataSet recordSet; + + recordSet = clsDatabaseLayer.GetDatabaseLayer().GetRecipeTipByID(recipeTipID); + + if (recordSet.Tables[0].Rows.Count > 0) + { + DataRow ldbrwRow; + ldbrwRow = recordSet.Tables[0].Rows[0]; + + PopulateFromDataRow(ldbrwRow); + } + + } + + private void PopulateFromDataRow(DataRow dataRow) + { + InitializeAllFields(); + + if (dataRow.IsNull("recipeTipID")) + recipeTipID = null; + else + recipeTipID = (Guid)dataRow["recipeTipID"]; + + if (dataRow.IsNull("recipeID")) + recipeID = null; + else + recipeID = (Guid) dataRow["recipeID"]; + + if (dataRow.IsNull("tipText")) + tipText = String.Empty; + else + tipText = (String)dataRow["tipText"]; + + if (dataRow.IsNull("tipIndex")) + tipIndex = 0; + else + tipIndex = (Int32) dataRow["tipIndex"]; + + if (dataRow.IsNull("Heading")) + isHeading = false; + else + isHeading = (((String)dataRow["Heading"]).ToUpper() == "Y"); + } + + private void InitializeAllFields() + { + recipeTipID = null; + recipeID = null; + tipText = String.Empty; + tipIndex = 0; + isHeading = false; + } + + public object Clone() + { + return this.MemberwiseClone(); + } + + + } +} diff --git a/JRCookbookBusiness/SharedRoutines.cs b/JRCookbookBusiness/SharedRoutines.cs new file mode 100644 index 0000000..ec0680d --- /dev/null +++ b/JRCookbookBusiness/SharedRoutines.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + internal static class SharedRoutines + { + public static string RemoveSpecialCharactersFromFileName(string str) + { + return Regex.Replace(str, "[^a-zA-Z0-9_. ]+", String.Empty, RegexOptions.Compiled); + } + + + internal static string GenerateTrackbackLinks(List trackbackList) + { + bool firstTrackback = true; + + StringBuilder trackbacksHTML = new StringBuilder(); + foreach(Trackback trackback in trackbackList) + { + if (firstTrackback) + { + firstTrackback = false; + } + else + { + trackbacksHTML.Append(" > "); + } + + trackbacksHTML.Append(trackback.GenerateLink()); + } + + return trackbacksHTML.ToString(); + } + } + +} diff --git a/JRCookbookBusiness/Trackback.cs b/JRCookbookBusiness/Trackback.cs new file mode 100644 index 0000000..3c5fb1c --- /dev/null +++ b/JRCookbookBusiness/Trackback.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Html; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public class Trackback + { + public String TrackbackText = String.Empty; + public String TrackbackURL = String.Empty; + + public String GenerateLink() + { + var builder = new HtmlContentBuilder(); + builder.AppendFormat("", TrackbackURL); + builder.AppendFormat("{0}", TrackbackText); + builder.AppendHtml(""); + + using (var writer = new System.IO.StringWriter()) + { + builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default); + return writer.ToString(); + } + } + + } +} diff --git a/JRCookbookBusiness/Utility.cs b/JRCookbookBusiness/Utility.cs new file mode 100644 index 0000000..9b48448 --- /dev/null +++ b/JRCookbookBusiness/Utility.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using HtmlToXamlDemo; +using Microsoft.VisualBasic; + +namespace JRCookbookBusiness +{ + public static class Utility + { + public static string ConvertHTLMLToRTF(string strInputHTML) + { + try + { + string objXAML = HtmlToXamlConverter.ConvertHtmlToXaml(strInputHTML, false); + + TextWriter asdf; + + if (File.Exists("C:\\ReussData\\DeleteMe.html")) + { + File.Delete("C:\\ReussData\\DeleteMe.html"); + } + asdf = new StreamWriter("C:\\ReussData\\DeleteMe.html"); + asdf.Write(strInputHTML); + asdf.Close(); + asdf.Dispose(); + asdf = null; + + if (File.Exists("C:\\ReussData\\DeleteMe.xaml")) + { + File.Delete("C:\\ReussData\\DeleteMe.xaml"); + } + asdf = new StreamWriter("C:\\ReussData\\DeleteMe.xaml"); + asdf.Write(objXAML); + asdf.Close() ; + asdf.Dispose(); + asdf = null; + + if (File.Exists("C:\\ReussData\\DeleteMe.rtf")) + { + File.Delete("C:\\ReussData\\DeleteMe.rtf"); + } + asdf = new StreamWriter("C:\\ReussData\\DeleteMe.rtf"); + asdf.Write(ConvertXamlToRtf(objXAML)); + asdf.Close(); + asdf.Dispose(); + asdf = null; + + return ConvertXamlToRtf(objXAML); + } + catch(Exception ex) + { + throw; + } + + + } + private static string ConvertXamlToRtf(string xamlText) + { + var richTextBox = new RichTextBox(); + MessageBox.Show("Before:" + ControlChars.CrLf + "width = " + richTextBox.Width.ToString() + ControlChars.CrLf + + "ActualWidth = " + richTextBox.ActualWidth.ToString() + ControlChars.CrLf + + "ExtentWidth = " + richTextBox.ExtentWidth.ToString() + ControlChars.CrLf + + "MaxWidth = " + richTextBox.MaxWidth.ToString() + ControlChars.CrLf + + "ViewportWidth = " + richTextBox.ViewportWidth.ToString()); + + richTextBox.Width = 10000; + + MessageBox.Show("Width:" + ControlChars.CrLf + "width = " + richTextBox.Width.ToString() + ControlChars.CrLf + + "ActualWidth = " + richTextBox.ActualWidth.ToString() + ControlChars.CrLf + + "ExtentWidth = " + richTextBox.ExtentWidth.ToString() + ControlChars.CrLf + + "MaxWidth = " + richTextBox.MaxWidth.ToString() + ControlChars.CrLf + + "ViewportWidth = " + richTextBox.ViewportWidth.ToString()); + + if (string.IsNullOrEmpty(xamlText)) return ""; + var textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); + using (var xamlMemoryStream = new MemoryStream()) + { + using (var xamlStreamWriter = new StreamWriter(xamlMemoryStream)) + { + xamlStreamWriter.Write(xamlText); + xamlStreamWriter.Flush(); + xamlMemoryStream.Seek(0, SeekOrigin.Begin); + textRange.Load(xamlMemoryStream, DataFormats.Xaml); + } + } + using (var rtfMemoryStream = new MemoryStream()) + { + textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); + textRange.Save(rtfMemoryStream, DataFormats.Rtf); + rtfMemoryStream.Seek(0, SeekOrigin.Begin); + using (var rtfStreamReader = new StreamReader(rtfMemoryStream)) + { + return rtfStreamReader.ReadToEnd(); + } + } + } + } + + +} diff --git a/JRCookbookBusiness/clsDatabaseLayer.cs b/JRCookbookBusiness/clsDatabaseLayer.cs new file mode 100644 index 0000000..7449e46 --- /dev/null +++ b/JRCookbookBusiness/clsDatabaseLayer.cs @@ -0,0 +1,1196 @@ +using System; +using System.Diagnostics; +using System.Data; +using System.Data.OleDb; +using JRCookbookBusiness; + +public class clsDatabaseLayer : clsDatabaseLayerBase +{ + static clsDatabaseLayer _DatabaseLayer = null; + + internal static clsDatabaseLayer GetDatabaseLayer() + { + if (_DatabaseLayer == null) + { + _DatabaseLayer = new clsDatabaseLayer(); + } + return _DatabaseLayer; + } + + public static void CloseSharedDatabaseConnection() + { + if (_DatabaseLayer != null) + { + _DatabaseLayer.CloseDatabaseConnection(); + _DatabaseLayer.Dispose(true); + _DatabaseLayer = null; + } + } + + public DataSet GetIngredientByID(Guid ingredientID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredient where ingredientid=@ingredientid")) + { + dbCommand.Parameters.AddWithValue("@ingredientid", ingredientID); + + return this.ExecuteDataSet(dbCommand); + } + + } + + public DataSet GetIngredientsBySearchString(String searchString) + { + using (OleDbCommand dbCommand = new OleDbCommand("SELECT * FROM ingredient where name like (@searchString) order by name")) + { + dbCommand.Parameters.AddWithValue("@searchString", "%" + searchString + "%"); + + return this.ExecuteDataSet(dbCommand); + } + + } + + public DataSet GetAllIngredients() + { + using (OleDbCommand dbCommand = new OleDbCommand("SELECT * FROM ingredient order by name")) + { + return this.ExecuteDataSet(dbCommand); + } + + } + + + public DataSet GetIngredientMeasureByID(Guid ingredientID, Guid measureID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredientmeasure where ingredientid=@ingredientid and measureid=@measureid")) + { + dbCommand.Parameters.AddWithValue("@ingredientid", ingredientID); + dbCommand.Parameters.AddWithValue("@measureid", measureID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetIngredientMeasureByIngredientID(Guid ingredientID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredientmeasure where ingredientid=@ingredientid")) + { + dbCommand.Parameters.AddWithValue("@ingredientid", ingredientID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetMeasureByID(Guid measureID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from measure where measureid=@measureid")) + { + dbCommand.Parameters.AddWithValue("@measureid", measureID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetMeasuresByIngredientID(Guid ingredientID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select measure.* from measure inner join ingredientmeasure ON measure.measureid=ingredientmeasure.measureid" + + " where ingredientmeasure.ingredientid=@ingredientid order by measure.description")) + { + dbCommand.Parameters.AddWithValue("@ingredientid", ingredientID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetAllCookbooks() + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from cookbook order by name")) + { + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetCookbookByID(Guid cookbookID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from cookbook AS r where cookbookid=@cookbookid")) + { + dbCommand.Parameters.AddWithValue("@cookbookid", cookbookID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetCookbookChapterByID(Guid cookbookID, Guid cookbookChapterID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from cookbookchapter where cookbookid=@cookbookid and cookbookchapterid=@cookbookchapterid")) + { + dbCommand.Parameters.AddWithValue("@cookbookid", cookbookID); + dbCommand.Parameters.AddWithValue("@cookbookchapterid", cookbookChapterID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetCookbookChaptersByParentChapter(Guid cookbookID, Guid? parentChapterID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from cookbookchapter where cookbookid=@cookbookid" + + " and (parentchapterid=@parentchapterid or (parentchapterid is null and @parentchapterid is null)) order by name")) + { + dbCommand.Parameters.AddWithValue("@cookbookid", cookbookID); + dbCommand.Parameters.AddWithValue("@parentchapterid", parentChapterID ?? (object)DBNull.Value); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetAllRecipes() + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipe order by recipename")) + { + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeByID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipe AS r where recipeid=@recipeid")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeHighlightsByParentChapter(Guid cookbookID, Guid? cookbookChapterID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipe AS r where cookbookid=@cookbookid" + + " and (cookbookchapterid=@cookbookchapterid or (cookbookchapterid is null and @cookbookchapterid is null)) order by recipename")) + { + dbCommand.Parameters.AddWithValue("@cookbookid", cookbookID); + dbCommand.Parameters.AddWithValue("@cookbookchapterid", cookbookChapterID ?? (object)DBNull.Value); + + return this.ExecuteDataSet(dbCommand); + } + } + + + public DataSet GetRecipeIngredientsByRecipeID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipeingredient where recipeid=@recipeid order by ingredientindex")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeIngredientByID(Guid recipeIngredientID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipeingredient where recipeingredientid=@recipeingredientid")) + { + dbCommand.Parameters.AddWithValue("@recipeingredientid", recipeIngredientID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeIngredientAll() + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipeingredient")) + { + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeProceduresByRecipeID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipeprocedure where recipeid=@recipeid order by procedureindex")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeProcedureByID(Guid recipeProcedureID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipeprocedure where recipeprocedureid=@recipeprocedureid")) + { + dbCommand.Parameters.AddWithValue("@recipeprocedureid", recipeProcedureID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeTipsByRecipeID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipetip where recipeid=@recipeid order by tipindex")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public DataSet GetRecipeTipByID(Guid recipeTipID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from recipetip where recipetipid=@recipetipid")) + { + dbCommand.Parameters.AddWithValue("@recipetipid", recipeTipID); + + return this.ExecuteDataSet(dbCommand); + } + } + + public Int32 DeleteCookbookByID(Guid cookbookID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM cookbook where cookbookid=@cookbookid")) + { + dbCommand.Parameters.AddWithValue("@cookbookid", cookbookID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 DeleteCookbookChapterByID(Guid cookbookID, Guid cookbookChapterID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM cookbookchapter where cookbookid=@cookbookid and cookbookchapterid=@cookbookchapterid")) + { + dbCommand.Parameters.AddWithValue("@cookbookid", cookbookID); + dbCommand.Parameters.AddWithValue("@cookbookchapterid", cookbookChapterID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 DeleteRecipeByID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM recipe where recipeid=@recipeid")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 DeleteRecipeIngredientByID(Guid recipeIngredientID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM recipeingredient where recipeingredientid=@recipeingredientid")) + { + dbCommand.Parameters.AddWithValue("@recipeingredientid", recipeIngredientID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 DeleteRecipeIngredientsByRecipeID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM recipeingredient where recipeid=@recipeid")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + + public Int32 DeleteRecipeProcedureByID(Guid recipeProcedureID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM recipeprocedure where recipeprocedureid=@recipeprocedcureid")) + { + dbCommand.Parameters.AddWithValue("@recipeprocedureid", recipeProcedureID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 DeleteRecipeProceduresByRecipeID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM recipeprocedure where recipeid=@recipeid")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 DeleteRecipeTipByID(Guid recipeTipID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM recipetip where recipetipid=@recipetipid")) + { + dbCommand.Parameters.AddWithValue("@recipetipid", recipeTipID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 DeleteRecipeTipsByRecipeID(Guid recipeID) + { + using (OleDbCommand dbCommand = new OleDbCommand("delete FROM recipetip where recipeid=@recipeid")) + { + dbCommand.Parameters.AddWithValue("@recipeid", recipeID); + + return this.ExecuteNonQuery(dbCommand); + } + + } + + public Int32 InsertCookbook(Cookbook cookbook) + { + using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO cookbook ([cookbookID],[name],[author],[copyright],[comments]) VALUES (@cookbookID,@name,@author,@copyright,@comments)")) + { + dbCommand.Parameters.AddWithValue("@cookbookID", cookbook.cookbookID); + dbCommand.Parameters.AddWithValue("@name", cookbook.name); + dbCommand.Parameters.AddWithValue("@author", cookbook.author); + dbCommand.Parameters.AddWithValue("@copyright", cookbook.copyright); + dbCommand.Parameters.AddWithValue("@comments", cookbook.comments); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 UpdateCookbook(Cookbook cookbook) + { + using (OleDbCommand dbCommand = new OleDbCommand("UPDATE cookbook SET [name]=@name,[author]=@author,[copyright]=@copyright,[comments]=@comments WHERE [cookbookID]=@cookbookID")) + { + dbCommand.Parameters.AddWithValue("@name", cookbook.name); + dbCommand.Parameters.AddWithValue("@author", cookbook.author); + dbCommand.Parameters.AddWithValue("@copyright", cookbook.copyright); + dbCommand.Parameters.AddWithValue("@comments", cookbook.comments); + dbCommand.Parameters.AddWithValue("@cookbookID", cookbook.cookbookID.Value); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 InsertCookbookChapter(CookbookChapter cookbookChapter) + { + using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO cookbookchapter ([cookbookchapterid],[cookbookID],[parentchapterid],[name],[comments]) VALUES (@cookbookChapterID,@cookbookID,@parentChapterID,@name,@comments)")) + { + dbCommand.Parameters.AddWithValue("@cookbookChapterID", cookbookChapter.cookbookChapterID); + dbCommand.Parameters.AddWithValue("@cookbookID", cookbookChapter.cookbookID); + dbCommand.Parameters.AddWithValue("@parentChapterID", cookbookChapter.parentChapterID ?? (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@name", cookbookChapter.name); + dbCommand.Parameters.AddWithValue("@comments", cookbookChapter.comments); + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 UpdateCookbookChapter(CookbookChapter cookbookChapter) + { + using (OleDbCommand dbCommand = new OleDbCommand("UPDATE cookbookchapter SET [cookbookid]=@cookbookID,[parentchapterid]=@parentChapterID,[name]=@name,[comments]=@comments WHERE [cookbookchapterID]=@cookbookChapterID")) + { + dbCommand.Parameters.AddWithValue("@cookbookID", cookbookChapter.cookbookID); + dbCommand.Parameters.AddWithValue("@parentChapterID", cookbookChapter.parentChapterID ?? (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@name", cookbookChapter.name); + dbCommand.Parameters.AddWithValue("@comments", cookbookChapter.comments); + dbCommand.Parameters.AddWithValue("@cookbookChapterID", cookbookChapter.cookbookChapterID); + + return this.ExecuteNonQuery(dbCommand); + } + } + + + + + public Int32 InsertRecipe(Recipe recipe) + { + //using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO recipe ([recipeID],[cookbookID],[cookbookchapterID],[recipename]," + + // "[author],[source],[webpage],[comments],[copyright],[servings],[nutritionservinglabel],[yield],[preparationtime],[cookingtime]," + + // "[readyintime],[inactivetime],[oventemperaturec],[oventemperaturef],[percentcaloriesfromalcohol],[percentcaloriesfromcarbs]," + + // "[percentcaloriesfromfat],[percentcaloriesfromprotein],[alanine],[alcohol],[alcoholfactor],[alphacarotene],[alphalinolenicacid]," + + // "[arachidonicacid],[arginine],[ash],[asparticacid],[betacarotene],[betacryptoxanthin],[betasitosterol],[betatocopherol],[biotin]," + + // "[caffeine],[calcium],[calories],[caloriesfromalcohol],[caloriesfromcarbs],[caloriesfromfat],[caloriesfromprotein],[campesterol]," + + // "[carbohydratefactor],[chloride],[cholesterol],[choline],[chromium],[copper],[cystine],[deltatocopherol],[dihomogammalinolenicacid]," + + // "[docosahexaenoicacid],[docosapentaenoicacid],[eicosadienoicacid],[eicosapentaenoicacid],[energy],[energyfromalcohol],[energyfromcarbs]," + + // "[energyfromfat],[energyfromprotein],[fatfactor],[fiber],[fluoride],[folate],[fructose],[galactose],[gammalinolenicacid],[gammatocopherol]," + + // "[glucose],[glutamicacid],[glycine],[histidine],[hydroxyproline],[iodine],[iron],[isoleucine],[lactose],[leucine],[linoleicacid]," + + // "[lycopene],[lysine],[magnesium],[maltose],[manganese],[mass],[methionine],[molybdenum],[monounsaturatedfat],[monounsaturatedfattyacid_14_1]," + + // "[monounsaturatedfattyacid_15_1],[monounsaturatedfattyacid_16_1],[monounsaturatedfattyacid_17_1],[monounsaturatedfattyacid_18_1]," + + // "[monounsaturatedfattyacid_20_1],[monounsaturatedfattyacid_22_1],[monounsaturatedfattyacid_24_1],[netcarbohydrates],[niacin]," + + // "[omega3fattyacids],[omega6fattyacids],[pantothenicacid],[phenylalanine],[phosphorus],[phytosterols],[polyunsaturatedfat]," + + // "[polyunsaturatedfattyacid_18_2],[polyunsaturatedfattyacid_18_3],[polyunsaturatedfattyacid_18_4],[polyunsaturatedfattyacid_20_3]," + + // "[polyunsaturatedfattyacid_20_4],[polyunsaturatedfattyacid_21_5],[polyunsaturatedfattyacid_22_4],[potassium],[proline],[protein]," + + // "[proteinfactor],[refuse],[retinol],[riboflavin],[saturatedfat],[saturatedfattyacid_10_0],[saturatedfattyacid_12_0]," + + // "[saturatedfattyacid_13_0],[saturatedfattyacid_14_0],[saturatedfattyacid_15_0],[saturatedfattyacid_16_0],[saturatedfattyacid_17_0]," + + // "[saturatedfattyacid_18_0],[saturatedfattyacid_20_0],[saturatedfattyacid_22_0],[saturatedfattyacid_24_0],[saturatedfattyacid_4_0]," + + // "[saturatedfattyacid_6_0],[saturatedfattyacid_8_0],[selenium],[serine],[sodium],[starch],[stigmasterol],[sucrose],[sugar],[sugaralcohols]," + + // "[theobromine],[thiamin],[threonine],[totalcarbohydrate],[totalfat],[transfattyacids],[transmonoenoicfattyacids],[transpolyenoicfattyacids]," + + // "[tryptophan],[tyrosine],[valine],[vitamina],[vitaminb12],[vitaminb6],[vitaminc],[vitamind],[vitamine],[vitamink],[volume],[water],[zinc])" + + // " VALUES (@recipeID,@cookbookID,@cookbookchapterID,@recipename," + + // "@author,@source,@webpage,@comments,@copyright,@servings,@nutritionservinglabel,@yield,@preparationtime,@cookingtime," + + // "@readyintime,@inactivetime,@oventemperaturec,@oventemperaturef,@percentcaloriesfromalcohol,@percentcaloriesfromcarbs," + + // "@percentcaloriesfromfat,@percentcaloriesfromprotein,@alanine,@alcohol,@alcoholfactor,@alphacarotene,@alphalinolenicacid," + + // "@arachidonicacid,@arginine,@ash,@asparticacid,@betacarotene,@betacryptoxanthin,@betasitosterol,@betatocopherol,@biotin," + + // "@caffeine,@calcium,@calories,@caloriesfromalcohol,@caloriesfromcarbs,@caloriesfromfat,@caloriesfromprotein,@campesterol," + + // "@carbohydratefactor,@chloride,@cholesterol,@choline,@chromium,@copper,@cystine,@deltatocopherol,@dihomogammalinolenicacid," + + // "@docosahexaenoicacid,@docosapentaenoicacid,@eicosadienoicacid,@eicosapentaenoicacid,@energy,@energyfromalcohol,@energyfromcarbs," + + // "@energyfromfat,@energyfromprotein,@fatfactor,@fiber,@fluoride,@folate,@fructose,@galactose,@gammalinolenicacid,@gammatocopherol," + + // "@glucose,@glutamicacid,@glycine,@histidine,@hydroxyproline,@iodine,@iron,@isoleucine,@lactose,@leucine,@linoleicacid," + + // "@lycopene,@lysine,@magnesium,@maltose,@manganese,@mass,@methionine,@molybdenum,@monounsaturatedfat,@monounsaturatedfattyacid_14_1," + + // "@monounsaturatedfattyacid_15_1,@monounsaturatedfattyacid_16_1,@monounsaturatedfattyacid_17_1,@monounsaturatedfattyacid_18_1," + + // "@monounsaturatedfattyacid_20_1,@monounsaturatedfattyacid_22_1,@monounsaturatedfattyacid_24_1,@netcarbohydrates,@niacin," + + // "@omega3fattyacids,@omega6fattyacids,@pantothenicacid,@phenylalanine,@phosphorus,@phytosterols,@polyunsaturatedfat," + + // "@polyunsaturatedfattyacid_18_2,@polyunsaturatedfattyacid_18_3,@polyunsaturatedfattyacid_18_4,@polyunsaturatedfattyacid_20_3," + + // "@polyunsaturatedfattyacid_20_4,@polyunsaturatedfattyacid_21_5,@polyunsaturatedfattyacid_22_4,@potassium,@proline,@protein," + + // "@proteinfactor,@refuse,@retinol,@riboflavin,@saturatedfat,@saturatedfattyacid_10_0,@saturatedfattyacid_12_0," + + // "@saturatedfattyacid_13_0,@saturatedfattyacid_14_0,@saturatedfattyacid_15_0,@saturatedfattyacid_16_0,@saturatedfattyacid_17_0," + + // "@saturatedfattyacid_18_0,@saturatedfattyacid_20_0,@saturatedfattyacid_22_0,@saturatedfattyacid_24_0,@saturatedfattyacid_4_0," + + // "@saturatedfattyacid_6_0,@saturatedfattyacid_8_0,@selenium,@serine,@sodium,@starch,@stigmasterol,@sucrose,@sugar,@sugaralcohols," + + // "@theobromine,@thiamin,@threonine,@totalcarbohydrate,@totalfat,@transfattyacids,@transmonoenoicfattyacids,@transpolyenoicfattyacids," + + // "@tryptophan,@tyrosine,@valine,@vitamina,@vitaminb12,@vitaminb6,@vitaminc,@vitamind,@vitamine,@vitamink,@volume,@water,@zinc)")) + //{ + + // dbCommand.Parameters.AddWithValue("@recipeID", recipe.recipeID); + // dbCommand.Parameters.AddWithValue("@cookbookID", recipe.cookbookID); + // dbCommand.Parameters.AddWithValue("@cookbookchapterID", recipe.cookbookchapterID ?? (object)DBNull.Value); + // dbCommand.Parameters.AddWithValue("@recipename", recipe.recipename); + // dbCommand.Parameters.AddWithValue("@author", recipe.author); + // dbCommand.Parameters.AddWithValue("@source", recipe.source); + // dbCommand.Parameters.AddWithValue("@webpage", recipe.webpage); + // dbCommand.Parameters.AddWithValue("@comments", recipe.comments); + // dbCommand.Parameters.AddWithValue("@copyright", recipe.copyright); + // dbCommand.Parameters.AddWithValue("@servings", recipe.servings); + // dbCommand.Parameters.AddWithValue("@nutritionservinglabel", recipe.nutritionservinglabel); + // dbCommand.Parameters.AddWithValue("@yield", recipe.yield); + // dbCommand.Parameters.AddWithValue("@preparationtime", recipe.preparationtime); + // dbCommand.Parameters.AddWithValue("@cookingtime", recipe.cookingtime); + // dbCommand.Parameters.AddWithValue("@readyintime", recipe.readyintime); + // dbCommand.Parameters.AddWithValue("@inactivetime", recipe.inactivetime); + // dbCommand.Parameters.AddWithValue("@oventemperaturec", recipe.oventemperaturec); + // dbCommand.Parameters.AddWithValue("@oventemperaturef", recipe.oventemperaturef); + // dbCommand.Parameters.AddWithValue("@percentcaloriesfromalcohol", recipe.percentcaloriesfromalcohol); + // dbCommand.Parameters.AddWithValue("@percentcaloriesfromcarbs", recipe.percentcaloriesfromcarbs); + // dbCommand.Parameters.AddWithValue("@percentcaloriesfromfat", recipe.percentcaloriesfromfat); + // dbCommand.Parameters.AddWithValue("@percentcaloriesfromprotein", recipe.percentcaloriesfromprotein); + // dbCommand.Parameters.AddWithValue("@alanine", recipe.alanine); + // dbCommand.Parameters.AddWithValue("@alcohol", recipe.alcohol); + // dbCommand.Parameters.AddWithValue("@alcoholfactor", recipe.alcoholfactor); + // dbCommand.Parameters.AddWithValue("@alphacarotene", recipe.alphacarotene); + // dbCommand.Parameters.AddWithValue("@alphalinolenicacid", recipe.alphalinolenicacid); + // dbCommand.Parameters.AddWithValue("@arachidonicacid", recipe.arachidonicacid); + // dbCommand.Parameters.AddWithValue("@arginine", recipe.arginine); + // dbCommand.Parameters.AddWithValue("@ash", recipe.ash); + // dbCommand.Parameters.AddWithValue("@asparticacid", recipe.asparticacid); + // dbCommand.Parameters.AddWithValue("@betacarotene", recipe.betacarotene); + // dbCommand.Parameters.AddWithValue("@betacryptoxanthin", recipe.betacryptoxanthin); + // dbCommand.Parameters.AddWithValue("@betasitosterol", recipe.betasitosterol); + // dbCommand.Parameters.AddWithValue("@betatocopherol", recipe.betatocopherol); + // dbCommand.Parameters.AddWithValue("@biotin", recipe.biotin); + // dbCommand.Parameters.AddWithValue("@caffeine", recipe.caffeine); + // dbCommand.Parameters.AddWithValue("@calcium", recipe.calcium); + // dbCommand.Parameters.AddWithValue("@calories", recipe.calories); + // dbCommand.Parameters.AddWithValue("@caloriesfromalcohol", recipe.caloriesfromalcohol); + // dbCommand.Parameters.AddWithValue("@caloriesfromcarbs", recipe.caloriesfromcarbs); + // dbCommand.Parameters.AddWithValue("@caloriesfromfat", recipe.caloriesfromfat); + // dbCommand.Parameters.AddWithValue("@caloriesfromprotein", recipe.caloriesfromprotein); + // dbCommand.Parameters.AddWithValue("@campesterol", recipe.campesterol); + // dbCommand.Parameters.AddWithValue("@carbohydratefactor", recipe.carbohydratefactor); + // dbCommand.Parameters.AddWithValue("@chloride", recipe.chloride); + // dbCommand.Parameters.AddWithValue("@cholesterol", recipe.cholesterol); + // dbCommand.Parameters.AddWithValue("@choline", recipe.choline); + // dbCommand.Parameters.AddWithValue("@chromium", recipe.chromium); + // dbCommand.Parameters.AddWithValue("@copper", recipe.copper); + // dbCommand.Parameters.AddWithValue("@cystine", recipe.cystine); + // dbCommand.Parameters.AddWithValue("@deltatocopherol", recipe.deltatocopherol); + // dbCommand.Parameters.AddWithValue("@dihomogammalinolenicacid", recipe.dihomogammalinolenicacid); + // dbCommand.Parameters.AddWithValue("@docosahexaenoicacid", recipe.docosahexaenoicacid); + // dbCommand.Parameters.AddWithValue("@docosapentaenoicacid", recipe.docosapentaenoicacid); + // dbCommand.Parameters.AddWithValue("@eicosadienoicacid", recipe.eicosadienoicacid); + // dbCommand.Parameters.AddWithValue("@eicosapentaenoicacid", recipe.eicosapentaenoicacid); + // dbCommand.Parameters.AddWithValue("@energy", recipe.energy); + // dbCommand.Parameters.AddWithValue("@energyfromalcohol", recipe.energyfromalcohol); + // dbCommand.Parameters.AddWithValue("@energyfromcarbs", recipe.energyfromcarbs); + // dbCommand.Parameters.AddWithValue("@energyfromfat", recipe.energyfromfat); + // dbCommand.Parameters.AddWithValue("@energyfromprotein", recipe.energyfromprotein); + // dbCommand.Parameters.AddWithValue("@fatfactor", recipe.fatfactor); + // dbCommand.Parameters.AddWithValue("@fiber", recipe.fiber); + // dbCommand.Parameters.AddWithValue("@fluoride", recipe.fluoride); + // dbCommand.Parameters.AddWithValue("@folate", recipe.folate); + // dbCommand.Parameters.AddWithValue("@fructose", recipe.fructose); + // dbCommand.Parameters.AddWithValue("@galactose", recipe.galactose); + // dbCommand.Parameters.AddWithValue("@gammalinolenicacid", recipe.gammalinolenicacid); + // dbCommand.Parameters.AddWithValue("@gammatocopherol", recipe.gammatocopherol); + // dbCommand.Parameters.AddWithValue("@glucose", recipe.glucose); + // dbCommand.Parameters.AddWithValue("@glutamicacid", recipe.glutamicacid); + // dbCommand.Parameters.AddWithValue("@glycine", recipe.glycine); + // dbCommand.Parameters.AddWithValue("@histidine", recipe.histidine); + // dbCommand.Parameters.AddWithValue("@hydroxyproline", recipe.hydroxyproline); + // dbCommand.Parameters.AddWithValue("@iodine", recipe.iodine); + // dbCommand.Parameters.AddWithValue("@iron", recipe.iron); + // dbCommand.Parameters.AddWithValue("@isoleucine", recipe.isoleucine); + // dbCommand.Parameters.AddWithValue("@lactose", recipe.lactose); + // dbCommand.Parameters.AddWithValue("@leucine", recipe.leucine); + // dbCommand.Parameters.AddWithValue("@linoleicacid", recipe.linoleicacid); + // dbCommand.Parameters.AddWithValue("@lycopene", recipe.lycopene); + // dbCommand.Parameters.AddWithValue("@lysine", recipe.lysine); + // dbCommand.Parameters.AddWithValue("@magnesium", recipe.magnesium); + // dbCommand.Parameters.AddWithValue("@maltose", recipe.maltose); + // dbCommand.Parameters.AddWithValue("@manganese", recipe.manganese); + // dbCommand.Parameters.AddWithValue("@mass", recipe.mass); + // dbCommand.Parameters.AddWithValue("@methionine", recipe.methionine); + // dbCommand.Parameters.AddWithValue("@molybdenum", recipe.molybdenum); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfat", recipe.monounsaturatedfat); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_14_1", recipe.monounsaturatedfattyacid_14_1); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_15_1", recipe.monounsaturatedfattyacid_15_1); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_16_1", recipe.monounsaturatedfattyacid_16_1); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_17_1", recipe.monounsaturatedfattyacid_17_1); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_18_1", recipe.monounsaturatedfattyacid_18_1); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_20_1", recipe.monounsaturatedfattyacid_20_1); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_22_1", recipe.monounsaturatedfattyacid_22_1); + // dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_24_1", recipe.monounsaturatedfattyacid_24_1); + // dbCommand.Parameters.AddWithValue("@netcarbohydrates", recipe.netcarbohydrates); + // dbCommand.Parameters.AddWithValue("@niacin", recipe.niacin); + // dbCommand.Parameters.AddWithValue("@omega3fattyacids", recipe.omega3fattyacids); + // dbCommand.Parameters.AddWithValue("@omega6fattyacids", recipe.omega6fattyacids); + // dbCommand.Parameters.AddWithValue("@pantothenicacid", recipe.pantothenicacid); + // dbCommand.Parameters.AddWithValue("@phenylalanine", recipe.phenylalanine); + // dbCommand.Parameters.AddWithValue("@phosphorus", recipe.phosphorus); + // dbCommand.Parameters.AddWithValue("@phytosterols", recipe.phytosterols); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfat", recipe.polyunsaturatedfat); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfattyacid_18_2", recipe.polyunsaturatedfattyacid_18_2); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfattyacid_18_3", recipe.polyunsaturatedfattyacid_18_3); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfattyacid_18_4", recipe.polyunsaturatedfattyacid_18_4); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfattyacid_20_3", recipe.polyunsaturatedfattyacid_20_3); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfattyacid_20_4", recipe.polyunsaturatedfattyacid_20_4); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfattyacid_21_5", recipe.polyunsaturatedfattyacid_21_5); + // dbCommand.Parameters.AddWithValue("@polyunsaturatedfattyacid_22_4", recipe.polyunsaturatedfattyacid_22_4); + // dbCommand.Parameters.AddWithValue("@potassium", recipe.potassium); + // dbCommand.Parameters.AddWithValue("@proline", recipe.proline); + // dbCommand.Parameters.AddWithValue("@protein", recipe.protein); + // dbCommand.Parameters.AddWithValue("@proteinfactor", recipe.proteinfactor); + // dbCommand.Parameters.AddWithValue("@refuse", recipe.refuse); + // dbCommand.Parameters.AddWithValue("@retinol", recipe.retinol); + // dbCommand.Parameters.AddWithValue("@riboflavin", recipe.riboflavin); + // dbCommand.Parameters.AddWithValue("@saturatedfat", recipe.saturatedfat); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_10_0", recipe.saturatedfattyacid_10_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_12_0", recipe.saturatedfattyacid_12_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_13_0", recipe.saturatedfattyacid_13_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_14_0", recipe.saturatedfattyacid_14_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_15_0", recipe.saturatedfattyacid_15_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_16_0", recipe.saturatedfattyacid_16_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_17_0", recipe.saturatedfattyacid_17_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_18_0", recipe.saturatedfattyacid_18_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_20_0", recipe.saturatedfattyacid_20_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_22_0", recipe.saturatedfattyacid_22_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_24_0", recipe.saturatedfattyacid_24_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_4_0", recipe.saturatedfattyacid_4_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_6_0", recipe.saturatedfattyacid_6_0); + // dbCommand.Parameters.AddWithValue("@saturatedfattyacid_8_0", recipe.saturatedfattyacid_8_0); + // dbCommand.Parameters.AddWithValue("@selenium", recipe.selenium); + // dbCommand.Parameters.AddWithValue("@serine", recipe.serine); + // dbCommand.Parameters.AddWithValue("@sodium", recipe.sodium); + // dbCommand.Parameters.AddWithValue("@starch", recipe.starch); + // dbCommand.Parameters.AddWithValue("@stigmasterol", recipe.stigmasterol); + // dbCommand.Parameters.AddWithValue("@sucrose", recipe.sucrose); + // dbCommand.Parameters.AddWithValue("@sugar", recipe.sugar); + // dbCommand.Parameters.AddWithValue("@sugaralcohols", recipe.sugaralcohols); + // dbCommand.Parameters.AddWithValue("@theobromine", recipe.theobromine); + // dbCommand.Parameters.AddWithValue("@thiamin", recipe.thiamin); + // dbCommand.Parameters.AddWithValue("@threonine", recipe.threonine); + // dbCommand.Parameters.AddWithValue("@totalcarbohydrate", recipe.totalcarbohydrate); + // dbCommand.Parameters.AddWithValue("@totalfat", recipe.totalfat); + // dbCommand.Parameters.AddWithValue("@transfattyacids", recipe.transfattyacids); + // dbCommand.Parameters.AddWithValue("@transmonoenoicfattyacids", recipe.transmonoenoicfattyacids); + // dbCommand.Parameters.AddWithValue("@transpolyenoicfattyacids", recipe.transpolyenoicfattyacids); + // dbCommand.Parameters.AddWithValue("@tryptophan", recipe.tryptophan); + // dbCommand.Parameters.AddWithValue("@tyrosine", recipe.tyrosine); + // dbCommand.Parameters.AddWithValue("@valine", recipe.valine); + // dbCommand.Parameters.AddWithValue("@vitamina", recipe.vitamina); + // dbCommand.Parameters.AddWithValue("@vitaminb12", recipe.vitaminb12); + // dbCommand.Parameters.AddWithValue("@vitaminb6", recipe.vitaminb6); + // dbCommand.Parameters.AddWithValue("@vitaminc", recipe.vitaminc); + // dbCommand.Parameters.AddWithValue("@vitamind", recipe.vitamind); + // dbCommand.Parameters.AddWithValue("@vitamine", recipe.vitamine); + // dbCommand.Parameters.AddWithValue("@vitamink", recipe.vitamink); + // dbCommand.Parameters.AddWithValue("@volume", recipe.volume); + // dbCommand.Parameters.AddWithValue("@water", recipe.water); + // dbCommand.Parameters.AddWithValue("@zinc", recipe.zinc); + + using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO recipe ([recipeID],[cookbookID],[cookbookchapterID],[recipename]) " + + "VALUES (@recipeID,@cookbookID,@cookbookchapterID,@recipename)")) + { + + dbCommand.Parameters.AddWithValue("@recipeID", recipe.recipeID); + dbCommand.Parameters.AddWithValue("@cookbookID", recipe.cookbookID); + dbCommand.Parameters.AddWithValue("@cookbookchapterID", recipe.cookbookchapterID ?? (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@recipename", recipe.recipename); + //Insert shell, then update + return this.ExecuteNonQuery(dbCommand) + this.UpdateRecipe(recipe); + } + } + + public Int32 UpdateRecipe(Recipe recipe) + { + using (OleDbCommand dbCommand = new OleDbCommand("UPDATE recipe SET alanine=@alanine,alcohol=@alcohol,alcoholfactor=@alcoholfactor,alphacarotene=@alphacarotene," + + "alphalinolenicacid=@alphalinolenicacid,arachidonicacid=@arachidonicacid,arginine=@arginine,ash=@ash,asparticacid=@asparticacid,author=@author,betacarotene=@betacarotene," + + "betacryptoxanthin=@betacryptoxanthin,betasitosterol=@betasitosterol,betatocopherol=@betatocopherol,biotin=@biotin,caffeine=@caffeine,calcium=@calcium,calories=@calories," + + "caloriesfromalcohol=@caloriesfromalcohol,caloriesfromcarbs=@caloriesfromcarbs,caloriesfromfat=@caloriesfromfat,caloriesfromprotein=@caloriesfromprotein,campesterol=@campesterol," + + "carbohydratefactor=@carbohydratefactor,chloride=@chloride,cholesterol=@cholesterol,choline=@choline,chromium=@chromium,comments=@comments,cookbookchapterid=@cookbookchapterid," + + "cookbookid=@cookbookid,cookingtime=@cookingtime,copper=@copper,copyright=@copyright,cystine=@cystine,deltatocopherol=@deltatocopherol," + + "dihomogammalinolenicacid=@dihomogammalinolenicacid,docosahexaenoicacid=@docosahexaenoicacid,docosapentaenoicacid=@docosapentaenoicacid,eicosadienoicacid=@eicosadienoicacid," + + "eicosapentaenoicacid=@eicosapentaenoicacid,energy=@energy,energyfromalcohol=@energyfromalcohol,energyfromcarbs=@energyfromcarbs,energyfromfat=@energyfromfat," + + "energyfromprotein=@energyfromprotein,fatfactor=@fatfactor,fiber=@fiber,fluoride=@fluoride,folate=@folate,fructose=@fructose,galactose=@galactose," + + "gammalinolenicacid=@gammalinolenicacid,gammatocopherol=@gammatocopherol,glucose=@glucose,glutamicacid=@glutamicacid,glycine=@glycine,histidine=@histidine," + + "hydroxyproline=@hydroxyproline,inactivetime=@inactivetime,iodine=@iodine,iron=@iron,isoleucine=@isoleucine,lactose=@lactose,leucine=@leucine,linoleicacid=@linoleicacid," + + "lycopene=@lycopene,lysine=@lysine,magnesium=@magnesium,maltose=@maltose,manganese=@manganese,mass=@mass,methionine=@methionine,molybdenum=@molybdenum," + + "monounsaturatedfat=@monounsaturatedfat,monounsaturatedfattyacid_14_1=@monounsaturatedfattyacid_14_1,monounsaturatedfattyacid_15_1=@monounsaturatedfattyacid_15_1," + + "monounsaturatedfattyacid_16_1=@monounsaturatedfattyacid_16_1,monounsaturatedfattyacid_17_1=@monounsaturatedfattyacid_17_1," + + "monounsaturatedfattyacid_18_1=@monounsaturatedfattyacid_18_1,monounsaturatedfattyacid_20_1=@monounsaturatedfattyacid_20_1," + + "monounsaturatedfattyacid_22_1=@monounsaturatedfattyacid_22_1,monounsaturatedfattyacid_24_1=@monounsaturatedfattyacid_24_1,netcarbohydrates=@netcarbohydrates," + + "niacin=@niacin,nutritionservinglabel=@nutritionservinglabel,omega3fattyacids=@omega3fattyacids,omega6fattyacids=@omega6fattyacids,oventemperaturec=@oventemperaturec " + + " WHERE recipeid=@recipeID")) + { + using (OleDbCommand dbCommand2 = new OleDbCommand("UPDATE recipe SET oventemperaturef=@oventemperaturef,pantothenicacid=@pantothenicacid,percentcaloriesfromalcohol=@percentcaloriesfromalcohol,percentcaloriesfromcarbs=@percentcaloriesfromcarbs," + + "percentcaloriesfromfat=@percentcaloriesfromfat,percentcaloriesfromprotein=@percentcaloriesfromprotein,phenylalanine=@phenylalanine,phosphorus=@phosphorus," + + "phytosterols=@phytosterols,polyunsaturatedfat=@polyunsaturatedfat,polyunsaturatedfattyacid_18_2=@polyunsaturatedfattyacid_18_2," + + "polyunsaturatedfattyacid_18_3=@polyunsaturatedfattyacid_18_3,polyunsaturatedfattyacid_18_4=@polyunsaturatedfattyacid_18_4," + + "polyunsaturatedfattyacid_20_3=@polyunsaturatedfattyacid_20_3,polyunsaturatedfattyacid_20_4=@polyunsaturatedfattyacid_20_4," + + "polyunsaturatedfattyacid_21_5=@polyunsaturatedfattyacid_21_5,polyunsaturatedfattyacid_22_4=@polyunsaturatedfattyacid_22_4,potassium=@potassium,preparationtime=@preparationtime," + + "proline=@proline,protein=@protein,proteinfactor=@proteinfactor,readyintime=@readyintime,recipename=@recipename,refuse=@refuse,retinol=@retinol,riboflavin=@riboflavin," + + "saturatedfat=@saturatedfat,saturatedfattyacid_10_0=@saturatedfattyacid_10_0,saturatedfattyacid_12_0=@saturatedfattyacid_12_0,saturatedfattyacid_13_0=@saturatedfattyacid_13_0," + + "saturatedfattyacid_14_0=@saturatedfattyacid_14_0,saturatedfattyacid_15_0=@saturatedfattyacid_15_0,saturatedfattyacid_16_0=@saturatedfattyacid_16_0," + + "saturatedfattyacid_17_0=@saturatedfattyacid_17_0,saturatedfattyacid_18_0=@saturatedfattyacid_18_0,saturatedfattyacid_20_0=@saturatedfattyacid_20_0," + + "saturatedfattyacid_22_0=@saturatedfattyacid_22_0,saturatedfattyacid_24_0=@saturatedfattyacid_24_0,saturatedfattyacid_4_0=@saturatedfattyacid_4_0," + + "saturatedfattyacid_6_0=@saturatedfattyacid_6_0,saturatedfattyacid_8_0=@saturatedfattyacid_8_0,selenium=@selenium,serine=@serine,servings=@servings,sodium=@sodium," + + "source=@source,starch=@starch,stigmasterol=@stigmasterol,sucrose=@sucrose,sugar=@sugar,sugaralcohols=@sugaralcohols,theobromine=@theobromine,thiamin=@thiamin," + + "threonine=@threonine,totalcarbohydrate=@totalcarbohydrate,totalfat=@totalfat,transfattyacids=@transfattyacids,transmonoenoicfattyacids=@transmonoenoicfattyacids," + + "transpolyenoicfattyacids=@transpolyenoicfattyacids,tryptophan=@tryptophan,tyrosine=@tyrosine,valine=@valine,vitamina=@vitamina,vitaminb12=@vitaminb12,vitaminb6=@vitaminb6," + + "vitaminc=@vitaminc,vitamind=@vitamind,vitamine=@vitamine,vitamink=@vitamink,volume=@volume,water=@water,webpage=@webpage,yield=@yield,zinc=@zinc WHERE recipeid=@recipeID")) + { + dbCommand.Parameters.AddWithValue("@alanine", recipe.alanine); + dbCommand.Parameters.AddWithValue("@alcohol", recipe.alcohol); + dbCommand.Parameters.AddWithValue("@alcoholfactor", recipe.alcoholfactor); + dbCommand.Parameters.AddWithValue("@alphacarotene", recipe.alphacarotene); + dbCommand.Parameters.AddWithValue("@alphalinolenicacid", recipe.alphalinolenicacid); + dbCommand.Parameters.AddWithValue("@arachidonicacid", recipe.arachidonicacid); + dbCommand.Parameters.AddWithValue("@arginine", recipe.arginine); + dbCommand.Parameters.AddWithValue("@ash", recipe.ash); + dbCommand.Parameters.AddWithValue("@asparticacid", recipe.asparticacid); + dbCommand.Parameters.AddWithValue("@author", recipe.author); + dbCommand.Parameters.AddWithValue("@betacarotene", recipe.betacarotene); + dbCommand.Parameters.AddWithValue("@betacryptoxanthin", recipe.betacryptoxanthin); + dbCommand.Parameters.AddWithValue("@betasitosterol", recipe.betasitosterol); + dbCommand.Parameters.AddWithValue("@betatocopherol", recipe.betatocopherol); + dbCommand.Parameters.AddWithValue("@biotin", recipe.biotin); + dbCommand.Parameters.AddWithValue("@caffeine", recipe.caffeine); + dbCommand.Parameters.AddWithValue("@calcium", recipe.calcium); + dbCommand.Parameters.AddWithValue("@calories", recipe.calories); + dbCommand.Parameters.AddWithValue("@caloriesfromalcohol", recipe.caloriesfromalcohol); + dbCommand.Parameters.AddWithValue("@caloriesfromcarbs", recipe.caloriesfromcarbs); + dbCommand.Parameters.AddWithValue("@caloriesfromfat", recipe.caloriesfromfat); + dbCommand.Parameters.AddWithValue("@caloriesfromprotein", recipe.caloriesfromprotein); + dbCommand.Parameters.AddWithValue("@campesterol", recipe.campesterol); + dbCommand.Parameters.AddWithValue("@carbohydratefactor", recipe.carbohydratefactor); + dbCommand.Parameters.AddWithValue("@chloride", recipe.chloride); + dbCommand.Parameters.AddWithValue("@cholesterol", recipe.cholesterol); + dbCommand.Parameters.AddWithValue("@choline", recipe.choline); + dbCommand.Parameters.AddWithValue("@chromium", recipe.chromium); + dbCommand.Parameters.AddWithValue("@comments", recipe.comments); + dbCommand.Parameters.AddWithValue("@cookbookchapterid", recipe.cookbookchapterID ?? (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@cookbookID", recipe.cookbookID); + dbCommand.Parameters.AddWithValue("@cookingtime", recipe.cookingtime); + dbCommand.Parameters.AddWithValue("@copper", recipe.copper); + dbCommand.Parameters.AddWithValue("@copyright", recipe.copyright); + dbCommand.Parameters.AddWithValue("@cystine", recipe.cystine); + dbCommand.Parameters.AddWithValue("@deltatocopherol", recipe.deltatocopherol); + dbCommand.Parameters.AddWithValue("@dihomogammalinolenicacid", recipe.dihomogammalinolenicacid); + dbCommand.Parameters.AddWithValue("@docosahexaenoicacid", recipe.docosahexaenoicacid); + dbCommand.Parameters.AddWithValue("@docosapentaenoicacid", recipe.docosapentaenoicacid); + dbCommand.Parameters.AddWithValue("@eicosadienoicacid", recipe.eicosadienoicacid); + dbCommand.Parameters.AddWithValue("@eicosapentaenoicacid", recipe.eicosapentaenoicacid); + dbCommand.Parameters.AddWithValue("@energy", recipe.energy); + dbCommand.Parameters.AddWithValue("@energyfromalcohol", recipe.energyfromalcohol); + dbCommand.Parameters.AddWithValue("@energyfromcarbs", recipe.energyfromcarbs); + dbCommand.Parameters.AddWithValue("@energyfromfat", recipe.energyfromfat); + dbCommand.Parameters.AddWithValue("@energyfromprotein", recipe.energyfromprotein); + dbCommand.Parameters.AddWithValue("@fatfactor", recipe.fatfactor); + dbCommand.Parameters.AddWithValue("@fiber", recipe.fiber); + dbCommand.Parameters.AddWithValue("@fluoride", recipe.fluoride); + dbCommand.Parameters.AddWithValue("@folate", recipe.folate); + dbCommand.Parameters.AddWithValue("@fructose", recipe.fructose); + dbCommand.Parameters.AddWithValue("@galactose", recipe.galactose); + dbCommand.Parameters.AddWithValue("@gammalinolenicacid", recipe.gammalinolenicacid); + dbCommand.Parameters.AddWithValue("@gammatocopherol", recipe.gammatocopherol); + dbCommand.Parameters.AddWithValue("@glucose", recipe.glucose); + dbCommand.Parameters.AddWithValue("@glutamicacid", recipe.glutamicacid); + dbCommand.Parameters.AddWithValue("@glycine", recipe.glycine); + dbCommand.Parameters.AddWithValue("@histidine", recipe.histidine); + dbCommand.Parameters.AddWithValue("@hydroxyproline", recipe.hydroxyproline); + dbCommand.Parameters.AddWithValue("@inactivetime", recipe.inactivetime); + dbCommand.Parameters.AddWithValue("@iodine", recipe.iodine); + dbCommand.Parameters.AddWithValue("@iron", recipe.iron); + dbCommand.Parameters.AddWithValue("@isoleucine", recipe.isoleucine); + dbCommand.Parameters.AddWithValue("@lactose", recipe.lactose); + dbCommand.Parameters.AddWithValue("@leucine", recipe.leucine); + dbCommand.Parameters.AddWithValue("@linoleicacid", recipe.linoleicacid); + dbCommand.Parameters.AddWithValue("@lycopene", recipe.lycopene); + dbCommand.Parameters.AddWithValue("@lysine", recipe.lysine); + dbCommand.Parameters.AddWithValue("@magnesium", recipe.magnesium); + dbCommand.Parameters.AddWithValue("@maltose", recipe.maltose); + dbCommand.Parameters.AddWithValue("@manganese", recipe.manganese); + dbCommand.Parameters.AddWithValue("@mass", recipe.mass); + dbCommand.Parameters.AddWithValue("@methionine", recipe.methionine); + dbCommand.Parameters.AddWithValue("@molybdenum", recipe.molybdenum); + dbCommand.Parameters.AddWithValue("@monounsaturatedfat", recipe.monounsaturatedfat); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_14_1", recipe.monounsaturatedfattyacid_14_1); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_15_1", recipe.monounsaturatedfattyacid_15_1); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_16_1", recipe.monounsaturatedfattyacid_16_1); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_17_1", recipe.monounsaturatedfattyacid_17_1); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_18_1", recipe.monounsaturatedfattyacid_18_1); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_20_1", recipe.monounsaturatedfattyacid_20_1); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_22_1", recipe.monounsaturatedfattyacid_22_1); + dbCommand.Parameters.AddWithValue("@monounsaturatedfattyacid_24_1", recipe.monounsaturatedfattyacid_24_1); + dbCommand.Parameters.AddWithValue("@netcarbohydrates", recipe.netcarbohydrates); + dbCommand.Parameters.AddWithValue("@niacin", recipe.niacin); + dbCommand.Parameters.AddWithValue("@nutritionservinglabel", recipe.nutritionservinglabel); + dbCommand.Parameters.AddWithValue("@omega3fattyacids", recipe.omega3fattyacids); + dbCommand.Parameters.AddWithValue("@omega6fattyacids", recipe.omega6fattyacids); + dbCommand.Parameters.AddWithValue("@oventemperaturec", recipe.oventemperaturec); + dbCommand.Parameters.AddWithValue("@recipeID", recipe.recipeID); + + + dbCommand2.Parameters.AddWithValue("@oventemperaturef", recipe.oventemperaturef); + dbCommand2.Parameters.AddWithValue("@pantothenicacid", recipe.pantothenicacid); + dbCommand2.Parameters.AddWithValue("@percentcaloriesfromalcohol", recipe.percentcaloriesfromalcohol); + dbCommand2.Parameters.AddWithValue("@percentcaloriesfromcarbs", recipe.percentcaloriesfromcarbs); + dbCommand2.Parameters.AddWithValue("@percentcaloriesfromfat", recipe.percentcaloriesfromfat); + dbCommand2.Parameters.AddWithValue("@percentcaloriesfromprotein", recipe.percentcaloriesfromprotein); + dbCommand2.Parameters.AddWithValue("@phenylalanine", recipe.phenylalanine); + dbCommand2.Parameters.AddWithValue("@phosphorus", recipe.phosphorus); + dbCommand2.Parameters.AddWithValue("@phytosterols", recipe.phytosterols); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfat", recipe.polyunsaturatedfat); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfattyacid_18_2", recipe.polyunsaturatedfattyacid_18_2); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfattyacid_18_3", recipe.polyunsaturatedfattyacid_18_3); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfattyacid_18_4", recipe.polyunsaturatedfattyacid_18_4); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfattyacid_20_3", recipe.polyunsaturatedfattyacid_20_3); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfattyacid_20_4", recipe.polyunsaturatedfattyacid_20_4); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfattyacid_21_5", recipe.polyunsaturatedfattyacid_21_5); + dbCommand2.Parameters.AddWithValue("@polyunsaturatedfattyacid_22_4", recipe.polyunsaturatedfattyacid_22_4); + dbCommand2.Parameters.AddWithValue("@potassium", recipe.potassium); + dbCommand2.Parameters.AddWithValue("@preparationtime", recipe.preparationtime); + dbCommand2.Parameters.AddWithValue("@proline", recipe.proline); + dbCommand2.Parameters.AddWithValue("@protein", recipe.protein); + dbCommand2.Parameters.AddWithValue("@proteinfactor", recipe.proteinfactor); + dbCommand2.Parameters.AddWithValue("@readyintime", recipe.readyintime); + dbCommand2.Parameters.AddWithValue("@recipename", recipe.recipename); + dbCommand2.Parameters.AddWithValue("@refuse", recipe.refuse); + dbCommand2.Parameters.AddWithValue("@retinol", recipe.retinol); + dbCommand2.Parameters.AddWithValue("@riboflavin", recipe.riboflavin); + dbCommand2.Parameters.AddWithValue("@saturatedfat", recipe.saturatedfat); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_10_0", recipe.saturatedfattyacid_10_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_12_0", recipe.saturatedfattyacid_12_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_13_0", recipe.saturatedfattyacid_13_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_14_0", recipe.saturatedfattyacid_14_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_15_0", recipe.saturatedfattyacid_15_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_16_0", recipe.saturatedfattyacid_16_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_17_0", recipe.saturatedfattyacid_17_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_18_0", recipe.saturatedfattyacid_18_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_20_0", recipe.saturatedfattyacid_20_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_22_0", recipe.saturatedfattyacid_22_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_24_0", recipe.saturatedfattyacid_24_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_4_0", recipe.saturatedfattyacid_4_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_6_0", recipe.saturatedfattyacid_6_0); + dbCommand2.Parameters.AddWithValue("@saturatedfattyacid_8_0", recipe.saturatedfattyacid_8_0); + dbCommand2.Parameters.AddWithValue("@selenium", recipe.selenium); + dbCommand2.Parameters.AddWithValue("@serine", recipe.serine); + dbCommand2.Parameters.AddWithValue("@servings", recipe.servings); + dbCommand2.Parameters.AddWithValue("@sodium", recipe.sodium); + dbCommand2.Parameters.AddWithValue("@source", recipe.source); + dbCommand2.Parameters.AddWithValue("@starch", recipe.starch); + dbCommand2.Parameters.AddWithValue("@stigmasterol", recipe.stigmasterol); + dbCommand2.Parameters.AddWithValue("@sucrose", recipe.sucrose); + dbCommand2.Parameters.AddWithValue("@sugar", recipe.sugar); + dbCommand2.Parameters.AddWithValue("@sugaralcohols", recipe.sugaralcohols); + dbCommand2.Parameters.AddWithValue("@theobromine", recipe.theobromine); + dbCommand2.Parameters.AddWithValue("@thiamin", recipe.thiamin); + dbCommand2.Parameters.AddWithValue("@threonine", recipe.threonine); + dbCommand2.Parameters.AddWithValue("@totalcarbohydrate", recipe.totalcarbohydrate); + dbCommand2.Parameters.AddWithValue("@totalfat", recipe.totalfat); + dbCommand2.Parameters.AddWithValue("@transfattyacids", recipe.transfattyacids); + dbCommand2.Parameters.AddWithValue("@transmonoenoicfattyacids", recipe.transmonoenoicfattyacids); + dbCommand2.Parameters.AddWithValue("@transpolyenoicfattyacids", recipe.transpolyenoicfattyacids); + dbCommand2.Parameters.AddWithValue("@tryptophan", recipe.tryptophan); + dbCommand2.Parameters.AddWithValue("@tyrosine", recipe.tyrosine); + dbCommand2.Parameters.AddWithValue("@valine", recipe.valine); + dbCommand2.Parameters.AddWithValue("@vitamina", recipe.vitamina); + dbCommand2.Parameters.AddWithValue("@vitaminb12", recipe.vitaminb12); + dbCommand2.Parameters.AddWithValue("@vitaminb6", recipe.vitaminb6); + dbCommand2.Parameters.AddWithValue("@vitaminc", recipe.vitaminc); + dbCommand2.Parameters.AddWithValue("@vitamind", recipe.vitamind); + dbCommand2.Parameters.AddWithValue("@vitamine", recipe.vitamine); + dbCommand2.Parameters.AddWithValue("@vitamink", recipe.vitamink); + dbCommand2.Parameters.AddWithValue("@volume", recipe.volume); + dbCommand2.Parameters.AddWithValue("@water", recipe.water); + dbCommand2.Parameters.AddWithValue("@webpage", recipe.webpage); + dbCommand2.Parameters.AddWithValue("@yield", recipe.yield); + dbCommand2.Parameters.AddWithValue("@zinc", recipe.zinc); + dbCommand2.Parameters.AddWithValue("@recipeID", recipe.recipeID); + + + return this.ExecuteNonQuery(dbCommand) + this.ExecuteNonQuery(dbCommand2); + } + } + } + /// + + + + public Int32 InsertRecipeIngredient(RecipeIngredient recipeIngredient) + { + using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO recipeingredient ([recipeIngredientID],[recipeID],[ingredientIndex],[ingredientText],[Heading],[linkType]," + + "[ingredientID],[quantityText],[unitText],[measureID],[measureQuantity],[linkQuality])" + + " VALUES (@recipeIngredientID,@recipeID,@ingredientIndex,@ingredientText,@Heading,@linkType,@ingredientID,@quantityText,@unitText,@measureID,@measureQuantity,@linkQuality)")) + { + + dbCommand.Parameters.AddWithValue("@recipeIngredientID", recipeIngredient.recipeIngredientID); + dbCommand.Parameters.AddWithValue("@recipeID", recipeIngredient.recipeID); + dbCommand.Parameters.AddWithValue("@ingredientIndex", recipeIngredient.ingredientIndex); + dbCommand.Parameters.AddWithValue("@ingredientText", recipeIngredient.ingredientText); + + if (recipeIngredient.isHeading) + { + dbCommand.Parameters.AddWithValue("@Heading", "Y"); + } + else + { + dbCommand.Parameters.AddWithValue("@Heading", "N"); + } + + dbCommand.Parameters.AddWithValue("@linkType", recipeIngredient.linkTypeAsString); + + if (recipeIngredient is RecipeIngredientItem) + { + var recipeIngredientItem = (RecipeIngredientItem)recipeIngredient; + dbCommand.Parameters.AddWithValue("@ingredientID", recipeIngredientItem.ingredientID ?? (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@quantityText", recipeIngredientItem.quantityText); + dbCommand.Parameters.AddWithValue("@unitText", recipeIngredientItem.unitText); + dbCommand.Parameters.AddWithValue("@measureID", recipeIngredientItem.measureID ?? (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@measureQuantity", recipeIngredientItem.measureQuantity); + dbCommand.Parameters.AddWithValue("@linkQuality", recipeIngredientItem.linkQuality); + } + else + { + dbCommand.Parameters.AddWithValue("@ingredientID", (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@quantityText", String.Empty); + dbCommand.Parameters.AddWithValue("@unitText", String.Empty); + dbCommand.Parameters.AddWithValue("@measureID", (object)DBNull.Value); + dbCommand.Parameters.AddWithValue("@measureQuantity", 0F); + dbCommand.Parameters.AddWithValue("@linkQuality", 0); + } + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 UpdateRecipeIngredient(RecipeIngredient recipeIngredient) + { + //using (OleDbCommand dbCommand = new OleDbCommand("UPDATE recipeingredient SET [recipeID]=@recipeID,[ingredientIndex]=@ingredientIndex,[ingredientText]=@ingredientText," + + // "[Heading]=@Heading,[linkType]=@linkType,[ingredientID]=@ingredientID,[quantityText]=@quantityText,[unitText]=@unitText,[measureID]=@measureID,[measureQuantity]=@measureQuantity," + + // "[linkQuality]=@linkQuality WHERE [recipeIngredientID]=@recipeIngredientID")) + //{ + // dbCommand.Parameters.AddWithValue("@recipeID", recipeIngredient.recipeID); + // dbCommand.Parameters.AddWithValue("@ingredientIndex", recipeIngredient.ingredientIndex); + // dbCommand.Parameters.AddWithValue("@ingredientText", recipeIngredient.ingredientText); + + // if (recipeIngredient.isHeading) + // { + // dbCommand.Parameters.AddWithValue("@Heading", "Y"); + // } + // else + // { + // dbCommand.Parameters.AddWithValue("@Heading", "N"); + // } + + // dbCommand.Parameters.AddWithValue("@linkType", recipeIngredient.linkTypeAsString); + + // if (recipeIngredient is RecipeIngredientItem) + // { + // var recipeIngredientItem = (RecipeIngredientItem)recipeIngredient; + // dbCommand.Parameters.AddWithValue("@ingredientID", recipeIngredientItem.ingredientID ?? (object)DBNull.Value); + // dbCommand.Parameters.AddWithValue("@quantityText", recipeIngredientItem.quantityText); + // dbCommand.Parameters.AddWithValue("@unitText", recipeIngredientItem.unitText); + // dbCommand.Parameters.AddWithValue("@measureID", recipeIngredientItem.measureID ?? (object)DBNull.Value); + // dbCommand.Parameters.AddWithValue("@measureQuantity", recipeIngredientItem.measureQuantity); + // dbCommand.Parameters.AddWithValue("@linkQuality", recipeIngredientItem.linkQuality); + // } + // else + // { + // dbCommand.Parameters.AddWithValue("@ingredientID", (object)DBNull.Value); + // dbCommand.Parameters.AddWithValue("@quantityText", String.Empty); + // dbCommand.Parameters.AddWithValue("@unitText", String.Empty); + // dbCommand.Parameters.AddWithValue("@measureID", (object)DBNull.Value); + // dbCommand.Parameters.AddWithValue("@measureQuantity", 0F); + // dbCommand.Parameters.AddWithValue("@linkQuality", 0); + // } + + // dbCommand.Parameters.AddWithValue("@recipeIngredientID", recipeIngredient.recipeIngredientID); + + + // return this.ExecuteNonQuery(dbCommand); + //} + + + + + using (OleDbCommand dbCommand = new OleDbCommand("DELETE FROM recipeingredient WHERE [recipeIngredientID]=@recipeIngredientID")) + { + dbCommand.Parameters.AddWithValue("@recipeIngredientID", recipeIngredient.recipeIngredientID); + + + this.ExecuteNonQuery(dbCommand); + } + + return InsertRecipeIngredient(recipeIngredient); + } + + public Int32 InsertRecipeProcedure(RecipeProcedure recipeProcedure) + { + using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO recipeprocedure ([recipeProcedureID],[recipeID],[procedureText],[procedureIndex],[Heading])" + + " VALUES (@recipeProcedureID,@recipeID,@procedureText,@procedureIndex,@Heading)")) + { + dbCommand.Parameters.AddWithValue("@recipeProcedureID", recipeProcedure.recipeProcedureID); + dbCommand.Parameters.AddWithValue("@recipeID", recipeProcedure.recipeID); + dbCommand.Parameters.AddWithValue("@procedureText", recipeProcedure.procedureText); + dbCommand.Parameters.AddWithValue("@procedureIndex", recipeProcedure.procedureIndex); + + if (recipeProcedure.isHeading) + { + dbCommand.Parameters.AddWithValue("@Heading", "Y"); + } + else + { + dbCommand.Parameters.AddWithValue("@Heading", "N"); + } + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 UpdateRecipeProcedure(RecipeProcedure recipeProcedure) + { + ////using (OleDbCommand dbCommand = new OleDbCommand("UPDATE recipeprocedure SET [recipeID]=@recipeID,[procedureText]=@procedureText,[procedureIndex]=@procedureIndex,[Heading]=@Heading" + + //// " WHERE [recipeProcedureID]=@recipeProcedureID")) + ////{ + //// dbCommand.Parameters.AddWithValue("@recipeID", recipeProcedure.recipeID); + //// dbCommand.Parameters.AddWithValue("@procedureText", recipeProcedure.procedureText); + //// dbCommand.Parameters.AddWithValue("@procedureIndex", recipeProcedure.procedureIndex); + + //// if (recipeProcedure.isHeading) + //// { + //// dbCommand.Parameters.AddWithValue("@Heading", "Y"); + //// } + //// else + //// { + //// dbCommand.Parameters.AddWithValue("@Heading", "N"); + //// } + + //// dbCommand.Parameters.AddWithValue("@recipeProcedureID", recipeProcedure.recipeProcedureID); + + //// return this.ExecuteNonQuery(dbCommand); + ////} + + + using (OleDbCommand dbCommand = new OleDbCommand("DELETE FROM recipeprocedure WHERE [recipeProcedureID]=@recipeProcedureID")) + { + dbCommand.Parameters.AddWithValue("@recipeProcedureID", recipeProcedure.recipeProcedureID); + + this.ExecuteNonQuery(dbCommand); + } + + return InsertRecipeProcedure(recipeProcedure); + } + + public Int32 InsertRecipeTip(RecipeTip recipeTip) + { + using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO recipetip ([recipeTipID],[recipeID],[tipText],[tipIndex],[Heading])" + + " VALUES (@recipeTipID,@recipeID,@tipText,@tipIndex,@Heading)")) + { + dbCommand.Parameters.AddWithValue("@recipeTipID", recipeTip.recipeTipID); + dbCommand.Parameters.AddWithValue("@recipeID", recipeTip.recipeID); + dbCommand.Parameters.AddWithValue("@tipText", recipeTip.tipText); + dbCommand.Parameters.AddWithValue("@tipIndex", recipeTip.tipIndex); + + if (recipeTip.isHeading) + { + dbCommand.Parameters.AddWithValue("@Heading", "Y"); + } + else + { + dbCommand.Parameters.AddWithValue("@Heading", "N"); + } + + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 UpdateRecipeTip(RecipeTip recipeTip) + { + //using (OleDbCommand dbCommand = new OleDbCommand("UPDATE recipetip SET [recipeID]=@recipeID,[tipText]=@tipText,[tipIndex]=@tipIndex,[Heading]=@Heading" + + // " WHERE [recipeTipID]=@recipeTipID")) + //{ + // dbCommand.Parameters.AddWithValue("@recipeID", recipeTip.recipeID); + // dbCommand.Parameters.AddWithValue("@tipText", recipeTip.tipText); + // dbCommand.Parameters.AddWithValue("@tipIndex", recipeTip.tipIndex); + + // if (recipeTip.isHeading) + // { + // dbCommand.Parameters.AddWithValue("@Heading", "Y"); + // } + // else + // { + // dbCommand.Parameters.AddWithValue("@Heading", "N"); + // } + + // dbCommand.Parameters.AddWithValue("@recipeTipID", recipeTip.recipeTipID); + + // return this.ExecuteNonQuery(dbCommand); + //} + + + using (OleDbCommand dbCommand = new OleDbCommand("DELETE FROM recipetip WHERE [recipeTipID]=@recipeTipID")) + { + dbCommand.Parameters.AddWithValue("@recipeTipID", recipeTip.recipeTipID); + + this.ExecuteNonQuery(dbCommand); + } + + return InsertRecipeTip(recipeTip); + } + + public DataSet GetIngredientUsageByID(Guid ingredientUsageID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredientusage where ingredientusageid=@ingredientusageid")) + { + dbCommand.Parameters.AddWithValue("@ingredientusageid", ingredientUsageID); + + return this.ExecuteDataSet(dbCommand); + } + + } + + public DataSet GetIngredientUsageByNameAndIngredientID(String normalizedIngredientName, Guid ingredientID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredientusage where normalizedingredientname=@normalizedingredientname AND ingredientid=@ingredientID")) + { + dbCommand.Parameters.AddWithValue("@normalizedingredientname", normalizedIngredientName); + dbCommand.Parameters.AddWithValue("@ingredientid", ingredientID); + + return this.ExecuteDataSet(dbCommand); + } + + } + + public DataSet GetIngredientUsageAll() + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredientusage")) + { + return this.ExecuteDataSet(dbCommand); + } + + } + + public Int32 DeleteIngredientUsageAll() + { + using (OleDbCommand dbCommand = new OleDbCommand("DELETE FROM ingredientusage")) + { + return this.ExecuteNonQuery(dbCommand); + } + } + + public Int32 InsertIngredientUsage(IngredientUsage ingredientUsage) + { + using (OleDbCommand dbCommand = new OleDbCommand("INSERT INTO ingredientUsage ([ingredientusageid],[normalizedingredientname],[ingredientID],[usagecount]) VALUES (@ingredientusageID,@normalizedingredientname,@ingredientID,@usagecount)")) + { + dbCommand.Parameters.AddWithValue("@ingredientusageID", ingredientUsage.ingredientUsageID); + dbCommand.Parameters.AddWithValue("@normalizedingredientname", ingredientUsage.normalizedIngredientName); + dbCommand.Parameters.AddWithValue("@ingredientID", ingredientUsage.ingredientID); + dbCommand.Parameters.AddWithValue("@usagecount", ingredientUsage.usageCount); + + return this.ExecuteNonQuery(dbCommand); + } + } + public Int32 UpdateIngredientUsage(IngredientUsage ingredientUsage) + { + using (OleDbCommand dbCommand = new OleDbCommand("DELETE FROM ingredientusage WHERE [ingredientusageID]=@ingredientusageID")) + { + dbCommand.Parameters.AddWithValue("@ingredientusageID", ingredientUsage.ingredientUsageID); + + this.ExecuteNonQuery(dbCommand); + } + + return InsertIngredientUsage(ingredientUsage); + } + + public DataSet GetIngredientSkipSearchWordByID(Guid wordID) + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredientskipsearchword where wordid=@wordid")) + { + dbCommand.Parameters.AddWithValue("@wordID", wordID); + + return this.ExecuteDataSet(dbCommand); + } + + } + + public DataSet GetAllIngredientSkipSearchWords() + { + using (OleDbCommand dbCommand = new OleDbCommand("select * from ingredientskipsearchword order by word")) + { + return this.ExecuteDataSet(dbCommand); + } + } + + public Guid GetNewIDCookbook() + { + return Guid.NewGuid(); + } + + public Guid GetNewIDCookbookChapter() + { + return Guid.NewGuid(); + } + + public Guid GetNewIDRecipe() + { + return Guid.NewGuid(); + } + + public Guid GetNewIDRecipeIngredient() + { + return Guid.NewGuid(); + } + + public Guid GetNewIDRecipeProcedure() + { + return Guid.NewGuid(); + } + + public Guid GetNewIDRecipeTip() + { + return Guid.NewGuid(); + } + + public Guid GetNewIDIngredientUsage() + { + return Guid.NewGuid(); + } + + + public Int32 JRJRUpdateAdhoc(String strCommand) + { + using (OleDbCommand dbCommand = new OleDbCommand(strCommand)) + { + return this.ExecuteNonQuery(dbCommand); + } + } + + public DataSet JRJRSelectAdhoc(String strCommand) + { + using (OleDbCommand dbCommand = new OleDbCommand(strCommand)) + { + return this.ExecuteDataSet(dbCommand); + } + } + +} diff --git a/JRCookbookBusiness/clsDatabaseLayerBase.cs b/JRCookbookBusiness/clsDatabaseLayerBase.cs new file mode 100644 index 0000000..175c65b --- /dev/null +++ b/JRCookbookBusiness/clsDatabaseLayerBase.cs @@ -0,0 +1,171 @@ +using System; +using System.Diagnostics; +using System.Data; +using System.Data.OleDb; +using JRCookbookBusiness; + +public class clsDatabaseLayerBase : IDisposable + +{ + private OleDbConnection m_dbcnctConnection; + private bool disposedValue; + + //public static String DockerHostMachineIpAddress => Dns.GetHostAddresses(new Uri("http://host.docker.internal").Host)[0].ToString(); + + protected bool OpenDatabaseConnection() + { + try + { + if (m_dbcnctConnection != null) + return true; + m_dbcnctConnection = new OleDbConnection(); + // m_dbcnctConnection.ConnectionString = "Persist Security Info=False;Integrated Security=SSPI;database=OrganLit;server=REUSS\SQLEXPRESS;Connect Timeout=30" + // m_dbcnctConnection.ConnectionString = "Persist Security Info=False;Integrated Security=False;User ID=OrganLitDBLogin;Password=OrganLitDBL0gin7;database=OrganLit;server=SIRJON\\REUSSSQL;Connect Timeout=30" + //m_dbcnctConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data source=\"" + "C:\\ReussData\\lc50.mdb" + "\""; + m_dbcnctConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\ReussData\\lc50.mdb"; + //m_dbcnctConnection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data source=" + "C:\\ReussData\\lc50.mdb"; + //m_dbcnctConnection.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)}; Dbq=C:/ReussData/lc50.mdb; Uid = Admin; Pwd =; "; + //m_dbcnctConnection.ConnectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)}; Dbq=C:/ReussData/lc50.mdb;"; + // m_dbcnctConnection.ConnectionString = "Data Source=tcp:bu7zkus8nd.database.windows.net,1433;Initial Catalog=OrganLitDB;User Id=OrganLitDBUser@bu7zkus8nd;Password=ILamfi0gAdm;"; + m_dbcnctConnection.Open(); + return true; + } + catch (OleDbException e) + { + m_dbcnctConnection = null; + Debug.Print("Error in OpenDatabaseConnection: " + e.Message); + //return false; + throw; + } + catch (Exception e) + { + m_dbcnctConnection = null; + Debug.Print("Error in OpenDatabaseConnection: " + e.Message); + //return false; + throw; + } + } + + protected bool CloseDatabaseConnection() + { + try + { + if (m_dbcnctConnection != null) + { + m_dbcnctConnection.Close(); + m_dbcnctConnection.Dispose(); + m_dbcnctConnection = null; + } + return true; + } + catch (OleDbException e) + { + Debug.Print("Error in CloseDatabaseConnection: " + e.Message); + return false; + } + catch (Exception e) + { + Debug.Print("Error in CloseDatabaseConnection: " + e.Message); + return false; + } + } + + protected DataSet ExecuteDataSet(OleDbCommand objOleDbCommand) + { + try + { + if (OpenDatabaseConnection() == false) + throw new ApplicationException("Database not opened"); + objOleDbCommand.Connection = m_dbcnctConnection; + OleDbDataAdapter ldbdaDataAdapter = new OleDbDataAdapter(); + ldbdaDataAdapter.SelectCommand = objOleDbCommand; + DataSet ldbdsDataSet = new DataSet(); + ldbdaDataAdapter.Fill(ldbdsDataSet); + + return ldbdsDataSet; + } + catch (OleDbException e) + { + //Debug.Print("Error in ExecuteDataSet: Procedure=" + e.Procedure + Constants.CRLF + "Error=" + e.Message); + Debug.Print("Error in ExecuteDataSet: Error=" + e.Message); + //return null/* TODO Change to default(_) if this is not a reference type */; + throw; + } + catch (Exception e) + { + Debug.Print("Error in ExecuteDataSet: " + e.Message); + //return null/* TODO Change to default(_) if this is not a reference type */; + throw; + } + //finally + //{ + // if (m_dbcnctConnection != null) + // { + // m_dbcnctConnection.Dispose(); + // m_dbcnctConnection = null; + // } + //} + } + + protected Int32 ExecuteNonQuery(OleDbCommand objOleDbCommand) + { + // Returns rows affected + + try + { + if (OpenDatabaseConnection() == false) + throw new ApplicationException("Database not opened"); + objOleDbCommand.Connection = m_dbcnctConnection; + Int32 lintRowsAffected = objOleDbCommand.ExecuteNonQuery(); + + return lintRowsAffected; + } + catch (OleDbException e) + { + //Debug.Print("Error in ExecuteNonQuery: Procedure=" + e.Procedure + Constants.CRLF + "Error=" + e.Message); + Debug.Print("Error in ExecuteNonQuery: Error=" + e.Message); + //return 0; + throw; + } + catch (Exception e) + { + Debug.Print("Error in ExecuteNonQuery: " + e.Message); + //return 0; + throw; + } + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + if (m_dbcnctConnection != null) + { + m_dbcnctConnection.Dispose(); + m_dbcnctConnection = null; + } + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + disposedValue = true; + } + } + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~clsDatabaseLayerBase() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } + + void IDisposable.Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } +} diff --git a/JRCookbookBusiness/clsDiacriticRemover.cs b/JRCookbookBusiness/clsDiacriticRemover.cs new file mode 100644 index 0000000..df123c8 --- /dev/null +++ b/JRCookbookBusiness/clsDiacriticRemover.cs @@ -0,0 +1,376 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookBusiness +{ + public static class clsDiacriticRemover + { + private static Char[] mc_Convert; + + /// + /// This function is ultra fast because it uses a lookup table. + /// This function does not depend on Windows functionality. It also works on Linux. + /// This function removes all diacritics, accents, etc. + /// For example "Crème Brûlée mit Soße" is converted to "Creme Brulee mit Sosse". + /// + public static String RemoveDiacritics(String s_Text) + { + StringBuilder i_Out = new StringBuilder(s_Text.Length); + foreach (Char c_Char in s_Text) + { + /* This switch statement is optional! + switch (c_Char) + { + // If you like you can add your own conversions, like here for German. + // Otherwise remove this switch and 'ä' will be translated to 'a', etc. + case 'ä': i_Out.Append("ae"); continue; + case 'ö': i_Out.Append("oe"); continue; + case 'ü': i_Out.Append("ue"); continue; + case 'Ä': i_Out.Append("Ae"); continue; + case 'Ö': i_Out.Append("Oe"); continue; + case 'Ü': i_Out.Append("Ue"); continue; + case 'ß': i_Out.Append("ss"); continue; + } */ + + if (c_Char < mc_Convert.Length) + i_Out.Append(mc_Convert[c_Char]); + else + i_Out.Append(c_Char); + } + return i_Out.ToString(); + } + + // static constructor + // See https://www.compart.com/en/unicode/U+0180 + static clsDiacriticRemover() + { + mc_Convert = new Char[0x270]; + + // Fill char array with translation of each character to itself + for (int i = 0; i < 0x270; i++) + { + mc_Convert[i] = (Char)i; + } + + // Store the replacements for 310 special characters + #region Fill mc_Convert + + mc_Convert[0x0C0] = 'A'; // À + mc_Convert[0x0C1] = 'A'; // Á + mc_Convert[0x0C2] = 'A'; //  + mc_Convert[0x0C3] = 'A'; // à + mc_Convert[0x0C4] = 'A'; // Ä + mc_Convert[0x0C5] = 'A'; // Å + mc_Convert[0x0C6] = 'A'; // Æ + mc_Convert[0x0C7] = 'C'; // Ç + mc_Convert[0x0C8] = 'E'; // È + mc_Convert[0x0C9] = 'E'; // É + mc_Convert[0x0CA] = 'E'; // Ê + mc_Convert[0x0CB] = 'E'; // Ë + mc_Convert[0x0CC] = 'I'; // Ì + mc_Convert[0x0CD] = 'I'; // Í + mc_Convert[0x0CE] = 'I'; // Î + mc_Convert[0x0CF] = 'I'; // Ï + mc_Convert[0x0D0] = 'D'; // Ð + mc_Convert[0x0D1] = 'N'; // Ñ + mc_Convert[0x0D2] = 'O'; // Ò + mc_Convert[0x0D3] = 'O'; // Ó + mc_Convert[0x0D4] = 'O'; // Ô + mc_Convert[0x0D5] = 'O'; // Õ + mc_Convert[0x0D6] = 'O'; // Ö + mc_Convert[0x0D8] = 'O'; // Ø + mc_Convert[0x0D9] = 'U'; // Ù + mc_Convert[0x0DA] = 'U'; // Ú + mc_Convert[0x0DB] = 'U'; // Û + mc_Convert[0x0DC] = 'U'; // Ü + mc_Convert[0x0DD] = 'Y'; // Ý + mc_Convert[0x0DF] = 's'; // ß + mc_Convert[0x0E0] = 'a'; // à + mc_Convert[0x0E1] = 'a'; // á + mc_Convert[0x0E2] = 'a'; // â + mc_Convert[0x0E3] = 'a'; // ã + mc_Convert[0x0E4] = 'a'; // ä + mc_Convert[0x0E5] = 'a'; // å + mc_Convert[0x0E6] = 'a'; // æ + mc_Convert[0x0E7] = 'c'; // ç + mc_Convert[0x0E8] = 'e'; // è + mc_Convert[0x0E9] = 'e'; // é + mc_Convert[0x0EA] = 'e'; // ê + mc_Convert[0x0EB] = 'e'; // ë + mc_Convert[0x0EC] = 'i'; // ì + mc_Convert[0x0ED] = 'i'; // í + mc_Convert[0x0EE] = 'i'; // î + mc_Convert[0x0EF] = 'i'; // ï + mc_Convert[0x0F1] = 'n'; // ñ + mc_Convert[0x0F2] = 'o'; // ò + mc_Convert[0x0F3] = 'o'; // ó + mc_Convert[0x0F4] = 'o'; // ô + mc_Convert[0x0F5] = 'o'; // õ + mc_Convert[0x0F6] = 'o'; // ö + mc_Convert[0x0F8] = 'o'; // ø + mc_Convert[0x0F9] = 'u'; // ù + mc_Convert[0x0FA] = 'u'; // ú + mc_Convert[0x0FB] = 'u'; // û + mc_Convert[0x0FC] = 'u'; // ü + mc_Convert[0x0FD] = 'y'; // ý + mc_Convert[0x0FF] = 'y'; // ÿ + mc_Convert[0x100] = 'A'; // Ā + mc_Convert[0x101] = 'a'; // ā + mc_Convert[0x102] = 'A'; // Ă + mc_Convert[0x103] = 'a'; // ă + mc_Convert[0x104] = 'A'; // Ą + mc_Convert[0x105] = 'a'; // ą + mc_Convert[0x106] = 'C'; // Ć + mc_Convert[0x107] = 'c'; // ć + mc_Convert[0x108] = 'C'; // Ĉ + mc_Convert[0x109] = 'c'; // ĉ + mc_Convert[0x10A] = 'C'; // Ċ + mc_Convert[0x10B] = 'c'; // ċ + mc_Convert[0x10C] = 'C'; // Č + mc_Convert[0x10D] = 'c'; // č + mc_Convert[0x10E] = 'D'; // Ď + mc_Convert[0x10F] = 'd'; // ď + mc_Convert[0x110] = 'D'; // Đ + mc_Convert[0x111] = 'd'; // đ + mc_Convert[0x112] = 'E'; // Ē + mc_Convert[0x113] = 'e'; // ē + mc_Convert[0x114] = 'E'; // Ĕ + mc_Convert[0x115] = 'e'; // ĕ + mc_Convert[0x116] = 'E'; // Ė + mc_Convert[0x117] = 'e'; // ė + mc_Convert[0x118] = 'E'; // Ę + mc_Convert[0x119] = 'e'; // ę + mc_Convert[0x11A] = 'E'; // Ě + mc_Convert[0x11B] = 'e'; // ě + mc_Convert[0x11C] = 'G'; // Ĝ + mc_Convert[0x11D] = 'g'; // ĝ + mc_Convert[0x11E] = 'G'; // Ğ + mc_Convert[0x11F] = 'g'; // ğ + mc_Convert[0x120] = 'G'; // Ġ + mc_Convert[0x121] = 'g'; // ġ + mc_Convert[0x122] = 'G'; // Ģ + mc_Convert[0x123] = 'g'; // ģ + mc_Convert[0x124] = 'H'; // Ĥ + mc_Convert[0x125] = 'h'; // ĥ + mc_Convert[0x126] = 'H'; // Ħ + mc_Convert[0x127] = 'h'; // ħ + mc_Convert[0x128] = 'I'; // Ĩ + mc_Convert[0x129] = 'i'; // ĩ + mc_Convert[0x12A] = 'I'; // Ī + mc_Convert[0x12B] = 'i'; // ī + mc_Convert[0x12C] = 'I'; // Ĭ + mc_Convert[0x12D] = 'i'; // ĭ + mc_Convert[0x12E] = 'I'; // Į + mc_Convert[0x12F] = 'i'; // į + mc_Convert[0x130] = 'I'; // İ + mc_Convert[0x131] = 'i'; // ı + mc_Convert[0x134] = 'J'; // Ĵ + mc_Convert[0x135] = 'j'; // ĵ + mc_Convert[0x136] = 'K'; // Ķ + mc_Convert[0x137] = 'k'; // ķ + mc_Convert[0x138] = 'K'; // ĸ + mc_Convert[0x139] = 'L'; // Ĺ + mc_Convert[0x13A] = 'l'; // ĺ + mc_Convert[0x13B] = 'L'; // Ļ + mc_Convert[0x13C] = 'l'; // ļ + mc_Convert[0x13D] = 'L'; // Ľ + mc_Convert[0x13E] = 'l'; // ľ + mc_Convert[0x13F] = 'L'; // Ŀ + mc_Convert[0x140] = 'l'; // ŀ + mc_Convert[0x141] = 'L'; // Ł + mc_Convert[0x142] = 'l'; // ł + mc_Convert[0x143] = 'N'; // Ń + mc_Convert[0x144] = 'n'; // ń + mc_Convert[0x145] = 'N'; // Ņ + mc_Convert[0x146] = 'n'; // ņ + mc_Convert[0x147] = 'N'; // Ň + mc_Convert[0x148] = 'n'; // ň + mc_Convert[0x149] = 'n'; // ʼn + mc_Convert[0x14C] = 'O'; // Ō + mc_Convert[0x14D] = 'o'; // ō + mc_Convert[0x14E] = 'O'; // Ŏ + mc_Convert[0x14F] = 'o'; // ŏ + mc_Convert[0x150] = 'O'; // Ő + mc_Convert[0x151] = 'o'; // ő + mc_Convert[0x152] = 'O'; // Œ + mc_Convert[0x153] = 'o'; // œ + mc_Convert[0x154] = 'R'; // Ŕ + mc_Convert[0x155] = 'r'; // ŕ + mc_Convert[0x156] = 'R'; // Ŗ + mc_Convert[0x157] = 'r'; // ŗ + mc_Convert[0x158] = 'R'; // Ř + mc_Convert[0x159] = 'r'; // ř + mc_Convert[0x15A] = 'S'; // Ś + mc_Convert[0x15B] = 's'; // ś + mc_Convert[0x15C] = 'S'; // Ŝ + mc_Convert[0x15D] = 's'; // ŝ + mc_Convert[0x15E] = 'S'; // Ş + mc_Convert[0x15F] = 's'; // ş + mc_Convert[0x160] = 'S'; // Š + mc_Convert[0x161] = 's'; // š + mc_Convert[0x162] = 'T'; // Ţ + mc_Convert[0x163] = 't'; // ţ + mc_Convert[0x164] = 'T'; // Ť + mc_Convert[0x165] = 't'; // ť + mc_Convert[0x166] = 'T'; // Ŧ + mc_Convert[0x167] = 't'; // ŧ + mc_Convert[0x168] = 'U'; // Ũ + mc_Convert[0x169] = 'u'; // ũ + mc_Convert[0x16A] = 'U'; // Ū + mc_Convert[0x16B] = 'u'; // ū + mc_Convert[0x16C] = 'U'; // Ŭ + mc_Convert[0x16D] = 'u'; // ŭ + mc_Convert[0x16E] = 'U'; // Ů + mc_Convert[0x16F] = 'u'; // ů + mc_Convert[0x170] = 'U'; // Ű + mc_Convert[0x171] = 'u'; // ű + mc_Convert[0x172] = 'U'; // Ų + mc_Convert[0x173] = 'u'; // ų + mc_Convert[0x174] = 'W'; // Ŵ + mc_Convert[0x175] = 'w'; // ŵ + mc_Convert[0x176] = 'Y'; // Ŷ + mc_Convert[0x177] = 'y'; // ŷ + mc_Convert[0x178] = 'Y'; // Ÿ + mc_Convert[0x179] = 'Z'; // Ź + mc_Convert[0x17A] = 'z'; // ź + mc_Convert[0x17B] = 'Z'; // Ż + mc_Convert[0x17C] = 'z'; // ż + mc_Convert[0x17D] = 'Z'; // Ž + mc_Convert[0x17E] = 'z'; // ž + mc_Convert[0x180] = 'b'; // ƀ + mc_Convert[0x189] = 'D'; // Ɖ + mc_Convert[0x191] = 'F'; // Ƒ + mc_Convert[0x192] = 'f'; // ƒ + mc_Convert[0x193] = 'G'; // Ɠ + mc_Convert[0x197] = 'I'; // Ɨ + mc_Convert[0x198] = 'K'; // Ƙ + mc_Convert[0x199] = 'k'; // ƙ + mc_Convert[0x19A] = 'l'; // ƚ + mc_Convert[0x19F] = 'O'; // Ɵ + mc_Convert[0x1A0] = 'O'; // Ơ + mc_Convert[0x1A1] = 'o'; // ơ + mc_Convert[0x1AB] = 't'; // ƫ + mc_Convert[0x1AC] = 'T'; // Ƭ + mc_Convert[0x1AD] = 't'; // ƭ + mc_Convert[0x1AE] = 'T'; // Ʈ + mc_Convert[0x1AF] = 'U'; // Ư + mc_Convert[0x1B0] = 'u'; // ư + mc_Convert[0x1B6] = 'z'; // ƶ + mc_Convert[0x1CD] = 'A'; // Ǎ + mc_Convert[0x1CE] = 'a'; // ǎ + mc_Convert[0x1CF] = 'I'; // Ǐ + mc_Convert[0x1D0] = 'i'; // ǐ + mc_Convert[0x1D1] = 'O'; // Ǒ + mc_Convert[0x1D2] = 'o'; // ǒ + mc_Convert[0x1D3] = 'U'; // Ǔ + mc_Convert[0x1D4] = 'u'; // ǔ + mc_Convert[0x1D5] = 'U'; // Ǖ + mc_Convert[0x1D6] = 'u'; // ǖ + mc_Convert[0x1D7] = 'U'; // Ǘ + mc_Convert[0x1D8] = 'u'; // ǘ + mc_Convert[0x1D9] = 'U'; // Ǚ + mc_Convert[0x1DA] = 'u'; // ǚ + mc_Convert[0x1DB] = 'U'; // Ǜ + mc_Convert[0x1DC] = 'u'; // ǜ + mc_Convert[0x1DE] = 'A'; // Ǟ + mc_Convert[0x1DF] = 'a'; // ǟ + mc_Convert[0x1E0] = 'A'; // Ǡ + mc_Convert[0x1E1] = 'a'; // ǡ + mc_Convert[0x1E2] = 'A'; // Ǣ + mc_Convert[0x1E3] = 'a'; // ǣ + mc_Convert[0x1E4] = 'G'; // Ǥ + mc_Convert[0x1E5] = 'g'; // ǥ + mc_Convert[0x1E6] = 'G'; // Ǧ + mc_Convert[0x1E7] = 'g'; // ǧ + mc_Convert[0x1E8] = 'K'; // Ǩ + mc_Convert[0x1E9] = 'k'; // ǩ + mc_Convert[0x1EA] = 'O'; // Ǫ + mc_Convert[0x1EB] = 'o'; // ǫ + mc_Convert[0x1EC] = 'O'; // Ǭ + mc_Convert[0x1ED] = 'o'; // ǭ + mc_Convert[0x1F0] = 'j'; // ǰ + mc_Convert[0x1F4] = 'G'; // Ǵ + mc_Convert[0x1F5] = 'g'; // ǵ + mc_Convert[0x1F8] = 'N'; // Ǹ + mc_Convert[0x1F9] = 'n'; // ǹ + mc_Convert[0x1FA] = 'A'; // Ǻ + mc_Convert[0x1FB] = 'a'; // ǻ + mc_Convert[0x1FC] = 'A'; // Ǽ + mc_Convert[0x1FD] = 'a'; // ǽ + mc_Convert[0x1FE] = 'O'; // Ǿ + mc_Convert[0x1FF] = 'o'; // ǿ + mc_Convert[0x200] = 'A'; // Ȁ + mc_Convert[0x201] = 'a'; // ȁ + mc_Convert[0x202] = 'A'; // Ȃ + mc_Convert[0x203] = 'A'; // ȃ + mc_Convert[0x204] = 'E'; // Ȅ + mc_Convert[0x205] = 'e'; // ȅ + mc_Convert[0x206] = 'E'; // Ȇ + mc_Convert[0x207] = 'e'; // ȇ + mc_Convert[0x208] = 'I'; // Ȉ + mc_Convert[0x209] = 'i'; // ȉ + mc_Convert[0x20A] = 'I'; // Ȋ + mc_Convert[0x20B] = 'i'; // ȋ + mc_Convert[0x20C] = 'O'; // Ȍ + mc_Convert[0x20D] = 'o'; // ȍ + mc_Convert[0x20E] = 'O'; // Ȏ + mc_Convert[0x20F] = 'o'; // ȏ + mc_Convert[0x210] = 'R'; // Ȑ + mc_Convert[0x211] = 'r'; // ȑ + mc_Convert[0x212] = 'R'; // Ȓ + mc_Convert[0x213] = 'r'; // ȓ + mc_Convert[0x214] = 'U'; // Ȕ + mc_Convert[0x215] = 'u'; // ȕ + mc_Convert[0x216] = 'U'; // Ȗ + mc_Convert[0x217] = 'u'; // ȗ + mc_Convert[0x218] = 'S'; // Ș + mc_Convert[0x219] = 's'; // ș + mc_Convert[0x21A] = 'T'; // Ț + mc_Convert[0x21B] = 't'; // ț + mc_Convert[0x21E] = 'H'; // Ȟ + mc_Convert[0x21F] = 'h'; // ȟ + mc_Convert[0x224] = 'Z'; // Ȥ + mc_Convert[0x225] = 'z'; // ȥ + mc_Convert[0x226] = 'A'; // Ȧ + mc_Convert[0x227] = 'a'; // ȧ + mc_Convert[0x228] = 'E'; // Ȩ + mc_Convert[0x229] = 'e'; // ȩ + mc_Convert[0x22A] = 'O'; // Ȫ + mc_Convert[0x22B] = 'o'; // ȫ + mc_Convert[0x22C] = 'O'; // Ȭ + mc_Convert[0x22D] = 'o'; // ȭ + mc_Convert[0x22E] = 'O'; // Ȯ + mc_Convert[0x22F] = 'o'; // ȯ + mc_Convert[0x230] = 'O'; // Ȱ + mc_Convert[0x231] = 'o'; // ȱ + mc_Convert[0x232] = 'Y'; // Ȳ + mc_Convert[0x233] = 'y'; // ȳ + mc_Convert[0x234] = 'l'; // ȴ + mc_Convert[0x235] = 'n'; // ȵ + mc_Convert[0x23A] = 'A'; // Ⱥ + mc_Convert[0x23B] = 'C'; // Ȼ + mc_Convert[0x23C] = 'c'; // ȼ + mc_Convert[0x23D] = 'L'; // Ƚ + mc_Convert[0x23E] = 'T'; // Ⱦ + mc_Convert[0x23F] = 's'; // ȿ + mc_Convert[0x240] = 'z'; // ɀ + mc_Convert[0x243] = 'B'; // Ƀ + mc_Convert[0x244] = 'U'; // Ʉ + mc_Convert[0x246] = 'E'; // Ɇ + mc_Convert[0x247] = 'e'; // ɇ + mc_Convert[0x248] = 'J'; // Ɉ + mc_Convert[0x249] = 'j'; // ɉ + mc_Convert[0x24C] = 'R'; // Ɍ + mc_Convert[0x24D] = 'r'; // ɍ + mc_Convert[0x24E] = 'Y'; // Ɏ + mc_Convert[0x24F] = 'y'; // ɏ + mc_Convert[0x261] = 'g'; // ɡ + + #endregion + } + } + +} diff --git a/JRCookbookBusiness/clsWord.cs b/JRCookbookBusiness/clsWord.cs new file mode 100644 index 0000000..6bb303a --- /dev/null +++ b/JRCookbookBusiness/clsWord.cs @@ -0,0 +1,128 @@ +using Microsoft.Office.Interop.Word; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using static System.Net.Mime.MediaTypeNames; +using System.Windows.Media.Animation; + +namespace JRCookbookBusiness +{ + internal static class clsWord + { + private static Microsoft.Office.Interop.Word.Application mobjWord; + private static bool mblnWordRunning = false; + + internal const int WORD_CHAPTER_NAME_FONT_SIZE = 18; + internal const int WORD_RECIPE_NAME_FONT_SIZE = 18; + internal const int WORD_RECIPE_SECTION_HEADING_FONT_SIZE = 14; + internal const int WORD_NORMAL_FONT_SIZE = 10; + internal const int WORD_NUTRITION_FONT_SIZE = 8; + + internal static Microsoft.Office.Interop.Word.Application WordApplication { get { return mobjWord; } } + + internal static void AddHalfSpaceLineAtEndOfDocument() + { + mobjWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + mobjWord.Selection.TypeParagraph(); + mobjWord.Selection.MoveUp(Microsoft.Office.Interop.Word.WdUnits.wdLine, 1); + mobjWord.Selection.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle; + mobjWord.Selection.ParagraphFormat.LineSpacing = 4F; + mobjWord.Selection.ParagraphFormat.SpaceAfter = 0F; + mobjWord.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory); + } + + internal static void Insert_HeaderText(String headerText) + { + if (mobjWord.ActiveWindow.View.SplitSpecial != WdSpecialPane.wdPaneNone) + { + mobjWord.ActiveWindow.Panes[2].Close(); + } + + if (mobjWord.ActiveWindow.ActivePane.View.Type == WdViewType.wdNormalView || mobjWord.ActiveWindow.ActivePane.View.Type == WdViewType.wdOutlineView) + { + mobjWord.ActiveWindow.ActivePane.View.Type = WdViewType.wdPrintView; + } + + mobjWord.Selection.Sections[1].Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false; + + mobjWord.ActiveWindow.ActivePane.View.SeekView = WdSeekView.wdSeekCurrentPageHeader; + mobjWord.Selection.WholeStory(); + mobjWord.Selection.Delete(Microsoft.Office.Interop.Word.WdUnits.wdCharacter, 1); + + mobjWord.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter; + + mobjWord.Selection.TypeText(headerText); + + mobjWord.ActiveWindow.ActivePane.View.SeekView = WdSeekView.wdSeekMainDocument; + + } + + internal static void Insert_PageNumberFooter(ref bool isFirstPageOfContent) + { + if (mobjWord.ActiveWindow.View.SplitSpecial != WdSpecialPane.wdPaneNone) + { + mobjWord.ActiveWindow.Panes[2].Close(); + } + + if (mobjWord.ActiveWindow.ActivePane.View.Type == WdViewType.wdNormalView || mobjWord.ActiveWindow.ActivePane.View.Type == WdViewType.wdOutlineView) + { + mobjWord.ActiveWindow.ActivePane.View.Type = WdViewType.wdPrintView; + } + + mobjWord.ActiveWindow.ActivePane.View.SeekView = WdSeekView.wdSeekCurrentPageFooter; + + mobjWord.Selection.WholeStory(); + mobjWord.Selection.Delete(Microsoft.Office.Interop.Word.WdUnits.wdCharacter, 1); + + if (isFirstPageOfContent) + { + mobjWord.Selection.HeaderFooter.PageNumbers.RestartNumberingAtSection = true; + mobjWord.Selection.HeaderFooter.PageNumbers.StartingNumber = 1; + + isFirstPageOfContent = false; + } + else + { + mobjWord.Selection.HeaderFooter.PageNumbers.RestartNumberingAtSection = false; + } + + mobjWord.Selection.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter; + + mobjWord.Selection.TypeText("Page "); + mobjWord.Selection.Fields.Add(mobjWord.Selection.Range, Microsoft.Office.Interop.Word.WdFieldType.wdFieldEmpty, "PAGE \\* Arabic ", 1); + + mobjWord.ActiveWindow.ActivePane.View.SeekView = WdSeekView.wdSeekMainDocument; + + } + + + internal static void ResetWord() + { + if (mblnWordRunning) + { + ShutDownWord(); + } + + mobjWord = new Microsoft.Office.Interop.Word.Application(); + mobjWord.Visible = false; + //mobjWord.Activate(); + //mobjWord.WindowState = Microsoft.Office.Interop.Word.WdWindowState.wdWindowStateMinimize; + + mblnWordRunning= true; + } + + internal static void ShutDownWord() + { + if (mblnWordRunning) + { + mobjWord.Quit(); + mobjWord = null; + mblnWordRunning = false; + } + } + + } +} diff --git a/JRCookbookControls/Bar0.bmp b/JRCookbookControls/Bar0.bmp new file mode 100644 index 0000000..a89f74f Binary files /dev/null and b/JRCookbookControls/Bar0.bmp differ diff --git a/JRCookbookControls/Bar1.bmp b/JRCookbookControls/Bar1.bmp new file mode 100644 index 0000000..325a7ad Binary files /dev/null and b/JRCookbookControls/Bar1.bmp differ diff --git a/JRCookbookControls/Bar2.bmp b/JRCookbookControls/Bar2.bmp new file mode 100644 index 0000000..81c57d3 Binary files /dev/null and b/JRCookbookControls/Bar2.bmp differ diff --git a/JRCookbookControls/Bar3.bmp b/JRCookbookControls/Bar3.bmp new file mode 100644 index 0000000..bbec9ea Binary files /dev/null and b/JRCookbookControls/Bar3.bmp differ diff --git a/JRCookbookControls/Bar4.bmp b/JRCookbookControls/Bar4.bmp new file mode 100644 index 0000000..c5373fa Binary files /dev/null and b/JRCookbookControls/Bar4.bmp differ diff --git a/JRCookbookControls/Delete.bmp b/JRCookbookControls/Delete.bmp new file mode 100644 index 0000000..8efa906 Binary files /dev/null and b/JRCookbookControls/Delete.bmp differ diff --git a/JRCookbookControls/Handle.bmp b/JRCookbookControls/Handle.bmp new file mode 100644 index 0000000..4ca03c6 Binary files /dev/null and b/JRCookbookControls/Handle.bmp differ diff --git a/JRCookbookControls/Heading.bmp b/JRCookbookControls/Heading.bmp new file mode 100644 index 0000000..13fc480 Binary files /dev/null and b/JRCookbookControls/Heading.bmp differ diff --git a/JRCookbookControls/JRCookbookAutoVerticalGrowTextBox.cs b/JRCookbookControls/JRCookbookAutoVerticalGrowTextBox.cs new file mode 100644 index 0000000..785a038 --- /dev/null +++ b/JRCookbookControls/JRCookbookAutoVerticalGrowTextBox.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.ComponentModel; + +namespace JRCookbookControls +{ + [System.Serializable()] + public class JRCookbookAutoVerticalGrowTextBox : TextBox + { + private int _MinCharactersToMultiLine = 0; + + public JRCookbookAutoVerticalGrowTextBox() + { + this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); + + this.TextChanged += JRCookbookAutoVerticalGrowTextBox_TextChanged; + this.MultilineChanged += JRCookbookAutoVerticalGrowTextBox_MultilineChanged; + this.Resize += JRCookbookAutoVerticalGrowTextBox_Resize; + + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public int MinCharactersToMultiLine + { + get + { + return _MinCharactersToMultiLine; + } + set + { + _MinCharactersToMultiLine = value; + this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); + } + } + + + + + private void JRCookbookAutoVerticalGrowTextBox_Resize(object sender, EventArgs e) + { + RecalculateTextBoxHeight(); + } + + private void JRCookbookAutoVerticalGrowTextBox_TextChanged(System.Object sender, System.EventArgs e) + { + this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); + RecalculateTextBoxHeight(); + } + + private void JRCookbookAutoVerticalGrowTextBox_MultilineChanged(System.Object sender, System.EventArgs e) + { + //while we can't hide the multiline property, we can at least enforce its value. + this.Multiline = (this.Text.Length >= _MinCharactersToMultiLine); + } + + private void RecalculateTextBoxHeight() + { + // amount of padding to add + const int padding = 3; + // get number of lines (first line is 0, so add 1) + int numLines = this.GetLineFromCharIndex(this.TextLength) + 1; + // get border thickness + int border = this.Height - this.ClientSize.Height; + // set height (height of one line * number of lines + spacing) + this.Height = this.Font.Height * numLines + padding + border; + } + + } +} diff --git a/JRCookbookControls/JRCookbookControls.csproj b/JRCookbookControls/JRCookbookControls.csproj new file mode 100644 index 0000000..bce0139 --- /dev/null +++ b/JRCookbookControls/JRCookbookControls.csproj @@ -0,0 +1,38 @@ + + + + net10.0-windows7.0 + true + true + JRCookbookStrongNameKey.snk + false + x86 + x86 + + + + + + + + + UserControl + + + UserControl + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/JRCookbookControls/JRCookbookControlsEnums.cs b/JRCookbookControls/JRCookbookControlsEnums.cs new file mode 100644 index 0000000..faf8359 --- /dev/null +++ b/JRCookbookControls/JRCookbookControlsEnums.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookControls +{ + public enum InsertLocation + { + InsertNone, + InsertBefore, + InsertAfter + } + +} diff --git a/JRCookbookControls/JRCookbookEditProcedure.Designer.cs b/JRCookbookControls/JRCookbookEditProcedure.Designer.cs new file mode 100644 index 0000000..9fded4b --- /dev/null +++ b/JRCookbookControls/JRCookbookEditProcedure.Designer.cs @@ -0,0 +1,100 @@ + +namespace JRCookbookControls +{ + partial class JRCookbookEditProcedure + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + txtProcedureText = new JRCookbookAutoVerticalGrowTextBox(); + btnHeading = new System.Windows.Forms.Button(); + btnDelete = new System.Windows.Forms.Button(); + toolTip1 = new System.Windows.Forms.ToolTip(components); + SuspendLayout(); + // + // txtProcedureText + // + txtProcedureText.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + txtProcedureText.Location = new System.Drawing.Point(110, 3); + txtProcedureText.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + txtProcedureText.MinCharactersToMultiLine = 0; + txtProcedureText.Multiline = true; + txtProcedureText.Name = "txtProcedureText"; + txtProcedureText.Size = new System.Drawing.Size(1476, 47); + txtProcedureText.TabIndex = 0; + txtProcedureText.TextChanged += txtProcedureText_TextChanged; + // + // btnHeading + // + btnHeading.ImageKey = "(none)"; + btnHeading.Location = new System.Drawing.Point(43, 3); + btnHeading.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + btnHeading.Name = "btnHeading"; + btnHeading.Size = new System.Drawing.Size(56, 63); + btnHeading.TabIndex = 2; + toolTip1.SetToolTip(btnHeading, "Toggle Header"); + btnHeading.UseVisualStyleBackColor = true; + btnHeading.Click += btnHeading_Click; + // + // btnDelete + // + btnDelete.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + btnDelete.ImageKey = "(none)"; + btnDelete.Location = new System.Drawing.Point(1591, 3); + btnDelete.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + btnDelete.Name = "btnDelete"; + btnDelete.Size = new System.Drawing.Size(56, 63); + btnDelete.TabIndex = 1; + toolTip1.SetToolTip(btnDelete, "Delete"); + btnDelete.UseVisualStyleBackColor = true; + btnDelete.Visible = false; + btnDelete.Click += btnDelete_Click; + // + // JRCookbookEditProcedure + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + AutoSize = true; + BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + Controls.Add(txtProcedureText); + Controls.Add(btnHeading); + Controls.Add(btnDelete); + Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + Name = "JRCookbookEditProcedure"; + Size = new System.Drawing.Size(1647, 134); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private JRCookbookAutoVerticalGrowTextBox txtProcedureText; + private System.Windows.Forms.Button btnHeading; + private System.Windows.Forms.Button btnDelete; + private System.Windows.Forms.ToolTip toolTip1; + } +} diff --git a/JRCookbookControls/JRCookbookEditProcedure.cs b/JRCookbookControls/JRCookbookEditProcedure.cs new file mode 100644 index 0000000..cdcc030 --- /dev/null +++ b/JRCookbookControls/JRCookbookEditProcedure.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbookControls +{ + public partial class JRCookbookEditProcedure : UserControl + { + private RecipeProcedure _recipeProcedure; + private bool _DeleteAllowed = true; + private bool _IsEmptyValue = true; + public event EventHandler DeleteRequested; + public event EventHandler IsEmpty_Changed; + + private static ImageList _allButtonImagesList = new ImageList(); + private static ImageList _allHandleImagesList = new ImageList(); + private static bool _ImagesAlreadyLoaded = false; + + private static Point _HandleLocationPoint = new Point(0, 0); + private static bool _isHandleLocationSet = false; + + private const string HEADING_IMAGE = "Heading.bmp"; + private const string NOT_HEADING_IMAGE = "NotHeading.bmp"; + private const string DELETE_IMAGE = "Delete.bmp"; + private const string HANDLE_IMAGE = "Handle.bmp"; + + public JRCookbookEditProcedure() + { + InitializeComponent(); + LoadImages(); + } + + public JRCookbookEditProcedure(RecipeProcedure procedureToEdit) + { + InitializeComponent(); + LoadImages(); + recipeProcedure = procedureToEdit; + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public RecipeProcedure recipeProcedure + { + get + { + return _recipeProcedure; + } + set + { + _recipeProcedure = value; + LoadControlFromObject(); + } + } + + public bool IsEmpty + { + get + { + return _IsEmptyValue; + } + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool DeleteAllowed + { + get + { + return _DeleteAllowed; + } + set + { + _DeleteAllowed = value; + btnDelete.Enabled = _DeleteAllowed; + } + } + + private void btnDelete_Click(object sender, EventArgs e) + { + if (this.DeleteRequested != null) + this.DeleteRequested(this, new EventArgs()); + } + + private void LoadControlFromObject() + { + if (_recipeProcedure == null) + { + txtProcedureText.Text = string.Empty; + txtProcedureText.Font = new Font(txtProcedureText.Font, FontStyle.Regular); + btnHeading.ImageKey = NOT_HEADING_IMAGE; + } + else + { + txtProcedureText.Text = _recipeProcedure.procedureText; + if (_recipeProcedure.isHeading) + { + txtProcedureText.Font = new Font(txtProcedureText.Font, FontStyle.Bold); + btnHeading.ImageKey = HEADING_IMAGE; + } + else + { + txtProcedureText.Font = new Font(txtProcedureText.Font, FontStyle.Regular); + btnHeading.ImageKey = NOT_HEADING_IMAGE; + } + } + } + + private void btnHeading_Click(object sender, EventArgs e) + { + if (_recipeProcedure != null) + { + _recipeProcedure.isHeading = !_recipeProcedure.isHeading; + } + LoadControlFromObject(); + } + + private void txtProcedureText_TextChanged(object sender, EventArgs e) + { + _recipeProcedure.procedureText = txtProcedureText.Text; + CheckForData(); + } + + private void CheckForData() + { + var blnNewIsEmpty = true; + + if (txtProcedureText.Text.Trim() != String.Empty) + { + blnNewIsEmpty = false; + } + + if (_recipeProcedure.isHeading) + { + btnHeading.ImageKey = HEADING_IMAGE; + } + else + { + btnHeading.ImageKey = NOT_HEADING_IMAGE; + } + + if (blnNewIsEmpty != _IsEmptyValue) + { + _IsEmptyValue = blnNewIsEmpty; + + if (blnNewIsEmpty) + { + btnDelete.Visible = false; + } + else + { + btnDelete.Visible = true; + } + + if (this.IsEmpty_Changed != null) + this.IsEmpty_Changed(this, new EventArgs()); + } + } + + public void ShowInsertionBar(JRCookbookControls.InsertLocation insertLocation) + { + modSharedRoutines.ShowInsertionBar(this, insertLocation); + } + + public void HideInsertionBar() + { + modSharedRoutines.HideInsertionBar(this); + } + + public void DragStarted() + { + modSharedRoutines.DragStarted(this); + } + + public void DragEnded() + { + modSharedRoutines.DragEnded(this); + } + + protected override void OnPaint(PaintEventArgs e) + { + // If there is an image and it has a location, + // paint it when the Form is repainted. + base.OnPaint(e); + + Image myBackgroundImage = _allHandleImagesList.Images[HANDLE_IMAGE]; + + if (!_isHandleLocationSet) + { + _isHandleLocationSet = true; + + int verticalMidpointImage = myBackgroundImage.Height / 2; + int verticalMidpointButton = btnHeading.Height / 2; + int newTop = verticalMidpointButton - verticalMidpointImage + btnHeading.Top; + + _HandleLocationPoint = new Point(0, newTop); + } + + + e.Graphics.DrawImage(myBackgroundImage, _HandleLocationPoint.X, _HandleLocationPoint.Y, new Rectangle(0, 0, myBackgroundImage.Width, myBackgroundImage.Height), GraphicsUnit.Pixel); + + } + + private void LoadImages() + { + if (!_ImagesAlreadyLoaded) + { + _allButtonImagesList = new ImageList(); + _allButtonImagesList.ImageSize = btnDelete.ClientSize; + _allButtonImagesList.Images.Clear(); + _allButtonImagesList.Images.Add(Properties.Resources.Delete); + _allButtonImagesList.Images.Add(Properties.Resources.Heading); + _allButtonImagesList.Images.Add(Properties.Resources.NotHeading); + _allButtonImagesList.Images.SetKeyName(0, DELETE_IMAGE); + _allButtonImagesList.Images.SetKeyName(1, HEADING_IMAGE); + _allButtonImagesList.Images.SetKeyName(2, NOT_HEADING_IMAGE); + + _allHandleImagesList = new ImageList(); + + double handleWidthToHeightRatio = (double)(Properties.Resources.Handle.Width) / (double)(Properties.Resources.Handle.Height); + int handleWidth = (int)((double)(btnHeading.Left) * 0.75); + int handleHeight = (int)((double)(handleWidth) / handleWidthToHeightRatio); + _allHandleImagesList.ImageSize = new Size(handleWidth, handleHeight); + _allHandleImagesList.Images.Clear(); + _allHandleImagesList.Images.Add(Properties.Resources.Handle); + _allHandleImagesList.Images.SetKeyName(0, HANDLE_IMAGE); + + _ImagesAlreadyLoaded = true; + } + + this.btnDelete.ImageList = _allButtonImagesList; + this.btnDelete.ImageKey = DELETE_IMAGE; + this.btnHeading.ImageList = _allButtonImagesList; + this.btnHeading.ImageKey = NOT_HEADING_IMAGE; + + + } + + } +} diff --git a/JRCookbookControls/JRCookbookEditProcedure.resx b/JRCookbookControls/JRCookbookEditProcedure.resx new file mode 100644 index 0000000..b3502c9 --- /dev/null +++ b/JRCookbookControls/JRCookbookEditProcedure.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 118, 17 + + \ No newline at end of file diff --git a/JRCookbookControls/JRCookbookEditRecipeIngredient.Designer.cs b/JRCookbookControls/JRCookbookEditRecipeIngredient.Designer.cs new file mode 100644 index 0000000..347b3e5 --- /dev/null +++ b/JRCookbookControls/JRCookbookEditRecipeIngredient.Designer.cs @@ -0,0 +1,151 @@ + +namespace JRCookbookControls +{ + partial class JRCookbookEditRecipeIngredient + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + txtIngredientText = new JRCookbookAutoVerticalGrowTextBox(); + btnHeading = new System.Windows.Forms.Button(); + btnDelete = new System.Windows.Forms.Button(); + btnIngredientLink = new System.Windows.Forms.Button(); + txtUnitText = new JRCookbookAutoVerticalGrowTextBox(); + txtQuantityText = new JRCookbookAutoVerticalGrowTextBox(); + toolTip1 = new System.Windows.Forms.ToolTip(components); + SuspendLayout(); + // + // txtIngredientText + // + txtIngredientText.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + txtIngredientText.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; + txtIngredientText.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; + txtIngredientText.Location = new System.Drawing.Point(487, 8); + txtIngredientText.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + txtIngredientText.MinCharactersToMultiLine = 60; + txtIngredientText.Name = "txtIngredientText"; + txtIngredientText.PlaceholderText = "Ingredient"; + txtIngredientText.Size = new System.Drawing.Size(1025, 47); + txtIngredientText.TabIndex = 2; + txtIngredientText.TextChanged += txtIngredientText_TextChanged; + // + // btnHeading + // + btnHeading.ImageKey = "(none)"; + btnHeading.Location = new System.Drawing.Point(43, 0); + btnHeading.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + btnHeading.Name = "btnHeading"; + btnHeading.Size = new System.Drawing.Size(56, 63); + btnHeading.TabIndex = 5; + toolTip1.SetToolTip(btnHeading, "Toggle Header"); + btnHeading.UseVisualStyleBackColor = true; + btnHeading.Click += btnHeading_Click; + // + // btnDelete + // + btnDelete.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + btnDelete.ImageKey = "(none)"; + btnDelete.Location = new System.Drawing.Point(1593, 3); + btnDelete.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + btnDelete.Name = "btnDelete"; + btnDelete.Size = new System.Drawing.Size(56, 63); + btnDelete.TabIndex = 4; + toolTip1.SetToolTip(btnDelete, "Delete"); + btnDelete.UseVisualStyleBackColor = true; + btnDelete.Visible = false; + btnDelete.Click += btnDelete_Click; + // + // btnIngredientLink + // + btnIngredientLink.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + btnIngredientLink.ImageKey = "(none)"; + btnIngredientLink.Location = new System.Drawing.Point(1535, 3); + btnIngredientLink.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + btnIngredientLink.Name = "btnIngredientLink"; + btnIngredientLink.Size = new System.Drawing.Size(56, 63); + btnIngredientLink.TabIndex = 3; + toolTip1.SetToolTip(btnIngredientLink, "Link Ingredient"); + btnIngredientLink.UseVisualStyleBackColor = true; + btnIngredientLink.Visible = false; + btnIngredientLink.Click += btnIngredientLink_Click; + // + // txtUnitText + // + txtUnitText.AutoCompleteCustomSource.AddRange(new string[] { "10 oz", "11-oz", "15-oz", "8-ounce", "8-oz", "can", "can (11 oz)", "can (15 oz)", "can (6 oz)", "cans", "cup", "cups", "dash", "dashes", "gallon", "gallons", "lb", "lbs", "ounces", "oz", "pinch", "pinches", "pint", "pints", "quart", "quarts", "recipe", "slices", "small", "Tbs", "Tbsp", "teaspoon", "tsp" }); + txtUnitText.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; + txtUnitText.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource; + txtUnitText.Location = new System.Drawing.Point(278, 8); + txtUnitText.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + txtUnitText.MinCharactersToMultiLine = 8; + txtUnitText.Name = "txtUnitText"; + txtUnitText.PlaceholderText = "Unit"; + txtUnitText.Size = new System.Drawing.Size(198, 47); + txtUnitText.TabIndex = 1; + txtUnitText.TextChanged += txtUnitText_TextChanged; + // + // txtQuantityText + // + txtQuantityText.Location = new System.Drawing.Point(116, 8); + txtQuantityText.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + txtQuantityText.MinCharactersToMultiLine = 0; + txtQuantityText.Multiline = true; + txtQuantityText.Name = "txtQuantityText"; + txtQuantityText.PlaceholderText = "Qty"; + txtQuantityText.Size = new System.Drawing.Size(150, 47); + txtQuantityText.TabIndex = 0; + txtQuantityText.TextChanged += txtQuantityText_TextChanged; + // + // JRCookbookEditRecipeIngredient + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + AutoSize = true; + BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + Controls.Add(btnDelete); + Controls.Add(btnHeading); + Controls.Add(btnIngredientLink); + Controls.Add(txtIngredientText); + Controls.Add(txtUnitText); + Controls.Add(txtQuantityText); + Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + Name = "JRCookbookEditRecipeIngredient"; + Size = new System.Drawing.Size(1647, 134); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private JRCookbookAutoVerticalGrowTextBox txtIngredientText; + private System.Windows.Forms.Button btnHeading; + private System.Windows.Forms.Button btnDelete; + private System.Windows.Forms.Button btnIngredientLink; + private JRCookbookControls.JRCookbookAutoVerticalGrowTextBox txtUnitText; + private JRCookbookAutoVerticalGrowTextBox txtQuantityText; + private System.Windows.Forms.ToolTip toolTip1; + } +} diff --git a/JRCookbookControls/JRCookbookEditRecipeIngredient.cs b/JRCookbookControls/JRCookbookEditRecipeIngredient.cs new file mode 100644 index 0000000..58102de --- /dev/null +++ b/JRCookbookControls/JRCookbookEditRecipeIngredient.cs @@ -0,0 +1,2698 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbookControls +{ + public partial class JRCookbookEditRecipeIngredient : UserControl + { + private RecipeIngredient _recipeIngredient; + private bool _DeleteAllowed = true; + private bool _IsEmptyValue = true; + + private static ImageList _allButtonImagesList = new ImageList(); + private static ImageList _allHandleImagesList = new ImageList(); + private static bool _ImagesAlreadyLoaded = false; + + private static Point _HandleLocationPoint = new Point(0, 0); + private static bool _isHandleLocationSet = false; + + public event EventHandler DeleteRequested; + public event EventHandler IsEmpty_Changed; + public event EventHandler IngredientLinkRequested; + + private const string INGREDIENT_LINK_IMAGE_BAR0 = "Bar0.bmp"; + private const string INGREDIENT_LINK_IMAGE_BAR1 = "Bar1.bmp"; + private const string INGREDIENT_LINK_IMAGE_BAR2 = "Bar2.bmp"; + private const string INGREDIENT_LINK_IMAGE_BAR3 = "Bar3.bmp"; + private const string INGREDIENT_LINK_IMAGE_BAR4 = "Bar4.bmp"; + private const string NOT_HEADING_IMAGE = "NotHeading.bmp"; + private const string HEADING_IMAGE = "Heading.bmp"; + private const string DELETE_IMAGE = "Delete.bmp"; + private const string HANDLE_IMAGE = "Handle.bmp"; + + public JRCookbookEditRecipeIngredient() + { + InitializeComponent(); + LoadImages(); + LoadControlAutoComplete(); + CheckForData(); + } + + public JRCookbookEditRecipeIngredient(RecipeIngredient IngredientToEdit) + { + InitializeComponent(); + LoadImages(); + LoadControlAutoComplete(); + recipeIngredient = IngredientToEdit; + CheckForData(); + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public RecipeIngredient recipeIngredient + { + get + { + return _recipeIngredient; + } + set + { + _recipeIngredient = value; + LoadControlFromObject(); + } + } + + public bool IsEmpty + { + get + { + return _IsEmptyValue; + } + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool DeleteAllowed + { + get + { + return _DeleteAllowed; + } + set + { + _DeleteAllowed = value; + //btnDelete.Visible = _DeleteAllowed; + } + } + + private void btnIngredientLink_Click(object sender, EventArgs e) + { + if (this.IngredientLinkRequested != null) + this.IngredientLinkRequested(this, new EventArgs()); + + this.LoadControlFromObject(); + } + + private void btnDelete_Click(object sender, EventArgs e) + { + if (this.DeleteRequested != null) + this.DeleteRequested(this, new EventArgs()); + } + + private void LoadControlFromObject() + { + if (_recipeIngredient == null) + { + btnHeading.ImageKey = NOT_HEADING_IMAGE; + txtQuantityText.Text = string.Empty; + txtUnitText.Text = string.Empty; + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR0; + txtIngredientText.Text = string.Empty; + txtIngredientText.Font = new Font(txtIngredientText.Font, FontStyle.Regular); + } + else + { + txtIngredientText.Text = _recipeIngredient.ingredientText; + + if (_recipeIngredient.isHeading) + { + btnHeading.ImageKey = HEADING_IMAGE; + txtQuantityText.Text = string.Empty; + txtQuantityText.Visible = false; + txtUnitText.Text = string.Empty; + txtUnitText.Visible = false; + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR0; + btnIngredientLink.Visible = false; + + txtIngredientText.Font = new Font(txtIngredientText.Font, FontStyle.Bold); + } + else + { + btnHeading.ImageKey = NOT_HEADING_IMAGE; + var recipeIngredientItem = (RecipeIngredientItem)_recipeIngredient; + txtQuantityText.Text = recipeIngredientItem.quantityText; + txtQuantityText.Visible = true; + txtUnitText.Text = recipeIngredientItem.unitText; + txtUnitText.Visible = true; + + txtIngredientText.Font = new Font(txtIngredientText.Font, FontStyle.Regular); + + btnIngredientLink.Visible = true; + + if (recipeIngredientItem.ingredientID == null) + { + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR0; + + } + else + { + switch (recipeIngredientItem.linkQuality) + { + case 0: + case 1: + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR1; + break; + case 2: + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR2; + break; + case 3: + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR3; + break; + case 4: + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR4; + break; + default: + btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR0; + break; + } + } + } + } + } + + private void btnHeading_Click(object sender, EventArgs e) + { + if (_recipeIngredient != null) + { + if (_recipeIngredient.isHeading) + { + _recipeIngredient = _recipeIngredient.ConvertToItem(); + } + else + { + _recipeIngredient = _recipeIngredient.ConvertToHeading(); + } + } + LoadControlFromObject(); + } + + private void txtQuantityText_TextChanged(object sender, EventArgs e) + { + if (_recipeIngredient is RecipeIngredientItem) + { + ((RecipeIngredientItem)_recipeIngredient).quantityText = txtQuantityText.Text; + } + CheckForData(); + } + + private void txtUnitText_TextChanged(object sender, EventArgs e) + { + if (_recipeIngredient is RecipeIngredientItem) + { + ((RecipeIngredientItem)_recipeIngredient).unitText = txtUnitText.Text; + } + CheckForData(); + } + + private void txtIngredientText_TextChanged(object sender, EventArgs e) + { + _recipeIngredient.ingredientText = txtIngredientText.Text; + CheckForData(); + } + + private void CheckForData() + { + var blnNewIsEmpty = true; + + if (txtQuantityText.Text.Trim() != String.Empty) + { + blnNewIsEmpty = false; + } + + if (blnNewIsEmpty && txtUnitText.Text.Trim() != String.Empty) + { + blnNewIsEmpty = false; + } + + if (blnNewIsEmpty && txtIngredientText.Text.Trim() != String.Empty) + { + blnNewIsEmpty = false; + } + + if (_recipeIngredient.isHeading) + { + btnHeading.ImageKey = HEADING_IMAGE; + } + else + { + btnHeading.ImageKey = NOT_HEADING_IMAGE; + } + + if (blnNewIsEmpty != _IsEmptyValue) + { + _IsEmptyValue = blnNewIsEmpty; + + if (blnNewIsEmpty) + { + btnIngredientLink.Visible = false; + btnDelete.Visible = false; + } + else + { + btnDelete.Visible = true; + btnIngredientLink.Visible = !_recipeIngredient.isHeading; + } + + if (this.IsEmpty_Changed != null) + this.IsEmpty_Changed(this, new EventArgs()); + } + } + + public void ShowInsertionBar(JRCookbookControls.InsertLocation insertLocation) + { + modSharedRoutines.ShowInsertionBar(this, insertLocation); + } + + public void HideInsertionBar() + { + modSharedRoutines.HideInsertionBar(this); + } + + public void DragStarted() + { + modSharedRoutines.DragStarted(this); + } + + public void DragEnded() + { + modSharedRoutines.DragEnded(this); + } + + protected override void OnPaint(PaintEventArgs e) + { + // If there is an image and it has a location, + // paint it when the Form is repainted. + base.OnPaint(e); + + Image myBackgroundImage = _allHandleImagesList.Images[HANDLE_IMAGE]; + + if (!_isHandleLocationSet) + { + _isHandleLocationSet = true; + + int verticalMidpointImage = myBackgroundImage.Height / 2; + int verticalMidpointButton = btnHeading.Height / 2; + int newTop = verticalMidpointButton - verticalMidpointImage + btnHeading.Top; + + _HandleLocationPoint = new Point(0, newTop); + } + + + e.Graphics.DrawImage(myBackgroundImage, _HandleLocationPoint.X, _HandleLocationPoint.Y, new Rectangle(0, 0, myBackgroundImage.Width, myBackgroundImage.Height), GraphicsUnit.Pixel); + + } + + + private void LoadControlAutoComplete() + { + var ingredientAutoComplete = new AutoCompleteStringCollection(); + ingredientAutoComplete.AddRange(new string[] + { + "1% lowfat milk", +"1% milk", +"100% berry juice", +"100% bran cereal", +"acorn squash", +"active dry yeast", +"alfalfa sprouts", +"all purpose flour", +"all purpose white flour", +"all purpose-flour", +"all-purpose baking mix", +"all-purpose flour", +"all-purpose flour, plus more for pan", +"allspice", +"almond extract", +"almond or vegetable oil", +"Ancho Chile, seeded and finely chopped", +"Ancho powder", +"anchovies, rinsed and patted dry", +"angel hair pasta", +"Angel Hair, uncooked", +"Angostura bitters", +"animal cracker cookies", +"apple brandy", +"apple butter", +"apple cider", +"apple cider vinegar", +"apple juice", +"Apple Layer", +"apple pie spice", +"apple, chopped", +"apple, cored and chopped", +"apple, peeled, cored and chopped", +"apple, sliced paper-thin", +"apples, peeled, cored and diced", +"apples, peeled, sliced", +"applesauce", +"apricot jam", +"apricot nectar", +"apricot preserves", +"Asian chili sauce", +"asparagus spears, drained", +"asparagus spears, large", +"asparagus, cut diagonally into 2-inch lengths", +"asparagus, cut in 1-inch pieces", +"asparagus, trimmed and cut into 1-inch pieces", +"assorted colors of paste food coloring", +"Assorted fresh vegetables or chips", +"assorted fruit, cut into small pieces", +"Assorted fruits for dipping such as sliced apples and pears and strawberries", +"Assorted sprinkles", +"assorted vegetables, thinly sliced", +"avocados, seeded, peeled and mashed", +"baby carrot, peeled and julienned", +"baby carrots", +"baby yellow squash", +"baby zucchini", +"bacon", +"bacon, chopped", +"bacon, diced", +"baking cocoa", +"baking potatoes", +"baking powder", +"baking soda", +"balsamic vinegar", +"bamboo skewers", +"banana", +"banana, peeled and sliced", +"bananas, sliced", +"barbecue sauce", +"barbeque sauce", +"barley", +"Basic Barbecue Sauce", +"Basic Barbecue Sauce recipe follows", +"Basic Tomato Sauce (see recipe below)", +"basil", +"basil leaves", +"basil sprigs", +"basil, chopped", +"bay leaf", +"bay leaf, broken", +"bay leaves", +"bay scallops or medium shrimp, peeled and deveined", +"BBQ sauce", +"bean sprouts", +"beaten egg", +"Bechemel sauce, hot", +"beef bouillon cube", +"beef bouillon cubes", +"beef boullion cubes", +"beef broth", +"Beef Broth or Water", +"beef round steak, 1/3-inch thick", +"beef stew meat", +"beef stock", +"beef strips, sliced", +"beef tips, cut into bite-size pieces", +"beef-flavor instant bouillon", +"beer", +"bell pepper, chopped", +"biscuit mix", +"black olives", +"black olives, sliced", +"black pepper", +"black pepper freshly ground", +"black pepper freshly ground, to taste", +"black pepper linguini cooked", +"black pepper to taste", +"blackberries, washed", +"blanched slivered almonds, toasted", +"blanched, sliced almonds", +"bleu cheese", +"blood orange juice or regular orange juice", +"Blue corn chips", +"blueberries", +"Blueberry Orange Sauce", +"blush wine", +"boiling water", +"boned and skinned chicken breasts", +"boneless and skinless chicken breasts, cooked and cooled", +"boneless beef round steak, cut into thin strips", +"boneless chicken breast halves, cooked & cooled", +"boneless pork tenderloin", +"boneless rump roast", +"boneless skinless chicken breast halves", +"boneless skinless chicken breasts", +"boneless skinless chicken breasts, halved", +"boneless, skinless chicken breast halves", +"boneless, skinless chicken breast halves, cubed", +"boneless, skinless chicken breast halves, cut into strips", +"boneless, skinless chicken breast, cut crosswise into 1/2-inch pieces", +"boneless, skinless chicken breast, cut into 1 1/2-inch pieces", +"boneless, skinless chicken breast, cut into 1/2-inch cubes", +"boneless, skinless chicken breast, cut into 1-inch pieces", +"boneless, skinless chicken breast, cut into bite-size pieces", +"boneless, skinless chicken breast, cut into strips", +"boneless, skinless chicken breast, trimmed of fat and cut into bite-size, thin strips", +"boneless, skinless chicken breasts", +"boneless, skinless chicken breasts, cut into 1/2-inch cubes", +"boneless, skinless chicken breasts, cut into 1-inch cubes (about 3/4 cup)", +"boneless, skinless chicken breasts, cut into julienne strips (1 1/2 x 1/4-inch)", +"boneless, skinless chicken breasts, cut into small cubes", +"boneless, skinless chicken breasts, diced", +"bourbon", +"bourbon or whiskey", +"bourbon, rum, or orange juice", +"bow tie pasta", +"Bow Tie pasta, uncooked", +"Bow Ties, Elbow Macaroni or other medium pasta shape, uncooked", +"Bow Ties, Mostaccioli or other medium pasta shape, uncooked", +"Bow Ties, Radiatore or other medium pasta shape, uncooked", +"Bow Ties, Rigatoni or other medium pasta shape, uncooked", +"Bow Ties, Wagon Wheels or other medium pasta shape, uncooked", +"bow-tie pasta cooked according to package directions and drained", +"bran", +"bran flake cereal", +"bran flakes", +"brandy", +"Bread", +"bread crumbs", +"bread flour", +"breadcrumbs", +"brisket or blade pot roast", +"broccoli", +"broccoli florets", +"broccoli florets, cut into small pieces", +"broccoli flowerettes", +"broccoli, florets", +"broiler-fryer chicken wings", +"broken tortilla chips", +"broken whole grain Melba toast", +"Brown gravy", +"brown sugar", +"brown sugar substitute", +"brown sugar, packed", +"bulb garlic, unpeeled", +"bulbs fennel, untrimmed", +"bunch cilantro, leaves only chopped", +"bunch green onion, whites and some greens, chopped", +"bunch green onions, chopped", +"bunch green onions, cut into 1-inch lengths, separate whites from tops", +"bunch scallions, chopped", +"bunch scallions, finely chopped", +"bunch scallions, finely sliced", +"bunch scallions, sliced", +"bunch scallions, trimmed", +"bunch scallions, trimmed and thinly sliced (green and white parts)", +"bunches arugula, cleaned and torn into bite-sized pieces", +"bunches scallions or spring onions, chopped", +"bunches scallions, sliced", +"bunches watercress, coarsely chopped", +"Burgundy wine", +"butter", +"butter cut into small pieces", +"butter melted", +"butter or margarine", +"butter or margarine melted", +"butter or margarine, cut into pieces", +"butter or margarine, melted", +"butter or margarine, softened", +"butter or margarine, softened or melted", +"Butter, Margarine or Oil", +"butter, melted", +"butter, softened", +"Butter/margarine", +"Butter-flavored cooking spray, as needed", +"butter-flavored vegetable cooking spray", +"Butter-flavored, non-stick cooking spray", +"Buttermilk", +"buttermilk (or nonfat yogurt, if desired)", +"buttermilk baking mix", +"buttermilk baking mix, or more", +"buttermilk or milk", +"buttermilk or sour milk", +"buttermilk, dairy sour cream, plain yogurt, or milk", +"button mushrooms", +"button mushrooms sliced thin", +"Cabernet Sauvignon", +"Cajun spice", +"Cake", +"cake flour", +"cake flour (not self-rising)", +"Calamata olives, sliced", +"canned bouillon, soup stock or vegetable stock", +"Canned consomme", +"canned corn, drained", +"canned diced green chiles", +"canned diced tomatoes with juices", +"canned fried onion rings crushed", +"canned green beans, drained", +"canned green chilies chopped", +"canned Italian plum tomatoes, crushed", +"canned low-sodium chicken broth", +"canned mild jalapeno chile chopped", +"canned or frozen tart cherries", +"canned pumpkin", +"canned sliced mushrooms drained well", +"canned solid-pack pumpkin", +"canned vegetable or low-sodium chicken broth", +"canned white beans (cannellini), rinsed and drained", +"canola oil", +"canola oil (or other low saturated fat oil)", +"canola oil or other vegetable oil", +"capers", +"capers drained", +"caramel candies, cut small pieces", +"caramel ice cream topping", +"caraway seeds", +"caraway seeds, lemon pepper, grated Parmesan cheese", +"carbonated water", +"cardamom", +"caribbean jerk seasoning", +"carrot, finely chopped", +"carrot, shredded", +"carrot, sliced", +"Carrot; in chunks", +"carrots peeled and diced", +"carrots peeled and thinly sliced", +"Carrots sliced into 1/4-inch rounds", +"carrots, cut into 1-inch lengths", +"carrots, diagonally sliced", +"carrots, diced", +"carrots, grated 1 can (8 oz.)", +"carrots, julienned", +"carrots, peeled and chopped", +"carrots, peeled and cut into 1/2 inch slices", +"Carrots, peeled and diced", +"carrots, peeled and quartered", +"carrots, peeled and thinly sliced", +"carrots, peeled, sliced", +"carrots, scraped and cut into 1/4-inch rounds", +"carrots, scraped and sliced diagonally into 3/4-inch thick ovals", +"carrots, scrubbed and sliced", +"carrots, sliced", +"carrots, sliced into 1/4-inch rounds", +"carrots, thinly sliced", +"carrots, thinly sliced diagonally", +"catfish fillets", +"catsup", +"cauliflower florets", +"cauliflower flowerettes", +"cayenne", +"cayenne pepper", +"Cayenne pepper to taste", +"cayenne pepper, or to taste", +"celery chopped", +"celery cut into 1/4-inch cubes", +"celery finely chopped", +"celery salt", +"celery seed", +"celery seeds", +"celery stalk diced", +"celery stalk, finely diced", +"celery stalks, chopped", +"celery stalks, finely diced", +"Celery stalks, for garnish", +"celery sticks", +"celery, chopped", +"celery, cut on the diagonal", +"celery, diced", +"Celery, sliced", +"celery, trimmed and sliced", +"Cheddar cheese grated", +"cheddar cheese shredded", +"cheddar cheese, grated", +"cheese soup", +"cherries, pitted, coarsely chopped, and drained", +"cherry juice blend", +"cherry juice blend, chilled", +"cherry pie filling", +"cherry preserves", +"cherry tomatoes", +"cherry tomatoes halved", +"cherry tomatoes, cut in half", +"cherry tomatoes, halved", +"cherry tomatoes, quartered", +"cherry tomatoes, rinsed and quartered", +"chestnuts", +"chicken", +"chicken bouillon cube", +"chicken bouillon cubes", +"chicken bouillon granules", +"chicken bouillon powder", +"Chicken bouillon; instant", +"chicken breast, diced 3/4-inch", +"chicken breast, shredded", +"chicken breasts", +"Chicken breasts- boned; cut", +"chicken breasts, bone-in", +"chicken broth", +"chicken broth or water", +"chicken broth, homemade or canned", +"chicken broth, skimmed of fat", +"chicken drumsticks, skin-on or skinless", +"chicken or vegetable bouillon cube", +"chicken stock", +"chicken stock or broth", +"chicken stock or canned chicken broth", +"chicken, cut in parts", +"Chicken, cut into serving pieces", +"chili pepper", +"chili powder", +"chili sauce", +"chilies in adobo sauce", +"chilled club soda", +"chilled Honey-Mustard Chicken with Fettuccine", +"Chinese parsley, chopped", +"chives", +"chocolate chips", +"Chocolate Ganache", +"chocolate or multicolored candy sprinkles", +"Chocolate shavings", +"chocolate syrup", +"chopped almonds", +"chopped basil or parsley", +"chopped broccoli, blanched and drained", +"chopped Canadian-style bacon or chopped, cooked turkey bacon", +"chopped candied ginger", +"chopped capers", +"chopped carrot", +"chopped carrots", +"chopped celery", +"chopped chives", +"chopped chives or scallions", +"chopped chutney", +"Chopped cilantro", +"chopped cooked chicken", +"chopped cooked chicken meat", +"chopped cooked turkey", +"chopped crystallized ginger", +"chopped dates", +"chopped dried apples or raisins", +"chopped dried apricots", +"chopped dried fruit such as apricots, raisins, apples, or pears", +"chopped dried tart cherries", +"chopped extra-lean ham", +"chopped fresh basil", +"chopped fresh chives", +"chopped fresh cilantro", +"chopped fresh cilantro sprigs", +"chopped fresh dill", +"chopped fresh kale, stems removed", +"chopped fresh marjoram", +"chopped fresh mint", +"chopped fresh mint or parsley", +"chopped fresh parsley", +"chopped fresh parsley leaves", +"chopped fresh rosemary", +"chopped fresh sage", +"chopped fresh spinach", +"chopped fresh thyme", +"chopped fresh tomato", +"chopped golden raisins", +"chopped green bell papper", +"chopped green bell pepper", +"chopped green bell peppers", +"chopped green olives", +"chopped green onion tops", +"chopped green onions", +"chopped green or sweet red pepper", +"chopped green pepper", +"chopped green pepper, ribs and seeds removed", +"chopped green sweet pepper", +"chopped Italian or curly parsley", +"chopped Italian parsley", +"chopped jalapeno peppers, or to taste", +"Chopped jalapeños", +"chopped macadamia nuts or walnuts", +"chopped mushrooms", +"chopped nuts", +"chopped nuts, if desired", +"chopped onion", +"chopped onions", +"chopped parsley", +"Chopped parsley for garnish", +"chopped peanuts", +"chopped pecans", +"chopped pecans, lightly toasted", +"chopped pecans, toasted", +"chopped peeled onion", +"chopped pimiento", +"chopped pitted dates", +"chopped pitted kalamata olives", +"chopped pitted prunes", +"chopped red bell pepper", +"chopped red bell peppers", +"chopped red onion", +"chopped reduced-fat ham or Canadian bacon", +"chopped rehydrated sun-dried tomatoes", +"chopped ripe black olives", +"chopped roasted red bell pepper, drained", +"chopped scallions", +"chopped seeded jalapeno chilies", +"chopped sliced dried beef or fully cooked ham", +"chopped sun-dried tomatoes", +"chopped sweet onion", +"chopped toasted nuts", +"chopped toasted pecans", +"chopped tomatoes", +"chopped turkey ham", +"chopped walnuts", +"chopped walnuts toasted", +"chopped walnuts, toasted", +"chopped watermelon, seeds removed or seedless", +"chopped yellow bell pepper", +"chopped yellow onion", +"chopped zucchini", +"chopped, cooked chicken", +"chunky salsa", +"chutney", +"Chutney Dressing", +"cider vinegar", +"cilantro", +"Cilantro Pesto", +"Cilantro sprigs", +"cilantro sprigs for garnish", +"cilantro, chopped", +"cinnamon", +"cinnamon stick", +"cinnamon stick, broken into several pieces", +"cinnamon sticks", +"cinnamon sugar", +"cinnamon-sugar", +"Citrus Pecan Sauce", +"clam juice", +"Clarified butter", +"Clove garlic crushed", +"clove garlic minced", +"clove garlic, chopped", +"clove garlic, crushed", +"clove garlic, finely chopped", +"clove garlic, finely minced", +"clove garlic, minced", +"clove garlic, peeled", +"clove garlic, peeled and chopped", +"clove garlic, peeled and finely chopped", +"clove garlic, pressed", +"clove garlic, thinly sliced", +"clove minced garlic", +"cloves", +"Cloves fresh garlic minced", +"cloves garlic", +"Cloves garlic freshly chopped", +"cloves garlic freshly minced", +"Cloves garlic minced", +"Cloves garlic peeled and crushed", +"cloves garlic, chopped", +"cloves garlic, crushed", +"cloves garlic, finely chopped", +"cloves garlic, halved", +"cloves garlic, minced", +"cloves garlic, peeled", +"cloves garlic, peeled and coarsely chopped", +"cloves garlic, peeled and finely chopped", +"cloves garlic, sliced very thinly", +"Cloves minced garlic", +"club soda", +"coarse grain Dijon mustard", +"coarse salt", +"coarsely chopped cashews", +"coarsely chopped dried tart cherries", +"coarsely chopped fresh mint", +"coarsely chopped green bell pepper", +"coarsely chopped nuts", +"coarsely chopped onion", +"coarsely chopped pecans", +"coarsely chopped plum tomatoes", +"coarsely chopped roasted peanuts", +"coarsely chopped walnuts", +"coarsely crushed purchased apple chips", +"coarsely ground black pepper", +"coarsely ground black pepper to taste", +"coarsely ground pepper", +"coarsely shredded apple", +"coarsely shredded carrot", +"coarsely-chopped almonds", +"coarsely-chopped cilantro", +"coarsely-chopped sweet onion", +"coarsley ground pepper", +"cocoa", +"cocoa powder", +"coconut", +"coconut milk", +"coffee liqueur", +"cold milk", +"cold water", +"collard greens, chopped and rinsed", +"commercial barbecue sauce", +"confectioners sugar", +"confectioner's sugar", +"confectioners' sugar", +"cooked asparagus cut into small pieces", +"cooked black beans", +"cooked boneless, skinless chicken breast, julienned", +"cooked broccoli florets", +"cooked brown rice", +"cooked capellini pasta", +"cooked chicken breast, cut into chunks (about 1/2 pound)", +"cooked diced chicken", +"Cooked ham; dice", +"cooked potatoes", +"cooked rice", +"cooked shrimp, coarsely chopped or", +"cooked smoked sausage links, cut into 3/4-inch pieces", +"cooked spaghetti, hot", +"cooked turkey breast cut into 1x2x1-inch cubes", +"cooked turkey chopped", +"cooked turkey cut in 1/2 inch cubes", +"cooked turkey cut into 1/2 inch cubes", +"cooked turkey cut into 1/2-inch cubes", +"cooked turkey diced", +"cooked turkey ham, diced into 1/4-inch cubes", +"cooked turkey, chopped", +"cooked turkey, cut into strips", +"cooked turkey, shredded", +"cooked white rice, held warm", +"cooked wild rice or long grain rice", +"cooked, crumbled bacon", +"cooked, peeled medium shrimp", +"cooked, skinless, boneless chicken breast, shredded", +"cooking oil", +"cooking sherry", +"Cooking spray", +"Cooking spray, as needed", +"coriander", +"corn chips", +"corn flakes", +"corn muffins", +"corn oil", +"corn oil for frying", +"corn oil, plus", +"corn tortillas", +"cornbread crumbled", +"cornflake cereal", +"Cornish game hens, split", +"Cornish Hens", +"Cornmeal", +"cornstarch", +"cornstarch dissolved in 2 tablespoons water", +"Cornstarch for dusting", +"cornstarch or arrowroot powder", +"cottage cheese", +"country-style turkey sausage, casing removed, broken into pieces", +"crab meat", +"crab meat, drained", +"cracked black pepper", +"cracked or crushed ice cubes", +"cracked pepper", +"Cracked peppercorns, to taste", +"cranberries", +"cranberries, whole", +"cranberry liqueur or port wine", +"cream", +"cream cheese", +"cream cheese (light or fat-free)", +"cream cheese, softened", +"cream of mushroom soup", +"cream of tartar", +"cream-style corn", +"cream-style horseradish", +"creamy or chunky peanut butter", +"creamy peanut butter", +"Creole seasoning", +"Crepes", +"crisp, red apples, cored and sliced", +"crispy rice cereal", +"croutons", +"Crumb Topping", +"crumbled blue cheese", +"crumbled feta cheese", +"crumbled goat cheese, for garnish", +"crunchy cereal nuggets", +"crused ice", +"crushed corn chips", +"crushed corn flakes", +"crushed cumin seed", +"crushed dried basil", +"crushed dried marjoram", +"crushed dried oregano", +"crushed dried parsley", +"crushed dried rosemary", +"crushed dried tarragon", +"crushed dried thyme", +"crushed fruit or berries", +"crushed herb seasoned stuffing", +"crushed ice", +"crushed Italian Seasonings", +"crushed Maraschino cherries with stems, for garnish", +"crushed mint leaves, packed", +"crushed oregano", +"crushed pineapple drained thoroughly", +"crushed pineapple in own juice, drained", +"crushed pineapple, drained", +"crushed potato chips", +"crushed potato or tortilla chips", +"Crushed red chili peppers", +"crushed red pepper", +"crushed red pepper flakes", +"crushed tortilla chips", +"Crust and Topping", +"cubed American Cheese", +"cubed cantaloupe", +"cubed cooked ham", +"cubed cooked turkey", +"cubed day-old bread", +"cubed feta cheese", +"cubed honeydew melon", +"cubed potatoes cooked", +"cubed watermelon", +"cubed, cooked chicken", +"cubed, cooked chicken breast", +"cucumber", +"cucumber peeled, seeded and cut into 1/4-inch cubes", +"Cucumber, thinly sliced", +"Cucumbers scored and cut into 1/4-inch slices", +"cumin", +"cumin seeds", +"Cupcakes", +"cups cake flour", +"cups refrigerated Alfredo Sauce", +"currant jelly", +"currants or raisins", +"curry powder", +"dairy non-fat sour cream", +"dairy sour cream", +"d'Anjou pears, peeled, cored, and cut in half", +"dark beer", +"dark brown sugar", +"dark brown sugar, packed", +"dark corn syrup", +"dark Karo syrup", +"dark or light corn syrup", +"dark raisins", +"dark red kidney beans rinsed and drained well", +"dark rum", +"dark rum or orange juice", +"dates", +"dates, chopped", +"dates, pitted", +"dates, sliced", +"dehydrated onion", +"Diced apples", +"diced avocado", +"diced black olives", +"diced cantaloupe", +"diced celery", +"diced cooked chicken", +"diced cooked chicken breast", +"diced cooked potatoes", +"diced cucumber", +"diced dried pears", +"diced fresh California nectarines", +"diced fresh California peaches and plums", +"diced fresh tomatoes", +"diced green bell pepper", +"diced onion", +"diced peeled onion", +"diced peeled tomatoes", +"diced potato", +"diced red bell pepper", +"diced Red d'Anjou pears", +"diced red onion", +"diced red sweet peppers", +"diced roasted red peppers", +"diced sun-dried tomatoes", +"diced tomato", +"diced TURKEY HAM", +"diced yellow pepper", +"diced zucchini", +"diced, boneless, skinless, cooked turkey", +"diced, cooked chicken", +"diced, cooked turkey", +"diced, cooked turkey or chicken", +"Dijon mustard", +"Dijon mustard with seeds", +"Dijon-style mustard", +"dill pickle relish drained", +"dill pickle spears", +"dill pickle, finely chopped", +"Dill sauce", +"dill seeds", +"dill weed", +"distilled white vinegar", +"Dough", +"dozen large eggs", +"drained black olives, pitted and sliced", +"drained cocktail onions", +"drained whole canned tomatoes", +"Dressing", +"dried apricot", +"dried apricots", +"dried apricots diced", +"dried basil", +"dried basil leaves", +"dried basil, crushed", +"dried black turtle beans", +"dried bread crumbs", +"dried bread crumbs buttered", +"dried chili flakes", +"dried chives", +"dried cilantro", +"dried cranberries", +"dried crushed red pepper", +"dried currants", +"dried dill", +"dried dill weed", +"dried dillweed", +"dried Italian herbs", +"dried Italian seasoning", +"dried marjoram", +"dried marjoram, crushed", +"dried minced onion", +"dried minced onion minced", +"dried navy beans", +"dried onion", +"dried oregano", +"dried oregano flakes", +"dried oregano leaves", +"dried oregano, crumbled", +"dried oregano, crushed", +"dried parsley", +"dried parsley flakes", +"dried rosemary", +"dried rosemary, crushed", +"dried sage", +"dried savory", +"dried savory, finely crumbled", +"dried tarragon", +"dried tarragon, crushed", +"dried tart cherries", +"dried thyme", +"dried thyme leaves", +"dried thyme leaves, crushed", +"dried thyme, crushed", +"dried thyme, finely crumbled", +"dried white raisins", +"dry breadcrumbs", +"dry ground mustard", +"dry lentils, rinsed", +"dry marsala wine", +"dry mustard", +"dry red wine", +"dry roasted peanuts, unsalted", +"dry rotini pasta", +"dry sherry", +"dry white beans", +"dry white wine", +"dry yeast", +"dry-roasted peanuts", +"egg", +"Egg beaten", +"Egg Noodles, uncooked", +"egg slightly beaten", +"egg substitute", +"egg substitute, slightly beaten", +"egg white", +"egg white, slightly beaten", +"egg whites", +"egg whites, lightly beaten", +"egg yolk", +"Egg yolks", +"egg yolks lightly beaten", +"egg yolks slightly wisked", +"egg, beaten", +"egg, lightly beaten", +"egg, slightly beaten", +"eggplant", +"eggs", +"eggs beaten", +"eggs slightly beaten", +"eggs, beaten", +"eggs, lightly beaten", +"eggs, separated", +"eggs, slightly beaten", +"eggs, well beaten", +"Elbow Macaroni, uncooked", +"English muffins, split in half", +"envelope dry onion soup mix", +"envelope onion soup mix", +"envelope unflavored gelatin", +"espresso coffee, hot", +"evaporated fat-free milk", +"evaporated skim milk", +"evaporated skimmed milk", +"extra lean ground beef", +"extra virgin olive oil", +"extra-lean ground beef", +"extra-virgin olive oil", +"fat from poultry drippings", +"fat-free (skim) milk", +"fat-free cream cheese", +"fat-free Italian dressing", +"fat-free Italian salad dressing", +"fat-free mayonnaise", +"fat-free sour cream", +"fat-trimmed loin roast, rolled and tied with bone", +"fennel", +"fennel bulb, cut in half lengthwise", +"fennel bulbs", +"fennel seed, crushed", +"fennel seeds", +"fennel seeds, crushed", +"Feta cheese", +"Feta cheese crumbled", +"feta cheese, crumbled", +"Fettuccine", +"Fettuccine, uncooked", +"Fettuccine, uncooked, broken in half", +"Fettuccini", +"Filling", +"fine bread crumbs, dry", +"fine dry bread crumbs", +"fine fresh bread crumbs", +"finely chipped candied ginger", +"finely chopped dates", +"finely chopped dill pickle spears", +"finely chopped fresh cilantro", +"finely chopped fresh garlic", +"finely chopped fresh mint", +"finely chopped fresh parsley", +"finely chopped garlic", +"finely chopped green onion", +"finely chopped green pepper", +"finely chopped hazelnuts", +"finely chopped onion", +"finely chopped parsley", +"finely chopped peeled onion", +"finely chopped red onion", +"finely chopped shallots or scallions", +"finely chopped walnuts", +"finely chopped, cooked ham", +"finely chopped, toasted pecans", +"finely diced green bell pepper", +"finely diced red bell pepper", +"finely diced red onion", +"finely grated lemon peel", +"finely grated orange peel", +"finely minced flatleaf parsley", +"finely minced fresh cilantro", +"finely minced fresh oregano leaves", +"finely minced garlic", +"finely minced ginger", +"finely shredded fresh basil", +"finely shredded lemon peel", +"finely shredded lime peel", +"finely shredded orange peel", +"finely shredded Swiss cheese", +"finely-chopped bell pepper", +"finely-chopped canned chipotle", +"finely-chopped celery", +"finely-chopped cooked chicken", +"finely-chopped onion", +"finely-diced plums", +"firm butter or margarine", +"firmly packed brown sugar", +"firmly-packed brown sugar", +"firm-ripe California avocado", +"flaked or shredded coconut", +"flat beer", +"flat-bottom ice cream cones", +"flat-leaf parsley", +"flour", +"Flour tortillas", +"fontina", +"French bread cubes", +"fresh apple, grated", +"fresh asparagus spears, cooked", +"fresh baby carrots", +"fresh basil", +"fresh basil chopped", +"fresh basil leaves", +"fresh basil leaves, chopped", +"Fresh Basil Leaves, thinly sliced", +"fresh basil, coarsely chopped", +"fresh basil, stems removed", +"fresh blueberries", +"fresh boneless, skinless chicken breasts", +"fresh boneless, skinless chicken breasts, cut into 1/2-inch dice", +"fresh boneless, skinless chicken breasts, sliced", +"fresh boneless, skinless chicken breasts, sliced thinly", +"fresh boneless, skinless chicken breasts, thickly sliced", +"fresh boneless, skinless chicken thigh cutlets", +"fresh bratwurst", +"fresh bread crumbs", +"fresh California nectarines", +"fresh California peaches, halved and pitted, coarsely chopped", +"fresh California plums", +"fresh chicken drumsticks", +"fresh chicken thighs", +"fresh chopped cilantro", +"fresh chopped oregano", +"fresh chopped thyme", +"fresh cilantro chopped", +"fresh cilantro coarsely chopped", +"Fresh Cilantro diced", +"fresh cilantro, minced", +"fresh cranberries", +"fresh diced rhubarb", +"Fresh dill sprigs", +"fresh flat-leaf parsley, coarsely chopped", +"fresh garlic minced", +"fresh ginger minced", +"fresh ginger peeled and minced", +"fresh ginger root, minced", +"fresh ginger, grated", +"fresh grated ginger", +"fresh green beans", +"Fresh ground pepper to taste", +"fresh jalapeno peppers, seeded and minced", +"fresh jalapeño, seeded and chopped", +"fresh lemon juice", +"fresh lemon peels, grated", +"fresh lime juice", +"fresh linguine", +"Fresh Mushrooms", +"fresh mushrooms, quartered", +"Fresh mushrooms, rinsed", +"fresh mushrooms, sliced", +"fresh mushrooms, whole", +"fresh orange juice", +"fresh oregano", +"fresh oregano, finely chopped", +"fresh parsley", +"fresh parsley sprigs, chopped", +"fresh parsley tightly packed", +"fresh parsley, chopped", +"fresh plum tomatoes, cut into small cubes", +"fresh raspberries", +"fresh rosemary finely chopped", +"fresh rosemary, minced", +"fresh sage", +"Fresh Shiitake Mushrooms, sliced", +"fresh snow peas", +"fresh snow peas, trimmed", +"Fresh spinach leaves", +"fresh spinach leaves, cleaned and stems discarded", +"fresh spinach leaves, trimmed and torn", +"fresh spinach washed, dried and torn", +"fresh spinach, washed, hard stems removed", +"fresh squeezed Texas Red Grapefruit juice", +"fresh strawberries, washed, hulled and finely chopped", +"fresh thyme", +"fresh thyme leaves", +"fresh tuna", +"fresh tuna steak, cooked", +"fresh white mushrooms", +"fresh white mushrooms or mushroom stems, wiped clean and finely chopped", +"Fresh White Mushrooms, quartered", +"Fresh White Mushrooms, sliced", +"fresh whole chicken", +"Fresh-ground black pepper", +"freshly chopped parsley", +"freshly chopped tomato", +"Freshly cracked black pepper to taste", +"freshly grated lemon peel", +"freshly grated nutmeg", +"freshly grated Parmesan", +"freshly grated Parmesan cheese", +"freshly grated Parmigiano-Reggiano cheese", +"freshly ground black pepper", +"Freshly ground black pepper, to taste", +"Freshly ground pepper, to taste", +"freshly ground pure horseradish", +"freshly ground white pepper", +"freshly ground white pepper to taste", +"freshly squeezed lemon juice", +"freshly squeezed lime juice", +"freshly squeezed Texas Orange juice", +"freshly-ground black pepper", +"Freshly-ground black pepper, to taste", +"Freshly-ground white pepper, to taste", +"fried or baked chicken wings", +"frozen apple juice concentrate, thawed", +"frozen baby peas", +"frozen biscuits", +"Frozen concentrate orange juice", +"frozen corn", +"frozen corn, thawed", +"frozen corn, thawed and drained", +"frozen green beans, thawed", +"frozen green peas", +"frozen green peas thawed", +"frozen green peas, thawed and well drained", +"frozen hash brown potatoes", +"frozen hash brown potatoes defrosted and patted dry", +"Frozen Italian green beans", +"frozen mango chunks", +"frozen medium shrimp, thawed", +"frozen mixed vegetables", +"frozen mixed vegetables, thawed and drained", +"frozen orange juice concentrate", +"frozen orange juice concentrate, thawed", +"frozen peaches", +"frozen peas", +"frozen peas and carrots", +"frozen peas, defrosted", +"frozen peas, thawed", +"frozen peas, thawed and drained", +"frozen pineapple juice concentrate", +"Frozen Shrimp, peeled & deveined", +"frozen small shrimp, thawed", +"frozen Southwestern seasoned chicken strips", +"frozen tart cherries", +"frozen tart cherries, coarsely chopped", +"frozen tart or sweet cherries", +"frozen unsweetened tart cherries", +"frozen unsweetened tart cherries, thawed", +"frozen unsweetened tart cherries, thawed and well drained", +"frozen waffles, toasted", +"frozen whole kernel corn", +"frozen whole onions", +"fructose", +"fully cooked diced chicken or turkey", +"fully cooked smoked sausage links, quartered lengthwise and sliced", +"fully-cooked ham", +"fully-cooked oven roasted turkey breast sliced", +"fusilli pasta cooked and drained", +"garlic", +"garlic clove, chopped", +"garlic clove, crushed", +"garlic clove, minced", +"garlic clove, peeled and quartered", +"garlic clove, peeled and smashed", +"garlic cloves, chopped", +"garlic cloves, crushed", +"garlic cloves, finely chopped", +"garlic cloves, mashed", +"garlic cloves, minced", +"garlic cloves, unpeeled", +"garlic minced", +"garlic powder", +"garlic salt", +"garlic, chopped", +"Garlic, finely minced", +"garlic, minced", +"Generous dash of cayenne pepper", +"ginger", +"ginger, freshly grated", +"Ginger-root; fresh; minced", +"goat cheese", +"gold tequila", +"golden raisins", +"Gorgonzola cheese crumbled", +"graham cracker crumbs", +"grainy mustard", +"Granny Smith apple diced", +"Granny Smith apple, halved, cored and thinly sliced", +"Granny Smith apples, peeled, cored, thinly sliced", +"granulated fructose", +"granulated garlic", +"granulated instant coffee", +"granulated sugar", +"grape", +"grapefruit juice", +"grated asiago", +"grated Asiago cheese", +"grated carrot", +"grated carrots", +"grated Cheddar cheese", +"grated Edam cheese", +"grated fresh ginger", +"grated fresh ginger root", +"grated Gruyere cheese", +"grated lemon peel", +"grated lemon rind", +"grated lemon zest", +"grated lime peel", +"grated low-fat Cheddar cheese", +"grated low-fat Swiss cheese", +"grated low-sodium Parmesan cheese", +"grated mozzarella cheese", +"grated onion", +"grated orange or lemon peel", +"grated orange peel", +"grated orange zest", +"grated Parmesan", +"grated Parmesan cheese", +"grated part-skim mozzarella cheese", +"grated provolone cheese", +"grated reduced-fat Cheddar cheese", +"grated reduced-fat Swiss cheese", +"grated Romano cheese", +"grated smoked gouda cheese", +"grated zucchini", +"Greek olives pitted", +"green beans, blanched and refreshed in cold water", +"green beans, cooked, drained", +"green beans, julienne, blanched", +"green beans, trimmed and cut in half", +"green bell pepper, chopped", +"green bell pepper, cut into chunks", +"green bell pepper, ribs and seeds removed, chopped", +"green bell pepper, ribs and seeds removed, diced", +"green bell pepper, seeded and chopped", +"green bell pepper, seeded and cut into thin strips", +"green bell pepper, seeded and sliced", +"green bell pepper, seeded, ribs removed, and julienned", +"green bell pepper, seeds and ribs removed, julienned", +"green bell pepper, thinly sliced", +"green chili peppers, chopped", +"green olives", +"green olives, sliced", +"green onion chopped", +"green onion finely chopped", +"green onion minced", +"green onion, finely chopped", +"green onion, sliced", +"green onions chopped", +"green onions finely chopped", +"Green onions sliced", +"green onions thinly sliced", +"green onions, chopped", +"green onions, julienned", +"green onions, minced", +"green onions, sliced", +"green onions, whites and tops, chopped", +"green onions, whites and tops, thinly sliced", +"green or red bell pepper, coarsly chopped", +"green pepper chopped", +"green pepper cut into 1/2-inch cubes", +"green pepper seeded and cut into 1/4 inch cubes", +"green pepper seeded and thinly sliced", +"Green Pepper Strips", +"green pepper, chopped", +"green pepper, finely diced", +"Green pepper; cubed", +"green split peas, rinsed", +"grilled chicken, diced", +"ground allspice", +"ground beef", +"ground beef, cooked and drained", +"ground beef, pork or turkey", +"ground black pepper", +"Ground black pepper, to taste", +"ground cinnamon", +"ground cloves", +"ground coriander", +"ground cumin", +"ground ginger", +"ground lean beef", +"ground mace", +"ground nutmeg", +"ground oats", +"ground pepper", +"ground pork", +"ground pork sausage", +"Ground Red Chiles", +"ground red pepper", +"ground round", +"ground sage", +"ground sausage", +"ground thyme", +"ground turkey", +"ground turmeric", +"ground white pepper", +"ground, roasted, skinned hazelnuts", +"Guacamole", +"half and half", +"Half and Half cream", +"half-and-half", +"hamburger buns", +"Hamburger buns toasted", +"hard-boiled eggs, chopped", +"head Boston lettuce, well washed, and drained", +"head cabbage, cut into wedges", +"head garlic, peeled and seperated", +"head of lettuce", +"head romaine lettuce, torn in pieces", +"head romaine lettuce, torn into bite-size pieces", +"heaping tablespoons of cottage cheese", +"heavy (whipping) cream", +"heavy cream", +"heavy whipping cream", +"Herb sprigs", +"herbed stuffing mix", +"herb-seasoned stuffing mix crushed", +"hickory-smoked barbecue sauce", +"hoisin sauce", +"homemade-type white bread, crusts removed", +"honey", +"Honey Glaze", +"honey mustard", +"honey roasted peanuts", +"horseradish", +"hot buttered noodles", +"hot coffee", +"hot cooked rice", +"hot espresso-style coffee", +"hot fudge topping", +"hot Italian sausage", +"hot pepper sauce", +"Hot pepper sauce, to taste", +"hot red pepper flakes", +"hot red pepper sauce", +"hot sauce", +"hot water", +"Ice cream", +"ice cubes", +"Ice ring", +"ice water", +"Idaho potatoes", +"Indian curry powder", +"Ingredients", +"instant chicken bouillon granules", +"instant coffee", +"instant coffee granules", +"instant minced onion", +"instant potato flakes", +"instant white or brown rice", +"Iow-sodium chicken broth", +"Italian dressing", +"Italian parsley, coarsely chopped", +"Italian salad dressing", +"Italian seasoned dry bread crumbs", +"Italian seasoning", +"Italian seasonings", +"Italian turkey sausage", +"Italian turkey sausage casing removed, cooked & crumbled", +"Italian turkey sausage, casing removed, cooked & crumbled", +"Italian-style bread crumbs", +"Italian-style turkey sausage", +"jalapeno chiles, stemmed, seeded and finely diced", +"jalapeno chiles, stemmed, seeded if desired and minced", +"jalapeno jelly", +"jalapeno pepper minced", +"Jalapeno pepper seeded and finely chopped", +"jalapeno pepper, minced", +"jalapeño pepper, minced", +"jalapeño pepper, seeded and diced", +"jalapeno pepper, seeded and minced", +"jalapeño pepper, stemmed, seeded and thinly sliced", +"Jalapeno peppers seeded and chopped", +"jalapeno peppers seeded and minced", +"jalapeño, cored and thinly sliced", +"jalapeño, seeded and minced", +"jalapenos coarsely chopped, with seeds", +"jumbo prawns", +"jumbo shells", +"Jumbo Shells, uncooked", +"Kalamata olives, pitted and sliced", +"ketchup", +"kielbasa sausage", +"kiwi", +"kiwi fruits, peeled, diced", +"kiwifruit, peeled and sliced", +"kiwis, peeled", +"kosher salt", +"kosher salt to taste", +"lager", +"lamb chops", +"lamb shanks", +"lamb stew meat", +"lasagna noodles", +"lasagna noodles, uncooked", +"lean beef cut into 1-inch cubes", +"lean beef stew meat, cut into 1-inch chunks", +"lean boneless top round steak", +"lean bulk pork sausage", +"lean ground beef", +"lean ground beef, browned and drained", +"Lean Loin of Pork", +"lean pork spareribs", +"lean, boneless pork loin, cut into 3/4-inch cubes", +"leaves fresh mint, julienned", +"leek, white only, chopped", +"leeks thinly sliced", +"leeks, chopped", +"lemon extract", +"lemon juice", +"lemon juice, freshly squeezed", +"lemon peel", +"lemon peel, freshly grated", +"lemon pepper", +"Lemon pepper seasoning", +"Lemon slices", +"lemon zest", +"lemon, thinly sliced", +"lemons", +"lentils, rinsed", +"lettuce leaves", +"Lettuce leaves washed and dried", +"lettuce, shredded", +"light brown sugar", +"light corn syrup", +"light cream", +"light cream cheese", +"light cream cheese, softened", +"light cream or table cream", +"light dairy sour cream", +"light or dark brown sugar", +"light rum, optional", +"light soy sauce", +"lightly beaten egg", +"lightly packed fresh basil leaves, chopped", +"lightly salted peanuts", +"lightly toasted pine nuts", +"lime juice", +"Lime wedges", +"lime, juiced", +"Linguine, uncooked", +"liquid hot pepper sauce", +"liquid smoke", +"liquid smoke flavoring", +"liquid sugar substitute", +"lite coconut milk", +"lite soy sauce", +"Loin lamb chops", +"long-grain rice", +"loosely packed cilantro leaves", +"loosely packed fresh basil", +"loose-pack frozen peas", +"loose-pack frozen whole kernel corn", +"Louisiana-style hot sauce", +"low fat milk", +"low fat yogurt", +"low sodium chicken broth, warm", +"low-calorie margarine", +"low-fat (1%) buttermilk", +"low-fat buttermilk", +"low-fat Caesar or Italian salad dressing", +"low-fat cheddar cheese", +"low-fat Cheddar cheese, grated", +"low-fat cheddar cheese, shredded", +"lowfat cottage cheese", +"low-fat cottage cheese", +"low-fat granola", +"Low-fat grated Cheddar cheese", +"low-fat low-sodium beef broth", +"low-fat low-sodium chicken broth", +"low-fat low-sodium chicken broth, boiling", +"lowfat milk", +"low-fat milk", +"low-fat or non-fat mayonnaise", +"low-fat peanut butter", +"lowfat ricotta cheese", +"low-fat ricotta cheese", +"low-fat sour cream", +"low-fat yogurt", +"low-fat, chunky vegetable spaghetti sauce", +"low-fat, part-skim ricotta cheese", +"low-fat, plain yogurt", +"low-sodium beef broth", +"low-sodium canned tomato sauce", +"low-sodium chicken broth", +"low-sodium chicken broth or water", +"low-sodium chicken broth, boiling", +"low-sodium chicken broth, skimmed of fat", +"low-sodium shredded mozzarella cheese", +"low-sodium soy sauce", +"low-sodium spaghetti sauce", +"low-sodium tomato sauce", +"macaroni, cooked according to directions, drained", +"mango", +"mango, peeled, seeded and chopped", +"Manicotti Shells, uncooked", +"Manicotti, uncooked", +"maple syrup", +"maple-flavored syrup", +"maraschino cherries", +"maraschino cherries, drained, rinsed", +"maraschino cherry juice", +"margarine", +"margarine melted", +"margarine or butter", +"margarine or butter melted", +"margarine or butter, melted", +"margarine, cut into pieces", +"margarine, melted", +"margarine, softened", +"marinara sauce", +"marjoram", +"marjoram leaves", +"marshmallow creme", +"masa flour", +"mascarpone", +"mashed ripe bananas", +"matzo meal", +"mayonnaise", +"Meatballs", +"meatless tomato or spaghetti sauce", +"Meatloves", +"Medium Egg Noodles", +"Medium Egg Noodles, uncooked", +"melted butter", +"melted butter or margarine", +"melted butter or oil", +"melted margarine", +"melted shortening", +"mesclun", +"mild enchilada sauce", +"mild italian turkey sausage", +"mild salsa", +"mild sausage", +"mild white vinegar", +"milk", +"milled black pepper", +"millet", +"minced celery", +"minced dill", +"minced flat-leaf parsley", +"minced fresh basil", +"minced fresh chives", +"minced fresh cilantro", +"minced fresh ginger", +"minced fresh ginger root", +"minced fresh gingerroot", +"minced fresh mint", +"minced fresh oregano", +"minced fresh parsley", +"minced fresh rosemary", +"minced fresh thyme", +"minced garlic", +"minced ginger", +"minced ginger root", +"minced golden raisins", +"minced green bell pepper", +"minced green onions", +"minced green parsley", +"minced Italian flat-leaf parsley", +"minced jalapeno", +"minced jalapeño pepper", +"minced jalapeño peppers", +"minced mint", +"minced onion", +"minced oregano", +"minced parsley", +"minced scallions", +"minced, seeded jalapeño pepper", +"miniature marshmallows", +"miniature semisweet chocolate chips", +"miniature semisweet chocolate pieces", +"mint sprigs", +"mixed fresh herbs, chopped", +"mixed whole pickling spice", +"molasses", +"Monterey Jack cheese", +"Monterey Jack cheese shredded", +"Monterey Jack cheese, grated", +"Monterey Jack or Cheddar cheese", +"mozzarella cheese coarsely shredded", +"Mozzarella Cheese, shredded", +"Muffins", +"Mushroom Sauce", +"mushrooms", +"mushrooms, chopped", +"mushrooms, halved", +"mushrooms, quartered", +"mushrooms, sliced", +"mushrooms, thinly sliced", +"mustard", +"natural peanut butter", +"naval oranges, peeled, sliced and quartered", +"navel oranges, peeled and sliced", +"nectarine, coarsely chopped", +"nectarines, pitted and coarsely chopped", +"new red potatoes", +"no cholesterol reduced-calorie mayonnaise", +"no-cholesterol reduced-calorie mayonnaise", +"non-fat buttermilk", +"Nonfat cooking spray, as needed", +"nonfat cottage cheese", +"non-fat cream cheese", +"nonfat dry milk powder", +"nonfat granola", +"non-fat Italian salad dressing", +"non-fat mayonnaise", +"nonfat milk", +"non-fat milk", +"nonfat plain yogurt", +"non-fat plain yogurt", +"nonfat powdered milk", +"nonfat sour cream", +"non-fat sour cream", +"nonfat whipped topping", +"nonfat yogurt", +"non-fat, plain yogurt", +"nonstick cooking spray", +"Non-stick cooking spray", +"Nonstick cooking spray, as needed", +"Noodles Thai Shrimp Sauce", +"noodles, cooked in salted water, drained", +"no-salt corn chips crushed", +"no-salt-added tortilla chips", +"nutmeg", +"Nutmeg to taste", +"oat bran", +"oatmeal", +"oil", +"Oil for frying", +"oil for sautéing", +"oil or melted butter", +"oil-packed sun-dried tomatoes, chopped", +"old-fashioned oats", +"old-fashioned or quick-cooking oats, uncooked", +"old-fashioned rolled oats", +"olive oil", +"Olive oil flavored cooking spray", +"olive oil or cooking oil", +"olive oil or vegetable oil", +"olive or vegetable oil", +"onion chopped", +"onion coarsely chopped", +"onion finely chopped", +"onion flakes", +"onion grated", +"onion powder", +"onion sliced", +"onion thinly sliced", +"onion, chopped", +"onion, diced", +"onion, finely diced", +"onion, minced", +"onion, peeled and chopped", +"onion, sliced", +"onion; chop fine", +"Onions, chopped", +"onions, coarsely chopped", +"onions, diced", +"onions, peeled and chopped", +"orange", +"orange extract", +"orange juice", +"orange juice concentrate", +"orange liqueur", +"orange marmalade", +"orange rind grated", +"orange slice halves", +"orange zest", +"oranges", +"oregano", +"oregano leaves", +"Oregano Leaves, crushed", +"oregano, chopped", +"oriental sesame oil", +"Orzo", +"orzo macaroni", +"oven roasted turkey breast finely chopped", +"oven-toasted cereal squares", +"Oyster Mushrooms, roughly chopped", +"Oyster Sauce", +"Pace thick & chunky salsa", +"packed brown sugar", +"packed cilantro leaves", +"packed dark brown sugar", +"packed fresh basil", +"packed light brown sugar", +"pancetta", +"papaya, halved, seeded, peeled and sliced", +"paprika", +"Paprika, to taste", +"Parmesan", +"Parmesan cheese", +"Parmesan cheese freshly grated", +"Parmesan cheese grated", +"Parmesan cheese, grated", +"Parmesano-Reggiano", +"Parmigiano-Reggiano cheese, grated", +"parsley", +"parsley flakes", +"parsley leaves (tightly packed)", +"parsley minced", +"parsley, chopped", +"parsley, finely chopped", +"parsley, minced", +"parsnips", +"parsnips, peeled and quartered", +"part skim ricotta cheese", +"part-skim mozzarella cheese", +"part-skim mozzarella cheese, grated", +"part-skim ricotta cheese", +"pasta", +"pasta shells", +"Pastry", +"peach low-fat yogurt", +"peach preserves", +"peach sorbet", +"peach yogurt", +"peaches, peeled, pitted and coarsely chopped", +"peaches, pitted and chopped", +"peaches, pitted and thinly sliced", +"peanut butter", +"peanut oil", +"peanuts", +"pear, cored and finely chopped", +"pear, peeled, cored, and sliced", +"pearl onions", +"pears", +"peas", +"pecan pieces, toasted", +"pecans, chopped", +"pecans, finely chopped", +"peel from one lemon", +"peeled clove garlic, chopped", +"peeled, diced eggplant", +"peeled, seeded and chopped cucumber", +"penne pasta", +"pepper", +"pepper, to taste", +"peppercorns", +"pepperoni", +"picante sauce", +"pimientos, chopped", +"pine nuts", +"pine nuts, toasted", +"pineapple", +"pineapple chunks, drained", +"Pineapple chunks; canned", +"pineapple juice", +"pineapple sherbet", +"pineapple slices canned in own juice", +"pinenuts", +"pita bread halves", +"pitted and chopped black olives, such as Kalamata", +"pitted dried red cherries, coarsely chopped", +"pitted prunes", +"Pizza Sauce", +"plain bread crumbs", +"plain Fettuccine, uncooked", +"plain lowfat yogurt", +"plain low-fat yogurt", +"plain nonfat yogurt, strained", +"Plain or vanilla yogurt", +"plain yogurt", +"plain, low-fat yogurt", +"plain, non-fat yogurt", +"plum tomato, diced", +"plum tomatoes, cored, seeded and cut in halves", +"plum tomatoes, diced", +"plum tomatoes, quartered", +"plum tomatoes, seeded and finely chopped", +"plums, any variety, pitted and sliced", +"plums, pitted and coarsely chopped", +"plums, seeds removed, and cut into thin slices", +"poached chicken, cut into chunks", +"poblano chiles", +"poppy seeds", +"porcini mushrooms", +"pork chops, 3/4-inch thick", +"pork loin, fat trimmed, and cut into 1/2-inch pieces", +"pork loin, trimmed of fat, cut into 1/2-inch pieces", +"pork sirloin cutlets, tenderized, about 1/4-inch thick", +"pork spareribs", +"pork tenderloin", +"pork tenderloin, cut in 2-inch pieces", +"pork tenderloin, cut in thin strips", +"pork tenderloin, trimmed of fat", +"pork, boneless cubed", +"port wine", +"portabella mushrooms, sliced 1/2-inch thick, gills removed", +"portobello mushrooms, sliced", +"Potato", +"potato peeled and diced", +"potato starch", +"Potatoes baked", +"potatoes diced", +"potatoes peeled and cut into 1/2-inch cubes", +"potatoes, baked and split in half", +"potatoes, diced", +"potatoes, dried flakes, mashed", +"potatoes, peeled and cubed", +"potatoes, peeled and sliced", +"potatoes, scrubbed and diced", +"poultry seasoning", +"powdered chicken bouillon mix", +"powdered garlic", +"powdered ginger", +"powdered milk", +"powdered pectin", +"powdered sugar", +"powdered sugar, sifted", +"prepared 9-inch pastry pie crust", +"prepared barbecue sauce", +"prepared chili sauce", +"prepared chunky vegetable spaghetti sauce", +"prepared horseradish", +"prepared marinara sauce", +"prepared mustard", +"prepared pesto sauce", +"Prepared pie dough for two single-crust 9-inch pies", +"prepared pizza sauce", +"prepared reduced-fat graham cracker crumb crust - (6 oz)", +"prepared sourdough starter", +"prepared yellow mustard", +"preserved ginger pieces", +"preserved ginger syrup", +"prosciutto", +"provolone cheese", +"provolone cheese, grated", +"pumpkin pie spice", +"pumpkin seeds", +"pure red chile powder", +"pure vanilla extract", +"quartered cherry tomatoes", +"quick cooking oats", +"quick cooking rolled oats", +"quick or old-fashioned oats", +"quick-cooking oats", +"quick-cooking rice", +"quick-cooking rice, uncooked", +"raisins", +"raspberries", +"raspberry jam", +"raspberry juice", +"raspberry preserves", +"raspberry sorbet", +"raspberry vinegar", +"ready-to-eat ham", +"ready-to-use 9-inch graham cracker pie crust (6 ounces)", +"real maple or maple-flavored syrup", +"real maple syrup", +"red and yellow bell pepper, peeled and julienned", +"red apple, diced", +"red bell pepper cut into 1/4-inch cubes", +"red bell pepper seeded & cut into 1/4-inch cubes", +"red bell pepper seeded and chopped", +"red bell pepper seeded and diced", +"red bell pepper seeded and sliced", +"red bell pepper, cut into chunks", +"red bell pepper, halved and sliced", +"red bell pepper, julienned", +"red bell pepper, ribs and seeds removed, diced", +"red bell pepper, ribs and seeds removed, julienned", +"red bell pepper, ribs removed and cut into strips", +"red bell pepper, seeded and cut into thin strips", +"red bell pepper, seeded, ribs removed, and julienned", +"red bell pepper, seeds and ribs removed, chopped", +"red bell pepper, seeds and ribs removed, cut into strips", +"red bell pepper, sliced", +"red bell pepper, thinly sliced", +"red bell peppers", +"red bell peppers, diced", +"red bell peppers, ribs and seeds removed, diced", +"red bell peppers, seeded and diced", +"red bell peppers, seeds and stems removed, cut into bite-size, thin strips", +"red currant jelly", +"red food coloring", +"red onion, minced", +"red onion, pared, thinly sliced", +"red onion, quartered", +"red onion, thinly sliced", +"red onions, halved", +"red or green bell pepper, diced", +"red or white seedless grapes, cut in half", +"red or white wine vinegar", +"red or yellow bell pepper, cut into short, thin strips", +"red or yellow bell pepper, ribs and seeds removed, cut into small strips", +"red pepper", +"red pepper flakes", +"Red pepper flakes to taste", +"red pepper sauce", +"red pepper, cut into strips", +"red pepper, minced", +"red peppers, diced", +"red raspberries", +"red skinned potatoes, peeled and diced", +"red vinegar", +"red wine", +"red wine vinegar", +"reduced fat all purpose baking mix", +"reduced-calorie Creamy Italian dressing", +"reduced-calorie mayonnaise", +"reduced-calorie stick margarine, melted", +"reduced-calorie tub margarine, softened", +"reduced-fat Cheddar cheese", +"reduced-fat Cheddar cheese grated", +"reduced-fat Cheddar cheese shredded", +"reduced-fat cream cheese", +"reduced-fat creamy peanut butter", +"reduced-fat margarine", +"reduced-fat mayonnaise", +"reduced-fat Monterey Jack cheese grated", +"reduced-fat Monterey Jack cheese shredded", +"reduced-fat Monterey Jack cheese, grated", +"reduced-fat shredded Cheddar cheese", +"reduced-fat sour cream", +"reduced-fat vanilla yogurt", +"reduced-fat whipped topping", +"reduced-sodium chicken bouillon", +"reduced-sodium reduced-fat chicken broth", +"reduced-sodium soy sauce", +"regular or low-fat sour cream", +"rehydrated cranberries, drained", +"rice vinegar", +"rice wine vinegar", +"rice, cooked", +"Rice; hot cooked", +"ricotta cheese", +"ricotta or whipped cream cheese", +"ricotta salata", +"ricotta salata cheese", +"Rigatoni", +"rinsed canned black beans, drained", +"ripe banana", +"ripe banana, peeled", +"ripe bananas, mashed", +"ripe Haas avocado, coarsely chopped", +"ripe medium bananas", +"ripe olives", +"ripe tomatoes, cored", +"ripe tomatoes, sliced", +"roast beef, chopped", +"Roasted red peppers", +"roasted, salted peanuts", +"rolled oats", +"Roquefort Cheese", +"rosemary", +"Rotini", +"round steak", +"Rum", +"russet potatoes", +"russet potatoes, peeled and diced", +"rye flour", +"safflower oil", +"saffron", +"sage leaves", +"sage seasoning mixture", +"Salad", +"salad greens, torn", +"salad oil", +"Salad or Olive Oil", +"salmon steaks", +"Salsa", +"Salsa Cruda", +"salsa prima roasted garlic", +"salt", +"Salt and black pepper to taste", +"salt and freshly ground black pepper", +"Salt and freshly ground black pepper, to taste", +"salt and freshly ground pepper", +"Salt and freshly ground pepper, to taste", +"Salt and pepper, to taste", +"salt pork fat melted or other fat", +"Salt, as needed", +"Salt, to taste", +"salted black beans, rinsed and lightly crushed", +"salted peanuts", +"salted, roasted whole almonds", +"Sauce", +"Sauce:", +"scallions, sliced", +"scallions, sliced thin crosswise", +"scallions, thinly sliced", +"scallions, trimmed and sliced thin", +"scallions, trimmed and thinly sliced", +"scallops", +"sea salt", +"sea scallops", +"seafood seasoning", +"seasoned bread crumbs", +"seasoned croutons", +"seasoned dry bread crumbs", +"seasoned dry breadcrumbs", +"seasoned Italian bread crumbs", +"seasoned pepper", +"seasoned rice vinegar", +"seasoned salt", +"seasoned tomato sauce", +"seedless green grapes", +"seedless green grapes, cut into halves", +"seedless raspberry jam", +"seedless raspberry preserves", +"seedless red grapes, cut into halves", +"self-rising flour", +"semisweet chocolate chips", +"semi-sweet chocolate chips", +"semisweet chocolate morsels", +"sesame oil", +"sesame or vegetable oil", +"sesame seed bagel, halved, toasted", +"sesame seeds", +"sesame sticks, optional", +"shallots, coarsly chopped", +"sharp cheddar cheese, grated", +"sharp cheddar cheese, shredded", +"sharp Cheddar cheese, sliced", +"shaved deli turkey ham", +"shelled, salted sunflower seeds", +"sherry", +"sherry or dry white wine", +"sherry vinegar", +"Shiitake mushrooms, quartered", +"shiitake, morel or chanterelle mushrooms", +"short grain brown rice", +"short ribs", +"shortening", +"shredded cabbage", +"shredded carrot", +"shredded carrots", +"shredded Cheddar cheese", +"shredded coconut", +"shredded colby-jack cheese", +"shredded cooked chicken", +"shredded green cabbage", +"shredded grilled chicken", +"shredded lettuce", +"shredded low-fat Cheddar cheese", +"shredded low-fat mozzarella cheese", +"shredded low-fat sharp cheddar cheese", +"shredded low-sodium Cheddar cheese", +"shredded Mexican-style cheese blend", +"shredded Monterey Jack cheese", +"shredded mozzarella", +"shredded non-fat Cheddar cheese", +"shredded onion", +"shredded part-skim mozzarella cheese", +"shredded reduced-fat Cheddar cheese", +"shredded romaine lettuce", +"Shredded Romano cheese", +"shredded Swiss cheese", +"shredded unsweetened coconut", +"shredded, pared apple", +"shredded, part-skim mozzarella cheese", +"shredded, reduced-fat Cheddar cheese", +"shredded, reduced-fat Monterey Jack cheese", +"shrimp, peeled and deveined", +"shucked oysters, drained", +"sifted cake and pastry flour", +"sifted confectioners' sugar", +"Sifted fruit sugar", +"sifted powdered sugar", +"skim milk", +"skim milk, room temperature", +"skim or lowfat milk", +"skim-milk ricotta cheese", +"skinless, boneless chicken breast, cooked", +"skinless, boneless chicken breasts, cut into bite-sized pieces", +"skinless, boneless chicken breasts, cut into slivers", +"skinless, boneless chicken breasts, diced", +"skinless, boneless chicken breasts, sliced in half crosswise", +"salmon, drained and flaked", +"slice finely chopped onion", +"sliced almonds", +"sliced almonds, coarsely chopped", +"sliced almonds, toasted", +"sliced bananas", +"sliced carrots", +"sliced celery", +"sliced fresh California nectarines", +"sliced fresh California peaches", +"sliced fresh mushrooms", +"sliced fresh strawberries", +"sliced green onion", +"sliced green onions", +"sliced green onions or red onion", +"sliced green onions with tops", +"sliced mushrooms", +"sliced onion", +"sliced onions", +"sliced peaches", +"sliced pepperoni", +"sliced pimentos", +"sliced plum tomatoes", +"sliced purple onion", +"sliced red onion", +"sliced red onions", +"sliced ripe olives", +"sliced scallions", +"sliced scallions, white and green parts", +"sliced shallots or chopped sweet onion", +"sliced shiitake mushrooms", +"sliced spring onions", +"sliced strawberries", +"slices bacon, chopped", +"Slices dried bread cubed", +"slices fat-free American cheese", +"slices mozzarella cheese", +"slices prosciutto", +"slices reduced-fat whole-wheat bread", +"slices sandwich bread", +"Slices turkey bacon cooked and crumbled", +"Slices turkey bacon cooked and diced", +"slices turkey bacon crisply cooked and crumbled", +"slices white bread", +"slices white bread, lightly toasted", +"slices white or wheat bread", +"Slices whole wheat bread lightly toasted", +"slices whole-wheat bread, finely crumbled", +"slivered almonds", +"slivered almonds, lightly toasted", +"slivered almonds, toasted", +"slivered blanched almonds, lightly toasted", +"small-curd cottage cheese", +"smoked chicken, shredded", +"smoked paprika", +"smoked pork", +"smoked salmon, cut into thin strips", +"smoked sausage", +"smoked turkey breast, shredded", +"smooth peanut butter", +"Snipped chives", +"snipped crystallized ginger", +"snipped dates", +"snipped dried apricots", +"snipped fresh basil", +"snipped fresh chives", +"snipped fresh mint", +"snipped parsley", +"snow peas", +"snow peas, cut in half diagonally", +"snow peas, stems removed", +"soda", +"soft bread crumbs", +"soft whole wheat bread crumbs", +"softened butter", +"soup stock", +"sour cream", +"sour milk", +"soy sauce", +"spaghetti cooked according to package directions", +"spaghetti cooked according to package instructions, drained", +"spaghetti pasta", +"spaghetti sauce", +"Spaghetti, cooked", +"Spaghetti, Fusilli or Linguine, uncooked", +"Spaghetti, Linguine or any other long pasta shape, uncooked", +"Spaghetti, Linguine or Thin Spaghetti, uncooked", +"Spaghetti, Thin Spaghetti or Linguine, uncooked", +"Spaghetti, uncooked", +"spaghetti, uncooked, broken in half", +"Spanish onion, finely chopped", +"spinach Fettuccine, uncooked", +"spinach leaves, stems removed and sliced into strips", +"Spinach, cooked & chopped", +"split bagels", +"Sprig parsley", +"sprigs fresh Italian parsley, coarsely chopped", +"sprigs parsley", +"sprigs rosemary", +"sprigs thyme", +"Stalk celery with leaves coarsely chopped", +"stalk celery, trimmed and chopped", +"Stalks celery chopped", +"stalks celery, chopped", +"stalks celery, diced", +"stalks celery, julienned", +"stalks chopped celery", +"steamed milk", +"stew beef chunks", +"stewed tomatoes", +"stick cinnamon", +"strained poaching liquid", +"strawberries", +"strawberries, sliced", +"strawberries, washed and stemmed", +"strawberry jam", +"strawberry puree", +"strawberry-banana yogurt", +"stuffing mix", +"stuffing mix, crushed", +"sugar", +"sugar snap peas, trimmed", +"sugar to taste", +"Sun Dried Tomatoes, softened and minced", +"sun-dried tomatoes in oil; drained, oil reserved, chopped", +"sun-dried tomatoes, drained and cut into strips", +"Sweet and hot mustard", +"sweet basil", +"sweet corn kernels", +"sweet Italian sausage, casing removed", +"sweet onion finely chopped", +"Sweet Pepper Flakes", +"sweet pickle relish", +"sweet potato", +"sweet potato, peeled and cubed", +"sweet potatoes, boiled, peeled and mashed", +"Sweet Red Bell Pepper, thinly sliced", +"sweet red peppers, coarsely chopped", +"sweetened flaked coconut", +"Sweetened whipped cream", +"Swiss cheese", +"Swiss cheese grated", +"Swiss cheese, shredded", +"Tabasco sauce", +"Tabasco, to taste", +"taco sauce", +"Taco shells", +"Tapioca; quick-cooking", +"tarragon", +"tarragon leaves", +"tarragon leaves, crushed", +"tea bags", +"tea bags (green or black)", +"tea bags herbal or black", +"teaspoons milk", +"teriyaki marinade", +"teriyaki sauce", +"Texas Oranges", +"Texas Red Grapefruit", +"Texas Red Grapefruit sections", +"Texas Red Grapefruit, halved", +"Texas Red Grapefruit, peeled, sectioned and chopped", +"Texas Red Grapefruit, sectioned", +"thyme", +"thyme leaves", +"thyme, bunch", +"thyme, crushed", +"toasted almond slivers", +"toasted chopped pistachio nuts", +"toasted cumin seeds", +"toasted oat cereal", +"Toasted pecan pieces", +"toasted pinenuts", +"toasted sesame seeds", +"toasted walnuts, chopped", +"toasted, sliced almonds", +"tomato juice", +"tomato ketchup", +"tomato paste", +"tomato peeled and cut into chunks", +"tomato sauce", +"Tomato slices", +"tomato, diced", +"tomatoes peeled, seeded and diced", +"tomatoes, cut into wedges", +"tomatoes, diced", +"tomatoes, peeled, seeded and diced", +"Topping", +"Toppings", +"Toppings:", +"torn green leaf lettuce", +"torn spinach leaves", +"torn spinach, washed and drained", +"tortilla chips", +"Tortilla Chips, crushed", +"truffle juice", +"Truffle Vinaigrette", +"turkey bacon, finely chopped", +"turkey breakfast sausage cooked", +"turkey breast cubed", +"turkey breast, cut thin strips", +"turkey broth", +"turkey broth and defatted pan juices", +"turkey drumsticks", +"turkey ham diced", +"turkey ham finely chopped", +"turkey liver", +"turkey sausage, casings removed", +"turkey stock", +"turkey tenderloins", +"turkey thighs boneless, skinless, quartered", +"turkey thighs skin removed", +"turkey thighs skinned & boned; cut into 1-inch cubes", +"turkey thighs skinned and boned", +"turkey thighs skinned, boned", +"turkey wings", +"turmeric", +"unbaked 9-inch (4 cup volume) deep-dish pie shell", +"unbaked 9-inch (4-cup volume) pie shell", +"unbleached all-purpose flour", +"unbleached flour", +"unbleached white flour", +"uncooked boneless chicken breast, sliced into thin strips", +"uncooked elbow macaroni", +"uncooked linguine", +"uncooked rice", +"undiluted frozen 100% juice berry concentrate", +"undiluted frozen orange juice concentrate", +"unflavored gelatin", +"unprocessed uncooked wheat bran", +"unsalted butter", +"unsalted butter melted", +"unsalted butter or herbed garlic butter", +"unsalted butter or margarine", +"unsalted butter, cut into small pieces", +"unsalted butter, melted", +"unsalted margarine", +"unsalted peanuts", +"unseasoned bread crumbs", +"unsulfured molasses", +"unsweetened apple juice", +"unsweetened apple juice concentrate", +"unsweetened applesauce", +"unsweetened chocolate", +"unsweetened chocolate, melted and cooled", +"unsweetened cocoa", +"unsweetened cocoa powder", +"unsweetened orange juice", +"vanilla", +"vanilla bean, split", +"vanilla extract", +"vanilla ice cream", +"Vanilla ice cream, softened", +"vanilla lowfat yogurt", +"vanilla yogurt", +"Veal or lamb shanks", +"vegetable base", +"vegetable cooking spray", +"vegetable oil", +"Vegetable oil cooking spray", +"Vegetable oil for sautéing", +"vegetable or olive oil", +"vegetable or peanut oil", +"vegetable or tomato juice", +"vegetable shortening", +"vegetable spray", +"very dry sherry", +"very lean pork, trimmed", +"very ripe banana, peeled", +"Vinaigrette", +"vinegar", +"vinegar (distilled)", +"vinegar, plain or flavored", +"vodka", +"Wagon Wheel Pasta, uncooked", +"walnut halves", +"walnut pieces", +"Walnuts", +"walnuts, finely chopped", +"walnuts, roughly chopped", +"walnuts, toasted", +"warm water", +"water", +"water chestnuts, sliced", +"water or milk", +"Watercress leaves for garnish", +"watermelon", +"wheat germ", +"wheat, rice or corn squares cereal", +"whipped cream", +"whipped honey", +"Whipped topping", +"whipping cream", +"white balsamic vinegar", +"White corn", +"white corn syrup", +"white crabmeat", +"white mushrooms, quartered", +"white mushrooms, well cleaned, and thinly sliced", +"white onion", +"white or yellow sharp cheddar, grated", +"white pepper", +"White pepper to taste", +"white raisins", +"white rice uncooked", +"white sugar", +"white vinegar", +"white vinegar, plus", +"white whole-wheat flour or all-purpose flour", +"white wine", +"white wine vinegar", +"White Wine, dry", +"whole allspice", +"whole bay leaves", +"whole berries for garnish", +"whole black peppercorns", +"whole blanched almonds", +"whole boneless skinless chicken breasts", +"Whole cloves", +"whole cranberry sauce", +"whole kernel corn", +"whole leaf spinach washed and dried", +"whole milk", +"whole natural almonds", +"whole nutmeg", +"whole shallot, finely chopped", +"whole turkey ham", +"whole turkey, neck and giblets removed", +"whole turkey, neck and giblets reserved", +"whole wheat flour", +"whole, pitted dates", +"whole-grain mustard", +"whole-wheat flour", +"whole-wheat or rye flour", +"Wide Egg Noodles", +"Wide Egg Noodles, uncooked", +"wieners", +"wild mushrooms", +"wild rice", +"wine", +"wine vinegar", +"won ton wrappers", +"Worcestershire sauce", +"Worcestershire sauce, to taste", +"Worchestershire sauce", +"yams, peeled and sliced", +"yellow bell pepper chopped", +"yellow bell pepper diced", +"yellow bell pepper seeded and cut into long, thin strips", +"yellow bell pepper, ribs and seeds removed, julienned", +"yellow bell pepper, seeded, ribs removed and chopped", +"yellow corn meal", +"yellow cornmeal", +"yellow mustard", +"yellow onion, peeled and chopped", +"yellow raisins", +"yogurt", +"Yukon Gold potatoes", +"zucchini" + + }); + txtIngredientText.AutoCompleteCustomSource = ingredientAutoComplete; + } + + private void LoadImages() + { + if (!_ImagesAlreadyLoaded) + { + _allButtonImagesList = new ImageList(); + _allButtonImagesList.ImageSize = btnDelete.ClientSize; + _allButtonImagesList.Images.Clear(); + _allButtonImagesList.Images.Add(Properties.Resources.Bar0); + _allButtonImagesList.Images.Add(Properties.Resources.Bar1); + _allButtonImagesList.Images.Add(Properties.Resources.Bar2); + _allButtonImagesList.Images.Add(Properties.Resources.Bar3); + _allButtonImagesList.Images.Add(Properties.Resources.Bar4); + _allButtonImagesList.Images.Add(Properties.Resources.Delete); + _allButtonImagesList.Images.Add(Properties.Resources.Heading); + _allButtonImagesList.Images.Add(Properties.Resources.NotHeading); + _allButtonImagesList.Images.SetKeyName(0, INGREDIENT_LINK_IMAGE_BAR0); + _allButtonImagesList.Images.SetKeyName(1, INGREDIENT_LINK_IMAGE_BAR1); + _allButtonImagesList.Images.SetKeyName(2, INGREDIENT_LINK_IMAGE_BAR2); + _allButtonImagesList.Images.SetKeyName(3, INGREDIENT_LINK_IMAGE_BAR3); + _allButtonImagesList.Images.SetKeyName(4, INGREDIENT_LINK_IMAGE_BAR4); + _allButtonImagesList.Images.SetKeyName(5, DELETE_IMAGE); + _allButtonImagesList.Images.SetKeyName(6, HEADING_IMAGE); + _allButtonImagesList.Images.SetKeyName(7, NOT_HEADING_IMAGE); + + _allHandleImagesList = new ImageList(); + + double handleWidthToHeightRatio = (double)(Properties.Resources.Handle.Width) / (double)(Properties.Resources.Handle.Height); + int handleWidth = (int)((double)(btnHeading.Left) * 0.75); + int handleHeight = (int)((double)(handleWidth) / handleWidthToHeightRatio); + _allHandleImagesList.ImageSize = new Size(handleWidth, handleHeight); + _allHandleImagesList.Images.Clear(); + //_allHandleImagesList.Images.Add(imgImageHandleList.Images[0]); + _allHandleImagesList.Images.Add(Properties.Resources.Handle); + _allHandleImagesList.Images.SetKeyName(0, HANDLE_IMAGE); + + _ImagesAlreadyLoaded = true; + } + + this.btnDelete.ImageList = _allButtonImagesList; + this.btnDelete.ImageKey = DELETE_IMAGE; + this.btnHeading.ImageList = _allButtonImagesList; + this.btnHeading.ImageKey = NOT_HEADING_IMAGE; + this.btnIngredientLink.ImageList = _allButtonImagesList; + this.btnIngredientLink.ImageKey = INGREDIENT_LINK_IMAGE_BAR0; + + + } + } +} diff --git a/JRCookbookControls/JRCookbookEditRecipeIngredient.resx b/JRCookbookControls/JRCookbookEditRecipeIngredient.resx new file mode 100644 index 0000000..56cd609 --- /dev/null +++ b/JRCookbookControls/JRCookbookEditRecipeIngredient.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 118, 17 + + + 118, 17 + + \ No newline at end of file diff --git a/JRCookbookControls/JRCookbookEditTip.Designer.cs b/JRCookbookControls/JRCookbookEditTip.Designer.cs new file mode 100644 index 0000000..454391b --- /dev/null +++ b/JRCookbookControls/JRCookbookEditTip.Designer.cs @@ -0,0 +1,100 @@ + +namespace JRCookbookControls +{ + partial class JRCookbookEditTip + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + txtTipText = new JRCookbookAutoVerticalGrowTextBox(); + btnHeading = new System.Windows.Forms.Button(); + btnDelete = new System.Windows.Forms.Button(); + toolTip1 = new System.Windows.Forms.ToolTip(components); + SuspendLayout(); + // + // txtTipText + // + txtTipText.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + txtTipText.Location = new System.Drawing.Point(112, 3); + txtTipText.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + txtTipText.MinCharactersToMultiLine = 0; + txtTipText.Multiline = true; + txtTipText.Name = "txtTipText"; + txtTipText.Size = new System.Drawing.Size(1461, 47); + txtTipText.TabIndex = 0; + txtTipText.TextChanged += txtTipText_TextChanged; + // + // btnHeading + // + btnHeading.ImageKey = "(none)"; + btnHeading.Location = new System.Drawing.Point(43, 3); + btnHeading.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + btnHeading.Name = "btnHeading"; + btnHeading.Size = new System.Drawing.Size(56, 63); + btnHeading.TabIndex = 2; + toolTip1.SetToolTip(btnHeading, "Toggle Header"); + btnHeading.UseVisualStyleBackColor = true; + btnHeading.Click += btnHeading_Click; + // + // btnDelete + // + btnDelete.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + btnDelete.ImageKey = "(none)"; + btnDelete.Location = new System.Drawing.Point(1591, 3); + btnDelete.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + btnDelete.Name = "btnDelete"; + btnDelete.Size = new System.Drawing.Size(56, 63); + btnDelete.TabIndex = 1; + toolTip1.SetToolTip(btnDelete, "Delete"); + btnDelete.UseVisualStyleBackColor = true; + btnDelete.Visible = false; + btnDelete.Click += btnDelete_Click; + // + // JRCookbookEditTip + // + AutoScaleDimensions = new System.Drawing.SizeF(17F, 41F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + AutoSize = true; + BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + Controls.Add(txtTipText); + Controls.Add(btnHeading); + Controls.Add(btnDelete); + Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); + Name = "JRCookbookEditTip"; + Size = new System.Drawing.Size(1647, 134); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private JRCookbookAutoVerticalGrowTextBox txtTipText; + private System.Windows.Forms.Button btnHeading; + private System.Windows.Forms.Button btnDelete; + private System.Windows.Forms.ToolTip toolTip1; + } +} diff --git a/JRCookbookControls/JRCookbookEditTip.cs b/JRCookbookControls/JRCookbookEditTip.cs new file mode 100644 index 0000000..db4bae6 --- /dev/null +++ b/JRCookbookControls/JRCookbookEditTip.cs @@ -0,0 +1,247 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using JRCookbookBusiness; + +namespace JRCookbookControls +{ + public partial class JRCookbookEditTip : UserControl + { + private RecipeTip _recipeTip; + private bool _DeleteAllowed = true; + private bool _IsEmptyValue = true; + public event EventHandler DeleteRequested; + public event EventHandler IsEmpty_Changed; + + private static ImageList _allButtonImagesList = new ImageList(); + private static ImageList _allHandleImagesList = new ImageList(); + private static bool _ImagesAlreadyLoaded = false; + + private static Point _HandleLocationPoint = new Point(0, 0); + private static bool _isHandleLocationSet = false; + + private const string HEADING_IMAGE = "Heading.bmp"; + private const string NOT_HEADING_IMAGE = "NotHeading.bmp"; + private const string DELETE_IMAGE = "Delete.bmp"; + private const string HANDLE_IMAGE = "Handle.bmp"; + + public JRCookbookEditTip() + { + InitializeComponent(); + LoadImages(); + } + + public JRCookbookEditTip(RecipeTip TipToEdit) + { + InitializeComponent(); + LoadImages(); + recipeTip = TipToEdit; + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public RecipeTip recipeTip + { + get + { + return _recipeTip; + } + set + { + _recipeTip = value; + LoadControlFromObject(); + } + } + + public bool IsEmpty + { + get + { + return _IsEmptyValue; + } + } + + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool DeleteAllowed + { + get + { + return _DeleteAllowed; + } + set + { + _DeleteAllowed = value; + btnDelete.Enabled = _DeleteAllowed; + } + } + + private void btnDelete_Click(object sender, EventArgs e) + { + if (this.DeleteRequested != null) + this.DeleteRequested(this, new EventArgs()); + } + + private void LoadControlFromObject() + { + if (_recipeTip == null) + { + txtTipText.Text = string.Empty; + txtTipText.Font = new Font(txtTipText.Font, FontStyle.Regular); + btnHeading.ImageKey = NOT_HEADING_IMAGE; + } + else + { + txtTipText.Text = _recipeTip.tipText; + if (_recipeTip.isHeading) + { + txtTipText.Font = new Font(txtTipText.Font, FontStyle.Bold); + btnHeading.ImageKey = HEADING_IMAGE; + } + else + { + txtTipText.Font = new Font(txtTipText.Font, FontStyle.Regular); + btnHeading.ImageKey = NOT_HEADING_IMAGE; + } + } + } + + private void btnHeading_Click(object sender, EventArgs e) + { + if(_recipeTip != null) + { + _recipeTip.isHeading = !_recipeTip.isHeading; + } + LoadControlFromObject(); + } + + private void txtTipText_TextChanged(object sender, EventArgs e) + { + _recipeTip.tipText = txtTipText.Text; + CheckForData(); + } + + private void CheckForData() + { + var blnNewIsEmpty = true; + + if (txtTipText.Text.Trim() != String.Empty) + { + blnNewIsEmpty = false; + } + + if (_recipeTip.isHeading) + { + btnHeading.ImageKey = HEADING_IMAGE; + } + else + { + btnHeading.ImageKey = NOT_HEADING_IMAGE; + } + + + if (blnNewIsEmpty != _IsEmptyValue) + { + _IsEmptyValue = blnNewIsEmpty; + + if (blnNewIsEmpty) + { + btnDelete.Visible = false; + } + else + { + btnDelete.Visible = true; + } + + if (this.IsEmpty_Changed != null) + this.IsEmpty_Changed(this, new EventArgs()); + } + } + + + public void ShowInsertionBar(JRCookbookControls.InsertLocation insertLocation) + { + modSharedRoutines.ShowInsertionBar(this, insertLocation); + } + + public void HideInsertionBar() + { + modSharedRoutines.HideInsertionBar(this); + } + + public void DragStarted() + { + modSharedRoutines.DragStarted(this); + } + + public void DragEnded() + { + modSharedRoutines.DragEnded(this); + } + + protected override void OnPaint(PaintEventArgs e) + { + // If there is an image and it has a location, + // paint it when the Form is repainted. + base.OnPaint(e); + + Image myBackgroundImage = _allHandleImagesList.Images[HANDLE_IMAGE]; + + if (!_isHandleLocationSet) + { + _isHandleLocationSet = true; + + int verticalMidpointImage = myBackgroundImage.Height / 2; + int verticalMidpointButton = btnHeading.Height / 2; + int newTop = verticalMidpointButton - verticalMidpointImage + btnHeading.Top; + + _HandleLocationPoint = new Point(0, newTop); + } + + + e.Graphics.DrawImage(myBackgroundImage, _HandleLocationPoint.X, _HandleLocationPoint.Y, new Rectangle(0, 0, myBackgroundImage.Width, myBackgroundImage.Height), GraphicsUnit.Pixel); + + } + + private void LoadImages() + { + if (!_ImagesAlreadyLoaded) + { + _allButtonImagesList = new ImageList(); + _allButtonImagesList.ImageSize = btnDelete.ClientSize; + _allButtonImagesList.Images.Clear(); + _allButtonImagesList.Images.Add(Properties.Resources.Delete); + _allButtonImagesList.Images.Add(Properties.Resources.Heading); + _allButtonImagesList.Images.Add(Properties.Resources.NotHeading); + _allButtonImagesList.Images.SetKeyName(0, DELETE_IMAGE); + _allButtonImagesList.Images.SetKeyName(1, HEADING_IMAGE); + _allButtonImagesList.Images.SetKeyName(2, NOT_HEADING_IMAGE); + + _allHandleImagesList = new ImageList(); + + double handleWidthToHeightRatio = (double)(Properties.Resources.Handle.Width) / (double)(Properties.Resources.Handle.Height); + int handleWidth = (int)((double)(btnHeading.Left) * 0.75); + int handleHeight = (int)((double)(handleWidth) / handleWidthToHeightRatio); + _allHandleImagesList.ImageSize = new Size(handleWidth, handleHeight); + _allHandleImagesList.Images.Clear(); + _allHandleImagesList.Images.Add(Properties.Resources.Handle); + _allHandleImagesList.Images.SetKeyName(0, HANDLE_IMAGE); + + _ImagesAlreadyLoaded = true; + } + + this.btnDelete.ImageList = _allButtonImagesList; + this.btnDelete.ImageKey = DELETE_IMAGE; + this.btnHeading.ImageList = _allButtonImagesList; + this.btnHeading.ImageKey = NOT_HEADING_IMAGE; + + + } + + } +} diff --git a/JRCookbookControls/JRCookbookEditTip.resx b/JRCookbookControls/JRCookbookEditTip.resx new file mode 100644 index 0000000..b3502c9 --- /dev/null +++ b/JRCookbookControls/JRCookbookEditTip.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 118, 17 + + \ No newline at end of file diff --git a/JRCookbookControls/JRCookbookMaskedTextBox.cs b/JRCookbookControls/JRCookbookMaskedTextBox.cs new file mode 100644 index 0000000..8892ba1 --- /dev/null +++ b/JRCookbookControls/JRCookbookMaskedTextBox.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JRCookbookControls +{ + public class JRCookbookMaskedTextBox: System.Windows.Forms.MaskedTextBox + { + private bool _blnMaskFullOnEnter = false; + private bool _blnAutoTab = false; + + public JRCookbookMaskedTextBox() + { + this.Enter += new System.EventHandler(this.MaskedTextBox_Enter); + this.TextChanged += new System.EventHandler(this.MaskedTextBox_TextChanged); + + + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool AutoTab + { + get + { + return _blnAutoTab; + } + set + { + _blnAutoTab = value; + } + } + + private void MaskedTextBox_Enter(System.Object sender, System.EventArgs eventArgs) + { + _blnMaskFullOnEnter = this.MaskFull; + } + + private void MaskedTextBox_TextChanged(System.Object sender, System.EventArgs eventArgs) + { + //Auto-tab if the mask is full + if (AutoTab) + { + if (_blnMaskFullOnEnter == false) + { + if (this.Focused) + { + if (this.MaskFull) + { + this.Parent.SelectNextControl(this, true, true, true, true); + } + } + } + } + } + + } +} diff --git a/JRCookbookControls/JRCookbookNumericTextBox.cs b/JRCookbookControls/JRCookbookNumericTextBox.cs new file mode 100644 index 0000000..cf5a221 --- /dev/null +++ b/JRCookbookControls/JRCookbookNumericTextBox.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace JRCookbookControls +{ + [System.Serializable()] + public class JRCookbookNumericTextBox: TextBox + { + private String _strLastValue = String.Empty; + private bool _blnAllowNegative = true; + private bool _blnAllowDecimal = true; + private bool _blnAllowEmpty = true; + + public JRCookbookNumericTextBox() + { + this.TextChanged += new System.EventHandler(this.NumericTextBox_TextChanged); + this.Validating += new System.ComponentModel.CancelEventHandler(this.NumericTextBox_Validating); + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool AllowDecimal + { + get + { + return _blnAllowDecimal; + } + set + { + _blnAllowDecimal = value; + } + + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool AllowNegative + { + get + { + return _blnAllowNegative; + } + set + { + _blnAllowNegative = value; + } + + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public bool AllowEmpty + { + get + { + return _blnAllowEmpty; + } + set + { + _blnAllowEmpty = value; + } + + } + + private void NumericTextBox_TextChanged(System.Object sender, System.EventArgs e) + { + bool blnValueIsOK = true; + Int32 intPosition = 0; + bool blnAlreadySeenDecimal = false; + + //Allow digits, one decimal point, and minus sign (if first character only) + foreach (char chrCharacter in this.Text) + { + switch (chrCharacter) + { + case char x when (x >= '0' && x <= '9'): + //OK + break; + case '-': + if (intPosition > 0 || AllowNegative == false) + { + blnValueIsOK = false; + } + break; + case '.': + if (blnAlreadySeenDecimal) + { + blnValueIsOK = false; + } + else + { + blnAlreadySeenDecimal = true; + } + break; + default: + blnValueIsOK = false; + break; + } + + intPosition += 1; + + if (!blnValueIsOK) + { + break; + } + + } + + if (blnValueIsOK) + { + _strLastValue = this.Text; + } + else + { + Int32 oldSelectionStart = this.SelectionStart - 1; + this.Text = _strLastValue; + if (oldSelectionStart >= 0 && oldSelectionStart <= this.Text.Length) + { + this.SelectionStart = oldSelectionStart; + } + } + + } + + private void NumericTextBox_Validating(System.Object sender, System.ComponentModel.CancelEventArgs e) + { + if (this.Text == String.Empty) + { + if (AllowEmpty) + { + return; + } + else + { + e.Cancel = true; + } + } + + //Now that we know it's not empty, make sure we have a digit + foreach (char chrCharacter in this.Text) + { + switch (chrCharacter) + { + case char x when (x >= '0' && x <= '9'): + //OK + return; + } + } + + //If we got here, we have hyphen or period, but no digits + e.Cancel = true; + } + + } + +} diff --git a/JRCookbookControls/JRCookbookStrongNameKey.snk b/JRCookbookControls/JRCookbookStrongNameKey.snk new file mode 100644 index 0000000..4ae9cf8 Binary files /dev/null and b/JRCookbookControls/JRCookbookStrongNameKey.snk differ diff --git a/JRCookbookControls/NotHeading.bmp b/JRCookbookControls/NotHeading.bmp new file mode 100644 index 0000000..6ddf02f Binary files /dev/null and b/JRCookbookControls/NotHeading.bmp differ diff --git a/JRCookbookControls/Properties/Resources.Designer.cs b/JRCookbookControls/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e8d4b40 --- /dev/null +++ b/JRCookbookControls/Properties/Resources.Designer.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace JRCookbookControls.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JRCookbookControls.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Bar0 { + get { + object obj = ResourceManager.GetObject("Bar0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Bar1 { + get { + object obj = ResourceManager.GetObject("Bar1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Bar2 { + get { + object obj = ResourceManager.GetObject("Bar2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Bar3 { + get { + object obj = ResourceManager.GetObject("Bar3", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Bar4 { + get { + object obj = ResourceManager.GetObject("Bar4", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Delete { + get { + object obj = ResourceManager.GetObject("Delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Handle { + get { + object obj = ResourceManager.GetObject("Handle", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Heading { + get { + object obj = ResourceManager.GetObject("Heading", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap NotHeading { + get { + object obj = ResourceManager.GetObject("NotHeading", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/JRCookbookControls/Properties/Resources.resx b/JRCookbookControls/Properties/Resources.resx new file mode 100644 index 0000000..64c16bf --- /dev/null +++ b/JRCookbookControls/Properties/Resources.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Bar0.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Bar1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Bar2.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Bar3.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Bar4.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Delete.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Handle.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Heading.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\NotHeading.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/JRCookbookControls/Search.BMP b/JRCookbookControls/Search.BMP new file mode 100644 index 0000000..18c8408 Binary files /dev/null and b/JRCookbookControls/Search.BMP differ diff --git a/JRCookbookControls/modSharedRoutines.cs b/JRCookbookControls/modSharedRoutines.cs new file mode 100644 index 0000000..0b4c345 --- /dev/null +++ b/JRCookbookControls/modSharedRoutines.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing; +using System.Windows.Forms; + +namespace JRCookbookControls +{ + + internal static class modSharedRoutines + { + internal static void ShowInsertionBar(Control control, JRCookbookControls.InsertLocation insertLocation) + { + if (insertLocation == InsertLocation.InsertBefore) + { + DrawLine(control, 0, 0, control.Width - 1, 0, System.Drawing.SystemColors.MenuHighlight); + } + else if (insertLocation == InsertLocation.InsertAfter) + { + DrawLine(control, 0, control.Height - 1, control.Width - 1, control.Height - 1, System.Drawing.SystemColors.MenuHighlight); + } + } + + internal static void HideInsertionBar(Control control) + { + DrawLine(control, 0, 0, control.Width - 1, 0, System.Drawing.SystemColors.Control); + DrawLine(control, 0, control.Height - 1, control.Width - 1, control.Height - 1, System.Drawing.SystemColors.Control); + } + + internal static void DragStarted(Control control) + { + control.BackColor = System.Drawing.SystemColors.MenuHighlight; + } + + internal static void DragEnded(Control control) + { + control.BackColor = System.Drawing.SystemColors.Control; + } + + private static void DrawLine(Control control, int x1, int y1, int x2, int y2, Color color) + { + System.Drawing.Pen myPen; + myPen = new System.Drawing.Pen(color, 1); + System.Drawing.Graphics line = control.CreateGraphics(); + line.DrawLine(myPen, x1, y1, x2, y2); + + //control.Refresh(); + + myPen.Dispose(); + line.Dispose(); + } + + } +}