Initial population
428
.gitignore
vendored
Normal file
@@ -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
|
||||||
37
JRCookbook.sln
Normal file
@@ -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
|
||||||
14
JRCookbook/CommonRoutines.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
19
JRCookbook/Constants.cs
Normal file
@@ -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";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
JRCookbook/CopilotIndices/18.3.511.5503/CodeChunks.db
Normal file
BIN
JRCookbook/CopilotIndices/18.3.511.5503/SemanticSymbols.db
Normal file
BIN
JRCookbook/DesignTimeBuild/.dtbcache.v2
Normal file
58
JRCookbook/JRCookbook.csproj
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net10.0-windows7.0</TargetFramework>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<AssemblyOriginatorKeyFile>JRCookbookStrongNameKey.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<Platforms>x86</Platforms>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1518.46" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\JRCookbookBusiness\JRCookbookBusiness.csproj" />
|
||||||
|
<ProjectReference Include="..\JRCookbookControls\JRCookbookControls.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="frmEditCookbookChapter.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="frmEditCookbook - Copy.Designer.cs">
|
||||||
|
<DependentUpon>frmEditCookbook.Designer.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="Properties\Resources.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="frmEditCookbook - Copy - Copy.resx">
|
||||||
|
<DependentUpon>frmEditCookbook - Copy.resx</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="frmEditCookbook - Copy.resx">
|
||||||
|
<DependentUpon>frmEditCookbook.resx</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Update="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
BIN
JRCookbook/JRCookbookStrongNameKey.snk
Normal file
114
JRCookbook/JRJRAdhocUpdateForm.Designer.cs
generated
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class JRJRAdhocUpdateForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
124
JRCookbook/JRJRAdhocUpdateForm.cs
Normal file
@@ -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<string> JRJRItems = new List<string>();
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
60
JRCookbook/JRJRAdhocUpdateForm.resx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
23
JRCookbook/Program.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Application.Run(new frmMainRecipe());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
JRCookbook/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// 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.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace JRCookbook.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// 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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap Search {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("Search", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
124
JRCookbook/Properties/Resources.resx
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="Search" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Search.BMP;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
BIN
JRCookbook/Search.BMP
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
180
JRCookbook/frmEditCookbook.Designer.cs
generated
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class frmEditCookbook
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
92
JRCookbook/frmEditCookbook.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
JRCookbook/frmEditCookbook.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
130
JRCookbook/frmEditCookbookChapter.Designer.cs
generated
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class frmEditCookbookChapter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
102
JRCookbook/frmEditCookbookChapter.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
JRCookbook/frmEditCookbookChapter.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
456
JRCookbook/frmEditRecipe.Designer.cs
generated
Normal file
@@ -0,0 +1,456 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class frmEditRecipe
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
725
JRCookbook/frmEditRecipe.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
JRCookbook/frmEditRecipe.resx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="mnuInsert.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
127
JRCookbook/frmFindIngredient.Designer.cs
generated
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class frmFindIngredient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
131
JRCookbook/frmFindIngredient.cs
Normal file
@@ -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<KeyValuePair<Int32,Ingredient>>();
|
||||||
|
foreach(var ingredient in ingredientList)
|
||||||
|
{
|
||||||
|
Int32 ingredientUsageCount = 0;
|
||||||
|
ingredientUsageCount = IngredientUsage.GetIngredientUsageCount(ingredient);
|
||||||
|
|
||||||
|
if (ingredientUsageCount > 0)
|
||||||
|
{
|
||||||
|
preferredIngredients.Add(new KeyValuePair<Int32,Ingredient>(ingredientUsageCount, ingredient));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the preferred ingredients in usage order
|
||||||
|
List<KeyValuePair<int, Ingredient>> sortedPreferredIngredients = preferredIngredients.OrderByDescending(x => x.Key).ThenBy(x => x.Value.name).ToList();
|
||||||
|
var alreadyAddedIngredients = new SortedList<Guid,Guid>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
123
JRCookbook/frmFindIngredient.resx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
398
JRCookbook/frmMainRecipe.Designer.cs
generated
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class frmMainRecipe
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
JRCookbookBusiness.JRCookbookBusinessAppManagement.ShutDownApp();
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
651
JRCookbook/frmMainRecipe.cs
Normal file
@@ -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<CookbookChapter> 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<RecipeHighlights> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
78
JRCookbook/frmMainRecipe.resx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="cmenuRecipe.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="cmenuCookbook.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>142, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="cmenuRoot.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>286, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="cmenuCookbookChapter.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>400, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="folderBrowserDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>588, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>964, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
232
JRCookbook/frmPickRecipeIngredient.Designer.cs
generated
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class frmPickRecipeIngredient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
238
JRCookbook/frmPickRecipeIngredient.cs
Normal file
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
JRCookbook/frmPickRecipeIngredient.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
92
JRCookbook/frmRecipeCopyMoveTo.Designer.cs
generated
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
|
||||||
|
namespace JRCookbook
|
||||||
|
{
|
||||||
|
partial class frmRecipeCopyMoveTo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
147
JRCookbook/frmRecipeCopyMoveTo.cs
Normal file
@@ -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<CookbookChapter> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
60
JRCookbook/frmRecipeCopyMoveTo.resx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
1552
JRCookbook/frmViewRecipeNutritionAll.Designer.cs
generated
Normal file
359
JRCookbook/frmViewRecipeNutritionAll.cs
Normal file
@@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
126
JRCookbook/frmViewRecipeNutritionAll.resx
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="Ingredient.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="percentcaloriesfromalcohol.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
BIN
JRCookbook/v18/.futdcache.v2
Normal file
242
JRCookbook/v18/DocumentLayout.backup.json
Normal file
@@ -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}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
226
JRCookbook/v18/DocumentLayout.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
55
JRCookbookBusiness/Constants.cs
Normal file
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
255
JRCookbookBusiness/Converters/CssStylesheet.cs
Normal file
@@ -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<StyleDefinition> _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
|
||||||
|
// <LINK href="http://sc.msn.com/global/css/ptnr/orange.css" type=text/css \r\nrel=stylesheet>
|
||||||
|
}
|
||||||
|
|
||||||
|
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<StyleDefinition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<XmlElement> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
844
JRCookbookBusiness/Converters/HtmlCSSParser.cs
Normal file
@@ -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: [<family-name>,]* [<family-name> | <generic-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> | <relative-size> | <length> | <percentage>
|
||||||
|
// absolute-size: xx-small | x-small | small | medium | large | x-large | xx-large
|
||||||
|
// relative-size: larger | smaller
|
||||||
|
// length: <point> | <pica> | <ex> | <em> | <points> | <millimeters> | <centimeters> | <inches>
|
||||||
|
// Default: medium
|
||||||
|
// font: [ <font-style> || <font-variant> || <font-weight ]? <font-size> [ / <line-height> ]? <font-family>
|
||||||
|
|
||||||
|
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: [ <list-style-type> || <list-style-position> || <list-style-image> ]
|
||||||
|
|
||||||
|
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<XmlElement> 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: [ <border-width> || <border-style> || <border-color> ]
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
JRCookbookBusiness/Converters/HtmlEncodedTextWriter.cs
Normal file
@@ -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
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void WriteString(string text)
|
||||||
|
{
|
||||||
|
text = WebUtility.HtmlEncode(text);
|
||||||
|
WriteRaw(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
577
JRCookbookBusiness/Converters/HtmlFromXamlConverter.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// HtmlToXamlConverter is a static class that takes an HTML string
|
||||||
|
/// and converts it into XAML
|
||||||
|
/// </summary>
|
||||||
|
internal static class HtmlFromXamlConverter
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Internal Methods
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#region Internal Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Main entry point for Xaml-to-Html converter.
|
||||||
|
/// Converts a xaml string into html string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xamlString">
|
||||||
|
/// Xaml strinng to convert.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// Html string produced from a source xaml.
|
||||||
|
/// </returns>
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes a root level element of XAML (normally it's FlowDocument element).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xamlReader">
|
||||||
|
/// XmlTextReader for a source xaml.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="htmlWriter">
|
||||||
|
/// XmlTextWriter producing resulting html
|
||||||
|
/// </param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads attributes of the current xaml element and converts
|
||||||
|
/// them into appropriate html attributes or css styles.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xamlReader">
|
||||||
|
/// XmlTextReader which is expected to be at XmlNodeType.Element
|
||||||
|
/// (opening element tag) position.
|
||||||
|
/// The reader will remain at the same level after function complete.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="htmlWriter">
|
||||||
|
/// XmlTextWriter for output html, which is expected to be in
|
||||||
|
/// after WriteStartElement state.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="inlineStyle">
|
||||||
|
/// String builder for collecting css properties for inline STYLE attribute.
|
||||||
|
/// </param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a content of current xaml element, converts it
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xamlReader">
|
||||||
|
/// XmlTextReader which is expected to be at XmlNodeType.Element
|
||||||
|
/// (opening element tag) position.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="htmlWriter">
|
||||||
|
/// May be null, in which case we are skipping the xaml element;
|
||||||
|
/// witout producing any output to html.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="inlineStyle">
|
||||||
|
/// StringBuilder used for collecting css properties for inline STYLE attribute.
|
||||||
|
/// </param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Conberts an element notation of complex property into
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xamlReader">
|
||||||
|
/// On entry this XmlTextReader must be on Element start tag;
|
||||||
|
/// on exit - on EndElement tag.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="inlineStyle">
|
||||||
|
/// StringBuilder containing a value for STYLE attribute.
|
||||||
|
/// </param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a xaml element into an appropriate html element.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xamlReader">
|
||||||
|
/// On entry this XmlTextReader must be on Element start tag;
|
||||||
|
/// on exit - on EndElement tag.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="htmlWriter">
|
||||||
|
/// May be null, in which case we are skipping xaml content
|
||||||
|
/// without producing any html output
|
||||||
|
/// </param>
|
||||||
|
/// <param name="inlineStyle">
|
||||||
|
/// StringBuilder used for collecting css properties for inline STYLE attributes on every level.
|
||||||
|
/// </param>
|
||||||
|
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
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads several items from xamlReader skipping all non-significant stuff.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xamlReader">
|
||||||
|
/// XmlTextReader from tokens are being read.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// True if new token is available; false if end of stream reached.
|
||||||
|
/// </returns>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
745
JRCookbookBusiness/Converters/HtmlLexicalAnalyzer.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// lexical analyzer class
|
||||||
|
/// recognizes tokens as groups of characters separated by arbitrary amounts of whitespace
|
||||||
|
/// also classifies tokens according to type
|
||||||
|
/// </summary>
|
||||||
|
internal class HtmlLexicalAnalyzer
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Constructors
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// initializes the _inputStringReader member with the string to be read
|
||||||
|
/// also sets initial values for _nextCharacterCode and _nextTokenType
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputTextString">
|
||||||
|
/// text string to be parsed for xml content
|
||||||
|
/// </param>
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
internal void GetNextContentToken()
|
||||||
|
{
|
||||||
|
Debug.Assert(NextTokenType != HtmlTokenType.Eof);
|
||||||
|
_nextToken.Length = 0;
|
||||||
|
if (IsAtEndOfStream)
|
||||||
|
{
|
||||||
|
NextTokenType = HtmlTokenType.Eof;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAtTagStart)
|
||||||
|
{
|
||||||
|
GetNextCharacter();
|
||||||
|
|
||||||
|
if (NextCharacter == '/')
|
||||||
|
{
|
||||||
|
_nextToken.Append("</");
|
||||||
|
NextTokenType = HtmlTokenType.ClosingTagStart;
|
||||||
|
|
||||||
|
// advance
|
||||||
|
GetNextCharacter();
|
||||||
|
_ignoreNextWhitespace = false; // Whitespaces after closing tags are significant
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NextTokenType = HtmlTokenType.OpeningTagStart;
|
||||||
|
_nextToken.Append("<");
|
||||||
|
_ignoreNextWhitespace = true; // Whitespaces after opening tags are insignificant
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsAtDirectiveStart)
|
||||||
|
{
|
||||||
|
// either a comment or CDATA
|
||||||
|
GetNextCharacter();
|
||||||
|
if (_lookAheadCharacter == '[')
|
||||||
|
{
|
||||||
|
// cdata
|
||||||
|
ReadDynamicContent();
|
||||||
|
}
|
||||||
|
else if (_lookAheadCharacter == '-')
|
||||||
|
{
|
||||||
|
ReadComment();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// neither a comment nor cdata, should be something like DOCTYPE
|
||||||
|
// skip till the next tag ender
|
||||||
|
ReadUnknownDirective();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// read text content, unless you encounter a tag
|
||||||
|
NextTokenType = HtmlTokenType.Text;
|
||||||
|
while (!IsAtTagStart && !IsAtEndOfStream && !IsAtDirectiveStart)
|
||||||
|
{
|
||||||
|
if (NextCharacter == '<' && !IsNextCharacterEntity && _lookAheadCharacter == '?')
|
||||||
|
{
|
||||||
|
// ignore processing directive
|
||||||
|
SkipProcessingDirective();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (NextCharacter <= ' ')
|
||||||
|
{
|
||||||
|
// Respect xml:preserve or its equivalents for whitespace processing
|
||||||
|
if (_ignoreNextWhitespace)
|
||||||
|
{
|
||||||
|
// Ignore repeated whitespaces
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Treat any control character sequence as one whitespace
|
||||||
|
_nextToken.Append(' ');
|
||||||
|
}
|
||||||
|
_ignoreNextWhitespace = true; // and keep ignoring the following whitespaces
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_nextToken.Append(NextCharacter);
|
||||||
|
_ignoreNextWhitespace = false;
|
||||||
|
}
|
||||||
|
GetNextCharacter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unconditionally returns a token which is one of: TagEnd, EmptyTagEnd, Name, Atom or EndOfStream
|
||||||
|
/// Does not guarantee token reader advancing.
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advances a reading position by one character code
|
||||||
|
/// and reads the next availbale character from a stream.
|
||||||
|
/// This character becomes available as NextCharacter property.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Throws InvalidOperationException if attempted to be called on EndOfStream
|
||||||
|
/// condition.
|
||||||
|
/// </remarks>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="character">
|
||||||
|
/// character value to be checked
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the character can be the first character in a name
|
||||||
|
/// false otherwise
|
||||||
|
/// </returns>
|
||||||
|
private bool IsGoodForNameStart(char character) => character == '_' || char.IsLetter(character);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="character">
|
||||||
|
/// character to be checked for validity in a name
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the character can be a valid part of a name
|
||||||
|
/// </returns>
|
||||||
|
private bool IsGoodForName(char character) => IsGoodForNameStart(character) ||
|
||||||
|
character == '.' ||
|
||||||
|
character == '-' ||
|
||||||
|
character == ':' ||
|
||||||
|
char.IsDigit(character) ||
|
||||||
|
IsCombiningCharacter(character) ||
|
||||||
|
IsExtender(character);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="character">
|
||||||
|
/// character to be checked
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the character is a combining character, false otherwise
|
||||||
|
/// </returns>
|
||||||
|
private bool IsCombiningCharacter(char character) => false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="character">
|
||||||
|
/// character to be checked
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the character is an extender, false otherwise
|
||||||
|
/// </returns>
|
||||||
|
private bool IsExtender(char character) => false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// skips dynamic content starting with '<![' and ending with ']>'
|
||||||
|
/// </summary>
|
||||||
|
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 <![ and then have some data and they will just end 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// skips comments starting with '<!-' and ending with '-->'
|
||||||
|
/// NOTE: 10/06/2004: processing changed, will now skip anything starting with
|
||||||
|
/// the "<!-" sequence and ending in "!>" or "->", because in practice many html pages do not
|
||||||
|
/// use the full comment specifying conventions
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// skips past unknown directives that start with "<!" but are not comments or Cdata
|
||||||
|
/// ignores content of such directives until the next ">"
|
||||||
|
/// character
|
||||||
|
/// applies to directives such as DOCTYPE, etc that we do not presently support
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// skips processing directives starting with the characters '<?' and ending with '?>'
|
||||||
|
/// NOTE: 10/14/2004: IE also ends processing directives with a />, so this function is
|
||||||
|
/// being modified to recognize that condition as well
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
539
JRCookbookBusiness/Converters/HtmlParser.cs
Normal file
@@ -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 <good>, 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. <b> <i> </b> </i>: 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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
internal class HtmlParser
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Constructors
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor. Initializes the _htmlLexicalAnalayzer element with the given input string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputString">
|
||||||
|
/// string to parsed into well-formed Html
|
||||||
|
/// </param>
|
||||||
|
private HtmlParser(string inputString)
|
||||||
|
{
|
||||||
|
// Create an output xml document
|
||||||
|
_document = new XmlDocument();
|
||||||
|
|
||||||
|
// initialize open tag stack
|
||||||
|
_openedElements = new Stack<XmlElement>();
|
||||||
|
|
||||||
|
_pendingInlineElements = new Stack<XmlElement>();
|
||||||
|
|
||||||
|
// initialize lexical analyzer
|
||||||
|
_htmlLexicalAnalyzer = new HtmlLexicalAnalyzer(inputString);
|
||||||
|
|
||||||
|
// get first token from input, expecting text
|
||||||
|
_htmlLexicalAnalyzer.GetNextContentToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Constructors
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Internal Methods
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#region Internal Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates an HtmlParser element and calls the parsing function on the given input string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="htmlString">
|
||||||
|
/// Input string of pssibly badly-formed Html to be parsed into well-formed Html
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// XmlElement rep
|
||||||
|
/// </returns>
|
||||||
|
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 = "<!--StartFragment-->";
|
||||||
|
internal const string HtmlEndFragmentComment = "<!--EndFragment-->";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts Html string from clipboard data by parsing header information in htmlDataString
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="htmlDataString">
|
||||||
|
/// String representing Html clipboard data. This includes Html header
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// String containing only the Html data part of htmlDataString, without header
|
||||||
|
/// </returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds Xhtml header information to Html data string so that it can be placed on clipboard
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="htmlString">
|
||||||
|
/// Html string to be placed on clipboard with appropriate header
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// String wrapping htmlString with appropriate Html header
|
||||||
|
/// </returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses the stream of html tokens starting
|
||||||
|
/// from the name of top-level element.
|
||||||
|
/// Returns XmlElement representing the top-level
|
||||||
|
/// html element
|
||||||
|
/// </summary>
|
||||||
|
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<XmlElement> _openedElements;
|
||||||
|
private readonly Stack<XmlElement> _pendingInlineElements;
|
||||||
|
|
||||||
|
#endregion Private Fields
|
||||||
|
}
|
||||||
|
}
|
||||||
733
JRCookbookBusiness/Converters/HtmlSchema.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// HtmlSchema class
|
||||||
|
/// maintains static information about HTML structure
|
||||||
|
/// can be used by HtmlParser to check conditions under which an element starts or ends, etc.
|
||||||
|
/// </summary>
|
||||||
|
internal class HtmlSchema
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Constructors
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// static constructor, initializes the ArrayLists
|
||||||
|
/// that hold the elements in various sub-components of the schema
|
||||||
|
/// e.g _htmlEmptyElements, etc.
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns true when xmlElementName corresponds to empty element
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xmlElementName">
|
||||||
|
/// string representing name to test
|
||||||
|
/// </param>
|
||||||
|
internal static bool IsEmptyElement(string xmlElementName) => _htmlEmptyElements.Contains(xmlElementName.ToLower());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns true if xmlElementName represents a block formattinng element.
|
||||||
|
/// It used in an algorithm of transferring inline elements over block elements
|
||||||
|
/// in HtmlParser
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xmlElementName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static bool IsBlockElement(string xmlElementName) => _htmlBlockElements.Contains(xmlElementName);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns true if the xmlElementName represents an inline formatting element
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xmlElementName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
internal static bool IsInlineElement(string xmlElementName) => _htmlInlineElements.Contains(xmlElementName);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
internal static bool IsKnownOpenableElement(string xmlElementName) => _htmlOtherOpenableElements.Contains(xmlElementName);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns true when xmlElementName closes when the outer element closes
|
||||||
|
/// this is true of elements with optional start tags
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="xmlElementName">
|
||||||
|
/// string representing name to test
|
||||||
|
/// </param>
|
||||||
|
internal static bool ClosesOnParentElementEnd(string xmlElementName) => _htmlElementsClosingOnParentElementEnd.Contains(xmlElementName.ToLower());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns true if the current element closes when the new element, whose name has just been read, starts
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentElementName">
|
||||||
|
/// string representing current element name
|
||||||
|
/// </param>
|
||||||
|
/// <param name="elementName"></param>
|
||||||
|
/// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns true if the string passed as argument is an Html entity name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entityName">
|
||||||
|
/// string to be tested for Html entity name
|
||||||
|
/// </param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entityName">
|
||||||
|
/// string representing entity name whose character value is desired
|
||||||
|
/// </param>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// initializes _htmlEmptyElements with empty elements in HTML 4 spec at
|
||||||
|
/// http://www.w3.org/TR/REC-html40/index/elements.html
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// initializes _htmlCharacterEntities hashtable with the character corresponding to entity names
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
2765
JRCookbookBusiness/Converters/HtmlToXamlConverter.cs
Normal file
22
JRCookbookBusiness/Converters/HtmlTokenType.cs
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// types of lexical tokens for html-to-xaml converter
|
||||||
|
/// </summary>
|
||||||
|
internal enum HtmlTokenType
|
||||||
|
{
|
||||||
|
OpeningTagStart,
|
||||||
|
ClosingTagStart,
|
||||||
|
TagEnd,
|
||||||
|
EmptyTagEnd,
|
||||||
|
EqualSign,
|
||||||
|
Name,
|
||||||
|
Atom, // any attribute value not in quotes
|
||||||
|
Text, //text content when accepting text
|
||||||
|
Comment,
|
||||||
|
Eof
|
||||||
|
}
|
||||||
|
}
|
||||||
586
JRCookbookBusiness/Cookbook.cs
Normal file
@@ -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<CookbookChapter> cookbookChapters = new List<CookbookChapter>();
|
||||||
|
public List<RecipeHighlights> recipeHighlights = new List<RecipeHighlights>();
|
||||||
|
|
||||||
|
private int mNumberRecipiesRendered = 0;
|
||||||
|
private int mTotalNumberRecipiesToRender = 0;
|
||||||
|
|
||||||
|
public event EventHandler<LongRunningStatusUpdatedEventArgs> 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<Cookbook> GetAllCookbooks()
|
||||||
|
{
|
||||||
|
DataSet recordSet;
|
||||||
|
var returnValue = new List<Cookbook>();
|
||||||
|
|
||||||
|
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<CookbookChapter>();
|
||||||
|
recipeHighlights = new List<RecipeHighlights>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Guid, String>();
|
||||||
|
var pagesAlreadyAdded = new SortedSet<String>();
|
||||||
|
var recipesAlpha = new SortedList<String, Recipe>();
|
||||||
|
|
||||||
|
|
||||||
|
//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("<html>");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("<head>");
|
||||||
|
builderCookbookIndex.AppendFormat("<title>{0}</title>" + Constants.CRLF, this.name);
|
||||||
|
builderCookbookIndex.AppendHtmlLine("<meta http-equiv=\"Content-Type\" content=\"text/html\">");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("<style type=\"text/css\">");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("<!--");
|
||||||
|
builderCookbookIndex.AppendHtmlLine(".cookbook_header{FONT-FAMILY: \"Arial\"; FONT-SIZE: 8pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.4in; MARGIN-RIGHT: 0.4in; MARGIN-TOP: 0.4in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderCookbookIndex.AppendHtmlLine(".cookbook_title{FONT-FAMILY: \"Arial\"; FONT-SIZE: 16pt; COLOR: #7598C4; FONT-WEIGHT: 400; FONT-STYLE: normal; BORDER-BOTTOM: #7598C4 1pt solid; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderCookbookIndex.AppendHtmlLine(".chapter_name{FONT-FAMILY: \"Arial\"; FONT-SIZE: 10pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0.05in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderCookbookIndex.AppendHtmlLine(".subchapter_name{FONT-FAMILY: \"Arial\"; FONT-SIZE: 10pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0.05in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderCookbookIndex.AppendHtmlLine(".recipe_name{FONT-FAMILY: \"Arial\"; FONT-SIZE: 10pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0.05in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("-->");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("</style>");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("</head>");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("<body text=#000000 vLink=#000000 aLink=#000000 link=#000000 bgColor=White leftMargin=25 topMargin=25 rightMargin=25 background=\"\">");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("<table cellSpacing=0 cellPadding=0 width=\"100%\" border=0>");
|
||||||
|
builderCookbookIndex.AppendHtml(HTMLAddCookbookName());
|
||||||
|
|
||||||
|
List<Trackback> trackbackList = new List<Trackback>();
|
||||||
|
|
||||||
|
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("</table>");
|
||||||
|
|
||||||
|
builderCookbookIndex.AppendHtmlLine("</body>");
|
||||||
|
builderCookbookIndex.AppendHtmlLine("</html>");
|
||||||
|
|
||||||
|
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(" <tr>");
|
||||||
|
builder.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builder.AppendHtml(" <p class=subchapter_name>");
|
||||||
|
builder.AppendFormat("<a href=\"{0}\">", chapterURL);
|
||||||
|
builder.AppendFormat("{0}", chapter.name);
|
||||||
|
builder.AppendHtmlLine("</a>");
|
||||||
|
builder.AppendHtmlLine("</p>");
|
||||||
|
builder.AppendHtmlLine(" </td>");
|
||||||
|
builder.AppendHtmlLine(" </tr>");
|
||||||
|
|
||||||
|
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<Guid, String> recipePageDictionary, SortedList<String, Recipe> recipesAlpha, SortedSet<String> pagesAlreadyAdded)
|
||||||
|
{
|
||||||
|
var builderAllRecipeIndex = new HtmlContentBuilder();
|
||||||
|
var builderChapterIndex = new HtmlContentBuilder();
|
||||||
|
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<html>");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<head>");
|
||||||
|
builderAllRecipeIndex.AppendFormat("<title>{0}</title>" + Constants.CRLF, this.name);
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<meta http-equiv=\"Content-Type\" content=\"text/html\">");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<style type=\"text/css\">");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<!--");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine(".cookbook_header{FONT-FAMILY: \"Arial\"; FONT-SIZE: 8pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.4in; MARGIN-RIGHT: 0.4in; MARGIN-TOP: 0.4in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine(".cookbook_title{FONT-FAMILY: \"Arial\"; FONT-SIZE: 16pt; COLOR: #7598C4; FONT-WEIGHT: 400; FONT-STYLE: normal; BORDER-BOTTOM: #7598C4 1pt solid; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine(".recipe_name{FONT-FAMILY: \"Arial\"; FONT-SIZE: 10pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0.05in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("-->");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("</style>");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("</head>");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<body text=#000000 vLink=#000000 aLink=#000000 link=#000000 bgColor=White leftMargin=25 topMargin=25 rightMargin=25 background=\"\">");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("<table cellSpacing=0 cellPadding=0 width=\"100%\" border=0>");
|
||||||
|
builderAllRecipeIndex.AppendHtml(HTMLAddCookbookName());
|
||||||
|
|
||||||
|
foreach (var recipe in recipesAlpha.Values)
|
||||||
|
{
|
||||||
|
builderAllRecipeIndex.AppendHtml(HTMLAddRecipeToIndex(recipe, recipePageDictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("</table>");
|
||||||
|
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("</body>");
|
||||||
|
builderAllRecipeIndex.AppendHtmlLine("</html>");
|
||||||
|
|
||||||
|
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(" <tr>");
|
||||||
|
builder.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builder.AppendHtml(" <p class=cookbook_title>");
|
||||||
|
builder.AppendFormat("{0}", this.name);
|
||||||
|
builder.AppendHtmlLine("</p>");
|
||||||
|
builder.AppendHtmlLine(" </td>");
|
||||||
|
builder.AppendHtmlLine(" </tr>");
|
||||||
|
|
||||||
|
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<Guid, String> recipePageDictionary)
|
||||||
|
{
|
||||||
|
var recipePageURL = recipePageDictionary.GetValueOrDefault(recipe.recipeID.Value, String.Empty);
|
||||||
|
var builder = new HtmlContentBuilder();
|
||||||
|
builder.AppendHtmlLine(" <tr>");
|
||||||
|
builder.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builder.AppendHtml(" <p class=recipe_name>");
|
||||||
|
builder.AppendFormat("<a href=\"{0}\">", recipePageURL);
|
||||||
|
builder.AppendFormat("{0}", recipe.recipename);
|
||||||
|
builder.AppendHtmlLine("</a>");
|
||||||
|
builder.AppendHtmlLine("</p>");
|
||||||
|
builder.AppendHtmlLine(" </td>");
|
||||||
|
builder.AppendHtmlLine(" </tr>");
|
||||||
|
|
||||||
|
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(" <tr>");
|
||||||
|
builder.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builder.AppendHtml(" <p class=recipe_name>");
|
||||||
|
builder.AppendFormat("<a href=\"{0}\">", allRecipesURL);
|
||||||
|
builder.AppendFormat("{0}", "All Recipes");
|
||||||
|
builder.AppendHtmlLine("</a>");
|
||||||
|
builder.AppendHtmlLine("</p>");
|
||||||
|
builder.AppendHtmlLine(" </td>");
|
||||||
|
builder.AppendHtmlLine(" </tr>");
|
||||||
|
|
||||||
|
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<Guid, String>();
|
||||||
|
var pagesAlreadyAdded = new SortedSet<String>();
|
||||||
|
var recipesAlpha = new SortedList<String, Recipe>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
410
JRCookbookBusiness/CookbookChapter.cs
Normal file
@@ -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<CookbookChapter> cookbookChapters = new List<CookbookChapter>();
|
||||||
|
public List<RecipeHighlights> recipeHighlights = new List<RecipeHighlights>();
|
||||||
|
|
||||||
|
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<Guid, String> recipePageDictionary, SortedList<String, Recipe> recipesAlpha, SortedSet<String> pagesAlreadyAdded, List<Trackback> 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("<html>");
|
||||||
|
builderChapterIndex.AppendHtmlLine("<head>");
|
||||||
|
builderChapterIndex.AppendFormat("<title>{0}</title>" + Constants.CRLF, this.name);
|
||||||
|
builderChapterIndex.AppendHtmlLine("<meta http-equiv=\"Content-Type\" content=\"text/html\">");
|
||||||
|
builderChapterIndex.AppendHtmlLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">");
|
||||||
|
builderChapterIndex.AppendHtmlLine("<style type=\"text/css\">");
|
||||||
|
builderChapterIndex.AppendHtmlLine("<!--");
|
||||||
|
builderChapterIndex.AppendHtmlLine(".trackback_links{FONT-FAMILY: \"Arial\"; FONT-SIZE: 8pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0.0in; MARGIN-RIGHT: 0.4in; MARGIN-TOP: 0in; MARGIN-BOTTOM: 0.1in; }");
|
||||||
|
builderChapterIndex.AppendHtmlLine(".chapter_header{FONT-FAMILY: \"Arial\"; FONT-SIZE: 8pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0.1in; MARGIN-LEFT: 0.4in; MARGIN-RIGHT: 0.4in; MARGIN-TOP: 0.4in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderChapterIndex.AppendHtmlLine(".chapter_title{FONT-FAMILY: \"Arial\"; FONT-SIZE: 16pt; COLOR: #7598C4; FONT-WEIGHT: 400; FONT-STYLE: normal; BORDER-BOTTOM: #7598C4 1pt solid; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderChapterIndex.AppendHtmlLine(".chapter_name{FONT-FAMILY: \"Arial\"; FONT-SIZE: 10pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0.05in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderChapterIndex.AppendHtmlLine(".subchapter_name{FONT-FAMILY: \"Arial\"; FONT-SIZE: 10pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0.05in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderChapterIndex.AppendHtmlLine(".recipe_name{FONT-FAMILY: \"Arial\"; FONT-SIZE: 10pt; COLOR: #484848; FONT-WEIGHT: 400; FONT-STYLE: normal; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; PADDING-TOP: 0in; PADDING-BOTTOM: 0in; MARGIN-LEFT: 0in; MARGIN-RIGHT: 0in; MARGIN-TOP: 0.05in; MARGIN-BOTTOM: 0in; }");
|
||||||
|
builderChapterIndex.AppendHtmlLine("-->");
|
||||||
|
builderChapterIndex.AppendHtmlLine("</style>");
|
||||||
|
builderChapterIndex.AppendHtmlLine("</head>");
|
||||||
|
builderChapterIndex.AppendHtmlLine("<body text=#000000 vLink=#000000 aLink=#000000 link=#000000 bgColor=White leftMargin=25 topMargin=25 rightMargin=25 background=\"\">");
|
||||||
|
builderChapterIndex.AppendHtmlLine("<table cellSpacing=0 cellPadding=0 width=\"100%\" border=0>");
|
||||||
|
|
||||||
|
if ((trackbackListForThisChapter?.Count() ?? 0) > 0)
|
||||||
|
{
|
||||||
|
builderChapterIndex.AppendHtmlLine(" <tr>");
|
||||||
|
builderChapterIndex.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builderChapterIndex.AppendHtml(" <p class=trackback_links>");
|
||||||
|
builderChapterIndex.AppendHtml(SharedRoutines.GenerateTrackbackLinks(trackbackListForThisChapter));
|
||||||
|
builderChapterIndex.AppendHtmlLine("</p>");
|
||||||
|
builderChapterIndex.AppendHtmlLine(" </td>");
|
||||||
|
builderChapterIndex.AppendHtmlLine(" </tr>");
|
||||||
|
}
|
||||||
|
|
||||||
|
builderChapterIndex.AppendHtml(HTMLAddChapterName());
|
||||||
|
|
||||||
|
Trackback thisTrackback = new Trackback();
|
||||||
|
thisTrackback.TrackbackURL = pageNameToUseWithExtension;
|
||||||
|
thisTrackback.TrackbackText = this.name;
|
||||||
|
|
||||||
|
List<Trackback> trackbackListForChildren = new List<Trackback>();
|
||||||
|
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("</table>");
|
||||||
|
builderChapterIndex.AppendHtmlLine("</body>");
|
||||||
|
builderChapterIndex.AppendHtmlLine("</html>");
|
||||||
|
|
||||||
|
|
||||||
|
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(" <tr>");
|
||||||
|
builder.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builder.AppendHtml(" <p class=chapter_title>");
|
||||||
|
builder.AppendFormat("{0}", this.name);
|
||||||
|
builder.AppendHtmlLine("</p>");
|
||||||
|
builder.AppendHtmlLine(" </td>");
|
||||||
|
builder.AppendHtmlLine(" </tr>");
|
||||||
|
|
||||||
|
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(" <tr>");
|
||||||
|
builder.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builder.AppendHtml(" <p class=subchapter_name>");
|
||||||
|
builder.AppendFormat("<a href=\"{0}\">", chapterURL);
|
||||||
|
builder.AppendFormat("{0}", chapter.name);
|
||||||
|
builder.AppendHtmlLine("</a>");
|
||||||
|
builder.AppendHtmlLine("</p>");
|
||||||
|
builder.AppendHtmlLine(" </td>");
|
||||||
|
builder.AppendHtmlLine(" </tr>");
|
||||||
|
|
||||||
|
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<Guid, String> recipePageDictionary)
|
||||||
|
{
|
||||||
|
var recipePageURL = recipePageDictionary.GetValueOrDefault(recipe.recipeID.Value, String.Empty);
|
||||||
|
var builder = new HtmlContentBuilder();
|
||||||
|
builder.AppendHtmlLine(" <tr>");
|
||||||
|
builder.AppendHtmlLine(" <td valign=top>");
|
||||||
|
builder.AppendHtml(" <p class=recipe_name>");
|
||||||
|
builder.AppendFormat("<a href=\"{0}\">", recipePageURL);
|
||||||
|
builder.AppendFormat("{0}", recipe.recipename);
|
||||||
|
builder.AppendHtmlLine("</a>");
|
||||||
|
builder.AppendHtmlLine("</p>");
|
||||||
|
builder.AppendHtmlLine(" </td>");
|
||||||
|
builder.AppendHtmlLine(" </tr>");
|
||||||
|
|
||||||
|
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<Guid, String> recipePageDictionary, SortedList<String, Recipe> recipesAlpha, SortedSet<String> 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<CookbookChapter>();
|
||||||
|
recipeHighlights = new List<RecipeHighlights>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
1310
JRCookbookBusiness/Ingredient.cs
Normal file
86
JRCookbookBusiness/IngredientMeasure.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
95
JRCookbookBusiness/IngredientSkipSearchWord.cs
Normal file
@@ -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<IngredientSkipSearchWord> GetAllIngredientSkipSearchWords()
|
||||||
|
{
|
||||||
|
DataSet recordSet;
|
||||||
|
var returnValue = new List<IngredientSkipSearchWord>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
269
JRCookbookBusiness/IngredientUsage.cs
Normal file
@@ -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<IngredientUsage> _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<IngredientUsage> GetIngredientUsageAll()
|
||||||
|
{
|
||||||
|
if (_allIngredientUsage == null)
|
||||||
|
{
|
||||||
|
_allIngredientUsage = new List<IngredientUsage>();
|
||||||
|
|
||||||
|
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<IngredientUsage> newList = new List<IngredientUsage>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
JRCookbookBusiness/JRCookbookBusiness.csproj
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0-windows7.0</TargetFramework>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<AssemblyOriginatorKeyFile>JRCookbookStrongNameKey.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<Platforms>x86</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<COMReference Include="Microsoft.Office.Interop.Word">
|
||||||
|
<WrapperTool>tlbimp</WrapperTool>
|
||||||
|
<VersionMinor>7</VersionMinor>
|
||||||
|
<VersionMajor>8</VersionMajor>
|
||||||
|
<Guid>00020905-0000-0000-c000-000000000046</Guid>
|
||||||
|
<Lcid>0</Lcid>
|
||||||
|
<Isolated>false</Isolated>
|
||||||
|
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||||
|
</COMReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DotNetProjects.Extended.Wpf.Toolkit" Version="5.0.103" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="2.2.0" />
|
||||||
|
<PackageReference Include="System.Data.OleDb" Version="7.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Converters\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
27
JRCookbookBusiness/JRCookbookBusinessAppManagement.cs
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
JRCookbookBusiness/JRCookbookStrongNameKey.snk
Normal file
22
JRCookbookBusiness/LongRunningStatusUpdatedEventArgs.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
138
JRCookbookBusiness/Measure.cs
Normal file
@@ -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<Measure> GetMeasuresByIngredientID(Guid ingredientID)
|
||||||
|
{
|
||||||
|
var returnValue = new List<Measure>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
3435
JRCookbookBusiness/Recipe.cs
Normal file
116
JRCookbookBusiness/RecipeHighlights.cs
Normal file
@@ -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<RecipeHighlights> GetAllRecipes()
|
||||||
|
{
|
||||||
|
DataSet recordSet;
|
||||||
|
var returnValue = new List<RecipeHighlights>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
295
JRCookbookBusiness/RecipeIngredient.cs
Normal file
@@ -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<String, IngredientSkipSearchWord> 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<String,String> allWords = new SortedList<String, String>();
|
||||||
|
|
||||||
|
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<String, IngredientSkipSearchWord>();
|
||||||
|
foreach (var loadVal in ingredientSkipWordsUnsorted)
|
||||||
|
{
|
||||||
|
ingredientSkipWords.Add(loadVal.word, loadVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<RecipeIngredient> GetRecipeIngredientAll()
|
||||||
|
{
|
||||||
|
List<RecipeIngredient> allIngredients = new List<RecipeIngredient>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
JRCookbookBusiness/RecipeIngredientHeading.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
163
JRCookbookBusiness/RecipeIngredientItem.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
135
JRCookbookBusiness/RecipeProcedure.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
137
JRCookbookBusiness/RecipeTip.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
41
JRCookbookBusiness/SharedRoutines.cs
Normal file
@@ -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<Trackback> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
30
JRCookbookBusiness/Trackback.cs
Normal file
@@ -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("<a href=\"{0}\">", TrackbackURL);
|
||||||
|
builder.AppendFormat("{0}", TrackbackText);
|
||||||
|
builder.AppendHtml("</a>");
|
||||||
|
|
||||||
|
using (var writer = new System.IO.StringWriter())
|
||||||
|
{
|
||||||
|
builder.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default);
|
||||||
|
return writer.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
109
JRCookbookBusiness/Utility.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
1196
JRCookbookBusiness/clsDatabaseLayer.cs
Normal file
171
JRCookbookBusiness/clsDatabaseLayerBase.cs
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
376
JRCookbookBusiness/clsDiacriticRemover.cs
Normal file
@@ -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;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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".
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
128
JRCookbookBusiness/clsWord.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
JRCookbookControls/Bar0.bmp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
JRCookbookControls/Bar1.bmp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
JRCookbookControls/Bar2.bmp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
JRCookbookControls/Bar3.bmp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
JRCookbookControls/Bar4.bmp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
JRCookbookControls/Delete.bmp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
JRCookbookControls/Handle.bmp
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
JRCookbookControls/Heading.bmp
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
73
JRCookbookControls/JRCookbookAutoVerticalGrowTextBox.cs
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
38
JRCookbookControls/JRCookbookControls.csproj
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0-windows7.0</TargetFramework>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<AssemblyOriginatorKeyFile>JRCookbookStrongNameKey.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<DelaySign>false</DelaySign>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<Platforms>x86</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\JRCookbookBusiness\JRCookbookBusiness.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="JRCookbookEditRecipeIngredient.cs">
|
||||||
|
<SubType>UserControl</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="JRCookbookEditTip.cs">
|
||||||
|
<SubType>UserControl</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="Properties\Resources.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
16
JRCookbookControls/JRCookbookControlsEnums.cs
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
100
JRCookbookControls/JRCookbookEditProcedure.Designer.cs
generated
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
|
||||||
|
namespace JRCookbookControls
|
||||||
|
{
|
||||||
|
partial class JRCookbookEditProcedure
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
244
JRCookbookControls/JRCookbookEditProcedure.cs
Normal file
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
123
JRCookbookControls/JRCookbookEditProcedure.resx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>118, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
151
JRCookbookControls/JRCookbookEditRecipeIngredient.Designer.cs
generated
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
|
||||||
|
namespace JRCookbookControls
|
||||||
|
{
|
||||||
|
partial class JRCookbookEditRecipeIngredient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
2698
JRCookbookControls/JRCookbookEditRecipeIngredient.cs
Normal file
126
JRCookbookControls/JRCookbookEditRecipeIngredient.resx
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>118, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>118, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
100
JRCookbookControls/JRCookbookEditTip.Designer.cs
generated
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
|
||||||
|
namespace JRCookbookControls
|
||||||
|
{
|
||||||
|
partial class JRCookbookEditTip
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
247
JRCookbookControls/JRCookbookEditTip.cs
Normal file
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
123
JRCookbookControls/JRCookbookEditTip.resx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>118, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||