From cae1a3ec46fdc5e735713f86d6d0da0a83d89db9 Mon Sep 17 00:00:00 2001 From: Jon Date: Sat, 7 Mar 2026 19:22:22 -0600 Subject: [PATCH] Initial population --- .gitignore | 428 ++ JRCookbook.sln | 37 + JRCookbook/CommonRoutines.cs | 14 + JRCookbook/Constants.cs | 19 + .../18.3.511.5503/CodeChunks.db | Bin 0 -> 778240 bytes .../18.3.511.5503/SemanticSymbols.db | Bin 0 -> 499712 bytes JRCookbook/DesignTimeBuild/.dtbcache.v2 | Bin 0 -> 177106 bytes ...01a4d00a-b844-4bf4-83a8-37c4396f6203.vsidx | Bin 0 -> 221 bytes ...17107a6e-83c4-46f1-b2bc-9f3254d89b22.vsidx | Bin 0 -> 322555 bytes JRCookbook/JRCookbook.csproj | 58 + JRCookbook/JRCookbookStrongNameKey.snk | Bin 0 -> 596 bytes JRCookbook/JRJRAdhocUpdateForm.Designer.cs | 114 + JRCookbook/JRJRAdhocUpdateForm.cs | 124 + JRCookbook/JRJRAdhocUpdateForm.resx | 60 + JRCookbook/Program.cs | 23 + JRCookbook/Properties/Resources.Designer.cs | 73 + JRCookbook/Properties/Resources.resx | 124 + JRCookbook/Search.BMP | Bin 0 -> 7654 bytes JRCookbook/frmEditCookbook.Designer.cs | 180 + JRCookbook/frmEditCookbook.cs | 92 + JRCookbook/frmEditCookbook.resx | 120 + JRCookbook/frmEditCookbookChapter.Designer.cs | 130 + JRCookbook/frmEditCookbookChapter.cs | 102 + JRCookbook/frmEditCookbookChapter.resx | 120 + JRCookbook/frmEditRecipe.Designer.cs | 456 +++ JRCookbook/frmEditRecipe.cs | 725 ++++ JRCookbook/frmEditRecipe.resx | 63 + JRCookbook/frmFindIngredient.Designer.cs | 127 + JRCookbook/frmFindIngredient.cs | 131 + JRCookbook/frmFindIngredient.resx | 123 + JRCookbook/frmMainRecipe.Designer.cs | 398 ++ JRCookbook/frmMainRecipe.cs | 651 ++++ JRCookbook/frmMainRecipe.resx | 78 + .../frmPickRecipeIngredient.Designer.cs | 232 ++ JRCookbook/frmPickRecipeIngredient.cs | 238 ++ JRCookbook/frmPickRecipeIngredient.resx | 120 + JRCookbook/frmRecipeCopyMoveTo.Designer.cs | 92 + JRCookbook/frmRecipeCopyMoveTo.cs | 147 + JRCookbook/frmRecipeCopyMoveTo.resx | 60 + .../frmViewRecipeNutritionAll.Designer.cs | 1552 ++++++++ JRCookbook/frmViewRecipeNutritionAll.cs | 359 ++ JRCookbook/frmViewRecipeNutritionAll.resx | 126 + JRCookbook/v18/.futdcache.v2 | Bin 0 -> 405 bytes JRCookbook/v18/DocumentLayout.backup.json | 242 ++ JRCookbook/v18/DocumentLayout.json | 226 ++ JRCookbookBusiness/Constants.cs | 55 + .../Converters/CssStylesheet.cs | 255 ++ .../Converters/HtmlCSSParser.cs | 844 ++++ .../Converters/HtmlEncodedTextWriter.cs | 26 + .../Converters/HtmlFromXamlConverter.cs | 577 +++ .../Converters/HtmlLexicalAnalyzer.cs | 745 ++++ JRCookbookBusiness/Converters/HtmlParser.cs | 539 +++ JRCookbookBusiness/Converters/HtmlSchema.cs | 733 ++++ .../Converters/HtmlToXamlConverter.cs | 2765 +++++++++++++ .../Converters/HtmlTokenType.cs | 22 + JRCookbookBusiness/Cookbook.cs | 586 +++ JRCookbookBusiness/CookbookChapter.cs | 410 ++ JRCookbookBusiness/Ingredient.cs | 1310 +++++++ JRCookbookBusiness/IngredientMeasure.cs | 86 + .../IngredientSkipSearchWord.cs | 95 + JRCookbookBusiness/IngredientUsage.cs | 269 ++ JRCookbookBusiness/JRCookbookBusiness.csproj | 40 + .../JRCookbookBusinessAppManagement.cs | 27 + .../JRCookbookStrongNameKey.snk | Bin 0 -> 596 bytes .../LongRunningStatusUpdatedEventArgs.cs | 22 + JRCookbookBusiness/Measure.cs | 138 + JRCookbookBusiness/Recipe.cs | 3435 +++++++++++++++++ JRCookbookBusiness/RecipeHighlights.cs | 116 + JRCookbookBusiness/RecipeIngredient.cs | 295 ++ JRCookbookBusiness/RecipeIngredientHeading.cs | 30 + JRCookbookBusiness/RecipeIngredientItem.cs | 163 + JRCookbookBusiness/RecipeProcedure.cs | 135 + JRCookbookBusiness/RecipeTip.cs | 137 + JRCookbookBusiness/SharedRoutines.cs | 41 + JRCookbookBusiness/Trackback.cs | 30 + JRCookbookBusiness/Utility.cs | 109 + JRCookbookBusiness/clsDatabaseLayer.cs | 1196 ++++++ JRCookbookBusiness/clsDatabaseLayerBase.cs | 171 + JRCookbookBusiness/clsDiacriticRemover.cs | 376 ++ JRCookbookBusiness/clsWord.cs | 128 + JRCookbookControls/Bar0.bmp | Bin 0 -> 7654 bytes JRCookbookControls/Bar1.bmp | Bin 0 -> 7654 bytes JRCookbookControls/Bar2.bmp | Bin 0 -> 7654 bytes JRCookbookControls/Bar3.bmp | Bin 0 -> 7654 bytes JRCookbookControls/Bar4.bmp | Bin 0 -> 7654 bytes JRCookbookControls/Delete.bmp | Bin 0 -> 7654 bytes JRCookbookControls/Handle.bmp | Bin 0 -> 3678 bytes JRCookbookControls/Heading.bmp | Bin 0 -> 7654 bytes .../JRCookbookAutoVerticalGrowTextBox.cs | 73 + JRCookbookControls/JRCookbookControls.csproj | 38 + JRCookbookControls/JRCookbookControlsEnums.cs | 16 + .../JRCookbookEditProcedure.Designer.cs | 100 + JRCookbookControls/JRCookbookEditProcedure.cs | 244 ++ .../JRCookbookEditProcedure.resx | 123 + ...JRCookbookEditRecipeIngredient.Designer.cs | 151 + .../JRCookbookEditRecipeIngredient.cs | 2698 +++++++++++++ .../JRCookbookEditRecipeIngredient.resx | 126 + .../JRCookbookEditTip.Designer.cs | 100 + JRCookbookControls/JRCookbookEditTip.cs | 247 ++ JRCookbookControls/JRCookbookEditTip.resx | 123 + JRCookbookControls/JRCookbookMaskedTextBox.cs | 60 + .../JRCookbookNumericTextBox.cs | 158 + .../JRCookbookStrongNameKey.snk | Bin 0 -> 596 bytes JRCookbookControls/NotHeading.bmp | Bin 0 -> 7654 bytes .../Properties/Resources.Designer.cs | 153 + JRCookbookControls/Properties/Resources.resx | 148 + JRCookbookControls/Search.BMP | Bin 0 -> 7654 bytes JRCookbookControls/modSharedRoutines.cs | 56 + 108 files changed, 28484 insertions(+) create mode 100644 .gitignore create mode 100644 JRCookbook.sln create mode 100644 JRCookbook/CommonRoutines.cs create mode 100644 JRCookbook/Constants.cs create mode 100644 JRCookbook/CopilotIndices/18.3.511.5503/CodeChunks.db create mode 100644 JRCookbook/CopilotIndices/18.3.511.5503/SemanticSymbols.db create mode 100644 JRCookbook/DesignTimeBuild/.dtbcache.v2 create mode 100644 JRCookbook/FileContentIndex/01a4d00a-b844-4bf4-83a8-37c4396f6203.vsidx create mode 100644 JRCookbook/FileContentIndex/17107a6e-83c4-46f1-b2bc-9f3254d89b22.vsidx create mode 100644 JRCookbook/JRCookbook.csproj create mode 100644 JRCookbook/JRCookbookStrongNameKey.snk create mode 100644 JRCookbook/JRJRAdhocUpdateForm.Designer.cs create mode 100644 JRCookbook/JRJRAdhocUpdateForm.cs create mode 100644 JRCookbook/JRJRAdhocUpdateForm.resx create mode 100644 JRCookbook/Program.cs create mode 100644 JRCookbook/Properties/Resources.Designer.cs create mode 100644 JRCookbook/Properties/Resources.resx create mode 100644 JRCookbook/Search.BMP create mode 100644 JRCookbook/frmEditCookbook.Designer.cs create mode 100644 JRCookbook/frmEditCookbook.cs create mode 100644 JRCookbook/frmEditCookbook.resx create mode 100644 JRCookbook/frmEditCookbookChapter.Designer.cs create mode 100644 JRCookbook/frmEditCookbookChapter.cs create mode 100644 JRCookbook/frmEditCookbookChapter.resx create mode 100644 JRCookbook/frmEditRecipe.Designer.cs create mode 100644 JRCookbook/frmEditRecipe.cs create mode 100644 JRCookbook/frmEditRecipe.resx create mode 100644 JRCookbook/frmFindIngredient.Designer.cs create mode 100644 JRCookbook/frmFindIngredient.cs create mode 100644 JRCookbook/frmFindIngredient.resx create mode 100644 JRCookbook/frmMainRecipe.Designer.cs create mode 100644 JRCookbook/frmMainRecipe.cs create mode 100644 JRCookbook/frmMainRecipe.resx create mode 100644 JRCookbook/frmPickRecipeIngredient.Designer.cs create mode 100644 JRCookbook/frmPickRecipeIngredient.cs create mode 100644 JRCookbook/frmPickRecipeIngredient.resx create mode 100644 JRCookbook/frmRecipeCopyMoveTo.Designer.cs create mode 100644 JRCookbook/frmRecipeCopyMoveTo.cs create mode 100644 JRCookbook/frmRecipeCopyMoveTo.resx create mode 100644 JRCookbook/frmViewRecipeNutritionAll.Designer.cs create mode 100644 JRCookbook/frmViewRecipeNutritionAll.cs create mode 100644 JRCookbook/frmViewRecipeNutritionAll.resx create mode 100644 JRCookbook/v18/.futdcache.v2 create mode 100644 JRCookbook/v18/DocumentLayout.backup.json create mode 100644 JRCookbook/v18/DocumentLayout.json create mode 100644 JRCookbookBusiness/Constants.cs create mode 100644 JRCookbookBusiness/Converters/CssStylesheet.cs create mode 100644 JRCookbookBusiness/Converters/HtmlCSSParser.cs create mode 100644 JRCookbookBusiness/Converters/HtmlEncodedTextWriter.cs create mode 100644 JRCookbookBusiness/Converters/HtmlFromXamlConverter.cs create mode 100644 JRCookbookBusiness/Converters/HtmlLexicalAnalyzer.cs create mode 100644 JRCookbookBusiness/Converters/HtmlParser.cs create mode 100644 JRCookbookBusiness/Converters/HtmlSchema.cs create mode 100644 JRCookbookBusiness/Converters/HtmlToXamlConverter.cs create mode 100644 JRCookbookBusiness/Converters/HtmlTokenType.cs create mode 100644 JRCookbookBusiness/Cookbook.cs create mode 100644 JRCookbookBusiness/CookbookChapter.cs create mode 100644 JRCookbookBusiness/Ingredient.cs create mode 100644 JRCookbookBusiness/IngredientMeasure.cs create mode 100644 JRCookbookBusiness/IngredientSkipSearchWord.cs create mode 100644 JRCookbookBusiness/IngredientUsage.cs create mode 100644 JRCookbookBusiness/JRCookbookBusiness.csproj create mode 100644 JRCookbookBusiness/JRCookbookBusinessAppManagement.cs create mode 100644 JRCookbookBusiness/JRCookbookStrongNameKey.snk create mode 100644 JRCookbookBusiness/LongRunningStatusUpdatedEventArgs.cs create mode 100644 JRCookbookBusiness/Measure.cs create mode 100644 JRCookbookBusiness/Recipe.cs create mode 100644 JRCookbookBusiness/RecipeHighlights.cs create mode 100644 JRCookbookBusiness/RecipeIngredient.cs create mode 100644 JRCookbookBusiness/RecipeIngredientHeading.cs create mode 100644 JRCookbookBusiness/RecipeIngredientItem.cs create mode 100644 JRCookbookBusiness/RecipeProcedure.cs create mode 100644 JRCookbookBusiness/RecipeTip.cs create mode 100644 JRCookbookBusiness/SharedRoutines.cs create mode 100644 JRCookbookBusiness/Trackback.cs create mode 100644 JRCookbookBusiness/Utility.cs create mode 100644 JRCookbookBusiness/clsDatabaseLayer.cs create mode 100644 JRCookbookBusiness/clsDatabaseLayerBase.cs create mode 100644 JRCookbookBusiness/clsDiacriticRemover.cs create mode 100644 JRCookbookBusiness/clsWord.cs create mode 100644 JRCookbookControls/Bar0.bmp create mode 100644 JRCookbookControls/Bar1.bmp create mode 100644 JRCookbookControls/Bar2.bmp create mode 100644 JRCookbookControls/Bar3.bmp create mode 100644 JRCookbookControls/Bar4.bmp create mode 100644 JRCookbookControls/Delete.bmp create mode 100644 JRCookbookControls/Handle.bmp create mode 100644 JRCookbookControls/Heading.bmp create mode 100644 JRCookbookControls/JRCookbookAutoVerticalGrowTextBox.cs create mode 100644 JRCookbookControls/JRCookbookControls.csproj create mode 100644 JRCookbookControls/JRCookbookControlsEnums.cs create mode 100644 JRCookbookControls/JRCookbookEditProcedure.Designer.cs create mode 100644 JRCookbookControls/JRCookbookEditProcedure.cs create mode 100644 JRCookbookControls/JRCookbookEditProcedure.resx create mode 100644 JRCookbookControls/JRCookbookEditRecipeIngredient.Designer.cs create mode 100644 JRCookbookControls/JRCookbookEditRecipeIngredient.cs create mode 100644 JRCookbookControls/JRCookbookEditRecipeIngredient.resx create mode 100644 JRCookbookControls/JRCookbookEditTip.Designer.cs create mode 100644 JRCookbookControls/JRCookbookEditTip.cs create mode 100644 JRCookbookControls/JRCookbookEditTip.resx create mode 100644 JRCookbookControls/JRCookbookMaskedTextBox.cs create mode 100644 JRCookbookControls/JRCookbookNumericTextBox.cs create mode 100644 JRCookbookControls/JRCookbookStrongNameKey.snk create mode 100644 JRCookbookControls/NotHeading.bmp create mode 100644 JRCookbookControls/Properties/Resources.Designer.cs create mode 100644 JRCookbookControls/Properties/Resources.resx create mode 100644 JRCookbookControls/Search.BMP create mode 100644 JRCookbookControls/modSharedRoutines.cs 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 0000000000000000000000000000000000000000..99178918aa97fc63223eb16ed188b572b580dde8 GIT binary patch literal 778240 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

_5E)ng@MM+ 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

