Imports System.Collections Imports DevExpress.Utils Imports DevExpress.Utils.Svg Imports DevExpress.XtraBars Imports DigitalData.Modules.Logging Imports EnvelopeGenerator.Common Imports EnvelopeGenerator.Common.Constants Imports EnvelopeGenerator.Common.My Imports GdPicture14 Imports GdPicture14.Annotations Partial Public Class frmFieldEditor Private ReadOnly LogConfig As LogConfig Private ReadOnly Logger As Logger Public ReadOnly Property State As State Private GDViewer As GdViewer Private Manager As AnnotationManager Private Controller As FieldEditorController Public Property Document As EnvelopeDocument = Nothing Public Property Receivers As List(Of EnvelopeReceiver) Public Property SelectedReceiver As EnvelopeReceiver = Nothing Private UnsavedChanges As Boolean = False Private SIGNATURE_LABEL As String Private Const SIGNATURE_WIDTH As Single = 1 Private Const SIGNATURE_HEIGHT As Single = 0.5 Public Sub New(pState As State) InitializeComponent() LogConfig = pState.LogConfig Logger = pState.LogConfig.GetLogger() State = pState End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load Text = $"{State.DbConfig.ExternalProgramName} - {Resources.Envelope.Signature_Editor}" SIGNATURE_LABEL = Resources.Envelope.Signature If Document Is Nothing Then Throw New ArgumentNullException("Document") End If If State Is Nothing Then Throw New ArgumentNullException("State") End If If MS_GDPICTUREKEY = "" Then Throw New ArgumentNullException("GDPictureKey") End If InitializeViewer() SetReceiver(Receivers.First()) Dim oItems = Receivers.Select(AddressOf CreateBarItem).ToArray() PopupMenu1.AddItems(oItems) Controller = New FieldEditorController(State, Document) If Controller.LoadElements() = False Then MsgBox(Resources.Envelope.Elements_could_not_be_loaded, MsgBoxStyle.Critical, Text) Else For Each oReceiver In Receivers LoadAnnotations(oReceiver.Id) Next GDViewer.DisplayFirstPage() ThumbnailEx2.LoadFromGdViewer(GDViewer) End If End Sub Private Sub InitializeViewer() DocumentViewer1.Init(LogConfig, MS_GDPICTUREKEY, New DigitalData.Controls.DocumentViewer.DocumentViewer.ToolbarSettings With { .ShowFlipButton = False, .ShowPrintButton = False, .ShowRotateButton = False, .ShowSettingButton = False }) DocumentViewer1.LoadFile(Document.Filepath) If DocumentViewer1.PdfViewer IsNot Nothing Then GDViewer = DocumentViewer1.PdfViewer AddHandler GDViewer.BeforeAnnotationAddedByUser, AddressOf Viewer_BeforeAnnotationAddedByUser AddHandler GDViewer.AnnotationAddedByUser, AddressOf Viewer_AnnotationAddedByUser AddHandler GDViewer.AnnotationMoved, AddressOf Viewer_AnnotationMoved Manager = GDViewer.GetAnnotationManager() Manager.InitFromGdViewer(GDViewer) Else Logger.Warn("Viewer could not be initialized!") End If End Sub Private Sub Viewer_AnnotationMoved(AnnotationIdx As Integer) UnsavedChanges = True End Sub Private Function CreateBarItem(pReceiver As EnvelopeReceiver) As BarItem Dim oItem = New BarButtonItem(BarManager1, pReceiver.Name) Dim oBaseCircle As SvgImage = SvgImageCollection1.Item(0) Dim oColorCircle = Helpers.GetColorCircle(oBaseCircle, pReceiver.Color) oItem.ImageOptions.SvgImage = oColorCircle AddHandler oItem.ItemClick, AddressOf ReceiverItem_Click oItem.Tag = pReceiver Return oItem End Function Private Sub ReceiverItem_Click(sender As Object, e As ItemClickEventArgs) Me.SuspendLayout() Dim oSelectedReceiver As EnvelopeReceiver = e.Item.Tag Dim oCurrentPage = GDViewer.CurrentPage Dim oCurrentPosition = GDViewer.GetVScrollBarPosition() If oSelectedReceiver.Id = SelectedReceiver.Id Then Exit Sub End If AddElementsToController() If Controller.SaveElements(SelectedReceiver.Id) Then SetReceiver(oSelectedReceiver) ClearAnnotations() For Each oReceiver In Receivers LoadAnnotations(oReceiver.Id) Next DisplayPage(oCurrentPage) GDViewer.SetVScrollBarPosition(oCurrentPosition) GDViewer.Redraw() ThumbnailEx2.ReloadThumbnails() TestViewerActionSuccessful("ReceiverItem_Click/Redraw") Else MsgBox(Resources.Envelope.Elements_could_not_be_saved, MsgBoxStyle.Critical, Text) End If Me.ResumeLayout() End Sub Private Sub SetReceiver(pReceiver As EnvelopeReceiver) Dim oBaseCircle As SvgImage = SvgImageCollection1.Item(0) txtReceiver.Caption = pReceiver.Name txtReceiver.ImageOptions.SvgImage = Helpers.GetColorCircle(oBaseCircle, pReceiver.Color) SelectedReceiver = pReceiver End Sub Private Sub DisplayPage(pPage As Integer) GDViewer.LockViewer = True GDViewer.DisplayPage(pPage) GDViewer.LockViewer = False End Sub Private Sub BarButtonItem1_ItemClick(sender As Object, e As ItemClickEventArgs) Handles BarButtonItem1.ItemClick If GDViewer IsNot Nothing Then GDViewer.AddStickyNoteAnnotationInteractive(SIGNATURE_LABEL, Color.Black, "Arial", FontStyle.Regular, 10, 1, 0) End If End Sub Private Sub Viewer_BeforeAnnotationAddedByUser(pAnnotationIdx As Integer) Dim oAnnotation As Annotation = GDViewer.GetAnnotationFromIdx(pAnnotationIdx) ApplyAnnotationStyleForNewAnnotation(oAnnotation, SelectedReceiver.Color) End Sub Private Sub SaveElements() Dim oCurrentPage = GDViewer.CurrentPage AddElementsToController() If Not Controller.SaveElements(SelectedReceiver.Id) Then MsgBox(Resources.Envelope.Elements_could_not_be_saved, MsgBoxStyle.Critical, Text) Exit Sub End If UpdateAnnotationTag() DisplayPage(oCurrentPage) GDViewer.Redraw() TestViewerActionSuccessful("btnSave_ItemClick/Redraw") UnsavedChanges = False End Sub Private Sub btnSave_ItemClick(sender As Object, e As ItemClickEventArgs) Handles btnSave.ItemClick SaveElements() End Sub Private Sub AddElementsToController() Dim oPageCount = GDViewer.PageCount For oPage = 1 To oPageCount GDViewer.DisplayPage(oPage) AddElementsToController(oPage) Next End Sub Private Sub AddElementsToController(pPage As Integer) Dim oAnnotationCount = GDViewer.GetAnnotationCount() For oAnnotationIndex = 0 To oAnnotationCount - 1 Dim oAnnotation As Annotation = GDViewer.GetAnnotationFromIdx(oAnnotationIndex) If TypeOf oAnnotation Is AnnotationStickyNote Then Dim oStickyNote As AnnotationStickyNote = oAnnotation Dim oPageOrientation As PageOrientation = GetOrientation() Controller.AddOrUpdateElement(oStickyNote, oPageOrientation) End If Next End Sub Private Sub UpdateAnnotationTag() Dim oPageCount = GDViewer.PageCount For oPage = 1 To oPageCount GDViewer.DisplayPage(oPage) Dim oAnnotationCount = GDViewer.GetAnnotationCount() For oAnnotationIndex = 0 To oAnnotationCount - 1 Dim oAnnotation As Annotation = GDViewer.GetAnnotationFromIdx(oAnnotationIndex) If TypeOf oAnnotation Is AnnotationStickyNote Then Dim oStickyNote As AnnotationStickyNote = oAnnotation Dim oTag = oStickyNote.Tag Dim oInfo = Controller.GetElementInfo(oTag) If oInfo.Guid = -1 Then Dim oElement = Controller.GetElement(oStickyNote) If oElement IsNot Nothing Then oStickyNote.Tag = GetAnnotationTag(SelectedReceiver.Id, oPage, oElement.Id) Else MsgBox("No Element for Update found!") Logger.Error("No Element for Update found!") End If End If End If Next Next End Sub Private Sub btnDelete_ItemClick(sender As Object, e As ItemClickEventArgs) Handles btnDelete.ItemClick Dim oSelected = GDViewer.GetSelectedAnnotationIdx() If TestViewerActionSuccessful("btnDelete_ItemClick/GetSelectedAnnotationIdx") = False Then Logger.Warn("Selected Annotation could not be fetched!") Exit Sub End If If oSelected = -1 Then Exit Sub End If If MsgBox(Resources.Envelope.Do_you_want_to_delete_the_signature, MsgBoxStyle.YesNo Or MsgBoxStyle.Question, Text) = DialogResult.Yes Then Dim oAnnotation = GDViewer.GetAnnotationFromIdx(oSelected) Dim oElement = Controller.GetElement(oAnnotation) ' Delete Element if it was already saved to db If oElement IsNot Nothing Then Controller.DeleteElement(oElement) End If GDViewer.DeleteAnnotation(oSelected) If TestViewerActionSuccessful("btnDelete_ItemClick/DeleteAnnotation") = False Then Logger.Warn("Annotation could not be deleted!") End If End If End Sub Private Sub LoadAnnotation(pElement As EnvelopeDocumentElement, pReceiverId As Integer) Dim oAnnotation As AnnotationStickyNote = Manager.AddStickyNoteAnnot(0, 0, 0, 0, "SIGNATUR") Dim oPage = pElement.Page Dim oReceiver = Receivers.Where(Function(r) r.Id = pReceiverId).Single() Dim oAnnotationColor = oReceiver.Color If oReceiver.Id <> SelectedReceiver.Id Then oAnnotationColor = Color.FromArgb(30, oReceiver.Color) oAnnotation.CanSelect = False End If If Manager.GetStat() = GdPictureStatus.OK Then ApplyAnnotationStyleForExistingAnnotation(oAnnotation, oAnnotationColor) oAnnotation.Width = CSng(pElement.Width) oAnnotation.Height = CSng(pElement.Height) oAnnotation.Left = CSng(pElement.X) oAnnotation.Top = CSng(pElement.Y) oAnnotation.Tag = GetAnnotationTag(pReceiverId, oPage, pElement.Id) Else Dim oStatus = Manager.GetStat() MsgBox(String.Format("GDViewer returned error [{0}] on action [{1}]", oStatus.ToString, "LoadAnnotation")) Logger.Error("GDViewer returned error [{0}] on action [{1}]", oStatus.ToString, "LoadAnnotation") End If End Sub Private Sub Viewer_AnnotationAddedByUser(pAnnotationIdx As Integer) Dim oAnnotation = GDViewer.GetAnnotationFromIdx(pAnnotationIdx) Dim oPage = GDViewer.CurrentPage Dim oTag = GetAnnotationTag(SelectedReceiver.Id, oPage, -1) If TypeOf oAnnotation Is AnnotationStickyNote Then Dim oStickyNote As AnnotationStickyNote = oAnnotation oStickyNote.Width = SIGNATURE_WIDTH oStickyNote.Height = SIGNATURE_HEIGHT oStickyNote.Tag = oTag ApplyAnnotationStyleForExistingAnnotation(oAnnotation, SelectedReceiver.Color) End If UnsavedChanges = True End Sub Private Function GetOrientation() As PageOrientation Dim oWidth = GDViewer.Width Dim oHeight = GDViewer.PageHeight If oHeight >= oWidth Then Return PageOrientation.Portrait Else Return PageOrientation.Landscape End If End Function Private Sub ApplyAnnotationStyleForExistingAnnotation(ByRef pAnnotation As Annotation, pColor As Color) ApplyAnnotationStyle(pAnnotation, pColor, pIsNewAnnotation:=False) End Sub Private Sub ApplyAnnotationStyleForNewAnnotation(ByRef pAnnotation As Annotation, pColor As Color) ApplyAnnotationStyle(pAnnotation, pColor, pIsNewAnnotation:=True) End Sub Private Sub ApplyAnnotationStyle(ByRef pAnnotation As Annotation, pColor As Color, pIsNewAnnotation As Boolean) If TypeOf pAnnotation Is AnnotationStickyNote Then Dim oAnnotation As AnnotationStickyNote = pAnnotation oAnnotation.Fill = True oAnnotation.FillColor = pColor oAnnotation.Text = SIGNATURE_LABEL oAnnotation.Alignment = StringAlignment.Center oAnnotation.LineAlignment = StringAlignment.Center oAnnotation.BorderWidth = 0.01 oAnnotation.FontSize = 16 oAnnotation.FontStyle = FontStyle.Regular oAnnotation.CanEditText = False oAnnotation.CanEdit = False oAnnotation.CanRotate = False If pIsNewAnnotation = False Then oAnnotation.CanResize = False End If End If End Sub Private Sub ClearAnnotations() Dim oPageCount = GDViewer.PageCount For oPage = 1 To oPageCount DisplayPage(oPage) Dim oAnnotationCount = GDViewer.GetAnnotationCount() For oAnnotationIndex = 0 To oAnnotationCount - 1 ' We always delete the first item in the list of annotations, ' because DeleteAnnotation expects and index, not an identifier GDViewer.DeleteAnnotation(0) If TestViewerActionSuccessful("ClearAnnotations") = False Then Logger.Warn("Annotation could not be cleared!") End If Next Next End Sub Private Function TestViewerActionSuccessful(pAction As String) As Boolean Dim oStatus = GDViewer.GetStat() If oStatus = GdPictureStatus.OK Then Return True Else MsgBox(String.Format("GDViewer returned error [{0}] on action [{1}]", oStatus.ToString, pAction)) Logger.Error("GDViewer returned error [{0}] on action [{1}]", oStatus.ToString, pAction) Return False End If End Function Private Sub LoadAnnotations(pReceiverId As Integer) Dim oPageCount = GDViewer.PageCount For oPage = 1 To oPageCount DisplayPage(oPage) If TestViewerActionSuccessful("LoadAnnotations/DisplayPage") = False Then Logger.Warn("Page could not be displayed!") End If Dim oCurrentPage = oPage Dim oElements = Controller.Elements. Where(Function(e) e.Page = oCurrentPage And e.ReceiverId = pReceiverId). ToList() For Each oElement In oElements LoadAnnotation(oElement, pReceiverId) Next Next End Sub Private Function GetAnnotationTag(pReceiver As Integer, pPage As Integer, pGuid As Integer) As String Return $"{pReceiver}|{pPage}|{pGuid}" End Function Private Sub frmFieldEditor_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing If UnsavedChanges Then Dim oResult = MsgBox(Resources.Envelope.There_are_unsaved_changes, MsgBoxStyle.Question Or MsgBoxStyle.YesNoCancel, Text) Select Case oResult Case MsgBoxResult.Cancel e.Cancel = True Case MsgBoxResult.Yes SaveElements() Case Else ' just let the form close End Select End If End Sub End Class