diff --git a/FormFields/User-BasedFormFieldVisibility/App.config b/FormFields/User-BasedFormFieldVisibility/App.config new file mode 100644 index 0000000..b50c74f --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/FormFields/User-BasedFormFieldVisibility/App.xaml b/FormFields/User-BasedFormFieldVisibility/App.xaml new file mode 100644 index 0000000..f441dce --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/FormFields/User-BasedFormFieldVisibility/App.xaml.cs b/FormFields/User-BasedFormFieldVisibility/App.xaml.cs new file mode 100644 index 0000000..7aeb98a --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace User_BasedFormFieldVisibility +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/FormFields/User-BasedFormFieldVisibility/Data/eSign_filling.pdf b/FormFields/User-BasedFormFieldVisibility/Data/eSign_filling.pdf new file mode 100644 index 0000000..a505055 Binary files /dev/null and b/FormFields/User-BasedFormFieldVisibility/Data/eSign_filling.pdf differ diff --git a/FormFields/User-BasedFormFieldVisibility/Data/profile1.png b/FormFields/User-BasedFormFieldVisibility/Data/profile1.png new file mode 100644 index 0000000..6519f17 Binary files /dev/null and b/FormFields/User-BasedFormFieldVisibility/Data/profile1.png differ diff --git a/FormFields/User-BasedFormFieldVisibility/Data/profile2.png b/FormFields/User-BasedFormFieldVisibility/Data/profile2.png new file mode 100644 index 0000000..fc09717 Binary files /dev/null and b/FormFields/User-BasedFormFieldVisibility/Data/profile2.png differ diff --git a/FormFields/User-BasedFormFieldVisibility/EsigningPdfFormsViewModel.cs b/FormFields/User-BasedFormFieldVisibility/EsigningPdfFormsViewModel.cs new file mode 100644 index 0000000..f279663 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/EsigningPdfFormsViewModel.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.ObjectModel; +using System.IO; +using System.Windows; +using System.Windows.Resources; + +namespace User_BasedFormFieldVisibility +{ + public class EsigningPdfFormsViewModel + { + private Stream m_documentStream; + public EsigningPdfFormsViewModel() + { + this.Employees = new ObservableCollection(); + string andrewFilePath = "../../Data/profile1.png"; + string anneFilePath = "../../Data/profile2.png"; + + Employees.Add(new Employee + { + Name = "Andrew Fuller", + ProfilePicture = GetFileStream("profile1.png"), + Mail = "andrew@mycompany.com", + BorderColor = true, + + }); + Employees.Add(new Employee + { + Name = "Anne Dodsworth", + ProfilePicture = GetFileStream("profile2.png"), + Mail = "anne@mycompany.com", + BorderColor = false, + + }); + } + + /// + /// Gets or sets the document path. + /// + public Stream DocumentStream + { + get + { + return m_documentStream; + } + set + { + m_documentStream = value; + } + } + /// + /// Gets or sets the collection of Employees. + /// + public ObservableCollection Employees { get; set; } + private Stream GetFileStream(string filePath) + { + Uri uriResource = new Uri("/User-BasedFormFieldVisibility;component/Data/" + filePath, UriKind.Relative); + StreamResourceInfo streamResourceInfo = Application.GetResourceStream(uriResource); + return streamResourceInfo.Stream; + } + } + /// + /// Class to represent the details of the Employees + /// + public class Employee + { + public string Name { get; set; } + public Stream ProfilePicture { get; set; } + public string Mail { get; set; } + public bool BorderColor { get; set; } + + } +} diff --git a/FormFields/User-BasedFormFieldVisibility/MainWindow.xaml b/FormFields/User-BasedFormFieldVisibility/MainWindow.xaml new file mode 100644 index 0000000..1f96f36 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/MainWindow.xaml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FormFields/User-BasedFormFieldVisibility/MainWindow.xaml.cs b/FormFields/User-BasedFormFieldVisibility/MainWindow.xaml.cs new file mode 100644 index 0000000..bafcfb6 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/MainWindow.xaml.cs @@ -0,0 +1,306 @@ +using Microsoft.Win32; +using Syncfusion.Pdf.Graphics; +using Syncfusion.Pdf.Interactive; +using Syncfusion.Pdf.Parsing; +using Syncfusion.Windows.Tools.Controls; +using System; +using System.Collections.ObjectModel; +using System.IO; +using System.Windows; + +namespace User_BasedFormFieldVisibility +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + private ObservableCollection AnneList = new ObservableCollection(); + private ObservableCollection AndrewList = new ObservableCollection(); + private Employee currentUser; + private string errors; + private bool isUser = false; + /// + /// Checks whether there are validation error in the Formfields. + /// + public bool isErrorMessage = false; + public MainWindow() + { + InitializeComponent(); + this.DataContext = new EsigningPdfFormsViewModel(); + pdfviewer.Load("../../Data/eSign_filling.pdf"); + } + + private void pdfviewer_DocumentLoaded(object sender, EventArgs args) + { + pdfviewer.ThumbnailSettings.IsVisible = false; + pdfviewer.IsBookmarkEnabled = false; + pdfviewer.EnableLayers = false; + pdfviewer.PageOrganizerSettings.IsIconVisible = false; + pdfviewer.EnableRedactionTool = false; + pdfviewer.FormSettings.IsIconVisible = false; + buttonAdv.IsEnabled = false; + UpdateFormField(); + } + + private void ComboBoxAdv_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) + { + ComboBoxAdv currentComboBox = sender as ComboBoxAdv; + if (currentComboBox != null) + { + currentUser = currentComboBox.SelectedItem as Employee; + isUser = true; + } + if (pdfviewer != null) + UpdateFormField(); + + if (isErrorMessage && comboBox.SelectedIndex != 0) + { + DisplayMessage(); + comboBox.SelectedIndex = 0; + errors = string.Empty; + } + } + + private void DisplayMessage() + { + MessageBox.Show(errors.Substring(0, errors.Length - 2) + ".", "Missing Field Alert", MessageBoxButton.OK); + } + + private void UpdateFormField() + { + if (pdfviewer.LoadedDocument.Form != null) + { + var FormFieldCollections = pdfviewer.LoadedDocument.Form.Fields; + + if (FormFieldCollections.Count > 0) + { + for (int i = 0; i < FormFieldCollections.Count; i++) + { + if (FormFieldCollections[i].Name == "LandlordName" || FormFieldCollections[i].Name == "LandlordDate" || FormFieldCollections[i].Name == "LandlordSignature") + { + AnneList.Add(FormFieldCollections[i]); + } + else + { + AndrewList.Add(FormFieldCollections[i]); + } + } + } + + if (currentUser.Mail == "anne@mycompany.com") + { + if (isUser) + { + ValidateAndSaveForm(); + if (!isErrorMessage) + { + buttonAdv.IsEnabled = true; + foreach (var item in AnneList) + { + if (item is PdfLoadedTextBoxField textFormField) + { + textFormField.Visibility = PdfFormFieldVisibility.Visible; + textFormField.ReadOnly = false; + } + else if (item is PdfLoadedSignatureField signatureFormField) + { + signatureFormField.Visibility = PdfFormFieldVisibility.Visible; + signatureFormField.ReadOnly = false; + } + } + foreach (var item in AndrewList) + { + if (item is PdfLoadedTextBoxField pdfLoadedTextBoxField) + { + PdfLoadedTextBoxField textBoxField = item as PdfLoadedTextBoxField; + PdfLoadedTextBoxField textbox = pdfviewer.LoadedDocument.Form.Fields[0] as PdfLoadedTextBoxField; + textBoxField.BackColor = PdfColor.Empty; + textBoxField.ReadOnly = true; + } + else if (item is PdfLoadedSignatureField pdfLoadedSignatureField) + { + PdfLoadedSignatureField signatureField = item as PdfLoadedSignatureField; + signatureField.ReadOnly = true; + } + } + } + } + } + else + { + buttonAdv.IsEnabled = false; + foreach (var item in AnneList) + { + if (item is PdfLoadedTextBoxField textFormField) + { + if (textFormField.Text == "") + textFormField.Visibility = PdfFormFieldVisibility.Hidden; + else + textFormField.ReadOnly = true; + } + else if (item is PdfLoadedSignatureField signatureFormField) + { + if (!(IsSignatureFieldSigned(signatureFormField)) && signatureFormField.Visibility != PdfFormFieldVisibility.Hidden) + signatureFormField.Visibility = PdfFormFieldVisibility.Hidden; + else + signatureFormField.ReadOnly = true; + } + } + } + AnneList.Clear(); + AndrewList.Clear(); + } + } + + /// + /// Validate the for fields and update the error message. + /// + public void ValidateAndSaveForm() + { + + errors = "Required field(s) that need to be filled: "; + foreach (PdfField formField in AndrewList) + { + if (formField is PdfLoadedTextBoxField textFormField) + { + if (string.IsNullOrWhiteSpace(textFormField.Text)) + { + errors = errors + textFormField.Name + ", "; + } + } + + else if (formField is PdfLoadedSignatureField signatureFormField) + { + if (!(IsSignatureFieldSigned(signatureFormField))) + { + errors = errors + signatureFormField.Name + ", "; + } + } + } + + if (errors != "Required field(s) that need to be filled: ") + { + isErrorMessage = true; + } + else + { + isErrorMessage = false; + } + } + /// + /// Checks if a signature field has been signed. + /// + /// The signature field to check. + public bool IsSignatureFieldSigned(PdfLoadedSignatureField signatureField) + { + bool isSigned = false; + if (signatureField.Page != null && signatureField.Page.Annotations.Count > 0) + { + foreach (var annotation in signatureField.Page.Annotations) + { + if (annotation is PdfLoadedInkAnnotation) + { + PdfLoadedInkAnnotation signature = annotation as PdfLoadedInkAnnotation; + if (signature.Name != signatureField.Name) + { + isSigned = false; + } + else + { + isSigned = true; + break; + } + } + else if (annotation is PdfInkAnnotation) + { + PdfInkAnnotation signature = annotation as PdfInkAnnotation; + if (signature.Name != signatureField.Name) + { + isSigned = false; + } + else + { + isSigned = true; + break; + } + } + else + { + isSigned = false; + } + } + } + return isSigned; + } + + private void button_Click(object sender, EventArgs e) + { + bool hasErrors = false; + PdfLoadedDocument pdfLoadedDocument = pdfviewer.LoadedDocument; + if (pdfLoadedDocument.Form != null && pdfLoadedDocument.Form.Fields.Count > 0) + { + errors = "Required field(s) that need to be filled: "; + foreach (var field in pdfLoadedDocument.Form.Fields) + { + if (field is PdfLoadedTextBoxField) + { + PdfLoadedTextBoxField textBoxField = field as PdfLoadedTextBoxField; + if (string.IsNullOrWhiteSpace(textBoxField.Text)) + { + errors = errors + textBoxField.Name + ", "; + hasErrors = true; + } + } + else if (field is PdfLoadedSignatureField signatureField) + { + if (!(IsSignatureFieldSigned(signatureField))) + { + errors = errors + signatureField.Name + ", "; + hasErrors = true; + } + } + } + if (hasErrors) + { + DisplayMessage(); + } + } + if (!hasErrors) + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.Filter = "PDF Files|*.pdf"; + string downloadsFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads"; + saveFileDialog.InitialDirectory = downloadsFolder; + saveFileDialog.FileName = "eSign_filling.pdf"; + + if (saveFileDialog.ShowDialog() == true) + { + var formFields = pdfviewer.LoadedDocument.Form.Fields; + foreach (var item in formFields) + { + if (item is PdfLoadedTextBoxField pdfLoadedTextBoxField) + { + PdfLoadedTextBoxField textBoxField = item as PdfLoadedTextBoxField; + textBoxField.BackColor = PdfColor.Empty; + textBoxField.Flatten = true; + } + else if (item is PdfLoadedSignatureField pdfLoadedSignatureField) + { + PdfLoadedSignatureField signatureField = item as PdfLoadedSignatureField; + signatureField.Flatten = true; + } + } + using (Stream saveStream = new FileStream(saveFileDialog.FileName, FileMode.Create, FileAccess.Write)) + { + pdfviewer.LoadedDocument.Save(saveStream); + } + pdfviewer.Load(saveFileDialog.FileName); + comboBox.IsEnabled = false; + isUser = false; + } + } + + } + } +} diff --git a/FormFields/User-BasedFormFieldVisibility/Properties/AssemblyInfo.cs b/FormFields/User-BasedFormFieldVisibility/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..99e6534 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/Properties/AssemblyInfo.cs @@ -0,0 +1,48 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] diff --git a/FormFields/User-BasedFormFieldVisibility/Properties/Resources.Designer.cs b/FormFields/User-BasedFormFieldVisibility/Properties/Resources.Designer.cs new file mode 100644 index 0000000..c8e371e --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace User_BasedFormFieldVisibility.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("User_BasedFormFieldVisibility.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/FormFields/User-BasedFormFieldVisibility/Properties/Resources.resx b/FormFields/User-BasedFormFieldVisibility/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/FormFields/User-BasedFormFieldVisibility/Properties/Settings.Designer.cs b/FormFields/User-BasedFormFieldVisibility/Properties/Settings.Designer.cs new file mode 100644 index 0000000..92da028 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace User_BasedFormFieldVisibility.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/FormFields/User-BasedFormFieldVisibility/Properties/Settings.settings b/FormFields/User-BasedFormFieldVisibility/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/FormFields/User-BasedFormFieldVisibility/User-BasedFormFieldVisibility.csproj b/FormFields/User-BasedFormFieldVisibility/User-BasedFormFieldVisibility.csproj new file mode 100644 index 0000000..d63b0eb --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/User-BasedFormFieldVisibility.csproj @@ -0,0 +1,116 @@ + + + + + Debug + AnyCPU + {7B96E505-1FDE-4188-86E8-0DF4B8D68FF6} + WinExe + User_BasedFormFieldVisibility + User-BasedFormFieldVisibility + v4.6.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/FormFields/User-BasedFormFieldVisibility/User-BasedFormFieldVisibility.sln b/FormFields/User-BasedFormFieldVisibility/User-BasedFormFieldVisibility.sln new file mode 100644 index 0000000..edcd4d8 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/User-BasedFormFieldVisibility.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.35818.85 d17.13 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "User-BasedFormFieldVisibility", "User-BasedFormFieldVisibility.csproj", "{7B96E505-1FDE-4188-86E8-0DF4B8D68FF6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B96E505-1FDE-4188-86E8-0DF4B8D68FF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B96E505-1FDE-4188-86E8-0DF4B8D68FF6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B96E505-1FDE-4188-86E8-0DF4B8D68FF6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B96E505-1FDE-4188-86E8-0DF4B8D68FF6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1E02E291-FA92-4A86-A823-5EF1008E243F} + EndGlobalSection +EndGlobal diff --git a/FormFields/User-BasedFormFieldVisibility/packages.config b/FormFields/User-BasedFormFieldVisibility/packages.config new file mode 100644 index 0000000..5f1b6c9 --- /dev/null +++ b/FormFields/User-BasedFormFieldVisibility/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file