using ComPDFKit.PDFDocument; using ComPDFKit.PDFPage; using ComPDFKitViewer.AnnotEvent; using ComPDFKitViewer.PdfViewer; using PDF_Master.Model; using PDF_Master.ViewModels.Tools; using Prism.Mvvm; using Prism.Regions; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media; using System.Windows; using System.Windows.Media.Imaging; using Prism.Commands; using PDF_Master.Helper; using Microsoft.Office.Interop.Word; using static Dropbox.Api.Files.FileCategory; using PDF_Master.Views.PropertyPanel.AnnotPanel; using System.Windows.Controls; using PDF_Master.CustomControl; using System.Windows.Markup; using ComPDFKitViewer; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Net; using System.Diagnostics; using static Dropbox.Api.TeamLog.TrustedTeamsRequestState; using System.Windows.Input; using Prism.Events; using Prism.Services.Dialogs; using PDF_Master.Views.BOTA; using ImTools; using PDF_Master.ViewModels.Tools.AnnotManager; using PDF_Master.EventAggregators; using DryIoc; using static Dropbox.Api.TeamLog.PaperDownloadFormat; using ComPDFKit.Import; using ComPDFKit.PDFAnnotation; using PDF_Master.Model.AnnotPanel; namespace PDF_Master.ViewModels.PropertyPanel.AnnotPanel { internal class LinkAnnotPropertyViewModel : BindableBase, INavigationAware { #region 文案 private string T_title; public string T_Title { get { return T_title; } set { SetProperty(ref T_title, value); } } private string T_page; public string T_Page { get { return T_page; } set { SetProperty(ref T_page, value); } } private string T_emptyTitle; public string T_EmptyTitle { get { return T_emptyTitle; } set { SetProperty(ref T_emptyTitle, value); } } private void InitString() { T_Title = App.MainPageLoader.GetString("Link_Title"); T_Page = App.MainPageLoader.GetString("Link_Page"); T_EmptyTitle = "Select an area or text on a page to add a link"; } #endregion 文案 public AnnotAttribEvent AnnotAttribEvent { get; set; } private LinkAnnotArgs linkAnnotArgs; public LinkAnnotArgs LinkAnnotArgs { get { return linkAnnotArgs; } set { if (linkAnnotArgs != null) { linkAnnotArgs.LinkDrawFinished -= linkAnnotArgs_LinkDrawFinished; } linkAnnotArgs = value; if (linkAnnotArgs != null) { linkAnnotArgs.LinkDrawFinished += linkAnnotArgs_LinkDrawFinished; } } } private Visibility isEmptyPanelVisibility = Visibility.Visible; public Visibility IsEmptyPanelVisibility { get { return isEmptyPanelVisibility; } set { SetProperty(ref isEmptyPanelVisibility, value); } } private AnnotArgsType annotType; public AnnotArgsType AnnotType { get { return annotType; } set { SetProperty(ref annotType, value); } } #region 输入框的验证、设置 private string pageNumTextContent; public string PageNumTextContent { get { if (CheckPageNumVaild(out int pageNum, pageNumTextContent)) { if (LinkAnnotArgs != null) { LinkAnnotArgs.DestIndex = pageNum - 1; LinkAnnotArgs.Content = string.Format($"To Page {LinkAnnotArgs.DestIndex}"); //isTextChanged = (int)AnnotAttribEvent.Attribs[AnnotAttrib.LinkDestIndx] != AnnotArgs.DestIndex ? true : false; SetImagePreview(LinkAnnotArgs.DestIndex); } } else { ImagePreviewVisibility = Visibility.Collapsed; BtnGOorBackVisibility = Visibility.Collapsed; BtnLocationIsEnabled = false; } return pageNumTextContent; } set { SetProperty(ref pageNumTextContent, value); } } private string pageWebTextContent; public string PageWebTextContent { get { if (CheckPageWebVaild(pageWebTextContent)) { pageWebTextContent = pageWebTextContent.Trim().ToLower(); if (!pageWebTextContent.StartsWith("http://") && !pageWebTextContent.StartsWith("https://")) { pageWebTextContent = "http://" + pageWebTextContent; } if (LinkAnnotArgs != null) { LinkAnnotArgs.URI = pageWebTextContent; LinkAnnotArgs.Content = LinkAnnotArgs.URI; //isTextChanged = (string)AnnotAttribEvent.Attribs[AnnotAttrib.LinkUri] != AnnotArgs.URI ? true : false; } } return pageWebTextContent; } set { SetProperty(ref pageWebTextContent, value); } } private string pageMailTextContent; public string PageMailTextContent { get { if (CheckPageMailVaild(pageMailTextContent)) { if (!string.IsNullOrEmpty(pageMailTextContent) && LinkAnnotArgs != null) { LinkAnnotArgs.URI = "mailto:" + pageMailTextContent.Trim(); LinkAnnotArgs.Content = LinkAnnotArgs.URI; //isTextChanged = (string)AnnotAttribEvent.Attribs[AnnotAttrib.LinkUri] != AnnotArgs.URI ? true : false; } } return pageMailTextContent; } set { SetProperty(ref pageMailTextContent, value); } } /// /// 设置预文本内容 /// private string pageNumPlaceHoldText = "输入目标页面"; public string PageNumPlaceHoldText { get { return pageNumPlaceHoldText; } set { SetProperty(ref pageNumPlaceHoldText, value); } } /// /// 是否显示输入框下方提示文案 /// private Visibility showPageNumTip = Visibility.Collapsed; public Visibility ShowPageNumTip { get { return showPageNumTip; } set { SetProperty(ref showPageNumTip, value); } } /// /// 输入框下方提示文案 /// private string pageNumTipText = "Page number error."; public string PageNumTipText { get { return pageNumTipText; } set { SetProperty(ref pageNumTipText, value); } } private bool pageNumTextIsEnabled = false; public bool PageNumTextIsEnabled { get { return pageNumTextIsEnabled; } set { SetProperty(ref pageNumTextIsEnabled, value); } } private bool pageWebTextIsEnabled = false; public bool PageWebTextIsEnabled { get { return pageWebTextIsEnabled; } set { SetProperty(ref pageWebTextIsEnabled, value); } } private string pageWebPlaceHoldText = "输入您要跳转的链接"; public string PageWebPlaceHoldText { get { return pageWebPlaceHoldText; } set { SetProperty(ref pageWebPlaceHoldText, value); } } private Visibility showPageWebTip = Visibility.Collapsed; public Visibility ShowPageWebTip { get { return showPageWebTip; } set { SetProperty(ref showPageWebTip, value); } } private string pageWebTipText = "Invalid link."; public string PageWebTipText { get { return pageWebTipText; } set { SetProperty(ref pageWebTipText, value); } } private bool pageMailTextIsEnabled = false; public bool PageMailTextIsEnabled { get { return pageMailTextIsEnabled; } set { SetProperty(ref pageMailTextIsEnabled, value); } } private string pageMailPlaceHoldText = "输入您要跳转邮件地址"; public string PageMailPlaceHoldText { get { return pageMailPlaceHoldText; } set { SetProperty(ref pageMailPlaceHoldText, value); } } private Visibility showPageMailTip = Visibility.Collapsed; public Visibility ShowPageMailTip { get { return showPageMailTip; } set { SetProperty(ref showPageMailTip, value); } } private string pageMailTipText = "The email is invalid.Please enter a valid email address."; public string PageMailTipText { get { return pageMailTipText; } set { SetProperty(ref pageMailTipText, value); } } #endregion 输入框的验证、设置 #region 按钮、图片的设置 private bool btnLocationIsEnabled = false; public bool BtnLocationIsEnabled { get { return btnLocationIsEnabled; } set { SetProperty(ref btnLocationIsEnabled, value); } } private bool btnLocationIsChecked = false; public bool BtnLocationIsChecked { get { return btnLocationIsChecked; } set { SetProperty(ref btnLocationIsChecked, value); } } private WriteableBitmap previewImage; public WriteableBitmap PreviewImage { get { return previewImage; } set { SetProperty(ref previewImage, value); } } private int imagePreviewWidth = 196; public int ImagePreviewWidth { get { return imagePreviewWidth; } set { SetProperty(ref imagePreviewWidth, value); } } private int imagePreviewHeight = 256; public int ImagePreviewHeight { get { return imagePreviewHeight; } set { SetProperty(ref imagePreviewHeight, value); } } private Visibility imagePreviewVisibility = Visibility.Collapsed; public Visibility ImagePreviewVisibility { get { return imagePreviewVisibility; } set { SetProperty(ref imagePreviewVisibility, value); } } private Visibility btnGOorBackVisibility = Visibility.Collapsed; public Visibility BtnGOorBackVisibility { get { return btnGOorBackVisibility; } set { SetProperty(ref btnGOorBackVisibility, value); } } private string btnGOorBackContent = "GO"; public string BtnGOorBackContent { get { return btnGOorBackContent; } set { SetProperty(ref btnGOorBackContent, value); } } private bool btnLinkPageIsChecked = true; public bool BtnLinkPageIsChecked { get { return btnLinkPageIsChecked; } set { SetProperty(ref btnLinkPageIsChecked, value); } } private bool btnLinkWebIsChecked = false; public bool BtnLinkWebIsChecked { get { return btnLinkWebIsChecked; } set { SetProperty(ref btnLinkWebIsChecked, value); } } private bool btnLinkMailIsChecked = false; public bool BtnLinkMailIsChecked { get { return btnLinkMailIsChecked; } set { SetProperty(ref btnLinkMailIsChecked, value); } } #endregion 按钮、图片的设置 private bool isLoaded = false; private bool isMail = false; private bool isSelected = false; private string historyBtnGOorBackTag = string.Empty; private int totalPage = 0; private int backPageIndex = 0; private int historyPageIndex = 0; private CPDFViewer pdfViewer; private CPDFDocument document; private Button btnGOorBack = null; private LinkAnnotProperty linkAnnot; private AnnotTransfer propertyPanel; private ViewContentViewModel viewContentViewModel; public IRegionManager region; public IDialogService dialogs; public IEventAggregator events; #region 命令 public DelegateCommand LoadedCommand { get; set; } public DelegateCommand PageNumTextLostFocusCommand { get; set; } public DelegateCommand PageNumTextGotFocusCommand { get; set; } public DelegateCommand PageNumTextKeyDownCommand { get; set; } public DelegateCommand PageMailTextLostFocusCommand { get; set; } public DelegateCommand PageMailTextKeyDownCommand { get; set; } public DelegateCommand PageWebTextLostFocusCommand { get; set; } public DelegateCommand PageWebTextKeyDownCommand { get; set; } public DelegateCommand BtnGOorBackPageCommand { get; set; } public DelegateCommand LocationCommand { get; set; } public DelegateCommand ToggleButtonTabCommand { get; set; } #endregion 命令 public LinkAnnotPropertyViewModel(IRegionManager regionManager, IDialogService dialogService, IEventAggregator eventAggregator) { region = regionManager; dialogs = dialogService; events = eventAggregator; LoadedCommand = new DelegateCommand(Loaded); PageNumTextLostFocusCommand = new DelegateCommand(PageNumTextLostFocus); //PageNumTextGotFocusCommand = new DelegateCommand(PageNumTextGotFocus); PageNumTextKeyDownCommand = new DelegateCommand(PageNumTextKeyDown); PageMailTextLostFocusCommand = new DelegateCommand(PageMailTextLostFocus); PageMailTextKeyDownCommand = new DelegateCommand(PageMailTextKeyDown); PageWebTextLostFocusCommand = new DelegateCommand(PageWebTextLostFocus); PageWebTextKeyDownCommand = new DelegateCommand(PageWebTextKeyDown); BtnGOorBackPageCommand = new DelegateCommand(BtnGOorBackPageEvent); LocationCommand = new DelegateCommand(LocationPage); ToggleButtonTabCommand = new DelegateCommand(ToggleButtonTabSelected); isLoaded = true; InitString(); } private void PageWebTextKeyDown(object obj) { if (obj is KeyEventArgs keyEventArgs) { if (keyEventArgs.Key == Key.Enter) { PageWebTextLostFocus(obj); } } } private void PageWebTextLostFocus(object obj) { if (!string.IsNullOrEmpty(PageWebTextContent)) { if (CheckPageWebVaild(PageWebTextContent)) { AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.URI); PageWebTextContent = PageWebTextContent.Trim().ToLower(); if (!PageWebTextContent.StartsWith("http://") && !PageWebTextContent.StartsWith("https://")) { PageWebTextContent = "http://" + PageWebTextContent; } AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkUri, PageWebTextContent); AnnotAttribEvent?.UpdateAnnot(); LinkAnnotArgs?.InvokeLinkSaveCalled(this, EventArgs.Empty); } } } private void PageMailTextKeyDown(object obj) { if (obj is KeyEventArgs keyEventArgs) { if (keyEventArgs.Key == Key.Enter) { PageMailTextLostFocus(obj); } } } private void PageMailTextLostFocus(object obj) { if (!string.IsNullOrEmpty(PageMailTextContent)) { if (CheckPageMailVaild(PageMailTextContent)) { AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.URI); AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkUri, "mailto:" + PageMailTextContent.Trim()); AnnotAttribEvent?.UpdateAnnot(); LinkAnnotArgs?.InvokeLinkSaveCalled(this, EventArgs.Empty); } } } private string pageNumTextStr = string.Empty; /// /// 页码文本框 Enter键 /// /// private void PageNumTextKeyDown(object obj) { if (obj is KeyEventArgs keyEventArgs) { if (keyEventArgs.Key == Key.Enter) { PageNumTextLostFocus(obj); pageNumTextStr = PageNumTextContent; } } } /// /// 页码文本框获取焦点 /// /// private void PageNumTextGotFocus(object obj) { BtnLocationIsEnabled = false; viewContentViewModel.ShowTip(false); } /// /// 页码文本框失去焦点 /// /// private void PageNumTextLostFocus(object obj) { if (!string.IsNullOrEmpty(PageNumTextContent) && pdfViewer.MouseMode == MouseModes.AnnotCreate && pageNumTextStr != PageNumTextContent) { if (CheckPageNumVaild(out int pageNum, PageNumTextContent)) { isSelected = false; propertyPanel.IsAddLink = false; if (LinkAnnotArgs.PageIndex == -1) { LinkAnnotArgs.PageIndex = pdfViewer.CurrentIndex; } historyPageIndex = LinkAnnotArgs.PageIndex; //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.GOTO); //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkDestIndx, pageNum - 1); //AnnotAttribEvent?.UpdateAnnot(); //isTextChanged = false; SetImagePreview(LinkAnnotArgs.DestIndex); //ImagePreviewVisibility = Visibility.Collapsed; //BtnGOorBackVisibility= Visibility.Collapsed; BtnLocationIsEnabled = false; if (viewContentViewModel.IsRightMenuSelectedTextAddLink == false) { int index = (int)AnnotAttribEvent.Attribs[AnnotAttrib.LinkDestIndx]; if (viewContentViewModel.IsSelectedTextAddLink) { viewContentViewModel.IsSelectedTextAddLink = false; //LinkAnnotArgs.DestIndex = pageNum - 1; //pdfViewer.CreatePageAnnot(pdfViewer.CurrentIndex, LinkAnnotArgs); } } //else //{ // //右键选择文本 创建链接 // LinkAnnotArgs.DestIndex = pageNum - 1; // LinkAnnotArgs?.InvokeLinkSaveCalled(this, EventArgs.Empty); //} if (LinkAnnotArgs.AnnotIndex != -1) { AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.GOTO); AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkDestIndx, pageNum - 1); AnnotAttribEvent?.UpdateAnnot(); } else { LinkAnnotArgs?.InvokeLinkSaveCalled(this, EventArgs.Empty); } //if (viewContentViewModel.IsRightMenuSelectedTextAddLink || viewContentViewModel.IsRightMenuCreateLink) //{ // viewContentViewModel.IsRightMenuSelectedTextAddLink = false; // viewContentViewModel.IsRightMenuCreateLink = false; // viewContentViewModel.SelectedPrpoertyPanel("PropertyPanelContent", null); // var annotArgs = new SelectToolArgs(); // pdfViewer.SetToolParam(annotArgs); // return; //} //添加后选中 //pdfViewer.SelectAnnotation(LinkAnnotArgs.PageIndex, LinkAnnotArgs.AnnotIndex); } else { BtnLocationIsEnabled = true; ImagePreviewVisibility = Visibility.Collapsed; BtnGOorBackVisibility = Visibility.Collapsed; } } else { BtnLocationIsEnabled = true; } } /// /// 模块选择 /// /// private void ToggleButtonTabSelected(object obj) { if (obj is RadioButton radioButton) { switch (radioButton.Tag) { case "Page": LinkAnnotArgs.LinkType = LINK_TYPE.GOTO; LinkAnnotArgs.URI = string.Empty; AnnotAttribEvent.Attribs[AnnotAttrib.LinkType] = LINK_TYPE.GOTO; AnnotAttribEvent.Attribs[AnnotAttrib.LinkUri] = string.Empty; isMail = false; if (btnGOorBack != null) { if (!string.IsNullOrEmpty(historyBtnGOorBackTag)) { ChangeBtnGOorBack(historyBtnGOorBackTag, btnGOorBack); } else { ChangeBtnGOorBack("GO", btnGOorBack); } } BtnGOorBackVisibility = string.IsNullOrEmpty(PageNumTextContent) ? Visibility.Collapsed : Visibility.Visible; break; case "Web": isMail = false; SetLinkType_URIState("Web"); BtnGOorBackVisibility = string.IsNullOrEmpty(PageWebTextContent) ? Visibility.Collapsed : Visibility.Visible; break; case "Mail": isMail = true; SetLinkType_URIState("Mail"); BtnGOorBackVisibility = string.IsNullOrEmpty(PageMailTextContent) ? Visibility.Collapsed : Visibility.Visible; break; } } } /// /// 设置BtnGOorBack状态 /// /// private void SetLinkType_URIState(string uri) { LinkAnnotArgs.LinkType = LINK_TYPE.URI; LinkAnnotArgs.URI = string.Empty; AnnotAttribEvent.Attribs[AnnotAttrib.LinkType] = LINK_TYPE.URI; AnnotAttribEvent.Attribs[AnnotAttrib.LinkUri] = string.Empty; if (btnGOorBack != null) { historyBtnGOorBackTag = btnGOorBack.Tag.ToString(); //ChangeBtnGOorBack("GO", btnGOorBack); switch (uri) { case "Web": if (!string.IsNullOrEmpty(PageWebTextContent)) { ChangeBtnGOorBack("GO", btnGOorBack); } //BtnGOorBackVisibility = string.IsNullOrEmpty(PageWebTextContent) ? Visibility.Collapsed : Visibility.Visible; break; case "Mail": if (!string.IsNullOrEmpty(PageMailTextContent)) { ChangeBtnGOorBack("GO", btnGOorBack); } //BtnGOorBackVisibility = string.IsNullOrEmpty(PageMailTextContent) ? Visibility.Collapsed : Visibility.Visible; break; } } } /// /// 定位目标范围 /// /// private void LocationPage(object obj) { //没有选择注释工具、也不是右键添加注释 //在阅读页,选择注释后,点击按钮 //需要设置相关参数 //if (AnnotAttribEvent.IsAnnotCreateReset == false && propertyPanel.IsAddLink == false) //{ // propertyPanel.IsLocationLink = true; // pdfViewer.SetMouseMode(MouseModes.AnnotCreate); // pdfViewer.SetToolParam(LinkAnnotArgs); //} if (pdfViewer.MouseMode == MouseModes.AnnotCreate) { historyPageIndex = pdfViewer.CurrentIndex; isSelected = false; BtnLocationIsChecked = true; if (region.Regions.ContainsRegionWithName(viewContentViewModel.TipContentRegionName)) { var views = region.Regions[viewContentViewModel.TipContentRegionName].Views; var isHas = views.FindFirst(q => q is Views.TipContent.LinkAnnotTip); if (isHas != null) { region.Regions[viewContentViewModel.TipContentRegionName].Activate(isHas); } else { region.RequestNavigate(viewContentViewModel.TipContentRegionName, "LinkAnnotTip"); } } //viewContentViewModel.TipVisible = Visibility.Visible; if (BtnLocationIsChecked && viewContentViewModel.TipVisible == Visibility.Visible) { pdfViewer.EnableDrawSelectArea(false); viewContentViewModel.ShowTip(false); BtnLocationIsChecked = false; PageNumTextIsEnabled = true; } else { pdfViewer.EnableDrawSelectArea(true); viewContentViewModel.ShowTip(true); PageNumTextIsEnabled = false; //BtnLocationIsChecked = true; } //CommonDrawData.LinkAreaSelectBrush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(50, 23, 112, 244)); //AnnotAttribEvent.IsAnnotCreateReset = true; } } private Rect paintrect; /// /// 链接事件 /// /// /// private void PDFViewer_CustomNotifyHandler(object sender, CustomNotityData e) { IsEmptyPanelVisibility = Visibility.Collapsed; //delete 键删除后 if (e.NotifyType == CustomNotifyType.LinkToolRemove) { IsEmptyPanelVisibility = Visibility.Visible; } //定位目标范围完成时,触发 if (e.NotifyType == CustomNotifyType.LinkAreaLocate) { if (e.NotifyData is AreaLocate areaInfo) { if (pdfViewer.ToolManager.CurrentAnnotArgs == null) { CleanLocationState(); return; } if ((pdfViewer.ToolManager.CurrentAnnotArgs.EventType == AnnotArgsType.AnnotLink && pdfViewer.MouseMode == MouseModes.AnnotCreate) || (viewContentViewModel.IsRightMenuSelectedTextAddLink && pdfViewer.MouseMode == MouseModes.AnnotCreate) || (viewContentViewModel.IsRightMenuCreateLink && pdfViewer.MouseMode == MouseModes.AnnotCreate)) { propertyPanel.IsAddLink = false; System.Windows.Size pageSize = pdfViewer.Document.GetPageSize(areaInfo.PageIndex); if (LinkAnnotArgs.PageIndex == -1) { LinkAnnotArgs.PageIndex = historyPageIndex - 1; } historyPageIndex = LinkAnnotArgs.PageIndex; AnnotAttribEvent = propertyPanel.AnnotEvent; LinkAnnotArgs = (LinkAnnotArgs)propertyPanel.annot; LinkAnnotArgs.IsPositionSet = true; LinkAnnotArgs.DestIndex = areaInfo.PageIndex; LinkAnnotArgs.DestinationPos = new System.Windows.Point(areaInfo.Area.X, pageSize.Height - areaInfo.Area.Y); if (viewContentViewModel.IsRightMenuSelectedTextAddLink == false) { if (viewContentViewModel.IsSelectedTextAddLink) { viewContentViewModel.IsSelectedTextAddLink = false; //pdfViewer.CreatePageAnnot(historyPageIndex, LinkAnnotArgs); } } //else //{ // //右键选择文本 创建链接 // //pdfViewer.CreatePageAnnot(historyPageIndex, LinkAnnotArgs); // LinkAnnotArgs.InvokeLinkSaveCalled(this, EventArgs.Empty); //} if (LinkAnnotArgs.AnnotIndex != -1) { AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.GOTO); AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkDestIndx, areaInfo.PageIndex); AnnotAttribEvent?.UpdateAnnot(); } else { LinkAnnotArgs.InvokeLinkSaveCalled(this, EventArgs.Empty); } BtnLocationIsChecked = false; PageNumTextContent = (areaInfo.PageIndex + 1).ToString(); //SetImagePreview(areaInfo.PageIndex); viewContentViewModel.TipVisible = Visibility.Collapsed; //精准定位 paintrect = LinkAnnotArgs.GetLinkCreateArea(); pdfViewer.GoToPage(historyPageIndex); BackToPage(historyPageIndex, areaInfo.PageIndex); //if (string.IsNullOrEmpty(PageNumTextContent)) //{ //pdfViewer.SelectAnnotation(historyPageIndex, LinkAnnotArgs.AnnotIndex); //} if (viewContentViewModel.IsSelectedTextAddLink) { viewContentViewModel.IsSelectedTextAddLink = false; } //右键选择文本 创建链接 //if (viewContentViewModel.IsRightMenuSelectedTextAddLink || viewContentViewModel.IsRightMenuCreateLink ) //{ // viewContentViewModel.IsRightMenuSelectedTextAddLink = false; // viewContentViewModel.IsRightMenuCreateLink = false; // viewContentViewModel.SelectedPrpoertyPanel("PropertyPanelContent", null); // var annotArgs = new SelectToolArgs(); // pdfViewer.SetToolParam(annotArgs); // return; //} } } } } private void CleanLocationState() { viewContentViewModel.TipVisible = Visibility.Collapsed; BtnLocationIsChecked = false; //没有选择注释工具、也不是右键添加注释 //在阅读页,选择注释后,点击按钮 //需要设置相关参数 if (propertyPanel.IsAddLink == false) { pdfViewer.SetMouseMode(MouseModes.PanTool); } } /// /// 前往/返回按钮 /// /// private void BtnGOorBackPageEvent(object obj) { if (obj is object[] arry) { btnGOorBack = arry[0] as Button; RadioButton btnLinkPage = arry[1] as RadioButton; RadioButton btnLinkWeb = arry[2] as RadioButton; RadioButton btnLinkMail = arry[3] as RadioButton; if (btnLinkPage != null && btnGOorBack != null && btnLinkWeb != null && btnLinkMail != null) { if (btnLinkPage.IsChecked == true) { LinkPageGoOrBack(); } if (btnLinkWeb.IsChecked == true) { LinkWebSave(); } if (btnLinkMail.IsChecked == true) { LinkMailSave(); } } } } /// /// 保存邮件链接 /// private void LinkMailSave() { if (CheckPageMailVaild(PageMailTextContent)) { //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.URI); //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkUri, "mailto:" + PageMailTextContent.Trim()); //AnnotAttribEvent?.UpdateAnnot(); //LinkAnnotArgs?.InvokeLinkSaveCalled(this, EventArgs.Empty); Process.Start("mailto:?to=" + PageMailTextContent.Trim()); } } /// /// 保存web链接 /// private void LinkWebSave() { if (CheckPageWebVaild(PageWebTextContent)) { //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.URI); //PageWebTextContent = PageWebTextContent.Trim().ToLower(); //if (!PageWebTextContent.StartsWith("http://") && !PageWebTextContent.StartsWith("https://")) //{ // PageWebTextContent = "http://" + PageWebTextContent; //} //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkUri, PageWebTextContent); //AnnotAttribEvent?.UpdateAnnot(); //LinkAnnotArgs?.InvokeLinkSaveCalled(this, EventArgs.Empty); if (PageWebTextContent.StartsWith("http://") || PageWebTextContent.StartsWith("https://")) { Process.Start(PageWebTextContent); } } else { BtnGOorBackVisibility = Visibility.Collapsed; } } /// /// 页码链接 GoOrBack /// private void LinkPageGoOrBack() { int pageIndex = Convert.ToInt32(PageNumTextContent) - 1; ////注释位置 //Rect rect = LinkAnnotArgs.GetLinkPaintArea(); ////定位 //Rect paintrect = LinkAnnotArgs.GetLinkCreateArea(); //double height = 0; //CPDFDocument doc = pdfViewer.Document; //CPDFPage docPage; //double zoom = pdfViewer.ZoomFactor; if (btnGOorBack.Tag.ToString() == "GO") { CPDFLinkAnnotation linkAnnot = LinkAnnotArgs.GetLinkAnnot(); if (linkAnnot != null) { CPDFDestination dest = linkAnnot.GetDestination(pdfViewer.Document); System.Windows.Point rawPoint = new System.Windows.Point(dest.Position_X, dest.Position_Y); CPDFPage docPage = pdfViewer.Document.PageAtIndex(pageIndex, false); pdfViewer.GoToPage(pageIndex, new System.Windows.Point(rawPoint.X, docPage.PageSize.Height - rawPoint.Y)); } else { pdfViewer.GoToPage(pageIndex); GoToPage(pageIndex); } //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkType, LINK_TYPE.GOTO); //AnnotAttribEvent?.UpdateAttrib(AnnotAttrib.LinkDestIndx, pageIndex); //AnnotAttribEvent?.UpdateAnnot(); historyPageIndex = LinkAnnotArgs != null ? LinkAnnotArgs.PageIndex : backPageIndex; //GoToPage(pageIndex); ChangeBtnGOorBack("BACK", btnGOorBack); } else { if (historyPageIndex != -1) { pdfViewer.GoToPage(historyPageIndex); //SelectAnnotation(); BackToPage(historyPageIndex, pageIndex); ChangeBtnGOorBack("GO", btnGOorBack); //pdfViewer.SelectAnnotation(historyPageIndex, LinkAnnotArgs.AnnotIndex); } } } private void BackToPage(int historyPageIndex, int pageIndex) { CPDFLinkAnnotation cPDFLink = LinkAnnotArgs.GetLinkAnnot(); if (cPDFLink == null) { pdfViewer.GoToPage(historyPageIndex); pdfViewer.SelectAnnotation(LinkAnnotArgs.PageIndex, LinkAnnotArgs.AnnotIndex); return; } //注释位置 Rect rect = LinkAnnotArgs.GetLinkPaintArea(); //定位 Rect paintrect = LinkAnnotArgs.GetLinkCreateArea(); double height = 0; CPDFDocument doc = pdfViewer.Document; CPDFPage docPage; double zoom = pdfViewer.ZoomFactor; docPage = doc.PageAtIndex(historyPageIndex, false); if (!rect.IsEmpty) { double vertical = pdfViewer.GetVerticalOffset(); if (docPage.PageSize.Height / 2 < rect.Top) { if (historyPageIndex < pageIndex) { //height = vertical + (rect.Bottom * zoom); height = vertical + (rect.Top * zoom); pdfViewer.ScrollToVerticalOffset(height); } else { height = vertical + (rect.Top * zoom); pdfViewer.ScrollToVerticalOffset(height); } } } pdfViewer.SelectAnnotation(LinkAnnotArgs.PageIndex, LinkAnnotArgs.AnnotIndex); } private void GoToPage(int pageIndex) { //注释位置 Rect rect = LinkAnnotArgs.GetLinkPaintArea(); //定位 paintrect = LinkAnnotArgs.GetLinkCreateArea(); //System.Windows.Point point = LinkAnnotArgs.DestinationPos; double height = 0; //CPDFDocument doc = pdfViewer.Document; //CPDFPage docPage; double zoom = pdfViewer.ZoomFactor; //docPage = doc.PageAtIndex(pageIndex, false); if (!paintrect.IsEmpty) { CPDFPage docPage = pdfViewer.Document.PageAtIndex(pageIndex, false); //pdfViewer.GoToPage(pageIndex, new System.Windows.Point(0, docPage.PageSize.Height - paintrect.Y*2)); double vertical = pdfViewer.GetVerticalOffset(); if (docPage.PageSize.Height / 2 < paintrect.Top) { if (historyPageIndex < pageIndex) { //height = vertical + (paintrect.Bottom * zoom); height = vertical + (paintrect.Top * zoom); pdfViewer.ScrollToVerticalOffset(height); } else { height = vertical + (paintrect.Top * zoom); pdfViewer.ScrollToVerticalOffset(height); } } height = vertical + (paintrect.Bottom * zoom); } } /// /// 选择注释 /// private void SelectAnnotation() { if (LinkAnnotArgs != null && !isSelected && LinkAnnotArgs.AnnotIndex >= 0) { pdfViewer.SelectAnnotation(LinkAnnotArgs.PageIndex, LinkAnnotArgs.AnnotIndex); isSelected = true; } else { isSelected = false; } } /// /// 设置前往/返回按钮的文本 /// /// /// private void ChangeBtnGOorBack(string flag, Button button) { switch (flag) { case "BACK": button.Tag = "BACK"; button.Content = "BACK"; break; case "GO": button.Tag = "GO"; button.Content = "GO"; break; default: break; } } /// /// 页码格式验证 /// /// /// /// private bool CheckPageNumVaild(out int pageNum, string text) { pageNum = -1; if (string.IsNullOrEmpty(text)) { return false; } if (text.Trim() != string.Empty) { if (!int.TryParse(text.Trim(), out pageNum)) { ShowPageNumTip = Visibility.Visible; PageNumTipText = " This field only accepts numbers"; return false; } } if (pageNum < 1 || pageNum > totalPage) { ShowPageNumTip = Visibility.Visible; PageNumTipText = " Page number out of range."; return false; } else { ShowPageNumTip = Visibility.Collapsed; } //BtnGOorBackVisibility = Visibility.Visible; return true; } /// /// web链接格式验证 /// /// /// private bool CheckPageWebVaild(string text) { BtnGOorBackVisibility = Visibility.Collapsed; if (string.IsNullOrEmpty(text)) { return false; } string checkUrl = text.ToLower().TrimStart("http://".ToCharArray()).TrimStart("https://".ToCharArray()); if (!Regex.IsMatch(checkUrl, "([a-zA-Z0-9/\\-%\\?#&=]+[./\\-%\\?#&=]?)+")) { ShowPageWebTip = Visibility.Visible; PageWebTipText = "Invalid link."; return false; } string matchText = Regex.Match(checkUrl, "([a-zA-Z0-9/\\-%\\?#&=]+[./\\-%\\?#&=]?)+").Value; if (matchText.Length != checkUrl.Length) { ShowPageWebTip = Visibility.Visible; PageWebTipText = "Invalid link."; return false; } else { ShowPageWebTip = Visibility.Collapsed; } BtnGOorBackVisibility = Visibility.Visible; return true; } /// /// 邮箱链接格式验证 /// /// /// private bool CheckPageMailVaild(string text) { BtnGOorBackVisibility = Visibility.Collapsed; if (string.IsNullOrEmpty(text)) { return false; } if (!Regex.IsMatch(text, "^[A-Za-z0-9\u4e00-\u9fa5_\\-\\.]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")) { ShowPageMailTip = Visibility.Visible; PageMailTipText = "The email is invalid.Please enter a valid email address."; return false; } else { ShowPageMailTip = Visibility.Collapsed; } BtnGOorBackVisibility = Visibility.Visible; return true; } /// /// 设置图像 /// /// private void SetImagePreview(int pageIndex) { ImagePreviewVisibility = Visibility.Visible; BtnGOorBackVisibility = Visibility.Visible; BtnLocationIsEnabled = true; int dpiHeight = (int)ImagePreviewHeight; int dpiWidth = (int)ImagePreviewWidth; if (dpiHeight <= 0 || dpiWidth <= 0) { return; } //int pageIndex = AnnotArgs.DestIndex; Rect MediaRect = GetPageRect(document, pageIndex, CPDFDisplayBox.MediaBox); System.Windows.Size pageSize = GetPageSize(document, pageIndex); double scale = Math.Min(dpiWidth / MediaRect.Width, dpiHeight / MediaRect.Height); scale = Math.Min(scale, 1); int cropWidth = (int)(scale * pageSize.Width); int cropHeight = (int)(scale * pageSize.Height); byte[] imageDatas = RenderPDFPageToArray(document, pageIndex, new Rect(0, 0, cropWidth, cropHeight), scale, true, true); WriteableBitmap WirteBitmap = new WriteableBitmap(cropWidth, cropHeight, 96, 96, PixelFormats.Bgra32, null); WirteBitmap.WritePixels(new Int32Rect(0, 0, cropWidth, cropHeight), imageDatas, WirteBitmap.BackBufferStride, 0); PreviewImage = WirteBitmap; } /// /// 链接画框完成时触发事件 /// /// /// private void linkAnnotArgs_LinkDrawFinished(object sender, bool e) { IsEmptyPanelVisibility = e ? Visibility.Collapsed : Visibility.Visible; SetTextBoxEnableOrNot(e, totalPage); } private void Loaded(object obj) { if (obj is CompositeCommandParameter composite) { if (composite.Parameter is LinkAnnotProperty linkAnnotProperty) { linkAnnot = linkAnnotProperty; } } } public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } public void OnNavigatedFrom(NavigationContext navigationContext) { } public void OnNavigatedTo(NavigationContext navigationContext) { //SolidColorBrush solidColorBrush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(50, 23, 112, 244)); //SolidColorBrush solidColorPen = new SolidColorBrush(System.Windows.Media.Color.FromRgb(23, 112, 244)); //CommonDrawData.LinkPen = new System.Windows.Media.Pen(solidColorPen, 0); //CommonDrawData.LinkBrush = solidColorBrush; //CommonDrawData.LinkAreaSelectPen = new System.Windows.Media.Pen(solidColorBrush, 0); //CommonDrawData.LinkAreaSelectBrush = solidColorBrush; //CommonDrawData.LinkAreaSelectBrush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(50, 23, 112, 244)); navigationContext.Parameters.TryGetValue(ParameterNames.PropertyPanelContentViewModel, out propertyPanel); navigationContext.Parameters.TryGetValue(ParameterNames.PDFViewer, out pdfViewer); navigationContext.Parameters.TryGetValue(ParameterNames.ViewContentViewModel, out viewContentViewModel); events.GetEvent().Subscribe(LinkAnnotTipClose, e => e.UniCode == App.mainWindowViewModel.SelectedItem.Unicode); if (propertyPanel != null && pdfViewer != null) { pdfViewer.CustomNotifyHandler -= PDFViewer_CustomNotifyHandler; pdfViewer.CustomNotifyHandler += PDFViewer_CustomNotifyHandler; AnnotAttribEvent = propertyPanel.AnnotEvent; AnnotType = propertyPanel.annot.EventType; document = pdfViewer.Document; totalPage = pdfViewer.Document.PageCount; if (viewContentViewModel.IsRightMenuCreateLink || viewContentViewModel.IsRightMenuSelectedTextAddLink) { IsEmptyPanelVisibility = viewContentViewModel.IsRightMenuSelectedTextAddLink ? Visibility.Collapsed : Visibility.Visible; SetTextBoxEnableOrNot(true, totalPage); //viewContentViewModel.IsRightMenuSelectedTextAddLink=false; } else { if (viewContentViewModel.IsSelectedTextAddLink) { IsEmptyPanelVisibility = viewContentViewModel.IsSelectedTextAddLink ? Visibility.Collapsed : Visibility.Visible; SetTextBoxEnableOrNot(true, totalPage); } else { if (propertyPanel.annot.AnnotIndex == -1 && propertyPanel.annot.PageIndex == -1) { IsEmptyPanelVisibility = Visibility.Visible; } if (AnnotAttribEvent.IsAnnotCreateReset == false && propertyPanel.annot.AnnotIndex != -1 && propertyPanel.annot.PageIndex != -1) { IsEmptyPanelVisibility = Visibility.Collapsed; } SetTextBoxEnableOrNot(false, totalPage); } } if (isLoaded) { if (pdfViewer != null && pdfViewer.ToolManager != null && pdfViewer.ToolManager.CurrentAnnotArgs?.EventType == AnnotArgsType.AnnotLink) { LinkAnnotArgs = (LinkAnnotArgs)propertyPanel.annot; //LinkAnnotArgs = pdfViewer.ToolManager.CurrentAnnotArgs as LinkAnnotArgs; //if (LinkAnnotArgs.AnnotIndex == -1) //{ // LinkAnnotArgs = (LinkAnnotArgs)propertyPanel.annot; //} if (btnGOorBack != null) { ChangeBtnGOorBack("GO", btnGOorBack); } if (AnnotAttribEvent.IsAnnotCreateReset) { LinkAnnotArgs = pdfViewer.ToolManager.CurrentAnnotArgs as LinkAnnotArgs; if (LinkAnnotArgs == null) { backPageIndex = pdfViewer.CurrentIndex; } else { LinkAnnotArgs.PageIndex = pdfViewer.CurrentIndex; } } } //右键选择文本 创建链接 else { LinkAnnotArgs = (LinkAnnotArgs)propertyPanel.annot; } } if (AnnotAttribEvent.IsAnnotCreateReset == false) { //根据选择的,链接,获取对应的信息 GetAnnotAttribute(); } if (LinkAnnotArgs == null) { LinkAnnotArgs = (LinkAnnotArgs)propertyPanel.annot; } } } private void LinkAnnotTipClose(LinkAnnotTipCloseArgs obj) { pdfViewer.EnableDrawSelectArea(false); viewContentViewModel.ShowTip(false); BtnLocationIsChecked = false; //PageNumTextIsEnabled = true; } /// /// 选择链接后,显示参数 /// private void GetAnnotAttribute() { if (AnnotAttribEvent.Attribs.ContainsKey(AnnotAttrib.LinkType)) { //设置显示的链接模块 SetLinkType((LINK_TYPE)AnnotAttribEvent.Attribs[AnnotAttrib.LinkType]); } if (AnnotAttribEvent.Attribs.ContainsKey(AnnotAttrib.LinkDestIndx) && !AnnotAttribEvent.IsAnnotCreateReset) { SetLinkPageNum((int)AnnotAttribEvent.Attribs[AnnotAttrib.LinkDestIndx] + 1); if (LinkAnnotArgs == null) { backPageIndex = pdfViewer.CurrentIndex; } else { if (LinkAnnotArgs.PageIndex == -1) LinkAnnotArgs.PageIndex = pdfViewer.CurrentIndex; } } //暂定 第一版 不显示邮箱、web链接模块 //if (AnnotAttribEvent.Attribs.ContainsKey(AnnotAttrib.LinkUri)) //{ // string linkUrl = (string)AnnotAttribEvent.Attribs[AnnotAttrib.LinkUri]; // if (!string.IsNullOrEmpty(linkUrl)) // { // if (linkUrl.StartsWith("mailto:", StringComparison.OrdinalIgnoreCase)) // { // SetLinkType(LINK_TYPE.URI, true); // if (AnnotAttribEvent.IsAnnotCreateReset) // { // SetLinkEmail(""); // } // else // { // SetLinkEmail(linkUrl.ToLower().TrimStart("mailto:".ToCharArray())); // } // } // else // { // if (AnnotAttribEvent.IsAnnotCreateReset) // { // SetLinkUrl(""); // } // else // { // SetLinkUrl(linkUrl); // } // } // } //} } private void SetLinkUrl(string url) { PageWebTextContent = url; PageWebTextIsEnabled = true; } private void SetLinkEmail(string email) { PageMailTextContent = email; PageMailTextIsEnabled = true; } /// /// 设置页码的数据 /// /// private void SetLinkPageNum(int pageNum) { if (pageNum > 0 && pageNum <= totalPage) { PageNumTextContent = pageNum.ToString(); BtnLocationIsEnabled = true; PageNumTextIsEnabled = true; ImagePreviewVisibility = Visibility.Visible; SetImagePreview(pageNum - 1); BtnLocationIsEnabled = true; //if (btnGOorBack != null) //{ // ChangeBtnGOorBack("GO", btnGOorBack); //} } } /// /// 根据链接类型显示模块 /// /// /// public void SetLinkType(LINK_TYPE linkType, bool isMail = false) { BtnLinkPageIsChecked = false; BtnLinkMailIsChecked = false; BtnLinkWebIsChecked = false; //暂定 第一版 不显示邮箱、web链接模块 if (linkType == LINK_TYPE.URI) { BtnLinkPageIsChecked = true; BtnGOorBackVisibility = Visibility.Collapsed; viewContentViewModel.SelectedPrpoertyPanel("PropertyPanelContent", null); return; } switch (linkType) { case LINK_TYPE.GOTO: BtnLinkPageIsChecked = true; break; case LINK_TYPE.URI: if (this.isMail || isMail) { BtnLinkMailIsChecked = true; } else { BtnLinkWebIsChecked = true; } break; default: BtnLinkPageIsChecked = true; break; } } /// /// 设置文本框和按钮的属性 /// /// /// private void SetTextBoxEnableOrNot(bool enable, int totalPage) { this.totalPage = totalPage; PageNumTextContent = string.Empty; PageWebTextContent = string.Empty; PageMailTextContent = string.Empty; PageNumTextIsEnabled = enable; PageWebTextIsEnabled = enable; PageMailTextIsEnabled = enable; PageNumPlaceHoldText = PageNumTextIsEnabled ? string.Format($"1-{totalPage}页") : "输入目标页面"; PageWebPlaceHoldText = PageWebTextIsEnabled ? "https://www.pdfreaderpro.com" : "输入您要跳转的链接"; PageMailPlaceHoldText = PageMailTextIsEnabled ? "support@pdfreaderpro.com" : "输入您要跳转邮件地址"; ShowPageNumTip = Visibility.Collapsed; ShowPageWebTip = Visibility.Collapsed; ShowPageMailTip = Visibility.Collapsed; BtnLocationIsEnabled = enable; } /// /// 将PDF的页面转换成数据流 /// /// /// /// /// /// /// /// public byte[] RenderPDFPageToArray(CPDFDocument document, int pageIndex, Rect renderRect, double currentZoom, bool renderAnnot = false, bool renderForm = false) { if (renderRect.Width <= 0 || renderRect.Height <= 0 || document == null) { return null; } try { byte[] bmpData = new byte[(int)renderRect.Width * (int)renderRect.Height * 4]; currentZoom = currentZoom * 96 / 72; int flag = 0; if (renderAnnot) { flag = 1; } uint bgColor = 0xFFFFFFFF; CPDFPage page = document.PageAtIndex(pageIndex); if (page.IsValid()) { page.RenderPageBitmapWithMatrix((float)currentZoom, renderRect, bgColor, bmpData, flag, renderForm); } return bmpData; } catch { return null; } } /// /// 获取页面的矩形 /// /// /// /// /// private Rect GetPageRect(CPDFDocument document, int pageIndex, CPDFDisplayBox displayBox) { CPDFPage currentPage = document.PageAtIndex(pageIndex); Rect boundBox = currentPage.GetBoundsForBox(displayBox); Rect boundRect = new Rect((int)(boundBox.Left / 72.0 * 96.0), (int)(boundBox.Top / 72.0 * 96.0), (int)(boundBox.Width / 72.0 * 96.0), (int)(boundBox.Height / 72.0 * 96.0)); return boundRect; } /// /// 获取页面的尺寸 /// /// /// /// private System.Windows.Size GetPageSize(CPDFDocument document, int pageIndex) { System.Windows.Size pageSize = document.GetPageSize(pageIndex); pageSize.Width = pageSize.Width / 72.0 * 96; pageSize.Height = pageSize.Height / 72.0 * 96; return pageSize; } } }