rj!C~N-4mmlmcu@DZr+b0&Get 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

    Vot)6jHJzo%@^$HgtsrcLqWe@ zp$Dwt>^*BZnT9ON@wDnaeg6;;dv^$kOjSXxq0UgS-Palog~j`ZfY>`jKx7I|sbKz$ zABul8Mc9+32$`%#e7s-pHAUFlrU;pY%mVt1=FrAaxUDkODg}}u>=HgKA&(zUd3(Fr zDjYTV4aD);HRw0`m+@=~hhZ}}hW6-vTMiwhS80Uvb%3qaieJ?S+znsuWHsa1;fQEev?~Z#E_!x^eBriLV1DNh)BC5f zH9XB1Y=m_4zbsnS-B#ZYJ=Ti@hfW4>+XN8kuUsw4WrxP&al4*{d8{N3H5P^i zIAZmWwV_BK)>@>}7xkG&D%+&NE8uaJpntD6MEmGZwKfJgr|2=QF)Db6;}Lkciwg#< zNo$O9urJ)n%Jo<<)Vh_! zR)7YX-lnj8$OoUWU-6aJP;v<0@FLa*y5pZftF7$~Mgzz{vcQV~XJ8SSMQbXh>#!SI zw77Hwj>488XfVq&J^>tt31(j^~ZD`B`IbHTuZzxtxFS}h>{kY7!u@b^>_l^=IQ zl%ICe|EB!3Jrs)4Pf~u`M*p4iQ(TAX$A_@ZYTM{_&leOu?OWT{Q3NLa#H7idA5a?!-gl|g5vcq+VKHULzJuuBo$YzHmC)sfYYH8D#fv4eY zJSTBrNe9)z2GjTsU&IeaK>jfKGp=H=6M&jUXg6m?W5$Jvm)}Ga&gBWdpvg#eJ$N$p zi+lN;mXHt;*YK9H*aOMlRAWx|=&hN&(-B_cqY;WoPT7a&|FeX<1n*Veb)FABop1x- zdiNsN1Fj9u*PLfN%aym3)0LTyKRNa|=Gp%SZ~l#w?~#3Sj_rP1)HYSRTiPssDV{4X zWq)HQgRK7=J(HG`|B&;@6hQia`(IoCa?p(&54tl3miXWf(QFEU3SaBP_qou&p@^^3 zzt`vQ4ym%Y1&ByDW)o@88Zp$rj4QU_cxRO51Uf@qp$=acE=wl4xGe>oNX=u2RM;SH z>pv1I)(ZzWqb$%LjQXNbyB?T5L&3JhD3O?#h<~YuQ}v~Q-VfT^(V=hci$r0u(|(9} zr%c2XmW!+VmjJp}&~T3uU8n~HHXs)M5-|*(o0lvT>-vuXWF25hI!a`n;ZRqgx2skA zC1Mfy%=-5VsO;h2t+KEqz{;vWguMz*9j{p~HuoO}=(<1)KU(@=U!-oH5v3L+>>MXy zTPvX2i@#&FgP|~7;BW0ze+gR!)y`ZY?&x0x2#}v~yS66i>1zWKs z2%-N4H#)yx4UMtzyETTd3vPaMO+u>?B=l-973!%F+xiy(+R=||m}j9e{E>EGg&x!t z1iCFigf^mUqBSte=0h=~A7y5o?Y?MI6pnx4Wr;_t#iRR60ev6bh#74U7`4E*kC+SK z077oeBm}JW+xknscSC8LUvnWEh>*?MgiKij%sCH=`3_@J>kl0_yt!c~!t*#L4+VtZ zVFCimaEz-zM0iLh!kNo~zPaC#zV>$D5m=wqUm_d_^i{2Z8EpG2z?u0QvTn zz`?Ts`RF;AtLn`9z99hN+pLia}!t|AcRjX2LhcOMqu*0GiQ{DP6m${|eva z*@drPT>-P%bU--z*$g+`CM9H2RQUQqukiJct6@Ev2Ixn>o($Cr4uuF`@5&OsK4P`F zsUJN$?SdoQ(Q!k9$}k}!d_Bc29DJ_|P@`|A?}FN-RMaL$bzKw=J_D$KRt2*e_pdZ+ zaZ1Cc{Rjt7m4$;%%K;raO&a~==nHc7r1m2mECY1Paxv0B5v5lr9LtWbQBgJnwSYc( zn-4X^FV8KM#9mltBilgDbhlxkU z$^nV_y7&l4bi$BERm+u7djs6?bbiB?)#8R&85Cf?=bpNNsD2Z@$=?G~0-UjxSb!Q% z%5GQ>;#X`%+K3ZKtn>%{QNIPKVR3eYy+Uk^q0UFWt)v*2PeHvz=SrrbVH8G83oIh}LiS*3VrI7ICPqF<wMn2g-gLA4^=W|hXJYS+OtC?3pIoOaAK@( zyl3ruE5v9FRWasUo2k)REJPL{cBpU-`!HK{*WAPYQS+|#%G4Y~h0R)%p;zi+lUAem zg!|P;qQ4}+Bl8_vY7sX_UKv9bjrrbYYP80>V}#b!3y&$nFW}y043#qGi<>DC!K!1- z$#8LV!?zPRPMQ-#ZHxIDi0OM{LWgT08)wmtE0oxpSZOARkWv#4B3P;^i4~iChoQt^ zlrmRWl*2(+Z#Nv%cQnE7xi_-D2i~KElfvB~$)=HI`z=$C%Aw8MucG%k(#RgSxvvck zQ*K$fBT^hIilMINz}k3iBB?6_*EjWHAU>n=l7zs}3wQ>Nr#BO(RRg7gN`jvlANLXD=kW+_lDN zMYSV_S|#nSFK`TL8G&e(#0EGWHM;{I0&S?zYdCFv!&2cFX8)_E&#Z`X$51CV3g^UX zv3RepIb>?Jq2SuZ`L$7YckL|EW~Rsdr8PmQ(;78F>LtG+1ew9BX5_DGWp}MA5G6A~ z<}4Nj9UDWnnCaT_`qaIJo(XqwCr2eJB|`u!zs#&I5nfvP0h#0&l4wzSY_jxO3#QH%I=w5E{QLd{aTu5IU*CVS<&l`p)PLJ-KUCEL%PolUUqK& zvM1?t%T8t!&E03tVnxuD7;5fRpO$=f9>y22)%Ztw$3&MtM`^>|NIl~H2}|a&)knO_ zE>_7)nbV5Oq8O?H)0=gzs5H02Na+h6n6yxl9$D~P+jvV#&A6;+oft#SVqbNfBfC;_ zq!leN>85Vbc;dV#3rn)u1@rD_Z(C9s&uC2|YAwG5iGWq>Sql=A6Xz&}bJntBW`E7@ zOe8TmqZNsHG1P;aoUnI{(27ZWIum`CDaCh=E&h^zUVH$KPUgf>bdkwwNdy)5adYU)l?V!!%3Gx8B!@Jshm^at+x#tDX1D+c_=Xs9x z?C`AjlzXOosQYdApWWBEPjYW_FLmd^eT8RTce#G%I?2`P+UQ#9n&^_8A3C3M-tD}? zd7`u1+32ir7CRlv*UHDr>&mmrL(1=zYn1bqJ@7h0gHooHDpM4ArPlF@<8{Z=44OZ=3ItgZ7V>l54a9w?jL!qRDt#-c%)&R{fK`V3S<94V>K`V>h?=7 z8^K46;AL>JL#jZ-XZ1ize9Q>5zZzjOrhQ+6o zk!WgK@hMJ}cIYW`17i3ZPb|eJ)FkzsQG6Ut;4E8Q_&2Y%dNEGmR#QXk#XhyJFIkjS zU-sW509lw!yLL{_{*fYqaBEg`BS6cro3a0rfMmX9bFtSf!K5^~K&=(ot0@vliMe^% zP39PxhaXh{3V1~}>Q{|q(O{YF;O(jQ0{fjQLJl=|3Df#cI|!bOY?~l)l3Vdx4Mgri zvoaV6s78o$wz_gO<*+$Jl6IqsG9OIfG#O2RZBJT^ejAMQL-1SkXgbUSHpK$wMANnS zw3oN+~b+ICB)_?#Ks}zf ziduEFf`vkj(+Dt~-Kn;k?IW}hhD2>@(V&kb?+p3GR-Z^hT@ndvlSrtsUoOZ%f>jal zm`-xnd}fu;_K8)8eVj&rYe(gIICj2KcdMcVRLaot7nc5JGoot*A z;rB2g74#gccB5%st(uGcMl0W(MD8kNM`9ZSu&EUsiNgI>v^&;5xdo?^p{e9X^#89v|a1#lz^H>M&KE*4EB z@u-MBS^+jrp@_e^6E3xP`y&zk<^c02azEi_5_OwWz^puA5th&>^T6+?BqxhJ@HT39&Fv z%hUt{u8FgZPJo6(Yt~1KSd%3d*vG2vq)x)Z%~M$Q@EL_?hRLE~xq3(wYve$2!k^+@ zoJ6be;1JBo+ic;gA()LU0>5aN(2~MET+RwcP-#ua@NNo5Dg$r{6mA2+`zc-EM+fxT0KS?R%Q9g5P*Ef8q`430wmwbi+pg&@9L*gZKD&9iTZX~GR zzKl(R*DL%@a4E^(rV|1)Fjx!Xoj39rUw$x)_9gu@HWL46Xm;x6GffaYKSXGd%c>YI z16<%yCA0@c)d)L^&s3TLGy9)8MvmZ3sv0A+&rK0>I3H?;O)+~S2|x~0F{zs+_L(_G z7Atgta53qkuI;Xst{JWj=hx1EIiGai=e*T<71;kD=j?Dcu#edD>^^oq`x!f(9mj%f zE30P}Y%wch1@J297w|67OY{+Xw=);)0e%iQ<=05_rLmGA{!@HZyvcLEXSc`aS>~DH z$#8$_e$jo8`zrT|?oRhw_X77A8gT4&9POxfOoi7K-?Kkqztw&r+%jmjueHyy7uqxJ zl6a*!ARa4j5KCa^{kifRx)JmPM~Y*>N5EzDOz~X#1Nm|JX89s{pWGxbkUh3fZO_5m zgx5(A+b*)jY^}B`=~~-N+c=xo#z3p_j`R}QN4m%Wxq_TWm%1KuMajeDMmkP93p_Wy zCG93JI_D`5CKME?d(ZNAdDnRtc*l4?@I30d0rV1oV!vjW zveVdJXq9DbGT21CN1vv5(2Ie4p=-qx=|h6E+8?d+@2SCl(~jrJ7<0sJj__@YmW^hb zQfLOUj@4a-<+x#K3q(*PXybSB;dM_|Nc0CL4&abdKZHwFQRCtR`#Mz$S&^bJc97Nx zcBqlLI<~QNQ1Ecan%(fgfenX8WmRoebCvpzf}D+$d1YBm?dFyZWwq<8TAIq5*Eg0m zS5>yGENiAKz^#-F^Cs3qoj&0P4f+p|3$OvSI|u9wQ-mzVNCn)%gFAQRPh8UwiKx4j zPQO1&8-{}F@bY&>W9>>>WM{bqLlT$3;PPZtAIi9n(TDh|4k37msWU46CLzjta6Gs2 zs|(`ajWGLz5hhFcID|`oa2gp6z&%7w5)18wli8hcNl@D=>2dKoRmRcd?5w1CH=q49 zKWN(A9%1KNLL+=h)$+EgwjfaCUQ4ieJ(7x@$LBw2^vM!-e!L^fwRIgZ{0(cUCP;rx zmFa#{ru$N5`l%_?PfX$Cu-a+~<$X}%W>eY*uc%Up$Kd18*3`7=$s+=%4#dHq}eFbn(>v_)Hm1E(L-=e zF~iF$D}lS4)>oG`Hqluo&J|xuHR#0GuvCi?F20J`Q{5aAU%@4?E%CmO_%ar$%_G7G z=E&{l$jP|5)Us_fg=d<=8N6$F&&^hrY=>f|qUN=es7DFUeO1Wl3Tl|M(5g zx%^{2nZy5Sj4*bADZEb|iE&o|8a4x2W-9hG>4n62R?n}*<)nz{;Fi`xYAxY$tB zT(-8Ru4N5flPal-u1=LyNo!IiRnS$q`LZgjd=afqo(FU~%1cV=%2YVZXccZJ%s89t zo6A7uQr1{rziM+Ou3@w?d9r9;RfBb;70HuDQ+*{)BIU{RP7^Gab(m7-iV3fPaSQH` zRPLOQ`k(~JJk&pG5WOe01z~#Xq{*q1CZ$d)MEzA#Ssn|RVgZwpfsB_ag`Z?FTu0+# zf;=T5YWp&29kP8fL>{nxm@Hb@-cCgFY%-E(h9dd%5F`&8d~dq~r$)QI-&E=Ihv)>Ji@HEwQMSyNus zNK2E8tEg{i0C>rGb|k@h(OCM7rwD4Mu$tt=nh5v$0Oy$e0CUMKws}aF_>BlWjcD}m z>cyL>ZP2nylCvUP)`R@B(t-?3<39eYQ+!wn&X-nMkf^WlTDePcr1_zWeoaMWR29dk z@ET5B=5!)tu<67MDJ@`&H9*qZFcI~tYF0hP;Re>9DMSSCCEiNUKRw5JX1X7D``wD` zk8lR=cHZpV4rkpzRpvQfb)4t$ITSeOUoO8W_sWxO=i4So2gJL@CG0`AfZj&ulIzK8 zGFEs9&<*!rLkwT5>M%JgPsgXBp>j4t>+6KSD#8s*#C0+LaMcoiKZ4?unrWbfMa{}3 zEWC|8YvRONtLMbx}?X zkukJWCS?7oAnOC+{;a!%PdO)8eqB@?iM2s{sJ?-Dd(@;u4nK=imB*%_>t(0gBVFNo zQhId+huiyO`0AI&j%aY3E<2h}=%8eC)K%(rb!>M{PwOSt*z(v8?1ypd<74jFbSiFX zdXZ%8l1?7wi)qdZ;aTNwVm9bJ9ZICs{zc<#+t)4?4sLC#2qnw zc}<-~(?@FMP0I>K7v#`MSO`AQHtIqwoCH}uDEm{FyMk`XCo1C zBwJz*Z#=}ckuHMURvQ3SnzyaM-ehF}oIeJ@hOMI{k{I3aws*tbOTnA?dO)b!*Qy

    x5c-1jx>XZ#X9lN1(HC!OXhu*&H&BTR6Zze9>usVCg*h=x3SQ8*tO_)cbKjBnU z+swnsr>d11HgWwYh3oHM3qJet#W(Ytf~gye<5N*{lY!*;`fD=Q_pK1O#MS}IfXSPC zS}2XPc@tg(xPEi)`dQ#5A%-upjpDAYN^jg=z>HhBAz1IsX?_WBgw_M<@7kdYhIZ(J z=6kZ6e_RRIBkKThdeDxj$L{El&xBGwY*X&1ub^Pu28uzK>E9!Pf-5cz)-DU3C z?tHi4dIx+2UgkQT<+%2_wz#TY^IZil(fN_{MduyPOPsy%Zs2O?Jf~!zsJx>*t=y$t zpzKq&DGQV=$H$I`99KAw18u@e$8?9o{(=2o`?+>1zau{<|55(Ae1hC1H-Lx!i88Uh zVSCK>TiX@3Q*66zn`}qgir5jhTpNW`;!mU(rF-a4=`GR~^f~Exx<&HQW2I%ZSSq5G zl2iN&?iM^N-X-2BULl?*_KQ8@QQ|tW61?)y6kY5K_8NPf-3Jx#Cf9m?4j%juFu&(v z@*{GW=T^_NWD_~pb2?j3-X|}U$Gu_iChtP;1h3%vi|5y#OKZyn0h%p)RaF_N!K&30 zZW}`lvU+RO_VZ5EqpbqZZ0g(aaDD{~wC!os-mEICtE|8F5A1w3yKo5}_NbhpLK?xhu^$YJ*rh2`PDSG}^_yXD7Yo0^ zV_JCq1Hu|we%KJ2JLrtZ)5o-j# zy|pB9J1X2ef_<&XW}lcNc2k5jBGYyRd!xQC&By(}hd|_H2wA71=mjsGe(_^-#Ab?+ z22{gCH#LW%KCPp;aVfhhRl;d_lmlPz18mxibwVyt?XTFj1g=RsGX4h+O3cg+Bsu%T zdGYJ0|BgeARyUnBznZ|w@htq@^)) zGoP#eg0;ns{Cy~EZyEw3FX90fkczf)&AtxRk@ltf5I_UEUA?|w6S#F&lP=Tx0Q1Aa z5xTWk6D~pBzJ^G{Y$NPbDW9r0jjCQ09Z(b#)QffwL^z{bJZ;@~lRo_BFDFc-c@Gc}DAycs^~m6R*@LHVWl6QSG#2IN*S`Rn2Q_ zrR{1?%^`s*lQxG|a#2{?hz!Dg-I^}0eT1Dl)B&#eA+AIn;HnIsYJf4$-^OUiHz+Xn z{%p1t%S<9j)f$&|o4mV2Rrik~GxfNV zlgO9&6hT5on|20zR9!uq&hoz8nMNk^4PN0J7L!hCm$v#Dl)}QN7OCAxXc{R8c|x06 z3>B4tr>~g(i&FTQZVwYI~kF@}jziJiL@yA<> z9jDDM>g>HS&=&1vK5fO|mnpdYDLV#FGNGmL)e&sRra*Ux`aBJPxrA}q0Mg@)%eWCM zLgI24c|qfT02$q!I7%X7FpW&)Ta7IeFh#^hOEBTr^Hfsw28giZwRQp&aUgk41txfD zVW+6PoiJ0vdlBkX$u3kmB{7wqfDZn3;akUVG{r`BzEu~+ld#a_$yTxelKK=guxJe@ z{0$akX6EKP@hDk~0#tmWrsf!_#dQkQq1H~X`RTat<h{DH-$Q^oWs23b!;>#;i zJ5EkI*dN{voE_O5@CV!CcR?jT7wlEMnk1s({8`GB0aIz}H+W7ewcrY(m8OEV`%4k& zXww(Q_>gwsTCaVfa}uIrClA>~+VK2;vanC^wtF7;9OeFtdxJY0cJ_Xk0{i%=bEfjB z(&hNZaiU{^{T2Bmx!3lj?NF&kyjfhtE?_h06?7W8n=BRnAnc1Spf;dTHI(r3ba+wmz5(>ht3I@uej^*6&|nr@iNhme0jl_Cb|oc8 zR{WI&OpejwU%>0yWB^_Fno6%qrfl0;@7;p9U z>68hKn#Aq#m3x?^BMZkJSudQs^jqPd$m*#u#M@)fz(i;d)6sv$C~3p$nhL_`((T@* zmo+b4F5GG+VMx2=4uBrcJm>=H6m6w_v4SmW&RKH4aOsk2;eE{moI31ujZORrzX=}0 z@ORBMc}?3ffL@4AJkmco9m-(giN68w-lLb_9RutUj~6t7);FY9k!(^ zZ1yCzqVY6%aa2nJP}tu-iTe|b6%LF~Z2rDn>_7zY`;$FkUT|6<4AA+;ynZC zbJ=9Sv~Uz8YV$HK=o)b*$mG|vrU>-<$#5pe%rc+n- zTuJ>aJzz3D`**tZLwy;vvQ}I@ zkOjzF;a#H9P!5)=a6df?NY!6D$xgFoh~)#BfK26|^qZj@20Z>x{wtDyO%dw`G5|>j zID;P@Mf&wZy`rE?cvK<3pD1n`@B%`W3)80xd_hAEwbrVsOp219dC8g6#BBo}K-~*( z;d~cb zi50q`y9|<_1)GK65_ipWN@TzZD0Z5*CHA2o#J44B?nidMnH?0#Av<48wI7Lj1{5f^ z%dpN33|p*~0AvLV9Lzc9NOE@IBl7Afg`%zj2N2X6?-{aWSc2jUg=!^~6kYwQca3|( zUspdfF~e9=)SS9ua4cuQ4h0@xg`CEx=JmrCs4bv|ngvhs66F)iwCZEVS6{^@S8ruO zeVMh)7pE(4Ku+wLzI5nPrJY225?~ca=TzLy&aGJYo#iFm|IZRag7#@7Lg>a=?94xY}(oa zFtN;yfE#CYfZPUt$D)1sN_R`i;+ACodzLcKx)cD9QS$Q-&JrsI(V_CjamJc90w;(4;K?Wy z)PC~+CFegsRxBHw4OrI0N`dWk^BqY`KL{Sx}mq>QPd5P1VLY?{p9z``5j}$p21?i6XPCj(;DnOpRLjP^YaP{^PE`Z)E}_O z(v%GgMV98iTA2IPJaO$HYBznR`voHn-p)QaCg+c5MtV%)+}mBb*Gz=T05z4PnG8Dp z-F-pr*)VuG)`;Yu?#|smNnAgO50V8;o3;@s40ZWCe2e1ibtE~S+meyHZYtnK9pY&5 z&QHQ?iszPQ}D9D&~MUO3)Gg&BA>UQ^9jS8I$wIBA~x; zbo6)o;WahGNo^!Kp7UTv&Tppz6Y{skSo+f@IK>0IGplKHK}*T7i8-eg<{XcFujwtWOKG-kK-Y45IRCyGh|P!o1Q2(##H=M!=D!9?E)L$-1`?aG|bhG`RfHPMDTJ z#_EcPvaVLLE-VCL4OLU45Z2&1ax}EkezH!GvwBewMV-_r1kqq0p3tg)vyQf9H5Q0f zgQ$|)Y*Lbq&_ZB93Z^!QMg7fMV$Yg04%S4}M2%ui1lbeb)K*PQ&Ec#pSC%*tS_suo zqiCU^zZWfAwV%un<;>T{0v6OVjRuQq-lkc(Wj-or-aQt29+gX@==neds>aDNLYY@8 zndcWmpP`m%6nz#5p*()$Eyf_PATTYOUdt$4Y3lGrUai${q0 zqQG8f53p<5PuQ{EH@%N|Z}eX3J;@vNZu8c9mwIP=J)W;TuY={lot~>a=Xmyej`3^& z&-!ycV?8$aC+^qXPrC1Q-|W8JeU|%2;2&>^`)KzHdY`+S^>k`+= zU~f?EDt0-YpEzG}J_5c6FLRy>cL8AsmxJw9AANt z{RbU4IL>z*?`U(Zag;g=9D@BV`{Ur@?IZi8_AYya{Sdobep`M@zE!?bK3hH>-XExj zdj(VFOz;u-qU}N3wYKwYgSO*rJ+^k+Hd~|Z2-|eHUBIM|r01l2>FdnS=1P}IXG<}u zTiPI1ONYU$hv%?<7G^tGBlthepzqLM(-UX|J&aDGcJeWKp4>~WA!m`j%uY^)y8(?= z;M$_Dxdl9ttx@j@w3L@MmfB`R`Y}UQg5oZ;%dvp_Q@}S{!`am-;HRg62d&|BMhbX- z3V2p2>oCz@)*B6NKwCNxt*YU+R5O?ZmxuPY;4f%#@l^ro-*edZG(KtcM*{o&(#MP0 zuEgAEXO^<17ueoJ6IRU;i0x6dj4`Ybz>uZ~UQp zx<`##e{@Q#lLBOCCNl)3BTUxw;<|VH!U6DpUKRoN zk5af1w1fn@G2E=bM7kDaE9|bQ`T?eC+VMaS`3wh)dizQR#(R(a7wu}zNrt|ee8O9U zm!p10KIW~#A$9oN%4fU{dAv5HT3Se-8ig6SxE(z?Xe1>cIelng(v!&hM)~Fb_E6X_ zeU3iHRBFrGp%bP5p&h;oXld|u`0IMRc7RtRct93@&kf^-(W~zyMT#5v8N2-K^R0*CG3Bre|5`LR1 zVIZH)Cq{e6SEEfS;6*9mnTd^V9^DbjUv@DHfoV*&#gkr2B+E$nQ>uj9QYCO#>{ex5 zoa&4IR0-QsB#1vxm2h&Zgq~ChZK)DAq)1>_rb_rx;*d%5=-q;Y5m;M0%;FOQ+%<`) z^Hl;^JkAQpP4kmx6mg$b&OR$(7$+E`e4GiS)3GWB42|j0a4aI7sa8d&D$&YbJZ9L` zz_6+9cvrzFQoG4v7^jJ=)k#Y)TFW5v<}+%qgO9S#y#-sqD1}>aOQ+#$3}PC=gN>}v~$_V#J#HR69QVBpU)IUi|87*71^ zGbNSa$)E8na)~hd`OtjyISbfb7BE#(ODKb$X_4UC8E_ z2k})F`afi2%*&S(-McN!%V@J>PqZ_jvCvuiv}byVhF<_uq@Xh2BiBVDe&p!;|3>)e;R z&j!E$d)&vkk8(G^v4;=JPq%J8PUrI!m0>odr&} zlYq|P9pz=^Ddj=s4&?^r3V5aO6y{r@WQVVC4D;f}@|^7Havz>~sl^0o3Mp!YZl zUPcJXZSp3$RxXnl$%n|3|`xc z67qb+PSPTC-emjPiCQEtoZrDt&>}fosgw0_=L}oy{I&2egQ@ zom|28YZ3daw2vLHN2u@=JI)C;1$UG3vB$DwwFK!SvY+kKB4Q&soAqhA*gM!8#Vz!=<$>qKAbUEUbmevs2hEJ$&U%c$q+@i1bclAw66> zk#%bXkr}}Z)}=>C@GusH{iLV@9C+7-U8P0v<_Y_y7Qt&F>=#-DZ)>nCwFq9GU_aL) zc&C9~p+)dI0lQp}fMGwoOpBm>J-bwkpou%XM2n#5H~X0uLF;OEu@*s_W_FPlLAzph zp%y{oTy}vLLAzS^Q!Rq_uk0skGdRE`m7TAJ!C;h~r-v(R*|~Z+YX&<<3xkyfh1THCnjr z9qIm6T6o0=!pGHG_=tnjn=7^O;T`0ZDlL52PT}K9ExhnF`fP<3o_`pvF4w{(+sG|t zT6o?nVqc+!=gefe%eC;V4tnb{EnKvp+4ahsk<^<#g6SD(y#n`NXG^c0!W(|wxV zjc|efDbn?`!ywTMc5&e|A)n-hA3EO2mO58_+4gDWGU-c}PxF`f)uvCg*Q9?K9z%<5 zD%XSJeB+mzPfPC^FRPv!FiY>1uH#$j0OMxq(Gh%0Kv$LW&B00I*nEDrpDB1noz6G; zncQE9JigJ-WOd?A$_77^v7C?O>-~&uhF;=l`5AVjbT@b54UufiB)&E{FrjoYUlU|P zrL}yu*ARF+DpPz?dS(-TnV~7GN%!xQz1phAym8#s0N7?};CaN=0HF1sPvWiyAo`L? z+|>X?Z<@qi4M21roTd1Dv?r!a^xm=D)c{1FHjPj5 z+s;3n$XykHa{j=E2m1mMp?WxU)QX;peb@8)BI%>DWuoOA&OSds3S#tkA3MY_tLWg_FB(hGc)ce+R~ zXZP}ve#ZQcTF1-$jG8Gf=B0iH!LfI9S5Gi5O^t*YEpW%DO zr+Kz_y(~Rm!n6DX(wFCS^GqCo0+!F4a|h4x4)DAh>F0=gg$}`A*0X#APxCYB>*Q`8 z_A}OBl{y~sGsbrQG4A*ocB%Gb?kW(lkp5i2T?In)E#o*T5aQgKcMmsg#X$HnR$3ta zhULu zFI;Xu%wG31mtC^)dG;?f2YolYb8`m!r$^8H01kU!^XO?Gms{DZ9zFRc{(JThkFIhkv;FKvj~??T+rVD%=+Uk0LiW5zkDAC% zV}JALveVhC>^YAvd6_L^&wBKTE5QG+9$h?>ZDxP*=%TyXKK5siE?mwU*)twpP=k*B zlSk)24OvfnbY3HCVo!N=_Dj5zJ?YU|*R#0@7U%X!=6%xB?2jIuzJW*C;~pK}iMl=J z(IFG==KkQ(&KT)Q_NYf&6Y<0G?>*XhkjVS-<1Bse&f-i zf}PJE_Gtb~b~by+quKq8v0r<%^rG|#`xPE^arcvMt7N}KF_Y1b((|zOM{Jhfk-H?N zLMc+x6%~H-{we+@o)8azb#)ce_p;s z?$QtFEr{2*MPH>a(5LHT^TY$Xx=vlJ z&QL4VLd5dp%A3lI%9F}N%Kgfnczf|e_=)gCh|zav_#3cMxGa1)d@$S+t`46aUKySj zo)R7%9u^LTdFVf(mqLFEJra5VHVfYheI;~7=u@y;Xb;tewuM%Q7KEmS%0q>rw2*M# za$a(th6TfqojaYcJ6AiGI0>iIX>@ivXE{rpna((;*vWJ>`(67r`&s)jyuJ9LeY<^w z{RR7|9k)B}Mtg_7)?Q>!hh;;d9kw~%Uc6{Mh3Jaj+lyDVH0PO<&5>rVX&Udtlj5_+AMoDd zUgH+yE3kz4gmIqH0>6qI5l?ZJF~JyNWE!gej{b`N4Bj97RKHul36>F`*1MFiD_1L* zC<&!gX}}Zw8fBp}P2MN(mUqhQ5ZQ5tTp<_AVJOEp`HTEX{t*8W{|>)_f1Y2=FXA1% zj&J3w_c1Zer0?=8{dUHkFyZlGOy6@N0`$ zbt?1KMJ$ra?3}}Pr7{@{Syhk;{d_(u+__3FdrP{)&me4Pq4Zhr-ki%nvrf7^pzBJc&jfVd66rFZWT8s&q+^SyMGyI;u>QOqvSmH~W>?`q@bh0l9rreLxmZsq@J#k1mJ? zO+Z#wR{P}Ue@=@8L6W{Y`)s^0X`sg02j?()U~s3lJ!KxF2L?A| z{dF0mrJR?!av`G!1~0Q_KBET)FC#61w?jW;-Zh`COJ(YoGkRihPct)CGJ0ZgGsc4p z*=h^|#xt*Y^9boXKFv2TkZ#9GG|W4{28*uS{LIGR>OYrm^)u^Uk^d-tJIKtDu9I%@ zGpoi5Rr;2nIU`>v(l`CgvVX7<(#?Km;jPLf=_Wrj@334feZ$YpdPe?&^mRWo?Jl)Y zy3x-}`my|?bc3H6|Gs>WtN($}PHG`jq6qV#>|USC2~9__HxRlt~QK)UAoerGFu<6Z1jX= zXT3d5x;UWktCWre^pUYrcR+8fls*;Ec~hiM`gG<~Q>0ILJ(Mk9mR2tLFFLc?J!tx2 z|19Z-+0r4<8075Y>@2Cvr+M}?Dd}CE6@Ht)ASL`vXc`{9{kNQ1&L^cWNf!|-&a&hi zjYmJ`wINHMS%0Bl%r{7nU*H$>oXO|=B>Us!^8)gc1qTCi^Y{b)bu2&q;r%`>y_f#l zKJS!_ou$+F`s9vB7k36^*Ya3Eu9)0`%6e1#f(2|

    f^J2S}WFE3y#Q<>}LvK6V! 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
    (tMzbEkf$ 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 literal 0 HcmV?d00001 diff --git a/JRCookbook/DesignTimeBuild/.dtbcache.v2 b/JRCookbook/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000000000000000000000000000000000000..158a82c97da3fc5e323882ae6dcbd1d49b6ec417 GIT binary patch literal 177106 zcmeEv37i~7^?w&fU^hSr5RO0~49J;G_R3}x1W9%ivXF~xLINzu>`d?Ou(LD697z@s zMLbYJ1q78#MDYL-0YMOyA0CJbC@PBg@$*7FW*x;_{_p#$tFP(Z?deRd|NrOn4^-9L z>FR#()%ohxt9sv>Wf(?tk2z2tx@<>R=VgNaG&nNmtth86sqRE_*zC?_ONn&0xFJy} zr4yN+L@8nHzABL^nqpVHu-}G4?jkc;T9wWYnT32Ioh^yo@Sz!adaAi}X{tSyYDuOB zmvk*%+BJ||+HMXkUeeLh*0rRiYtUTUn(SD-G?iSscre-0(VpmR8#LROq*AFR?Mpg3 zml&sZB|GW=#fwvkj#Q$(wQF#&tu@)QbkIyJ?QCyt9ax%ZYiUU&2~DCi)nzVePc9xD z>}W~QN839(TU(4d%tzl?HaT3#Wz(0Kh3;I+6f;4eXg5SBGvXn7u*Eb7x&~TO$)wrY zx+IktOf6Z`)t>4cY;W&u?MSt@v<#$Di(8XsOR{Cjz>=f9*`!(QF^lP;?56an*(TuOA#tC(XEeuq9VW z;e&?gGB!J;D*6`8KZ}@3=dvfa#)+_a%Yymc(fO;=8MD}*%9W^X^yd@Fkz&6?>lWEg zsLhU)sFs)K^KnAkk2VxMzA&dLW%im&Rm;w}@lG&hd!mAp&D!K1Fpm zXADJ!T&Aw(tlnW_-Yh&FD4s13S?nf;Z1&M6sH}@|b4SU{rp#1)dwwup%H=X6=~Dk< z;<>e@y+4y40N0(~Zq$=2tusqjZ!gBT(2Fb8S2oEnFd?o!pa^u@SM)wm^sraQ_%LM; zM(dml)ZSgi5HLXTaEG4q3L?MNroL;lMn5VYTjrUjM z{pGIrQE)UA5>4nF#sy(};<}Za_=A&lL5G0uzTre6&!|oUDs(|3tp(Lt>0&vNS&=BF zlQdQl$KdZ2;2Q~xFZ>|maOg&h*(DVgSzYDm$8vF4EIZ56s$5~T$bC#ttr30gZSf6- z^k}-2-exi?(T!TWOec#H?M8DbO&w}1F6Rtukl=>HopmMX7z#^AT@~sh0Bvzp6dd)#)Zaz(o=;XRUAm&HtEWxPC&pk{rl`gtV~3EP zHWbVvwFs8#>@jo`@y8Q|k=KiH6-j~S_FQ2kzMMpPF5E4^jhVyHFygtn_2O=0bOK#@tvU!?nz9+F48cmja`<7`WXWh*Q{>Hn+F+Lo{z)+}aiI=v2ZVjj?7T zpKtfbep~1z3TNRZTObNAo}U{TZk8edmeQDwXr;-x2GRY_Ydo42V}>KHXro2S z@7EF^f`$0&!BQjFpLU5_DlV4QZvYkzGYz^vRoCcfF3ZgX61t&bv}Zhs`pgn*tFaR! z2e})8QbPeUN?W?RiI51EeKu1km{`0kvfd<~Lb*_7rw00YBSuN$*vGOeh`+x+WA;ep z$E`rXf=}r7U3V{&J9=DEkbA-}-op2!o^)a;n=6*mNfvon8!hYU{a_GcPeV0ksxVz> zc>|G|`~Xlw_|Y+Bx;b^=KHl(T>~{h?%RqMlfCdI_I>2s@+k1K{52M~%%fHKCR!72DUeF4z{uB- zt{hT0Gygdd!7@@K_2U60jx9@B-cJA}1SIiAL@cpr5c}QDjrn$U`7aY<-AxQQ$&Q6f z8S;>L8c4HYtGfP4BVC}a=3HT{&n#>sg9%yKEWkVq^en(&Qf#mwjH&lIuoimFT0d)r z#C8;=Bfv}pGS?&wsZ2bN2tthbE+PmT;TKMkS=J=u_E;r~%7a8>3^%@EC>*|}(a#8* zfRJIB8gPzf6QpmAZ=^Ye45GO6{Q?LfVi*IBM+l{5g0|k47qhL54bnvTp{4G2q42FM z3`m{gM}benia{aTl#mkz%SJ4tu&nTFpw%#HpO(oDKtE$GFiFD>a|k(>v2^ev;T4#& zb*wMF*wHy&0;bS|cKG?(i^;cCst`^A@gV##7anu(dW@ra+9AZ+EWVZ&|f0oEE_V5-#7J&7Y1UQ`^WVjaVf7gJAxOj_)<(hI<;VMy@e z^v#+-2GYdxwjA&=PwNm1h|ONouaPBPs*l7~(iw6uz$|TCq@@?EHAhJ- zUQ0WxW(w^`&L%vAg*Jw&d!i;bH_&n~F=VX)bO;~7k#A~S`Dzg(Y&~97A>n{Oex|BL_FSWLfL1M>5X;TM;r;>Gzf&?4JuNz&_@OtF3V}m zFXAX*)il^xirEc0I@f4V1mb9*Y(zZk^aJ8q;e0>| zL_B1t0P%P_1c=8|4K|*xnt`RIZn=28T5 zj5%UEB8&*)5=3aZ0(WxA8onG5m-iKbxV*0T;Q%gAk% z`erc84e16z+?s9ybQdCSQXdC|CZ)G1q%jT`1saioV>S)8%1|5N@_GlXbu6Qh&DmmN zP^#R~Y>jQxh+Ce1?qs4Wb1 zZXJs%#hP`QiQRTkoIH$R1Tl8#YdLBDaoh+oUagQf;O zo~!&xl&8a-a(v*hGFJ(1ik_mq>whpN-kX>7i&SR~{(ca6mPsDo|JnN9q0(ss_SEQg}eFj)H zD86kyWzC+b_$*LrSccgs>3DZq-sB-32QCdY>fkDjE!} zo7uji(_O_^3BBw^+r!T9b!&@)N!c)B&9hH~gz4>EzTxs&P{2Jbyp+?ZQXqRkQf-+j z`&kx_puv_KE z62kX^o7=X|;hl*v$J%)X< z>ZjmPgONB6G{x;n3)e(!z@>}KD7U7c1F;69BrjrgSu`LWI}Bb-J{<#Ej`#&IYv`{Y z%yjRh)qs8loM=D|yF#>Op1M^hap^Fo%bYS#+C(OQi* z;_l%@Hfvgk?|uiIs7o!?XyZiJ_#?1rFyPo^V_8o|92qw2<*v`=`6n<4F17SZ8}+6{ zaikcBj5L_ZZD;g<0cK`e!}`x*T4F{4Gpm0ER!04IK>X)F0r8*z0faww%&mT!e4`X_ zPe&zqj6`?cg^+5PR9(Ds8{itB0c2WRxJ0{w&dxHzCLq+?y6DuL+@#qXxHK4g(YaXK zf{=ILGE=jFNXJCxMzkiEv;@!nfKJ1v{8@=i+1ymlTc>&sAT)woqXtV~H7OqiUNp1^ zd>@v+n@jfX+X9VU%mu>GdWpJMC`vT9P8k&A8`A>=mK7_veGPj>3MWR?!@wgNzBn8a zx6II5%gEgN#?2#9#-TS?B4h2%=F6oxZIGt(BoOgc)Z87pf9P9;s^WHEs>pcJVZy73 zBeU((w4euxqk%fK^<~|twdaX z_Q;n2nTG2rfXusVL1Tc9Wg`%6?a3u+(@R?Z>KL;b$!NxdMpK~?DphWluz-P6$BKfP z+K?y>^ALeSS%*E8gT+%zVkzMhCn4f7Ikb!teuUWEyS!Y=$%7Lv^WKxeXlSdDok7=^ zCgn*Xw~Z2OdlG}8cnt^$E!jpRK%wQTT@I`~K89|y(XhghOKOUEpwuwxTXf+bLS~J} z$~VAT!MTo1S|^3_w=?B^>6Wp?)E;vL52OcMR`T+6DxDQleuSLnZXD%vKEe_T+?T)$ ziRFAma3kHra$+J|%rVaO^pm-)5U6cqcXoVX%vP5L;VL%1XH9hTW4@5hIGPVLk=r9a zOl$U-v|*GYzej1e<0G*WZ=4u{>P3p))o5_1BU+1hS9_|*e}!|3o!R8Wcylopge!wZ z%)M9-XobkR|e_IEfE48$@F6}q=TvTQQz=hoMWUJ6H(FAhh6}^q7 zMReBy9ZgCt6z@epJPXk+h~AHAE257eItLLyJVo@tZN9>ScSPkX_cgq@{HM zMQw;Ih0BqK@8#7y%*(am4s7{ z%gFng7{+h=FER^-99kQ&!tG4WkA>hB}^ zA)=ok`UOSC<*thNj4O>?6Vc%6@*1dogYt6hMG)~;_oxxNr-c_Poen2UXJQX!G4V$b zRC1L{XnN}E`94CpN4zcy*65`mr9$V(eauKjAs__XZhvJlF^&=*(u6AO^&=KDUgK%i z{-vZd3vH(fm_m&=ASod1h(d0Zs&Nm`+$f5AF}oH2&UD}&6+*ZFon=?9^}w{0j$S)` zoZIU&+ecbV{MkP|YA6VI>3eBt!{`_j{~{v9e?Z9S8%tobRU8lQJErwm* z#bRQAAjf)A%mH)|B3_`)1#}pqd5Dfc6hmaM+>9~3h2&gn<9ALL<3*!f#$~6E2o@3| z4TIrZqnl}uv$B||qKQmnnR}g<#l#}iK2|rzCDT{tKEGu#URgz(4C<+b$-I`uL>o%N zS>3hc&&3o)lpG=x1}jXTU$YpmHANRl`Ukr8GC-$-xJW~HWZJm1xP@EK;$Z3}ud;-i z+QG1Q$*bPuCGV>LLZt-wVv7l^y+tpmxlDK8@iblU&V#k&jwHrJZU{B5+G1i23gT+b za;-hvxjm;*>j-q*W-XN?DW~fx85efB>R3lbA$CW!0nr|aHd5qiC!VfT|GHY~bdxzU z$q(mcSF`*>)u24h#k>ogX=9aSVS5#4n$OEGqH2Nyk%- zwXD}HurN|YHGcQxie7isGJc-xE(}|>#o(=f)k`P#z;`wVhjTGFXcj`<9;A3aC98F| z1&E3BfL@o**6J>9^tP|OShUr5_`%tO)plOiXS>UbN#&4Rq|um*G=TPS)$~l|?ivdAqZiY?y{xLoHuH&T+hUNE@Vf*Qsx zFGlZCyOF{Y1E2m0NTF zMT|GnqAgYG>S-<_n0M^p=pJOfyn7r7%8ip~5@S@p{n7;XYNB}(T#WAMzq(u?JqGVch)q^Q&hwgdQh~sv^2MLK7=0NQ!ys6i=5SBUt4@sf;>0`9jamEtE z@M*n0%<yA!K+8JqTY+2iRU@&AIO-1DowXS3B1-ig^USS-f7;JWZZ!sB4g9hs+E&SOI4_O zQ4MDOayB%E!l$~MhVHC9M^2B<4vf3KMOr#L&9WY_+PAy%h{?)2&BBMoTI)SBrdtwF zh|@{ab|4wkt(s({j{8XMk_Yh7nN;T{6se)py;!%<204+82`C12YrQQ3Xk$~lm5hn$ zP(oT*Yu!suj}p>{p1UxVklJSkm+z67xC0n!kK|fx<~Q^^wxK+HA&C1R{n^Lea{iF-km=ABnpjk(-c#>9QVtyu}DaIdj_S;oYt zfLHSpPvLbtwv35S1G8@FD$oTY_m0m1{dA4O>PBGcWm6ipDW8`y@hC`%ba_GjLzI^i zXJ_HF|GnbyNrB>VkfQkvq-v7h;=o937Yl)wtlvDdtCQ?WutZ+X6lzn9HbL_ z&W!1<_h2F{51Mpmz%(?y2}qFcG_|k3g0ZuJ7VS=(@Iz2AYTH#A(-7?@o1LY>+`-HXBCB2msZW8z8BqI;5>fQUkRG+jz>lNW-=#IqnJn#9(qV)1+5jEQf6 zsA%`q?QEL~a>Gg2MnJq`h_6)Vdvs(xG4A*4;X6+$=e3w(W6zJbE3A#zZrC)jbZ_yw>^_ zjfuTMf#$tZhkx70XiUrkV$JitAF+QBoc&)Yey{yA^vt@ad{-%OQ;@O_l-tI%HGD~f z@;4e|t@<=JJLP^&FXd-*_Hzhb}Vu2|S%nmoh}{ySrGn@#f^!)U#JS7YMDX)0<$u1ec7{Sga+TJyS$c~)*& zV}iF5BVExFUPJAm^wlx%XGN0K!Vg)&Zd$Ea#nB2<%#!z=0-=!yJnjvm=7lp3RGL`4a8WU1Bbjy2w{A%9TsYrgVtweAwgo ziFJ#saC$e?S12EyUzo^?6zd6REh;4nLuP3i`HCzg3S+FiBTtcV-ALYl;Tv+Hqsud9 zE-IG>y9jx{Tw=u@IS5RdWFs@0&Zdi{bn-;j^pV3sI1=1O4w=c<;IdZo-svd+$VNYr zO=QL{F$+n)#5q!N*j2i=Zw0w6Oi4edv`C>_q2neyJ(XW)U8C_f;YT{*wLs*UR63w* zZE5fCON|u0eo5o>Q@>)M*gpW|{SuY@xtK0y%xz}o0`ezG&Mp(>OesE;$qghjG8f%* zNb{Rie7@ZwYhoXYVF;47SnQ9-U9>sf0(%k5QRqZm+;X5thnM&#st4;zSk{Nqp1R_0 z`bes!h4q!LTAP>_8Uy@w)Sat!Ca9PyE|T6J7bS~}oC2~eA#tS@gM&1%SWPTfkdp)J zFUhB*`p`5{;y|0(r5&{Bt}r((0sBS1hO`(Y?VrpPaToRg4gYHrVJ6Qk;s2^@J+`L1!nr5wX6k2M{YxRsw?7LY#&Ossw>0zUW27OK(5AK5{!fnm`Hh z`uGgWSW`lqawBFI5+$->1zp3}rktO3u@?DeDxn5%uE#I?sb6USERPc!R0MnXW{1dS zaGHDrBcHuI7iZEN0;^@whj$Nf@~t%!MH1wY9ji;R84)k`4s|m1jimE^W}=WBR;`AI zko}w-n~RAde8h;=ib>=HN*-Mqwdmq5fAks>&d8WFo6Zi=709J>adVzTLo>xUaxX6o zp(%IR!vFrxc6NgY_pDVLFKjMfsk%4Ci z`JeTc%u!In9cMrJl&u(2ve=BhJM#J;>(G)D(AW6MjWLVBQFl32Or zbE8LlH@c@pP+NQUmtph|Qqf#};9#4YY?+`YKR7(1qm9>1)`-IV*Hars0v z?8J0fhm0kA;Mu6iH;HK>Wh&uHoJ+(AP{fciVWVki0ZlAaiSs}TM;8D>WQeN&+$wF*IcVnFhpvjsW66w*lfmcL3r)#{lu4ml8B_ci4%Nc1uHSuoK7=6Y^S6 z^EwcsqsrZcOeK~H6o&vk#yo3u+fXQH%?&iN(>zG0WzB+_B{hg7cVDN!$#tH%0`LG3GcqT#j?al|aLJn`w~murkkeGLyQ<<0MTEBNEr zfZ+K7Z+LE87M$&bsj|iGYpBIL@ZC89FZ8Y#*Mci#5bs8=c>%ec1JE+}jmUW1q#5Im z-b>u1J}z#?i_>H2Yv~f>I5bs^yKf_&f^cUK&xq!SBD|{AYG{F^O7)S{gG94c*-1Kh zPg}PhKClFw8jy?RThM;E%`FIQb47NfQ*%^Y+=|vVH|Q1F*~JI&;SV8KY~oyT>vXR8 zFfs=9x{cP@VX16r^9W|fMQ-~i0;Rq z_W^nU&;tYovgR_2N)$(m0wp|EM%WP<&N!K)o5G~GDfc+}AaH*gUvq{?Cui*t`3Ukq ziu}$vIYEAFoct`__#eFCjFZkA-f{9v$mZ181lgQ%(ltand3)Ep#zg05XH0aBgh7wp z758Njk7g;p2GX37DDXw6A8<=GoYwEoK2hs`8W^0`?|Q{*{b=~&>xiC1gyt>2jfh*; zcL1Sf8FlXvkSc;UA2K|489T8#;Qo$m-#-LVKSsoj{AYmv7ZF;z_$4Bz1@4Si-$rdI zq|DS*T76gdsVQoE2>C52{5?g1t#YDq4&W>bK%_ zVY18BLo{vfGUyfcbcxlTH0lVA!`tlbozzuW65R9c3!VW087 z|2x>A9imm~9i+-}Gqj{mhSZTG<7h{@v%Fl&k^YEO!->pkh1_=Zj}^Hc&`O*7bzas@^saW;* z%t=1z@0mw>zwcKsqEJqlB8!_6e{-IU61zDc;6)%+m4?3|P4y{N+s3@w&$&r-)&E+O zt)$Z5YF+l=JZPqJg+#oqeUhp<)WKt2fZ=MV%T!AW@g;wq959+o)u?EVj(Wamm+gFN zd3kgtv)J$4n&d8zu6n<#3RkAUHbn`#_dGD$PO=D$dCfG}aybgM~-_jN0A6}8CPF>|sH*nR75c(tZmP4%j3 z%i?PEg=_GQnlWTDLHk{J?OH_FBf0?}s40L+KHx6^UMXUcSX&B{eMOam(NVA68AR;b zVw(z=DmLSk=tgS5EN(=py$7YXNX-H?^JR(kGD$ZT4hhHPVx?Wa6psGTF)w8j(-cP94J(GZ3 zgs*MLx73gdrXS|3$a_Z%_&M2y|F5tO*!T?ce zs=TIr(QZwP>v~0%v2hp`+*xUJyDZdoWiq-dkxA?FOa{gJs)?Vv3-`d&H=e$6d1^S9 zl%{XksO4G-`rZ9vvt=ZO%=Yj)CC`d@PeT+(V^Ciex)cIGqUu;GENne@d4Tp=%5fYu zm}He_oK%NZT8(1kWJP&6WWE-|N)2A>JB=>nhg1uaI)anxBm-}&qBMHyd|AEdsYqi@ zBfetSB(xSrO-*)AUXwMIF?oJpWz<%|6tCM=0L6+?Qw1U3RwXH*kg2VQDZZfIo}wP2 ze8sK@=!b&pVKO0tRY^ubWlZ*xuQFKw6jURVenZtrP-RT{qAE@ST~|u84z*s&yo9nKuo}%Rirc(v3Y`)^f z^3$=B@#Rxx%4-d~0k|>+6bu$1yq*wW1N02OZ!h%eRqD`*!stZ%>;A6vEMB*lN%rdt z6SViQT7qYT-v5E;@By;jRECqjZ_!47_-}nXfS4U!ouNPAG(loyiE0DxCiq=ou!UUY znt1W)=k$94?{;;DE2Zz#yW$6keu(I&{!ewG&cc1_=XiIv)xK#xgH0~luNJ?+@B3K4 zuP6_a(QQ%u13&I(cZQ7Rp{gkUjR*5;ACMVEHd!u^y>7`kEZ}kP=xCXbARDm3Rh1s} zp>??|>jBeAOBl=lJq$Hb=)~XpvDA z0@J~(g7fk585{*mu`_G2EAq|{&g&W!cSp9Pg0tbo5|xrX5+?RQPF3vmGe&j0#BoXu zhAE`55zWY`3W^^f>N88OL2qy5q0VI4Hj7#KTUCR5s6wTa{adLhW+ThN7Nzbia=O?b zj};@H$LYjSHirYz(!|_|1$+ZjiFL3B=Ut4s0eRTepjdQRvp-yn(@Cb}2u}H!Vh#v7 zA>e&%V#_mdoKblT76(nl*e156o=cC#VTg`EbR=@CcIM`jKPp)iMsKMe zA&SUCf(D2o*Ia2Fs2+`F6Qk*5+!~(6ad>Zk>!I|@P^7h4wpE;fC#nOgCz}!laUvcZ zV7=n8QncCd{OU4FJR;~Vml>DQWMv>rMb)c(22!dWdVh|elg^{c#R4~R-g$2!9;vqC zc@+0tv?*GUQPqeyV-E=hCK{AjL77AkqE(1i;~mAG_Z?T~JRP}IukhyDk|@!^!-80Y zEUF?YOD}axoTlredl~3Rf>@8|huXyymk!9+Ch~bRg%T)=O~|3Dl)kWm4%gAG6ZB*Y zp3HLI#S^FbTUn|4lVtK+1MY~DyTk3vAyBYAWwu5(LZ|f_P5}PR{ zD%&4ZKg4k+#V%L;>UDZ;4+8wC#wWE00sKbWbRoY}!*;pjXXW%*oae3)JW=wv7;qPt zeByN;EKKB3-H>xghr4134^%6~1G>%5@1jjy3}lXB)07vsTkRt+g326KiQ{MDsIJPnGX`#UN-#O^X4D1pJT zQWkH-@2ayozsGyhbZH57BO2Iuj2TU|UboJ~sL{`r7w#U#oADtv$M_z`-7Xo$TaZ%? z9{!vzw~69y$f!!yozZq}D6U2pHJH1yC?AC49TR-RX=mbEWKq(9>liJQG2naKS5w&0J*sZZRFr%H@a)5-_&<1tnXP)h;WxzY$#P^Svwo3q8lpea6t z%uP$|+B$Zs_bdl);!eD%#!7|7C6s&^&+WRmR%+@D#7FQ@^&j=J|J=hp$kghi$CpXX zr7mY$;$FO``knf?bUG#O!!x^1EUHxJGW^VYx(XiwN|bP*-xe>`*S#5exSRZ2PHS=+ zl0}X8TXeUUcmPDJxmOKe-kCx?ggmOa?L5-Kj(8Xk6+zBJm%V9xd1fd_>i6N%qId+k zRr3zcO&)8+XF_Bv=EY;kro`;vukp185TrhfyhmF#9-P;*Tos=~*2!6N%2@mlaxa|p z!+wVv;`4Y%HE^34`e>F;%qKE-8>oF0-$FZix$Q-JD6+FKU^y%hUjPCn%R!!vtAen* zhUZsW5?B}S+vBhIxvTem$xXZ`7hfVTzKrMlS_Q(-(P+h2@U!Zd{B!LoPVrUGyUN60 zJneZ`{p@R|&mfa3ROk4Ry1ra|9nY17I~x$$YrmS-glG z0sQf~DK#HE_XLZVke?QRi>>Kap~j_r?rSH-?~ze8H@>p3CzmA2Fk2FTbmQbl&ZUWB z91qn}(R!%HD3Y10c&u6yKgQ*Q;xF{G_$!{N$<}`6+yp89jts|HC%^j2Lqlef#BDjn z^p(n~bPn?tuj_kLMe!ee)YyZfT`0n(C#;&-oZpnAdNsR;&EyE*C@c5*_;!R{k@Fy2 zr3LeL$Vuz@mM^l{FXzSXc$%Yg=6bG#b8N3Y*PYD(3wt7JMl=i2Y()DbnuF*dLP2)qqB9V!L9`apdPHX;>O-^@(K(3v5uK0dLPP_Il891>OhiM7h7qL^ zU4&=^Q3lZ{qAa2uqCBFD5fu=X5N$)W1JNajE<Jml1sh(N__D4bd}*o<;O^M9(4m7NX}7eHYR9 z5d8qrj}ZL?(a#b6647rE{T9*h5d8ts9}$fs`V*o*BYGLp-w^!+(Z4A&j`8nVs3Y*+ zLEbpbpHI#+tW+!7;womdp4_N$yfq8a`h>2yE7Ns`xYo+^m*uqC9yr~a8vg2<+>k9} zxF3>xra`g?NYFI`-8qu4=;)~$$$HWS8Vj(Jw$9nw%SWYeSyvbsw130`oi8T9`cnNyHjLj>l_^W2h!PoQor}JCb2(jmZ0%nNIEfyM6}RwUE8Qs*GYN1;YAQZ z?ClAGO$LFD0s#%bfD&Fnn=S&>;sW|@R%WyEnibWoAZ9f$>u<&Gm_7DD)Qo6vM6(dh zMzlX7s2f>@C;}9PtO#UfA8YPdNyiE~R(y$tco*ucAoY}h_KEdNtVCix5vzn)X~Rki z)<>|)fz=DFJ`m6ouqJ>P{Jgm5B|9(Ac`eTCXkH@o@|PF5yolvxDlbBLttqgQ*Mt@^hnr)1O9kJP)$JjlNIl?%z;d7F)uAT+J z)N`CTgr-j8JfhRGGMvx*1O4)f*8X~~VsnHky0;FO^v10_aSbwkRMyw-<%QAH2(+Sw z7!Z#)QM_L*9%DDI&Dk}?xry>r{GK-1XV+PKinpoToFw ziP2PNhwD;lDNx3(EY^;&-3;ograCyn;Nb0aJIj&y4r=)b`!m+wypJ*QEaeg}Ao@Nc z{AnD8B|>JKscx2}-2&@YGnb0uC&;-$?);?(_&Uo4^R41K88$NX--7wwbl*1JmU(j4 zBtz*$X2JXo<$+8(N!POTji@KLw+;-pcP;Krq}n?>%=X3N82YM_tSJp^2=ZSyXDtwj ztdUYK50iIN9}UV2!`u4{=HMbrlwaf_ln=H23=Hgj>Bhu%jB?oAd#(6il)*3YV7Mn& zqAe~<`$GE1{GeQhq|8(t+wvpnlEW`9Q=<#YLvd_&bapOHwGFnnv~_e0c8K2q-F}y@ zPG?I{Lg5lz+&ubP@moAdI~BORm?w((Hf`K;8(%(9q%uviVTeOYTf8k?(I-*^OP4Hd z?`m6`N+rzB7V$ga+vMPrS5G)!W+RwTwK~w!KDc;r$zW@1YH>@VJt6*pPh-UKw($vS zbz&zTc6IuxAL={Y(9mtf6A8LLP z`3dpqs6{mrwy45)uOy@wC4s!Pi;gkvI~M4gm$Oc5CnRf zufHs~MlKFpBRgCDTsn;MBB%HyNx{m#hLq%GI@z0ydLA48fwAFV7#m!&i}$TYa4G%+ zJg)%HP*{HJ>R?`ynYCS-3EPGKnslpUqi~i?E*WTT9~?}k+ES_1;#RRc&=kTlMRYElZ!iBm$rA9EnQ2EEn!&+Q9p_< zrgtyUyEo`vN759W1*8&%ltVHd@eVil_^ZG;r-3B9NMow^1=X`b^(MEYM4ueM<8&yo z%`d1PfKLyGWgvX>@e|9;90+9RyC1D8kifbt)7EF|&0r z>gW*gcEQBFwKaq}4U^F%Br|u1fxCI&ZeZf9YtkjRTpGDO8l~y1Jy6X&&IgZ2g2zNK zk7Ue4)|$zN)M0VDShR>{4vz+huL6f>2XfdD&NN8Mfy6RL$AP2c!O;XG%9?UE(Ga$# zZA1aZ%-aI+wh+8s7+e4wb7P52LwcNO0U8Yg#AJjslWjn}(VcB`ZNW+R2vB!uYJf5 zrZ?7Ez9{AI?|!TdH!_XygRcAHT_kgV+yEvwQe>P}%U?s7VwHVDFH^WKZZkO90!}Wh zMs?{s&h7`5nKvvudx|@qc$a{ zqMErJ1DDv;6PJM1q2QN12k#rfZTN+1!Hgi*1Nk?JPzwij}94`FIH8cZU zx35Lrz7EmLsNlb$fo%!;gu`y=LDoMKg*TF@r$XKJgfZw!v{7e)!&g2y#P7s7`bKg<^WEbL(d-3f)Tf`=bxJ<_> zp`94Sd2>s{3OtZv?j5(Fx*tUJX|UL@O3!r>4>z`=W4GQ$ZSbttTOw`FsN0@fP9d0r5WJV8BZ-nswcm6@^`Y zMT#d;sG)fdFV{K^vB+0Oy69$}zYI?8twZrF{`@*1%*37u`DGKW~)y~_FjWkT0m|kWSdynE5 zh<*k3Y!T8`M9yt)4dIYCC3VP=fh04NzXgBTp%lLZli7eW!Ce^v*U>eE;|h?Dg>BB! zy7C0{Gy8u6=e)%kBqQ*>dX3;yw~WAqf+1TE?;eU=7ydPZ8SxiXng$j81T=F+y$qZ| zBaC%XVIvr8sL_5!0B3U*M}( zmVm=W^823-2P5;J1A zAdaMn8igbOJUk5?Ir6lvRJ3ZQ5e$euP(YzKXCl`Nn%JH|b)FgvYOYUh1UtrX<9mnd z2hLUsnwMcO$|NHW_2Ij=@5q-9-L4`Y6rZDt-g`Z*LwWd~UDFRt4dw17ll$~+^y&T3 zj?^B3y2J(7=|uVB|mfjZ{!d7SjCVZ87sbqdm1S<ZR3~xr;+d(7vk|x9&Y#4?L( zz};Ffrk3Ya-#(`p4dF_|^1PN(W(kJaf{mol1ap00PVGI?D>WWH8p7U1T1NjGTA4xE zMhmu7J`235^)T^f-(T7Yp2QY>UEgZbO)v8WlVlG!%CkxoZv3lz(T~QE;n7%2UDv#=Ia}nIo8gi$S!!Aw;kp zHr87$4=*)@Ar025%n*clHgp~V?W2fbDlA~uD{}a=K#_5-iyyb^rbh6_hO*&r;0V92 zWCmS+rnt6XkSj`HY#SI;!aV0yZWJ29l@4LvLnLzp(^+vfqD#QirC>>EG&r~IH>)8$ zY0zkRsbr>Xqgin|_)&WrQsRihN6m!$I()ak@dLRek(sdVaP1X6-TCJbA6^0DThSZ1 zjqSMiZA4U#p?p^8XmN3Z3yWOweej~RcwihpecZ-h+t-r4S&_TPvuG{%?&xa;JP6!!L(PGm|^)W*u%lM6$VoyudzJ`~wWB4JfN1EO*nEOX(<_`RgydWovzl5@O0rEOYm7F!mor zu-f$qOU?_8U`rYVYZ8_mQkkh;_ac6FqsTVgRSt+9PQoiE{8ke>BqaEcPbZ~vd=J#d z9-!Wynbc#;H@U+__;sManXyr@Xa*V`t6(3+s1|!taye6P2q!bqay6JMy6EI)H4DvZ zFVxO#6q{Nc(Jp(o6mfA>a~n};bKbhGM-`dO%HH5&4)~b`=s@tJ#5>BkjeNZ-AItu0 z5JKPj>%Xxxyje>W-fBo@K4G?OPr81_PD`aXWXjQ&g8o54!;Qw)cEki!Gkg1?^5&u% z4?_*A%`|c=lOfle@bcM{F6I-Z>b%&9 zfkekWrVfS7%u(P2=GEdD@SzR{xN@x|1w|v65o}x?dN>I$OZaGIwvGie>LvhxhTb)& znOReMooxtb$Di}cw1g9(STCoP>INH3(2w?YZ8f(z~^f4sg^iSe!9Cn zWkx#3R3oZrSlIaKWS&mMgpT70;&kxjG}B_PT%emLNR=%i%guU}3iLB4)&iB5wmJdT z%qk8k1XP;5nV}(k;qZf459YL1pQM<1+5lu1S>pCaa$=tzHTf729V#IecVQc8go|YE zRZI*n4VI-}fp^M)zNW>&BbOh7@?kQy(b#$PX{uPAEy;37E-?YxB2z}W?{4bT`OHvVUue09vl)jUXj zN=~;TEhzm`te8Z=dA$^TU4{q-`S!+%;%iN=QBtfl^VhI(;w6=tx&r*X0g-L% z?Ff6;=vKRxvJ)$19U`8OPG;;a;OQzvBWRhh0e6;I)(bQUrxTgm%P_ks-N zDMK}L@4HbAV{2Hx3Ai+P%9xmJX4W=^7q@}{zZmaj)={lAWV*R+T5H)Mo*9R^ynt=H z_#lxX?nGqUbURD$z<#oIG?EFezs|L+x+fx-nZ5^HvcdN!0Kw|pwmr2iwigC|KR%VmAR73-jnz<*mp+We)rOBygrXNDR z!rWc_228&Mrj?7X;MdpZ&1_$>G4pL`U&=envqdzs3_E)^i5Gta%i~~K$&|q?Zy1TT ziuKpA_!^-$wufEL*S$A0G4;$i8|VK8JpUCDjPs|MrW_HiA$^)p0%%x8Ou)CjQ_9@` z6FmPLk!{2;cH5i&oI#O&GxbED%9Y6O#!PwLdhEpdIJ{D)QLTV(JhNHg0)gp2Tjqp1fE0G#~SLj~Spyokza{(L z5MG7iHxSWaYpcj(K49E!D}wANy?Pvc)lA4V6-mC7`Kr?jcVgUW1uhLro&YATj>^nBcI-8R zG{0%~K_%UgQ<-8ZSkx&w#86{qcpdwe6OhYnvI#t_-^FR*b+x% zW^AmPfDW7RiRfh>*P*i5CLHGA;!OP62X58&qUY_RcPt5Cfi)93%(r#yG1ijHY{Eud zoCUs==RM9Cb?>5vovrxv1&x=aZ7P`y7>5hC**+Kb)Q@N(eq$qJ&!Do=94coL1=oE> zjp%nG0X{WYL@=MVG&9$1Z9D*8JJ4usHirvj-$;|T_hz?7u&IT^U~-wmAuuei# zu4li}J)Fp9%}k`FpTDhY>2)=fGGDND78&q0N|Dp`RPKhHkX?c#SwDuNS6JBncVh9 zaH?gpn}A+s)HaqDSAfwg!Kjj$ozh`O8^NEnVb-u4=A)H)TZ_K-7O-^{*iy?mf7YE7 zS8B!*4J)~cDP}%l&n#ePEUpH#*MQlH8fznO=wnOY>1eTvXy*1>@VE)wUI#{%jlZjm zxV<-`wdybu_tVKd-3Xr8hWNdJ*oL@vP?fK4$mJTNSJ672IR~@D9t094SKtY*!`xg-XVRs{ z+}Kh=$!O^HK3bWhhro$rRT7tQLo&aZ`M`T-6+bb~j3M_AFWfI-9yuT^x+h7VJ znfZJYEIx$@2G;fs0D<{erqZRH+srt;9m*C2I0R!DJhc|Ji#UZPJ@a}y^afb6?t6jY-TU^Ar?M`F0wm8wuS~7<^2nd zJJ7E~L*u8D8QT*)H6!9v14`?JytKjH(4$>^Y`_?5{LWbovCP>%U}|4PI5=R-9LT)2 zCzqtV_M+WZTO(KTkpvB%Wj&NKOZ$PFITYDTPR=u$X(T^7R+~ODnHl?3gE$x*^;?Sr zE30aJjnSKlxj><*=@G>awagkHWxy#0F%LC%IFPH&Xy$K2qBQIbdv!<){$;0z9Wk3g zW`$2F90dl{{ZG#G#&)A`qr8p=rqJ%&!keiE5DoT>vo`lGFPC!iSb6jtl56A}oaP9> z`x;&xs3n(c={PhqoazuKpa7G#+4|CCa8$@`qa@;T(kC#4zmH{Sxbu+Btn&GhIQYdO z643&Fx4QXNTt?|%{(20*Hye#fMJsdG4yHN~;kbyg+07Jg?25Fe@^d6lp@bd@qp`)* zGEZG#XBp~fz4fUTiDD%Ew4V_j!nTVO#R-qjB;guKp0a#~lH;W~KqZ7Om+FYcb z*?)R2+b^$@BF$MoM?Y-r&gDi1D7ZkSl`&w&mC^;OQ%i-*Tp9OEjk%r-OC*K-D`_RNBrCBsY?w>axzEVeSQ zD5o4D5#zi1Z0m$5tjFYGs~-w~w~!XjLIGYHrUJMuIBJ znB$b7Yx0z5G58q9dHB{TJ13(XGgzW&7w6++$2%wkMic8NRvHQ%kTCZ0{KO|E2JoGg zVTlUB;^?D|`ID2gVU@A#7K-MnzD}!zLLy@|Tg#JFQ5*|ORi1U_)6CLxYKf)3az0NA zAwC2l&k)SDz7tR_Vi;`gx}3xiXhQ1g|0~MHbe8bc)Bn{w+`IW4z(E#ms!!&&XESsI zOHs6fyQ70Tk~QeD{vG3-d-!l8FkWR{Uu&XBas@ixwJA{;GD~(jEYGA9MUg`h>`miV zGDjwU`Fwl4MO;k3i4s4EQzM<hQeNrN$UyLPn3=uZH_&ADWY0W3; z7h{%h(%>@<;!4y3&Kej^TzKfv;*I$6DnxHZbS)y=cwbzHKi`GudPHmne*++x!Hf3* zdLN=&5S@nKZUeL$(Cq}dtGAV~u_5-}P7AI02!15>XCfgF@O;-y- zj{DS`u4aJWA5g!$>Jq=RjqpQwxF3BCm8IGvp0e@qqreB7UcvUYLx6@6*+!de^T;NN zj&Y!4J?9vlIo4Q$ZI-UXSJ={rjeOW7hOJ@PfCM%kf-M$ctRT1hu{FKa&wdS zHJvR$XOqm{HWJQOgtIXKrM!U7oYmF>dSwA!tYAf{t#lN>$8Uc?^e04rM)X%ie?#<7 zME^p>IzFiP#GZ&)Gv;WLYy}MKELf}HEb#@F$-IIU#{t4pOz=ttixlCA_qI?hWlI(n zSxSU}C?J&yNM9@zvEUC*3%nTkVx9Z9nvRpSIl_*h=d(<_+U$Yz9elFJ8*Bxp$6DipGD zgp(J>8mb!Dvjk^2YJvH@KxwN|~>bPnvhY)9n0ZRvatR3NfBSIp;EFYM`HnW?G=RS?|xJ z2e62vCrTaatCxj!WoPlqk*8QHJiJ(bZ+=U02mc_>r@f>_FAWXR8engmJ#e;}2pNdZ-!rW=h z+(Z&;X?c;lMatO2>gxd5@r!X7v;u6S*GH?)3>ko#%Zo*GbRd&9i^fb^eDeLBv^Q?d zq_u5tiWU}RBxW?PB3V9{g@ae)AbZUwx@y>fKGOj*}wvJS@B6Au6yd#+ArOVB&htLY+^;y`zCne-Qa(cGBXTXep< z&!vhC(D+)TnavCHXg{*OaTIAqYY7z8Zs?k{%dYlz0kiON}jVoX`es$I=RHLk3{-If} zix}Q>RXIaTP1MoGTn@S=S%FzJjwai_%b2;*gqg)Q6FHh}6_l~pMl)G16s-pbaq-Zp zDXXp8A3xal!1=)bz9(Fq{_HL~dW&b6W0DzTZ+mISjge@PI-^yE+^Dgy-Lml~wSQwy zpcc)TQ=>gvpUsRJd#ds`cI`7u#%^bjhKoDlAUAwjhG3Nh9xlKGJU^+{GZUVDGKn$f z>rBshJ+)BMog-BM>7s&kYRO`rCV!*ePpUPV>yzrIxb?~9byDg2l=X>yY4F0o!zsLd zmSJ2?;Tj6>pzux#@1k%mh3hC>PvPAZZlG`@h4)Z+FNOC}xQW8e6mFq#D}~!Ayr07D z6h1)V4hkQn@F5C!Qur{1k5Kq1g~JH<$0)sv0&u(W0_WWn+;~4ue}~2G#&r+92YjEP zuq)xbmr~IANeXZ(dLO0tQvfdT0zJw814spRpUnkyGIrcj7ukTfk@2*ykuU1+qX{}b;yDN(;?Uh3+UG#TXwQ>?A zCsiw_P;yGOaw;XKRx2wgSy8QYQ$qi*M5tC)Q?j~RSxd>#LQGlx(b4HdC^> zTG>j;)@tQkO3tlT&ZFeKYUM&oF057tC>f|$OiIjZWss7=YGs&`;cDd~N-nBavXo@2 zl{_W+YNbF)p;{?ZQm$5ZP_m<1xs;MitCh^L@D7mRxxs{SztCjat^8RY& z1C)HATDg;wJFAtCQu5Ji_v08bFl9#F#)KjHe`7A{&z##w*Az&_mxda>v;7|e%18^7t^8m~v;0ORm5O5@bBMCSP zz)=Jo4d7@3jsb8C0mlJ2j(`&YoIt<=01F6+1BesQ0-%L}HUMn|EC#TcfTaMI5^yqr zlL_bn&_lp#0ILZ&9l+@XtOc-^fHMJ{Nx&umn+VtnU@HM<12~(2egORhoDbl90ulfc z1f&3@2p9q|M8F7u5dv}mas(6r6bL8+C=#$8z;*&I0dNTcmjSqpfXe|~PQVoat{~t_ z09O+5W&m#{;06FU5O52CTL`!dz+D7<9Kgp3cnrW}1pE@fF9~=Nz>5UD1mGnC{s7<) z1dIb1C!h+TO2EqiUMApQ0RBb5D*#?0z}STVV;5?00Cpi@cL2K+um^xW2xtb-Ou$|M z_99?k0Q(ZKKY;xSm;+!A0fzuMgn&Z<97@1E0P_f#4`4n4M*%pBfMWq1OTh5}jwfIN zfCU7^0mKPt0nkD~8-O+fIskMK& z2ZsD;8p;)5^y_!+X?spfDaIG2Y@>WxD&vg z1bi64hY9!?fR7PyH-Nhd_&9)%6YvQDpCI6q06s~;{Q&MK-~j*+5bz*?2MKrtz#{}a z3gA%!9s}?g0gnTCoPaL@_!0q60(g>urvN-fz*hl$m4K%KJWaqe0G=V>>j1t^z;ghe zBjDQrzD>Xj0A3*Ad%MuoIQ|2Ue@yYe_Z8zm-R0ErpHui1g?iBW*&`e=33VTzSMPXkG`%yT6!hsYH zrf>*_`4o<#@G1(&P&kgl@f1#=a3X~T6c$lvqtH%aF@-J)%P5>mVHJg53Tr5=qp*R( zMhZy^DGGxWMk!<|Pm|Lns_dVIGCUDa@x3qwp#U3n(n4u!uq%g$@dx6qZtWHHA|s zET^!N!fFbqQ&>x3J%tSv&ZN*sVKarZC~T#0HidI2^iw#G!ub>~q>!MHq>!R8NMVFR zhC+_Q#S{t@N))zH*g@eE3YSs1oWkoVTuI@L6y8bUy%cVua0`XoD7>G-2Pxc1;Ug68 zqVRDFpP+Crh5IPnPvHRypQ7+-3Xf3u428!ie1XE3C_G8wDGFbu@O28`pzuu!-=gq5 zh3`;!fx?d{{Di{)Quq~xUsHII!b=o>PvH*~Dip>kR4M$K!pju?PT`*v{zc(G6pR_C zj_*QYHwrT->`9@C!b}Q#QP_vVz7+POZ~%n^DI84U5DJG%}U7z)Qy zIG#d$#&zQ6@kKLMRVk_*KHdhX4NwQ5ju|wa0O%y33qThE%K$7R;A8+N6L2bkQwit> z&`rQf04oVN4Zvvx^b)Fn&llro%s6d)?Tqntlx&zWekLUwXN>nza_)@re)(5QCIy+4 zWU@^rJ7h8@lS^gtTA92~Ca;&t8)R~wOx`V%_sHZUdotRO%H(4*xl1N@%jDxSxko0S zkjcF=`J_zllga%uc|azglF5TIc}OOomdV31c|<0kk;$Vnc}ymsmC5I1^0-X?MC`2OuijSo`GHJ+D3c$_$qbq7A(K62(j=2+naq^QUNYHRCi}=_ zmQ41Q$!wYICzJhUa)35<7wnXHn@X);+Y zlU_=QveV^XXUJrYOxDU|olMqKLWnlVzs{tD3TvbMt4}7ID4{Hy{CTW>mB$E+J zGEL*7l+ci#l}Sz}c}i$xznBt2RFHoaWm1w!Sti?LvRx)SC>d)SzeN6ZsZ1`D$!leD zxlCRslh@1S3Yok?CRfVjjWT%?B}C_&mp@)D|GGvd?~utm z<+FFmzpj%coCLfl`M`ZF*nS6{A`q*8R5P^5gvL?)kU!ZPJijvu4=+VRge^^!pGR1*Q?&v5*Wrtxn! zjeo0Y{Q0Kw?>1HO;CoHuKWrNRQPcR3o5p`iul?(V%JHXH$A8{bt&abqY5Z4|>(>O^ z|41{)|0=C2*NaW0CLDiBW+D*(tb`PXD%bCuNO@@I>XNx+Qmve%a{Zxcyi$YlB+g9g zMwRPNP2<&?T&GyMPF1;HZW{kvO|Da|Tq{(re>RQ(yC&BPD_6J5Wi*eAW`9X^Te()M zT)Q@p?^cs*rIl;7$~B{Te9xL(tF2sXRj%gd@tHNb)>^sNt6cjukI$;fwcg6LQRUjN zd3^txTpO)in^mqk&Ep5vA

    ($NUC)ec4TDkHn*K3-`m)GRVTe%7< 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 E0D$!{w*UYD literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..bdb8ba2b3bdda1177ba679827e18861d4b242637 GIT binary patch literal 322555 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 z zui%D}5bo+4^#sG1(A#_n&S#7DEw4#^oFau2{vVj=%Q(gys;=>Nxm35ckCFDmEM;l{ zyR(tZ&O7F=%UB9ly2_Mcs2d)hZ@sZ^YxP=;`*+~tYrt=(XtGbF#ZW&w;6}`0>TaO; zCJS-j0+SX#ZO18OT5n)U`NJRPt*iBB=78XZfpdA;h#_XJaeW4NTw)jSf+4$oj{z5O z0qeDnc4^mtn8s^jkz)2>hYK`-HWZhrUB8{L&sFOY9=lo>HtM`qJxkJuQ*g7H(EsiA_}R^{aV>;@#+VL^_&+bZt^<# z<*oW`qaK3t;fApckRgDRJSx~AcA(fO*0`r5S$BWZ%Uu8t1_gPezb6NoL=*}JR7yY0?RnIMYPzV5?m6SNQYOFfpjJI$`qmSGMk~n zbX&GKJgk|^G`!J*Ns_fOXYANV6==N&DnId!Bbx>fIe}yg!xnBWTZ0RBD3Y?p4!>4A zM#Qy(-N&7}jysjRP#kjnuZy2spc3vEABzB~2VHoaX8>|@N~A7A@(qkF zXbchsCeI<~V#YPo!$EvELzd@gRH zbbgs;Gyd4+b14V^e1Q-n1+PAzf)UMzD5lDi3tlSOtj`tL0KsYVtfIkso;_E)7U^X` z?*U!Fg0LFP)xJc3UZ>xW7=4}oO2nODpT?=$JBCJLn_q8)U1TVG}4dmwVKI9&e= zfRx?1A$|q@EcrUGFn}s5CDNh*sJ34T!cjhNMtTRy=gwY`EecAK7t#fUdU6f#+c(T{4R35q$Aiae^og~_^)@_C6 zf>CwbDy;wobwkIBEoJ5r4}$|jt3NcDL=A<&8O3o5YpoxF^#RE|N^_Z0L8#)5Gc*?H z?pI@jY}DO>m4PUYpZuf@1SW_Lc)~Y%$G9>7QzhnPqqDN@$q|*1bz&0=Oa|?Mr=MhG zzpv1nimhYlQP>evEO`6wRQ1=6%fCFv(oNSzO(!rO^E<7=LQ=W0OwaUKrn3>NyL7xw zwX{aX!@AC?kK0#hDeOl=GME_D@!kAFEMGdL->{qQ);ITet@>?)wnEFnO&6MIPfGd` z)e|pB@$K-4?gfGddnB7CVqdA-a@LyzAd|JB!ZnU-(NF+dJ4GYK>cd<#>pIXdA0Ln# z;P^gQ9=OCSSuwAV;{|4h`ECii;VFF2*o7ur!F;71CZ6Y{FIg#t8XXb9dM z*UWes8m{t%3tU8q<4VZNj!<2403^wCa!&)5h0_?*4!j9h)gKH7U;uvY+H!d(a)xtv zmNjI#z;%6>(Yr`FdN$%MC-DIENq=MkSL&C(Xzcs+2}-RWLarocLphK06i7r7~gS zx^>Qx*vF@>v-;5jRK8=TKmVgLgD>8V0C*6TsJ8|meEQL>tOPXOIP-cud(9iN7zyAA zU$dCdXu54#Ju|@*dQ+hN*PEdrB7Nsdq2`TyO+zv5*H)PG)%qiERIOWN0;DO5DJv}# zDM7iy)eiB7`>6p*RDw9P95Bom|8NYzC>T*k`@_}==?Sl9xHq{8*PM*o6O$^3yQ8lT zcXMb%V$wdx!faX{HwU>q&~K_IUMg)ORher%0q8eYDS$0dW{tEl=L~G_R*YN><^Y5T z2gYN_>v=}@*<~gR2}8h=vVfC2k{Qcbcn>?G+*6x(fH}`stU>8k1D|799xtO5dKH-0 zFDbWFi*4nlu>agvO28CM^QW1tQ@;0$;T;J4;3q%hLEtCn>6sRNx=o+-2++DJDEK<$ z0)65+0*Nk_LpWS)FH+T`@&O|aRt@Tt-lJN@E)1(`ROQ_6<+^j3s@U<>Dqp8B5^vDR zjJW+q{Vby?LpFD#Y?VHMZ}rJ*5I(EiGe##u$1rahcr;(dOuYo^;m&#h-vpG(nm`oE zwf#zI3gx-JU?SU;g{;Ybqg~y`v``#@D{3MviBBnvdhQ?8XV|C< z;G?E#YMQF1S|J+HK0{4)+Eb!$)@$EvL+Yv)sw$;@1Q=zyzF$A?Htn5#E>M8!h|-7U z&9?hi>eoZY6W&Wvpg~phZR+2?MjQLGkBr-26FZiGz*eGqk0|oy*gRI#@j%3*j=r3ZCvt9hChPpI~{`R)q|Kp=&T9-AGoYgSW(oR zsOkf<3jM$v!-1VI$>BeR+U@jCk~I<^IB8=pkI;uaLbLWz1N9W!LMiUA-w3=9t-E6+ zELeErC4O;=Nzh}d@W=;-Aka3uk5qlG0p~sV`AMVFB}K-5<2%r zLiY)i^&Tf#n-HSBYWEpt8BZOxsF(nNF7?P{4Z}KcNS0LnfWNHek8^a)qhcz3V=Wr% zFqmRJhSv#8#{yo2CP1I=1}_3B!n!WeUYBLN6Vtjul^eA_WB9|J1Os?&>7gq9lB0O) zSt5?@Ifc=;QvVsEsZcMQZ!$aIM^PU#QcPbi)VnF8xZcZ+DE$(LkWesjxK1(Bka`QY z$-(bv(;Y3kqeFLe=?+d#kM0=M9izHqwMl52JWfV;xQzezf;14%2_1-PLcP^Gqeu!M zEYM-pvbwZBgSNn8>*hS<^tH!$4`XKAY!*`I5$Tn61F zw2R@NphpJ`HSrAWCjLAL$jU{k8||5QueUTIlbvi83N)z^Q}bwK9Z1S#a=}N4dHjSQ zCR=Z?+ms(OtGfY@4D3%J$_lf$!c%^$M{UewP_c%$Rnf5pcwxF>!Ue(v=?X>&#>410q5tJq~s;kyRpew+zrwSTS zl^D&AB5iW455y0+FNgJk@&$;m%DSAAFro=>rkEoht1^f98*-e^aqcU2^6lN~^iV(D zr+q`Zo{B%bdTB|Ke>pwQgiEhM;^H!&ln8Qa`~Gl4-s|ni(u%NHfVU-55gpC5i)o zFngGB)g#so_g896{#%{A!LhU*DL2jGiYYc(gXhGu^-On0(6A*k-Gn+&BJ;GF)>Oy4 zu1M&~i9OohVB0yQD`?-NN1J=GOkWt%p9$lo8YZZgnMBp&Zat3Dr=O#~J8k2VQ21D6 zOjLNe(LSwMZtXCeoWx6}#zq4?rh*-)*9PuBSDwpG^_)YMr=?MC$uTjcLl`}`)yUL< z3cd%Q;^q$ZHX|lEJ%i0PdIm*OXJ{05>O3f>9)}#m24;C0K>as+90DwPtXGTRX*jEd z2;{J{HKHR1q|+5{gpDBwb0C}mfJCfco>e6;#{O5Ln%k}qHtWhfZH+4B@W>b_CDCI{ zk3*ONUoE$)8E-mB8&q6q0nyKnhS=B}tZE#Yc3eX&*9lcb$~N0<3-1*rcjM5`GlQI> zd;mMT!^k$#h31vI2~g8^_WHnWx-5Go9bjO`WEQ-~BpTXr)`7I#s|s(DS~p_EY&L?} zZ(5GY3`J*ybxWXGFf&RCBt#8 z0PtIKTX>Hy!A%~GL!@?ND$t-Y#k!%$sDpgtrYVZlnca9}z2#6)%}*7AUNun&`cxI@ zl{zaY1kDBH)>q0V*LzyMo%oFwq+C^qE?RspC|r=83~?Pl<4UlGSFoXEJ(Qbs8jlp0 zgRWyv)DbyHipUw6gd+uC~k znDn1NhaV$a26kpuCq^$Pg&agLL>+)*8ArwnwJ2$#8KaeUga`#s@INBc_0PaS6iMPiaoEG?&zi(o{3Qp-|JFVUme9IOo%hM3%;U;wMz+}+Rv zMQYHL&=+7A1HlEN@&tDAL%x7OVL#4VLWpF6jtfehLPM1jVL}f>emjYSmxIJHdZ6NL z6N}G(J2&a6VwGU?8;nxhL}cPd#sYPohw3LA1YF6U@+T7#f&ZbD>6NUxxiS;K>mNeV zXF0GrwH3aIY|aY-x4-_6on-U4LC8s?3?V-e9yhuOe+9(q01Fq;fERGEkd<(i=zk|G z$)zM7K4DAmoTocI2e~t?I~VCr8X^XCXP@r$)Z^}TBJa3!gQk&pFpHc-&rK!ZKP5A| zq|J5ujHgB>z?P`d7ixQM+SCLux!t{FA)}_UE|Mk!WH)e;AlpPi+Zidf-cHV5t`*oC z1WSg?I2DaRZYu{HYP6eBLfH&&${zU!5r#!kzT&HawTXy)!GXLujfQvwce^wwv-@KU!F>lks7w-9#n zj;BV^gwVP8ncpIJ!^-vQgJj}x3t9OF1Cc(SXB@ElLe0UW6=^Gc70(DJC-fl?y7(1h z%U>_k*U7aBz=m`lzw1xZL7{{_C0rjixa@b0`kntd4IP183fHKQG6!iOjS^8qV-Q|L z25JQ@A%P4DdQ3Dzs1FcVt+R2paQ_HUvy$&&(oKrLVk?tYgHECb3~kjz=sk3dZq)8s zdSs36M5Yy+4@I*;cf|C3v5f=!IidI))K5G%(SOa=1uhPZ7lW>e;0EHrFg9Ppi9?Hm zx0&^2chTwNq1|WPtyJNl2@(=|VvfGvr0#k8dYigi)ZL+OKS)od^(H?^Z|YLF$65tF zqKNso-PURHCXcncsnrgvXH?zG^`<3y2n^Zfh`ZP6O(S}fpQV_erEZV1fRX2MoH$F3 zDrr@TAE$ieK(T>khO3wS&zw+1)fa!{qGf~)N!>3!%L^Aze=}G)wWul%Nowm z+&UW*fO&-Xf=!F?IbMHX#0t=Jx6F9>oa)$+vr^kNKPNthZ{@<)Yvyvji$o7MQE3+( z7=)Xf${2`*-cbR2O3{Y^01OcH4-BxwW>Op62i6xLKES4o|oCkM=9XiydLyL8&M~9Z`(4Y>D>d*=uTCGDF9a^tL{^D5U03KTK zHdp6`x)?6l8GUCug5BidR`(h~gHQP&s#J-7(W^&>HN|T;v?*cXub{??{P;xeaZl(n zp{UwmR}5kg)xF9fN$u9G8~hE{D3>&$$D14k015yH00AKPC-Eoc_bF^U$@f`OzR_uQ zyH{D2;cX0?4nQ1eHXgr3-Sx)UA=F9bn$S53P~!;0&bKMU6a+aEGnXjAusM2fx%*@; zeRj+qqe53@K~a(>UsjvaEsqBw6Wc|93PFO0!TiZWqU(eWLQ3+tPD3?bZlBfBI+|>{ zO=pWbJ4BO6r-wS7ep5O})#+EGGow!K0*ha)pCU&FNd_P1FLD@wh4WTy^SG&@a5o`w z5n)o_KOsr))yH#rdV?_*0L;NL3ZdqP&=F%B(bZt}P+uIUeG10Q9L44-HdiH!RF&4| z0aL=HF%$x!#`XKI`$My+0c4k1`Avs_t`&58^ zV{Df5OGz%8BG#uvCo;8?I58)sH2+q>SvQ>BDr38GfccMR{87XL^_|&)q)$*_^)CfI=wzo>8Z+uW z-hjhfL;5<>XB{yGzCl2Xd;-fd#uyr=pqA)8ctehdi@g(&@GUSvXddCK_p$qUK*l+> z=rYDRb?7pLWTBulzX`%Q!<#a??A4t367{V%{%TRiN+IZuA`XKw+)JLm&H#M=D#-=J z8nbSEUBr9=K>`jdg%ihXzy27N`A7T~EqHtgaRqNd=iRG47*E9`Rq6?JYdu-mS8b#E zcuiw&gyBuE#@q;IAH{oqILGvO?H>-4FW3&Q32dJ=)@H~$BdnCa#)8TES=MI71?2E= z_G#wB4tTyDd&{4=S`O(pE|t4;ANe@SY|g6UFeJGw*>0l}Y#@gaBz(yFo5mVN+PIib z&uX37tYh#cBH9haG{#XaCH{@?$rBx0-zl)}o_&QTJiDGR zoos9YG`L7oK&~>=6iFI*g&jCB-Ez9|_G*`X-tPtL-=5TG4Kjw2r`sCtTxhs>8@sGiOGLY_X%IrJ0^4F{+Qm@MNYOjdUmjDky#i{WA5{~tRMjQV?*<=Hl4 zf}njCjQYcL{hgyae+ZzZgHZrGe|9j6B5xF^tyAl9?tnaHhVwv`sd1c#7;HU`K0rOa zHs0d!u-=Lsr30Ina@v>ayIE}Wa!l@80|Rl6fKl*ga9Eg~`JB}p%s2s+x*9awZQa}W zH&tV95RRKESC9vYf|_)3i!N@{#T~l1%cc*1tVb6Q>f%vdyjmA$bTOl^5X+@$D90*k z))z6S?r#1n_l>X`VA6uMX6MUvxg9Qb3f681LV?2oBGWyv&%^q;pP4!o1w+Aci47*eA(BQNc3#KXneqDLbG*14 z2Sm(LYc$ZVCmZxNs2Ytr(CP!bfj)e@tw@^CJNaQ(aHYkJSi+#BnD)rBzgUr8z&27h z@mC0FSgKz~IMU29M`(`NAVg)^hLdF#pKvvWvJZ;xwsLfcpe z7Qq{4BWdg30dV+0pViHi=q7o0@R*m6$BGSy940t-=wNq3mrkriV<9;wgT^_Gh7lMX z1|T)g0LBn5CGMWs6?VGcyH#Xxe(d+r+>J9Lo5+qPG{;w~0w?)%82*uZuJidTSp-f3 z{BtjIaeylTgtP36ssW>ckqg*qq4$^MpQ2aMf)4^8N-(8Tb?Ha34`L zNU(D2c|6V=XEvaE!?swi`6y6sHAfuuoZ3>$^OV_Q@0&lcWH&|oTsL#)R zhQ-g*{oML|T~uiM`zT=>0UHVcaW&8(?ghjxrxXykWMj7N^=7nzRXKI06~n{(keVnD z?2j7ZQHhao^sY=efDS__uHh@!7z}l1tNyk@Uu@Q+RCxj&j;Eq)AX`M}Y%+O}{1#o_ zrpr5YIk8`tE_a^E<%7E1$s3oi*5w%+5ldvU(5qBMmHO8;rrnp~{L>cw`jZIg%AU?| ziRd34E&tB~b$c$)rq|NNMs!`F8F7=m!*st;rC&|e1+_YwG&Jnjbw-y34O{Of-7qMe z5iAjRMyYH#bbyXgk6Q-)%+s;>=&-ggw=4|vXz3W?iu2{J-DuDgc^@XltO0f#i`{B% zEQh!z1?C?wol~48a>dfTReuxn4g}U5HKRD zQ5>PDJ-}lHYRA>agrg)4d2gwvOfw$-50fhM!st`=`u!aJ1$BXhK0Z%>F;~CtGzHX0 z(9SB;t^JxbpkH;HABorKD$0U=IuE5;MzO5Z*~n_G)ivC;Azi-8inhiZBnm22olm|d zLMHNg8-XH3)3~mhVh}`KmC{pQUz#Z>~|V_n@ui)H&Z6)B>i;+Q2vVTeD@QiCEs0(b^&Xig$r> z+-~#NShTW69c|TjxI3J7o{)b)EF%^V;E%9ig}&WU>;_sKEF)SRLC&tz@}Nq3h}?q% zykpithRc8gSi?rsb;m7Mo)$CA0fqn?!O427X5=Kc(!@FoO#!8rjQjzEPYZdqzF4M$ zJkxmR=CVHb=BSCjM=uu`#_}Y=Iff{qiy+BY>maC9v9*=$WbBA1bPqGIhJe;-tM%+} z#IgxSxluzQUhS+`v6E`HxRN0O-fbQp7X;XLMCBU|>>>a@3PZb9rH%R#=BPp6W<4pO zlZ?b|)YKp8Q{cl9VM9cy+-MsK$5bm_Mdu?-{sjf%g^$i9&c$ZL9%$Bo7V1LYlxJWc$)mZ6xTX(iq3SM&??xgrEV2JywSQ9FcD|^o!W~S3rZ}7hR6P4vN1)m+lPzw zM_)Ip6?JeR5nvh8m#TF=_Qa)EZXocZkv5^9czS+OojJ9?2ft-`nKD3X%>9+IgE-Qu zY#2=N_RB_H+p3qE^`%L6o;mX{!2nXmYoo3DB0m7<6L&!A0T~3$7ysmofOcFo%>DHx z1ic<7MB(pwsR-!U{1F5yrt9JjPft_9RK>Crf@+9G!PywiFmF70NqUJbN%!}JaTQp5s*M?T-xG)2xQds&poYOD z{BGjiTh-sFI0Q(qy?()4r9x-Wa|E~kg0Z+UQ~?9W;Kme~Cqfe-DYq zxaHiWqIDKcrTGCil=K-}fmJ8>pKGZ!|9%Nm<2f~pjDC0s1xfK50PBDza<^b&eqE#L ztRyd7%|0}Cz?2Z0KwpB`Y1p~~!DMD4mRl-Jhh^wk9*{{-y7}SGAREh_;$s0P*$W&x z$UwrSCrJ4V?d~5R2-vH=d?}(FBbHxShitFX+y!s+Bk&+-sdA|Nt|EOdp(P{s@D~9b zfwS@9z@e4Kx}WI-i?I?$EU(snxUy)b0VR1UggA4h|1fv(hkRzSNyx%>!}M`fF3k3x zW82vX!Vj$OzhqC^QBD_0M_kWAL}Ym(^EB&^L;3@VceCCK7u0KQA^7<*M57$b2#V2Z zCm04=kxRFc?C0?eL~%oA9|B~z#rf6O6k9~J7bAl~2-nAtpC!@#maY=55ir9==hrEl z^6O@iYLp(fWDw*b+=%}sIV#k-{4FmY(Fcn3l~R%1eZ_M_{C)+Aq$_2O4p_>NA(sSX z^V`Z*x_|(WtjekQ`(oOKU;+n^w!^Za*0IR}Ro9G8Te14IYkCDU?bSV_+8Ty#Q(g5^CR9mm=~%|PKDix7P>OEUyAaJriHOzUOtM_$>AB^d zE)+ym9Bfr^5Xa&M^{+yU;tQ|N$f6E9iq&C&(UDd~tyqfx&+~k9 z4yP>wzVn~=`d=3pS1HLkzu$LxmixJ%`*DfsH#za(9)6upd5&43{tdIq8EaH~jZwba z6M82!wnlZ<=vv@?t}qVBtEgMBletqVt1X9mvA1ZFt?jFCEQ+&b|NX&~eiG($5~#Sb zNABEf*(qRZ~Q;_FH6 zi*+BUDG_x{U+^&L5I;=M1)diRJkhFAoQ*}EAQyRR99ruBoYqHmrP(@=t9T|gKEQXK zC?bcxWqBrxjFLr?LWcAfP_$q7f*fKJmkBU7O8LIVYAZNF+)5N*$$q{1DiwGafG0MY zq=4PT0G9nFzaH0ZOwLN!v>a~+CK|q!Y68N)>5anYTBI)sPCsu-h5S$+l0H2SQpu-NbG?{OW?rbz~eh7JI z*@#|Jo&w-IlI67q%kwjPyrx{mjljh5%77T?6_n`GCFXj*N>ql(UbbtdJ~Ir0sEm*d zI57mM6fT{{Oj{-8!sw8o<-m@xD~THdWkv2DXpV6DBm;4Da6HnQf8gU4Zj%=`qw8kK?0pZr^aclx%KaP@jVFIai zU!gV?=zF{f@KLFHN^}}u$Ang9v)1dkJ|PtGB^1WK)vKXCT@gn4bm>Dg^qN6E>k1^R zxD=c8MU*8xGQs1#n_fSUOa_7)3BqW3Rv$bhJp!0E*(@8;?;C)0N(^(u$mjF<9`5cy zu6Cnn<%T7ascyc}`XO(vP5iQSTmq{lxa7iOI zn#)uO1bE}R5ub%vw0oI7{4QUVuW!4rALAn6so_Jq8=^4;AcX_WL;j#wQ~e>6L}g^( znV6iu06ggxd)TY+X^eaZ6fTHe0EYLH5|g z|8jY;8tI-4I`q#4n(BK;;Qb4hmv&~%FT4ovXs!xvFPSc83Mh0jS2?Ul^`y$@iIWeK zpwR-uFs2_4YARhY{=UR5U#Ax)bTKoIXRTfjp`zckC~c!NJ*~Ia=pP$3z#WtpkbNT> z%({Jw~J5prL!fb=T@X zx=6xz&CsI|I9*-s9sF)gPfPD8vX}%@5IQ@^1S6qD?q5BA*r1nFD~DT7l^l2Jlab@C zK3tDo?lY?n76b^e)HPbayU8$Z%+3=u)nfg4O-3G{r866Ce%4MGULa&T=3Ho~PzfqK zeoX57#((zi&Y0#V|&1u%0<=RDt)uuU2qU_Whtn^CFp*Y^9N4ZnOnzLSW@FrWe zE3G+PE5B0+w5GB$vjj!JXqd!eQ$z$)vW`Xn%&}fIVh^!|BnvJraxfS}Y#@V zJnkgji&f{mIeT_{!wE?K_Ezhf$LNKw`8zYz+3jGMe%{Davea1s0b1sRsD5NgRB^Y1WXNcrrg4WSQl__V!s}Z>!T!V@EPDndTxtR zdfp|`2raDC*pO*jq*O#E(&^Qr8K&e6H!O--_JR>!Ui{I;PGR3<8-vR&DCP;57##XO z9BaKE@*1D@H#sc1u20tm&bAxmt)8%y4(R)vR6L}`8?9bUK(c3@7ITCa8pz++s0ZtG zBeA8_=ebor5e_G3hQ5hLgu4lXhtuoy9OoIU#W4mm@6`uEzi~#+$?40p`99x_Yhp|v zs*pRNw3pa` z`~~_1{)@6jx3j?`rU`l6y*Azx1Hwi7Dy0GB_Uk20cy)Jm*Mm{AnuVY+}C=x^o4 zc^YHFI94yh0_l$R)n}0?nFb*ED!k4o#TzJXV6MUw+O8wG?cAXB5i1%@uF!i zTd0q48a+Bqu2RC+=QHF8^9>4{6IpRISl$q{u z&<2hKG3VbAAdx^Jx?W%;hd9I@$SoBn!)nKrWY2>pVU}Y>wg|-Ip ztwJBhZa9|=2?9L$A_vw05(xaqzf4 zq&CEm9C#j{B$Pi;+Tagk%e7;xb`Yi1sW6LL)agD5-kfI^7MgvxRqT{&WgO$jvU(cb)_`^d<{>Xj_{79&f0r~6N3IZGMuqQPC#mqk^vDYF#Vkpacj_6xfYT^i&sk z2f_(HbZ1ccV~KG6+*yD2=oa(JpMhe!(DbeJddR# zDR9h$O2l8ROvvrdh!YYsKvXWP)l=BOCOy@lr<(Oto1W^?TRZjCD!p~3kSTuau%23P z;vr9M)?3m2W-brnQNEsdjWY|3Yye!G!tMn~8Iz06bW6n^#e<{78{!Aa)3G7Ad;dm| zp9yrz&>BOTp6Yy7o&p%bsYH>CFe6%XEC|Q=3Nlu{nm!Bc=W6X-t4sThZ)RV|Vc=lX zX#!a{ZWTs`P{VL;Wif*nb8GgEem%ku(^!f$*?<`_)*So!d2G%yyYF1C`7V==)gl?W zlinzx=|U@|y^o{r!2TC~FRrQ8z*1e)q=5zvG;3hFF0R)tt$L5gE!VVZz^QJ$-9VqN z@wnwPD>aabTLwmS&4Bi=wwl5K&qm8hX!+Tyi;*%*YoOn(D9HaFnExA08$UE_ycomK z-b>gpK?Tw;aFnzoIoF6&_eF=-`n=vZ&MpHt&R}bO-Ui#(Hx92E*(`&tK{+EyA%%x; z_Lkrd{Gwr1&S403M7JgMZCZp1^nQ4x5YACJ_deYJN?7@lCTN0Q>rSFg3HUT_m+no) zDvn!nJ%+_gXe!upiN4MnLI#eisznv;y1q-305JgE8Vz#;l;Efoffx|JI?-_)H3e7n zf+LA1r)Y#{!%*j2Md`MQHAVTApu?YEdm zOf(VBtLweZd->kmY~wA5A=7os<4yA&RJ=S(XnQzA`Gxa;x zn6=-r-iBvET-mYNTBYoQQ_9cN+d*mKdK=Y;m<6uo45u#8p>lJkw>a~*BcXqWi_3g! zvbpK{;B0-nQXeYOy-Ng!xt&wDROz$z1&74btx7vBFkPkxdbOrcY1n{_5%FmD?Ss19 zC!%7z{&kZf=jkoR5T573&v8drD1Bo5{|U-pqb>w zok+vzG>dOBp+Gd)Tel2R0*2+rZHCic6=ovm&g8{7hq1ii!?Nb|tu1Qt8M`bsRZ&MOkLF+!9UJrp=Cea5&36~si}Kv(0CC6cjzJ-b1Pek<_B zTa1*LA{eHofE99RH;G#(`dzK60f9bIMsF`sE8}84sz1nB*xYHbVRS4rVL9g@&zJ>I z&bahAK7BlN z%(FZSKzP#Gs|;Sag|8q8Cs5~hL;2XCU7psBEwsbXU1I@iQ5de88GedU!r1Z^_m_yv zz8=;StdeZ^1hec<>WSdYGi4PvW*AEv+9>)h>7b-OK5>;J$7A%X+aLar&k`j&8_SLp zrNEt;C`uS}W*GE|WC~M0Gs+c=S=>sFhFUnf%BY3=uN= za=?_ImWZdB9F-L0AMh4;;=~O2L8|8j=F7?d0M`&EL1|L3Td7)l&d%kUD~-}{iX(H&_IA$~;N_y2`ok#}gul?C zDCiJDGX8YPt|a-(uVVUtFoyUk_<@isO7uLVtim)X(5+S0XtUiJ1-!`R?tt+1L+}}D zEQY)ypu}NF3XknRg|MHd=~1*bD2F-hX%^C-fmgf1AFO+wz>B_xKem`$ulUYWM`n)ht=+TtZyzYnXK0VUk8Oj+l(G0o=P84^Tg2gjGtu5$CX__#k; z--(`5-}&Q-#U0@Ks9S*Pfz3!q72@-lmz)w0t-;_J(G%-C;ATW<{c+oL6noz7FfxEG zfoMUk@mdQSd^CfTi(mqu8D^MbB&nU-Xs7?)PY6lA59$repbHv__)a9fw?{T|G}KLqpj`ksrjreC!v z>vmEejwol$DF*;DFBX_Ms4+Feg697gYqcLpF3X^UBpl#LgvzuVY_&ojF%rayTZ;{C z4pOMeT*RQ~&rkp4)u0&BA;MK6OJ$+ZA8@Vs%gRg#2@Lj(Y;c|x&LSc5pCsxagd58h zyuzAgRjpo8(h3Gzf$mS}u0lPD(CCS}KzK1iyX{Hiz!WiTk$ftvvf`wvrQU-O^QaH@ zRBt%*8SMhH#cf{T;B2G(5EKl~;b_(BMFj%@;g%Prez=d10U5nI5rf)nZ07lkg=g7& z>N~;&SjdXtjfBB}bjsF;X>TVerRzLtgr8ahV;JU6gdTMw^k|btn>D&zp94(GX&4`M z`dny`8O_q6y+>x$laaN<8qG4Iy-R&GkfOcW0h9Q-wOW$asJF?y)i?A&XpPULB-#G) zn+TriS;pjg7c<9$7?_J=GtN+D={C~cg&Y<3J@otn#m9{~f0cLOw!&bq)qM>{ioTD& zUFy+o*1F3M7Idn`LnD{~Ep+&r*!OQ z*>|BWH(&oG?Q(e~(&0Fy5$Lk?=Q8c$q!!(F^AQ&RoYbfbVp*Z@Q*Ng5R+e`VYvDMO z^wq-Kp|#donva~=yD>#ZEoO1>gAppN#ikz{q1fvBgk_<|N`Vz(VGvs&a`U<>bGQsF z0tEsK;$=NOXh2lRtt=t0+WdrPtQ&eAoUAISN%5v?=K2PQ)`i9oGxYtn5Ex(!lmo6cYc zQ>V^YsoOX$!#cyeOKuB#o}r%<1cOgzes^PJy$!eBcF{{xiNx(`ebtHo1GV z-oLThn7b0~KC!*-CQ>H=p8{P=%I{5lKqBuh&^vr+sY3AZj1V{B-PYslF8 zd4@L#p_=f9k=CH!0rcaXzYJ|G8HiyBEpi3?cE3mobE?=IT&vtXCR5ZMuRa*gHsl{X zMV9JAxCN00JMUpIiN*>KgyumwB=(q~B0eAT3;?(jUHBFV3HK5am1;LdRXTZ3S9F@9 zGhdvyTb~JsimFw<*lY!xh|(Gs19i1%N=5Zb&^i(FqcUv{)R#UBM2XO%gR1U!#)YSB zge&A7Q4kxXHJuD&06vvRI6U6s5v|ehT_F1R><(?h-uFk363g97wkr_F6y%gA89)f7?6Pny$aksV3pswyy|^$vUy>U+cCnVO7ldRl$Is>&Mfnu;LLQ0Q`iMapG$PwYEqLa>aZL|HhPA3 zI}|`v$t9v>04py=%Cl8-y{`v&tze3}m+4uWmmBq%PtCZK%f<8Hq44aSSjrQg&g_8L z$sc@d&3UXmf5vwMi9^ZDpcz+E@FFDRpca}&7FUcYs1>hQt4}rQQw{n=v+iiqCwi=f z_7khLaHT#qtWT^_p&!Ceq;nSPWPtyn^)WLj9q@FCDjx zWFG>5uT>l02?oLvftIYbeoxCQU4C}o2Hi^^O^qIDv{9j4Ub9{3?Psi(RsBlzAOa>J zmh>#+B1sBZXX#=rUgp!_Mq&hTuiL#ZkDuQTf56Kn;NC}~_A6zD`fK{f2{MW5fsE)7 zA@-PJ!N#uK>Dw8-*;}%6w_R`c)2=t$PsN<&^)&Msb|#^(7FyeHL5bc|tV>!nm1B?Y zy<=Pm{@gmCD}n&j2AxazL^{cmdQ3(BbqLBtp@w|E*hhfu=!SE8*r7~kCGN7z+3!;Z zoI}E|P-4KMf_V1{WC`K{GY;PA5!$_828xm)GPaKlkvT`SWreITciOK9TE}V6&(~D2 z1>!pI4~-Db0(5&o3nun_i>?J6bH?~(-BydIpimxoAZzs=M-rf3*cb72Cyf;z&~(NE zl57rG1^?#*`u%{Ops1bDhqLD@--uF4%oLy**g~ISgQ<1;CO9xffruKUdA|Dx$&rae z_{;5C@xPD1uK!-CbUl*6ev4FxM2tTny4G5*IUf z{*gmFNeek4<#zAh=;m&ed}Nw_G2KdO|5T|BxD1YQtsZL9Lk)VU*QY3ba00p&nM#^t5v!|=_aL{ zm2OkI$Li7PRaTNt4=cUKO48}H(wnUtm)ty_uf1GY%vz!O6ibMz&C>pmD?F%eo+bmS ztqONJCl6CA==YrR0jt#!Tjduo)>DZdsaC0%*m}`h@G4tx zgL<3Qn^R@$?J)_v&QA4m@<|3)S(USw^EPbb(y;R%^BlG}!)8xGg-xs1#o5Z%3Ej&A zUKz9vfh-5~Liy=CIGPp<6;dRmgZ5*j42-`?VgwNGLk)m7C^&K?5z@a^=ss2qnGswn z_nP{PSFe8T?qk&DZ4EiZ2`M+Mj<6u0oOF33o>Hg!ERbhdwjzo+Y{nk?^Iu$On7v)SM$0EX`Re*7q4j zM?VY2tbF60{y1vCQYKvpR?NO6EOVbs>X*!EQ-$;3#x0Tq8l+pyzD1~(c3NR2zukB~ z#3T?DFD6tY2d7z;9Go`Qtx9`wjS5c4typmKO#-l|89Z03y$#yiq`l4B+orueN_1*3 zETEOzJFLBHj1B~AXfOR2Y16c)=?O;@C#WW@;+m|oTGAC*OE0hUm(xg5oxM}ttc2J5 zTD;g-MJh_AZ;cApt2(X3W)+Z9IiL}7BtOk~DG0aBz%8-cO3d@M0o}7!e?SI5;B~~7 zoEG|OoejmJfp`$Zpp<@`?Pi)Dmx4N=2a3nZvzRml{eWyMXmvtAsJA+lMYiw|IH*t& zJidk8PTSX9I0++GWk_MALwvhd$J3dEN}x!%NURvODty$RyhXMMUr87^IkLopsO#u2 zYgV4OwpmNuF1EybPIGR8Ln~@18Cr97V7rNR?<3?X$aF4 zpRP2?OQr4aQFmmxdn=-4!IpZpIwzAB@+7K{I0Y|Faxbj7KWM{WlCS}Tn?Mz6qkii5 zBD&dtrg6LrXOvM~A%IVMVo3YIISI9ws&ux>DlPVYGY>$UZMT8{G&NvUuU@3hQ$*KyLW%4Tdm}rw^n6 z+|~l4yplK&xkZbG>$i1lc1ft2G5iidd&D55J;7w*vBW!8r`%uzWQ&Vz2T8iMRNTyFA?P zGK-v33@UY=KZSLI?YE&ln@L(Z^Y2>cZE@6;GdUoJ^SENiFIw(^trs+l|3~1L)15Mv%}%?!MoSM@Qy! zo_VRyxz#@;$tQR|)xk4RZY#DD9tH;&{7e{rO)xoGfAf;_uSq)S_sPvW+`cgagR&Ph zS!md?)T7^+jlAhsCTR>z1K6t6W`xndPjdvtI}qauycBy!vD+D39P)*brf^$8-%zc% z5$t%E1_sT@tRAw={fT8JIBexPmr2=4hf6{~2^NN!oPhikAvYv$eC*Qr*wEVp0gO>E$_jWR*j;A;6A!fIZIx>|gX+gVj6_ zup@rizrIrQ0HS9opTc*TUF89G#IO9koB(?x!jjH=|3?q7FZY1zyMJCi38&Anrxq?t zy)LJhfzyt6;0iDycanO_)je5#r8;k#hNtUqX6vp>omZmsW_jc43_SxsnZrZ(7W5Ku z<7%_>7E#x$u0#2)#;D;H4sX)VA+1}c2@b@Kb?Fb)22&8nc83e%rtHPru}MdWE|!@} z38sna^O*M>6;NKJQG%F|6dq5+=2qLFK;&`4U`p!UhlAbb-wQR9P#KhoKZC%?rau&B zXDlw$#XeN-YdAhi34|*SN#ULVI&edfZTJIs9}F`Mb=;{bob%L1&5WtNPoQo9!@Lrfoiwx3kX4{*R&QFRCQ-Q?uz`|1B-GzE{3j?46yh%Zm25j8jXXn^lrd%e zJ)z)tP^;k9@GIHIA^W!yiFPWwIn! z^T{MEjjAX7n4#%iKG;-x4c23Zen#P}Lhpu-o?BV&bRs&x7+C0OJ4=AEvq>fV(<>&;6oMI6&OC1NlVj=*(j8AUz4{!Ei;^C9CAIl0mp1CtqYGvV4cF*`*4<-L&jI(G)7k|zQ$Dd zN7id3!)SstMm;E=*2rdc^c(aPw&1=EHr6oWBU;$^xO0$3SrBZaN1jA$1ZLNHFmQg5 z(+OHSsOX@alaw_wmcn;Teu53lSB`WD3&=712~}H_G=BR%2gr+tvzvu1@)0m z>qSisXQnANnn?b8>(oi+g`@Py{Cp3~xunFmYlBBvZLuF9>JD@c9c!h2%5lQizavjS zj2k&W#eSixN)!soko425B;TeGADVP{LVvsYH0e;o^$^Z7GHSTs3B+$L7VQ(lMflQQ z8!<-wv#edeLP5n-v&V6HgK8vTBRlgb4lMmOUMHQuQ7vm#@1@db*Euh!(E?G#5J>0o z*Mkrsp~zCQ3>52Py)DbK_JxYl99N>>v+vaL`&C_`cadiL3u5sA@s@;O6)wF@fT-K6 z9%V!tUAmA%!dtsjgV@92%%`ZA3AT|+;N+0A&~A(j1>n_M0Ov)zVS_#!;BJ5#nX4r* zd$88d!0skp*P!c~bsYz_P1p74SDm_Um43BS*Lj|GUAOYq=vQ>9uh(^HUAI}kf@X#@ zLMuc12Pi9DuAGds+x3+q>zr~hPseOrM(x)C=6PMoG=(>3DnXg6+_^?gTAii%emY-qW|49ytS!C|{H zl>>SqlyS+X-5YW}dz#eKpq^&+w5g|4JuB5Ste*AiNvo&d>;TCNk2^{pvL&wf(>Yi@hh^!bVXLr!T4LaMQOxIh;@;IwF9X4*V&gUWNmz*w$o%dAgN4{l?p*8x* zIh-APWGUW|)1nCP*&0#|K9)O+iwDHuFyxu>zsx%*w>!K%gAXqKSuHh6bZYSMAb7#BKbS0H+k_6{DBFQoon?-+B8@=T`bp5Phjt* zGlJ?sHh+{pN4Y?0dWSc6U|1mj(XsLs*0Wzfr9(ChuOXDmGrC%9iGEBF)o*kT9+)as zipO~QV8BOy@M95H-YcH}P+?3tLZ%NAP83_v)$MMGu#MP&Z~3{a=jEg0v{qjYE5pz5 z*sSW>41mTGWyIcjlArL4WFq*)Msp}U-oaCWT!vO-U`sTWs8V{1N2lojSk(`+7O@rP z7$*kxIeJ3?+4#mv9U`d1t8y@sIa5ovW`>o(&#yDc8ZzOxWQwxwmD&b*hQrXMhjDz| zWqy}j20Kr@N@yD7ynusL!0`ES;LQ`Kr92Kw4{wc8DaHD7gAe>_wrM!63A%;I>Qi`Q%T~MLN>wK6d_MZ>OkS1&z zJL*{EamlHMV?4;wg3(PymAY!T>oIZyy~cz?CpV;3I1sI*+n6zaq{pH;6+Oiuk#8VRD?8FAcN8 zUemX#3OiV>$g8QOoK!}6$r?(io=`erL!FsJy#u8ENJ4Kb(DrIASfWe3aBzuNC@yK$ zB^|n?PnUG-5-%KFGN5xe>5?HqfxaXZ{;1zkdhoG9^SzH|1t0ERKVuth)46Nrwn*zZ zEyVn|5^S}*lERoCrvC22+II(wjUORU$+{B4Li|OhI!|6>p&dt&%gfE>+H&h@T;kLG z%;%G4CUh|O*mLHw|0j)p$Q*kxe;WXibKrSS%Q`vLWPAxNsRM>GR-!=(Q2LxQ z7T|v(6tGq*F|34pw~wt?BGV~GS!xQ5f`|dgpH3JFVf%8Yh-}nEihUvA!~)Qy3Gj%J zI5;`%BVH2((u3-EQQB~^9fKmX5f>lg;4MY8)d7$s+#=B8Gs(8N1tcJ0qx1AL;GKM{ zf{~9Orzfb~yK6%S#AKBc;L#8?U02Q4j!Na@XJK@^-+W@0&|t@PKH-;i49);L2Fpc0 z6_A;mI&|C}=o6j7fv$t*X-F#ix&0wc_%CYI-{%TW}h4L;Cff8J~XJ6dl>112xu;@6i+OsK_n|Jf+q>bR8Q?1W0!t<}RYExGw-}bjNsh^E$Q+ ztwK;T$Wh)A0~(eZ(F>t3h86av7+&Wxycow7DoaGDOpFzo1y~KIr9fXw=(F$^aADOJ zX;Tck25n3zF3{~@xsVzYkPn)~9KjpUOgKbnL9lAPDdvfgTmZ#qr!&*2$h&Zu{oh2A zssDjFSteLYq{OH!KRLK37H2T3{E6yCS2JIKV7Vsg_bfQtO_OzGsurHE&C|5UW8*(^ zehATttg7^S*05Uni*2ttPXCoV9wlYtuFj+(2rmPHwpTyx)ZBJ`$(_`#UFw;k(LsG4 zq7IN_=nwMzbZ@3h2re!h(S1%lBXB*i&=PRAJC*AiUdb<O zHmRGo?oHb6r)Wn+sZGvS-DGGa0ApE9Zz7B#gl6v`8A8M3A<CBb7fx5l&Aq)^^`?lJsTsTypgj)_JEG}B+ zzgMf9nsifxZfdqU@;CA1ow~^%_@-gq#G|g)O=;c4i{*&ae@Ic>`Jjk+NSqcz_y{4C-+`)f8rsXOrf09SZaaAt()Q z@Xy(T)hh4T?VP%P+r;f9+6j{5lujfLBJGywad@cFaKHj!p7P?zcvcd(afcLhlfZhI zFXCPb_mTzz4#+^B@CQDV&;oRYho|>HMQa{fUY7EV}=WR9YQ#-f&rN90~mK245x@? zzhkvs2LP5gEYgk*)?h+Taf<`FUqsTDj{bff#C8#ccwK|D1SSl{j=1{CQXS$T<(#5G zvHKCxApMeM`tl5&x7B!_U*OqTPX?1Y=t@%qT^&APDd7!Uc? zW6cjiutc!ERPPCkMvlN?SZ6b0*h=<=S70AmJU7@Ne$>7*x-=O&u~OCpb2i5I(1$Tm0$k zpa4;Tj#%&??k2C#4`6EUDbW&^qSRRH^U=M5_#Hk3BZ+Pq*<>S{;HO^|pe~_{^iHA%x&k zSvrT0-b*|{%QnhR4xV@W;2SIwu_bzyyNMflU_>FP?_=N7JcM83IU=3dIGB>|TxRg*( zveVn^Gh7tLxHH0%N$!14%L((`12u)I?wg#PLpYsQtLNZJ-X&+w`@cku;wx?$fqFn)*6M-KBFa)^)(v}`UAJWSc(uhWc8#Zp_&&<$ zg<3@Q6SKo|0pn_h-=uP zF&{Dl{iy)2)NSf*1wK`TgUbFgQe+X^-mlo0tQk|<5ETl0#ACs-^yn>>NLwN z(bKiMeyN^r()A7cV9@zr?yBQ0HWBO@qO3MeqH&U%X{RRjS%eQo;d=I(_-fFKgOeO2 zxqG$W)AgDZwEZarpn&bd{*yWOsQNc*u*NhM0iZy(x3cfGx{?=f(v=Om8VXjM^7x`o z<@rIn(jm~i^~y_I*m=NB2e4a8X6rC7T<|OK0<3mSpLX~TQ%Ni0i*goqdMCb>RzXVn zp^uy5duZaO|1`I=l>_fa2KR*V{O1xgeFUp~K3A1Z#0A5A%MyfWq`iYu7tyS5-27J} z2obcmcIq!92qBP|;RxB?3>=|_o)Uue`rWLS_IqZ*4I*RWO`)xyGi-{5&T|!~hi=mwuu+@LOTxU9Ss%~SedT7=qb^g! zTkw}ra=>y67^+zCJYOh&F~gRBS~i#iuT9gd>PpdW|?*X%&AP)m@j>t6H5yKOd%hYWt@MQ|Iq#+{KNK# z>K}Oi8HWFM82+9M1bY8vpaeLhkT_%ZAq;THxqW;W!t62qEAbLd2Xq_|2qB(xQm+9$ z1ypt_^hYv5U+Qy$)}OC!I&RExduH;fB|guwPD2!bC#im#-aFegC*dmm2*W}l0PPwA zU8!W6T{OhEL4F9awsSTHwG4xgfN+K0KmbF5Y_T1%nc)2XpWFq0k<{B#OU9<-cBfg) zpY-r1GE3j)rcn1phe*{(4THQ=0-k_VCbTdTCX5H+VWHuSU*|C~4dv&x^H}~mr{H8x7DLFbP{!Gkte*^HxhH8t%dH#Z}!}rXRcy}{ef?D*)9$S!3;pt-a@r{Y51`&{iIvZjaXi` ze?V_W#TV@<-ix2i#60itU&$}ke^l9vtoGKtDNUNvpeZn9ps4_Ev}sC@T8QWz)Sa@* zglDI$QOmHVtT(_7xMN3JQ#V^MiAp)OFdi&9MK+YP&QLGXmV2Y#!3|m6VbW)kHUj$> zOSF5bb^{vMYj>*-c4&K<{-IBM31&vD0G+?dL`Aqhsdd_(NhdKoF}e(VYYregJWVS& z1K==N1AKa!e%GZp59(9i1y2e*;45?cEd3td{-9!>fL{nex51*>QP`^as*Y<$h?&q zi&$nx5BLfH{Qm*a1fn&lO@9t+0w~LYn~F0?7gb#r%B0{K!7~8T5ln!-l`9iSh*b|r2^DFd!bUC6F}WY6?4c*Jg5|J84nRz>?}~L1bOpby(GJVP zjF|u%!BZ{l0Kou+UNS+W;k}wxI~w#jW-)y{rf)|qfMolgC5zvxu|?L2ymEt@>dckr z$>Odh-d_pMz?z&uPV-Kp6ZmNejJT2#wxWfrfuNS_8(fQU9J<-)#i4wT>^W-ZRD9ep zPB=x|{BrmJR3Qnd*gM)+F~6Z4E6R~jAFW1(o;ln9ab+x&6{42RJSqW7;=5g>p^s{91A6(wDsJjd|THnG-Yy< z%Fq=5iMUmulCHr^Z14=4hmQVP{+@O5`1j@dmAmy1_UO4z^XAXt)7R)ZT={zK*{WZ; zk}!_@IS=@s3HFUl&`nC5GzvoaBtvd{%dMjpc9~)L)Fn?pSt=n~sc4lQn79WUoEca* zupFZ))0!g^CTEO-GC>M;VT33OW59-xhtWxM@u(dxi9o;%sr!l=9}cq6{IVerv=vNv zu{X0EXGZ~rBS+EATT8aF)ZR+a?sYfFqT`E<@HH!py=9SM)rJ*bt#5}FcHjDQqL=>6 zG}T5;sIeQ7V(ZBzCtIE3-|*d;#!s*d%fI~err}l<>rsB#&D0T6BoaxtQCx=(s0Dru z9>Ssc(G6Vd`Jr0TXG`&JEYFB0510d8#m7R=$Z07h=Gj?if&CONZ%h~E>%Bg4gS5_w zL&2@IXhm=rCSm^*0RxveW#y76TvoTS z#)YE-+i4I1SdbZ5g0U_YdIc65#=_Nl6zhtL9UM7#d~~{vd8iW%tgSOa1>^r}^aq~? zLYj}!*p6eO^qlP*!l|9)&ItQu`S>oL-|L1HTM4%gkkosX2ZH7A_$U%3#CH5h@2b

    + /// 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 0000000000000000000000000000000000000000..18c840847c2435bb1e9c51ab2aee06868092a102 GIT binary patch literal 7654 zcmeH~%}&BV6ov5xT)S~^a0MpHj>NrdWas0M7$1Qpgs^f=kYM+`06(%b;VEK-M~QOrMj;S}AALBm(IfM#6uMe409UD;Z7hrWdMD<1?vd3(*1$Qo ztFaWiM!+hyu>hAhv}y5S0%b`5lZLNzkTp_PWGxumbu67OO_>hJIL!ooq7-QHq1B`b zommyy_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..64996d5c04b1d3438dd09793a7e4ef0d62c72106 GIT binary patch literal 405 zcmZQ(U|7Ol@@2_r4}QH0!)Y$r@Y}_AqI1b KfJwMM$SDA#1B)X7 literal 0 HcmV?d00001 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.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 0000000000000000000000000000000000000000..4ae9cf80e6fd2f7b789a81c8b16c4984c0c20fdb GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096oRtFdKpjUOKDMAoLSJzr^JF^-|R7#-X z^(qls3N$aCGG|V8aL)y8F;UC~B_VVlHKmELJ^HLcI8gVI#ocIr2eIeMNA}-G*CW&# zk3K+5OxGeA0dbV?Gq=yDNK(FG7&!A1m?JHiH=l%SItw3Z76O)B%`-f^it?C|9JtaO zgoZp=$3<>EYrl)T#K?dok#Ydsi&SsNL9WLXAjqgFrNgPf=N08Z4QsFEPUm`%Wd%`U zOW|L~N;+Co>|6Y!JH1~=VBh1v4j$(rvrXmLaD0HV)GHw2JR$+qypg`!VzqC$!d~Xo zU&wpTElOagmIo)%aRRx=AaK>SWWv>9Vy?h8-d8s#31wmPB-xZ#PS2IK1SH~J`cGbh zAV{{gY-*^g!C)F-8|YI*>Aj691DPxTLPbXM{A6&f?!K1`k&|EFcVbR0k) zty}z1;6;*tO5#Xkl{I0T%y4;V2bLJ-wrx=%cfQly%gQK8@i!PGA7y>74=5BRsb|2|)5q4{V3R(-m${x_defpohPGtp$@MPQk@|C&mE?e%dDT9x~yz^Ige i_tSgSX4XnNp2G$|h!$|P;-#jdW}-FfLaVQUH5YPouNWr) literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a89f74fed277d301e9e6738767cf8ed4c0ed4851 GIT binary patch literal 7654 zcmeI0?@Lor7{}K?(Cc1gBsq1OIYqNyC`Ljr$^<2_2nuzfQg0G!hKfP<3X1n)KssR9G+6igLSiPPg5=-Sz01kIy~3+ubkMA`koV+~<7n`F{4CbMMZ! zefRei-F({!ubJ@7_di$YR?X-8q5suN_MA_^i!UkLzrocOykS*?OWK%5Qvfnejj~=K zXJd1(G*4qH!#oDG7h;;HF_mHdzuJN8*`|9;bGA+d4t5SVzBjRXr2SRk`OOLP3ze#`5C1 zm;_v=x}N-OE25Qdu}zF8L%mvC+aKI_@2#-sWsTMyw2urcip9+xt|MAds)^tF0xMbe z%{XMUxx?v{A?6xop)r+VK7L&06CJ(XvsW+8R#gn#=yqByib)&K(^xXtXMA`kC6)`;6nyK@sbT)7+h>qVpJKUt%avHJpFh0j zCdd1?QcKGzwo<^~Cdm6LrzqE*z65ZAGq$E<=ho}Tveu37C>iSQaz1-3)*QOoXqwJk zySV3py%?-GIE8`J;$nscsEPb~(>{Ig528VI(=Z2z2zy+Dj`2y^D+-}8%u{8AxtSMZN zZ-&H+=VxmU*sIE?3UWU0DznwsOkX%V13%jm^*zMR>6qYP8Q48YqAZFsT$oTGkK~Kr zeuDGF!-fBT)ZbCY0=kZ97tPaHRio442d4cr4*g#goX!a}Jz;Q7jTRT@NqK2ZWtyHb zb5S=+p&Fw&PF%rEz(=*I>LCeY*0p3@=zsxbQB87OfTr4T9O%WE2AE&?kl4xDa)(S7 zm<-I|fT{udbG?{Xa;XllnN$^UhTI|g2g`@S1*d{@h{lZ_&S9Lm0<8cuFd2R(LM|9M z9K&!lp&29R(nO0L3M``HVrby6+Cmp1%-(3Z!W=$oSrT&rnrdU8HMYwt>UwFOxXh(l QB86bNUW#&P9_Vy`0P1n|wEzGB literal 0 HcmV?d00001 diff --git a/JRCookbookControls/Bar1.bmp b/JRCookbookControls/Bar1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..325a7ad8d93f746b11731810d66afddf22222f2f GIT binary patch literal 7654 zcmeHJF;2uV5DXunrhww4E2t@`uA=9!yy3nAqC-$z52Gv@?b_?C6B3e0u`bbiGTt4J z9p|2&-|w2XJ>q_k>*4phYHnKm1<%jdaYof&~@tCp=%v*qN_wY%7KV**ewx2 z3pv&=EbH<1BmW@{b(NN$oREN2A!pmVup*&fii#Epa+*SeMd@Sgy)!W}PwG{n+4D?M$3cB+&6rR$X9U02B&A786q*mtgA z;-PR14>|UIbPFaR>zDAb<~+J^mL!U#i`Q0yg><1lD&sB(3GQ-`EUn8mOM^4`_4aj< zpRO}B-gOzrLQiM#%Lu6JynbF1;y>y_sh&2Eu6)9kb%ciDkgSI!T|Uydj!8g3ylMJ% zk*G)Kv8II|1YJK##XP;b$Vx`LU6R8OLY=Ns5!7*;%h#o5(*-$FoPpNjf?8Mjq0(fX zS>v4qK2ORfU7_V*jxeDcl=#H0F2Xul2)YEFA&*N#h*#)BR?vG|UN%IK&E*ic&k4JO zG+58nqZo&0iPeR1H3e%pl;8%#b%oOYE(#?^=@MzE?>2Y-L&5Nj%hqvdg>n3~>I%=^ Vh5QO#-gSi*8N%+Du_Np>%@6z+sTcqN literal 0 HcmV?d00001 diff --git a/JRCookbookControls/Bar2.bmp b/JRCookbookControls/Bar2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..81c57d3ee3c2cd7b64965b64eb8419c6d3e8d05e GIT binary patch literal 7654 zcmeHKF-`+95IjCWO+yhW1vLd#Dti9P8~6%{7KGA=NtPRp?X~w3bcrLKm7Mm*X z+CM72`o-mAz%6Nk;uP?@=MOW%axxQ(C zuYRr9Yj=O~wPoAa<;d3Xe>;(oJp(jL@zk$gb-@?R3Rf(sHN@69D-h1^7mGK7MOVWd zr>j@Lu9x<;m&l@-&`T5lEY1GV6VEuvn2Ea^9wo0`-NizS#h<41lPZlWc+Uu z)|^LIV~MS623;TDTl<8?8-ztyVovDk41Og7rro@MZ8PE-b)i(F&7-TF@WeVs!*EE} zA=xdv6xWyp1jL7-t&2n*UB*h|3n`;1u6(5tZ|WjTht^_}@j`GpIDUzfOvD1>=@O8I z{#qj^3&1yIHeIa1Kqa^!2*kq|m6A2H;^QRQ&-8|5w>8kEF=rXn_{39Pgf&wLx&+No z#}&>O8R8zRW&a)_t>gxx_3PG{;U#(HKDL_j>%g`Oz|r*O1d8MA)YMZC}z zO8dVklwkd1beS~NcUzX}wA=8E^ZYuk)KQ~))fJw-7xF7KchMDEln@rb5<9}1VfY2j CR$4p& literal 0 HcmV?d00001 diff --git a/JRCookbookControls/Bar3.bmp b/JRCookbookControls/Bar3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bbec9ea024a40d3e1842223c37230af403867f3f GIT binary patch literal 7654 zcmeHKF;c@Y5Hug4rb*$M6x0+{sp$DD4IkhuFlnJk4~s8ePSQ!IggCZmbQ61|_3CcD zl4a-VdB5p~c*OZ0$HVcs>Fx&n1=rth4^x3-5dcl zmlOJhY2EB!(;w1Mm&H!u^THtjw?Nc5ALLzP4~Vhv&j58hp3A816SFRl{;dH-PywGsVx`d|d_frx!iOVzjg>`2>v%s4!WBt2( z$xQQzZ3C5YKJFxa{C{XBU514rG=Z*%;N~iUjuD~zX(+T_v1k`ojKMxV{in>s$ z5Yy;NZ#b2@?$x?NY+l}n(Lp{;4|iz?#lRLoP>Iy9dQ-lf4MvhNB)J0e) zb3v1!GoBQ6UrRhPT>&g7Tte$(Yz6cCzU KfgNtA>wW+f+Xp}Z literal 0 HcmV?d00001 diff --git a/JRCookbookControls/Bar4.bmp b/JRCookbookControls/Bar4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c5373fa34871626f81a84a5834fdf4104874ea95 GIT binary patch literal 7654 zcmeHKu};J=3@tyv%))S|4$KTpH!;J%!Y}YEAXXS|ho|$!N@CY`DZRE*tZS4wFZSz8 z>gXPyKX1E}J)phAbANuWx|@^#1@mv$^qd@MepYGQ;B`p0OO_l5R+T*ovSSZncsK+A z%*B*?VOyVG_wt7@%*(~N0EBWe+vbHGarI)%kQNLu^kPg*FNViL>W5)u5EdemGlFS) z?IT+NnMnE}y%-P^or2jRm*$21vUtIBFRZ-^94V>g-aYT z7gK(Ziaf%#R$gu`akZF7FO&^rMoWbR?YWYq|0WCZ5*u4PX5jVleWYKVYs|RuD%5f{ zok6dHKy2{-b*z9FR~{@+UiEXBdm&)$ zG+ueOiijLC*u4;9ykrJihdipOcv?bJv+)8Q%D|nRi|WjIxfd0I?K7AtaONs)H6)mH zN)HEAJHU_OrG|H%DnO;f&i~+rU#<$a8jNtGYm{p0vHs=!^&y_EH;cPwvsWujR$$qw1e!q)2%d?Q|b zNghpXQRf_46s=ay7S<~WvhfPS#H2sswH5L35?nu@LlSKw@S+9#kXSF6cmo|G65|CE zZ=gd&V!UAD4RnY|j2BG2fesOg@q&pr&>@!NeQr5Rr7s zi#lygg#W8;>af;&fg;EluOLiJ8ayu^phLquC-ok)!#Zp|q+WFWXi`xr(n|`_T%_*? zdUcM0E8H}xl}fErua#Pb)SBzNf&Qm@?L>g%hwBXCUKGekPiw?WYVD|Cy)@Jge4}&x JLeKv8x&WMq3!nf1 literal 0 HcmV?d00001 diff --git a/JRCookbookControls/Handle.bmp b/JRCookbookControls/Handle.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4ca03c652c8d3fa5e743aa5d2db7504f84eb1e5a GIT binary patch literal 3678 zcmd7SF_P0z490OWL%~pR1{D-rQ&4N@xdNl3=qM@}&Y_w!P^hHbo+A967dDCgyc2d( zY?9x~e)ebO*)RL$>$eYbe0_c^^1#-olQ;72IR5ZnYx-B5H7OKof-)F@b^&a|9BF7IA^Xz>WtJg+BFFs=*OR6k3E$Nrk}?NEDhcDNq<3 zfkdH2_(&@ZjzFT&V#3!H#qxFp5``X9Q>7XlfkdIlv`wi7M<7w?aZ6mO21g)K=yAJ3 zsRlg|=AW`UXn@gz%M<7w?<0G(Es=*OR6k3A$hbWerJC=8%&=M+87#x8_ zp~qu0r5YT8M4`tcb)^~{fkdIl^)!+yu3O$x(MsAuqUh)5q@NM=w z?HyPm`^R?LKNH%y)=2Cgob~w^nTMvM=g7|CZJ*1?EHodxOwF#j8M_QD+mjR4L+i*k zv>Dk(Ca0|WydX1+tQ)QN=aJ1xtM7Kh?&=aZBu>B8o6bC+^ve6}-QQ=%m;YV=`+C)x z^TWDv>y|(=2k&%&F0|&0e1|rFmpO^Rgp5UADi4-4ibki2McKnu7`e literal 0 HcmV?d00001 diff --git a/JRCookbookControls/Heading.bmp b/JRCookbookControls/Heading.bmp new file mode 100644 index 0000000000000000000000000000000000000000..13fc4809b6cd57e711162038fc8953c5f2edb333 GIT binary patch literal 7654 zcmeHLv1)`s5H;9Yq}3)MsRDKuRw*Rd284WrO&S})AF%fuw6P5+Rua+tOMWBSbCYFt z+}thdc}Heoz47_jefM^DgS4UkG-c0%g`UNc-A?Vkl_Yl_CsG8tSmSwM8 lq-hE{6sf8z3`53^qNr&a5gFo=zdPUr8zHDm&e+TK>l^-oaS;Fj literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4ae9cf80e6fd2f7b789a81c8b16c4984c0c20fdb GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096oRtFdKpjUOKDMAoLSJzr^JF^-|R7#-X z^(qls3N$aCGG|V8aL)y8F;UC~B_VVlHKmELJ^HLcI8gVI#ocIr2eIeMNA}-G*CW&# zk3K+5OxGeA0dbV?Gq=yDNK(FG7&!A1m?JHiH=l%SItw3Z76O)B%`-f^it?C|9JtaO zgoZp=$3<>EYrl)T#K?dok#Ydsi&SsNL9WLXAjqgFrNgPf=N08Z4QsFEPUm`%Wd%`U zOW|L~N;+Co>|6Y!JH1~=VBh1v4j$(rvrXmLaD0HV)GHw2JR$+qypg`!VzqC$!d~Xo zU&wpTElOagmIo)%aRRx=AaK>SWWv>9Vy?h8-d8s#31wmPB-xZ#PS2IK1SH~J`cGbh zAV{{gY-*^g!C)F-8|YI*>Aj691DPxTLPbXM{A6&f?!K1`k&|EFcVbR0k) zty}z1;6;*tO5#Xkl{I0T%y4;V2bLJ-wrx=%cfQly%gQK8@i!PGA7y>74=5BRsb|2|)5q4{V3R(-m${x_defpohPGtp$@MPQk@|C&mE?e%dDT9x~yz^Ige i_tSgSX4XnNp2G$|h!$|P;-#jdW}-FfLaVQUH5YPouNWr) literal 0 HcmV?d00001 diff --git a/JRCookbookControls/NotHeading.bmp b/JRCookbookControls/NotHeading.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6ddf02feece21e260244c3db7f4e53f802ba2585 GIT binary patch literal 7654 zcmeI0v5ta35I~id#M;K*`ilDid;f~$=m-@Z9W+u{kx0l9xPQ6d@W$Q4EbQ*c7!YD+ zl7(eV;yOoGfIPRf+{I~ULEAnR;Z#J@t1RQ=A8O%ldSlAc)q8Xr7Th>>* ziA;M&P&KZBB-b%Q-pfeWlFNXx-c*xkyk`D^q+im$ouNNpFcMiKY4i zViKD6uAfZkvIL1LaH(9wl|AXE`!cCP6?5+^>+7ByPDk>q7pr&d^(|bzs@GpK7tJ}* zS5;NtZ9uEQ9Kk7y0;+u9hYnJP3=z4q zER$dND2k9-lO%yM$8pj$MaqyN=0fBchS--u3X)=9h#bSvyZH)&;9`$Bj%V7xT-V*8 zF%y^E_3`5z`@QFRCwqipIFm1aJ{mR=J;lE#`hN`Qj?@hMVqfZdc-SXCw;#?oRsnO- JOtLSkuRob}+|B?1 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..18c840847c2435bb1e9c51ab2aee06868092a102 GIT binary patch literal 7654 zcmeH~%}&BV6ov5xT)S~^a0MpHj>NrdWas0M7$1Qpgs^f=kYM+`06(%b;VEK-M~QOrMj;S}AALBm(IfM#6uMe409UD;Z7hrWdMD<1?vd3(*1$Qo ztFaWiM!+hyu>hAhv}y5S0%b`5lZLNzkTp_PWGxumbu67OO_>hJIL!ooq7-QHq1B`b zommyy_ literal 0 HcmV?d00001 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(); + } + + } +}

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

    ZKcR|H+YQp;B< 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 k$N#V2kN)+q|0n + + + 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 0000000000000000000000000000000000000000..4ae9cf80e6fd2f7b789a81c8b16c4984c0c20fdb GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096oRtFdKpjUOKDMAoLSJzr^JF^-|R7#-X z^(qls3N$aCGG|V8aL)y8F;UC~B_VVlHKmELJ^HLcI8gVI#ocIr2eIeMNA}-G*CW&# zk3K+5OxGeA0dbV?Gq=yDNK(FG7&!A1m?JHiH=l%SItw3Z76O)B%`-f^it?C|9JtaO zgoZp=$3<>EYrl)T#K?dok#Ydsi&SsNL9WLXAjqgFrNgPf=N08Z4QsFEPUm`%Wd%`U zOW|L~N;+Co>|6Y!JH1~=VBh1v4j$(rvrXmLaD0HV)GHw2JR$+qypg`!VzqC$!d~Xo zU&wpTElOagmIo)%aRRx=AaK>SWWv>9Vy?h8-d8s#31wmPB-xZ#PS2IK1SH~J`cGbh zAV{{gY-*^g!C)F-8|YI*>Aj691DPxTLPbXM{A6&f?!K1`k&|EFcVbR0k) zty}z1;6;*tO5#Xkl{I0T%y4;V2bLJ-wrx=%cfQly%gQK8@i!PGA7y>74=5BRsb|2|)5q4{V3R(-m${x_defpohPGtp$@MPQk@|C&mE?e%dDT9x~yz^Ige i_tSgSX4XnNp2G$|h!$|P;-#jdW}-FfLaVQUH5YPouNWr) literal 0 HcmV?d00001 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 + { + ///