using ComPDFKit.PDFDocument; using ComPDFKit_Conversion.Converter; using ComPDFKitViewer.PdfViewer; using Dropbox.Api.Team; using Microsoft.Win32; using PDF_Master.CustomControl; using PDF_Master.EventAggregators; using PDF_Master.Helper; using PDF_Master.Model; using PDF_Master.Model.HomePageToolsDialogs; using PDF_Master.Model.PageEdit; using PDF_Master.Properties; using PDFReader_WPF.Helper; using Prism.Commands; using Prism.Events; using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using WIA; using static PDF_Master.Model.Dialog.ToolsDialogs.SaftyDialogs.DeleteSafetySettintgsModel; namespace PDF_Master.ViewModels.PageEdit { public class PageEditContentViewModel : BindableBase, INavigationAware { #region 文案 private string T_title; public string T_Title { get { return T_title; } set { SetProperty(ref T_title, value); } } private string T_rotateLeftToolTip; public string T_RotateLeftToolTip { get { return T_rotateLeftToolTip; } set { SetProperty(ref T_rotateLeftToolTip, value); } } private string T_rotateRightToolTip; public string T_RotateRightToolTip { get { return T_rotateRightToolTip; } set { SetProperty(ref T_rotateRightToolTip, value); } } private string T_deleteToolTip; public string T_DeleteToolTip { get { return T_deleteToolTip; } set { SetProperty(ref T_deleteToolTip, value); } } private string T_deleteLook = ""; public string T_DeleteLook { get { return T_deleteLook; } set { SetProperty(ref T_deleteLook, value); } } private string t_Insert; public string T_Insert { get { return t_Insert; } set { SetProperty(ref t_Insert, value); } } private string t_InsertFile; public string T_InsertFile { get { return t_InsertFile; } set { SetProperty(ref t_InsertFile, value); } } private string t_InsertaBlankPage; public string T_InsertaBlankPage { get { return t_InsertaBlankPage; } set { SetProperty(ref t_InsertaBlankPage, value); } } private string t_InsertaCustomPage; public string T_InsertaCustomPage { get { return t_InsertaCustomPage; } set { SetProperty(ref t_InsertaCustomPage, value); } } private string t_Extract; public string T_Extract { get { return t_Extract; } set { SetProperty(ref t_Extract, value); } } private string t_Replace; public string T_Replace { get { return t_Replace; } set { SetProperty(ref t_Replace, value); } } private string t_Split; public string T_Split { get { return t_Split; } set { SetProperty(ref t_Split, value); } } private string t_InsertPage; public string T_InsertPage { get { return t_InsertPage; } set { SetProperty(ref t_InsertPage, value); } } private string t_Reverse; public string T_Reverse { get { return t_Reverse; } set { SetProperty(ref t_Reverse, value); } } private string t_ExtractPage; public string T_ExtractPage { get { return t_ExtractPage; } set { SetProperty(ref t_ExtractPage, value); } } private string t_ReplacePage; public string T_ReplacePage { get { return t_ReplacePage; } set { SetProperty(ref t_ReplacePage, value); } } private void InitString() { T_InsertFile = App.MainPageLoader.GetString("PageEdit_Insert"); T_Insert = App.MainPageLoader.GetString("PageEdit_InsertFile"); T_InsertaBlankPage = App.MainPageLoader.GetString("PageEdit_InsertaBlankPage"); T_InsertaCustomPage = App.MainPageLoader.GetString("PageEdit_InsertaCustomPage"); T_Extract = App.MainPageLoader.GetString("PageEdit_Extract"); T_Replace = App.MainPageLoader.GetString("PageEdit_Replace"); T_Split = App.MainPageLoader.GetString("PageEdit_Split"); T_InsertPage = App.MainPageLoader.GetString("PageEdit_InsertPage"); T_Reverse = App.MainPageLoader.GetString("PageEdit_Reverse"); T_ExtractPage = App.MainPageLoader.GetString("PageEdit_ExtractPage"); T_ReplacePage = App.MainPageLoader.GetString("PageEdit_ReplacePage"); T_Title = App.MainPageLoader.GetString("Thumbnails_Title"); T_DeleteToolTip = App.MainPageLoader.GetString("ToolTipsPageEdit_Delete"); T_DeleteLook = App.MainPageLoader.GetString("T_DeleteLook"); T_RotateRightToolTip = App.MainPageLoader.GetString("ToolTipsPageEdit_RotateRight"); T_RotateLeftToolTip = App.MainPageLoader.GetString("ToolTipsPageEdit_RotateLeft"); } #endregion 文案 public CPDFViewer PDFViewer; public PageEditItem CurrentPageEditItem = null; public ViewContentViewModel viewContentViewModel; private IDialogService dialogs; private IEventAggregator eventor; /// /// 用于筛选多窗体时间的唯一识别码 /// private string unicode = null; /// /// 项数据集合 /// public ObservableCollection PageEditItems { get; set; } /// /// 页面范围的项集合 /// public ObservableCollection PageRangeItems { get; set; } #region 属性 /// /// 判断是否是添加页面 /// public bool IsAddPages { get; set; } = false; /// /// 增加两个变量,用于记录当前控件内已经刷新图片的索引值,用于显示页面尺寸大小时,先显示当前范围可见Item的页面尺寸 /// private int startRefreshedIndex = 0; private int endRefreshedIndex = 0; /// /// 正在初始化(正在初始化过程中 不发布通知BOTA刷新的事件) /// public bool Initializing = false; /// /// 是否是第一次加载 /// private bool isFirstLoad = true; /// /// 记录多选项中最后一项的索引 /// public int maxSelectedIndex = -1; private Visibility showTip = Visibility.Collapsed; /// /// 是否显示渐隐提示 /// public Visibility ShowTip { get { return showTip; } set { SetProperty(ref showTip, value); } } private Visibility isLoading = Visibility.Collapsed; /// /// 是否正在处理中 /// public Visibility IsLoading { get { return isLoading; } set { SetProperty(ref isLoading, value); } } private int listSelecedIndex; /// /// 缩略图选中项的索引 /// public int ListSelectedIndex { get { return listSelecedIndex; } set { SetProperty(ref listSelecedIndex, value); if (!IsSelectFormSelf && value >= 0) { //显示页面范围选择控件 TxtPageInputVisibility = Visibility.Visible; TbPageRange = (ListSelectedIndex + 1).ToString(); } } } /// ///右键不会选中页面, 不要跳转 /// /// 判断是否是右键选择 private bool isMouseRightButtonDown = false; public bool IsMouseRightButtonDown { get { return isMouseRightButtonDown; } set { SetProperty(ref isMouseRightButtonDown, value); } } /// /// 右键选择索引 /// public int RightSelectedIndex = 0; /// /// 右键选择 集合 /// public List RightSelectedIndexs = new List(); /// /// 多选 /// private bool isMultiSelected; /// /// 是否有多选 用于判断倒序和替换功能 /// public bool IsMultiSelected { get { return isMultiSelected; } set { SetProperty(ref isMultiSelected, value); } } private int comboxSelectIndex; /// /// 下拉框选项集合 /// public int ComboxSelectIndex { get { return comboxSelectIndex; } set { SetProperty(ref comboxSelectIndex, value); //隐藏tb页面范围显示控件 TxtPageInputVisibility = Visibility.Collapsed; //选中指定的页面范围 SuitPageRange(comboxSelectIndex); } } private Visibility tbPageRangeVisibility = Visibility.Visible; /// /// 页面范围的文本显示 /// public Visibility TbPageRangeVisibility { get { return tbPageRangeVisibility; } set { SetProperty(ref tbPageRangeVisibility, value); if (value == Visibility.Visible) { comboxSelectIndex = -1; } } } private string tbPageRange; /// /// 页面范围显示的内容 /// public string TbPageRange { get { return tbPageRange; } set { SetProperty(ref tbPageRange, value); } } private Visibility txtPageInputVisibility = Visibility.Collapsed; /// /// 页面自定义输入框的显示 /// public Visibility TxtPageInputVisibility { get { return txtPageInputVisibility; } set { SetProperty(ref txtPageInputVisibility, value); } } /// /// 页面缩放状态,-1 为最小值,1为最大值 /// private int zoomIndex = 0; public int ZoomIndex { get { return zoomIndex; } set { SetProperty(ref zoomIndex, value); } } private string toastText = App.MainPageLoader.GetString("PageEdit_Failed"); /// /// Toast提示 /// public string ToastText { get { return toastText; } set { SetProperty(ref toastText, value); } } private Visibility isBOTAThumb = Visibility.Collapsed; /// /// 是否是BOTA侧边栏的缩略图 /// public Visibility IsBOTAThumb { get { return isBOTAThumb; } set { SetProperty(ref isBOTAThumb, value); } } private Visibility showedPageSize = Visibility.Collapsed; /// /// 显示页面尺寸 /// public Visibility ShowedPageSize { get { return showedPageSize; } set { SetProperty(ref showedPageSize, value); //if (IsBOTAThumb != Visibility.Visible) //{ // if (value == Visibility.Visible) // { // HidePageSize = Visibility.Collapsed; // } // else // { // HidePageSize = Visibility.Visible; // } //} } } private Visibility hidePageSize = Visibility.Collapsed; /// /// 隐藏页面尺寸 /// public Visibility HidePageSize { get { return hidePageSize; } set { SetProperty(ref hidePageSize, value); } } private bool canPaste = false; /// /// 是否可以粘贴 /// public bool CanPaste { get { return canPaste; } set { SetProperty(ref canPaste, value); } } /// /// 页面缩放的范围 /// private List ItemSizes = new List() { new Size(104,142), new Size(208, 294), new Size(312,441) }; //选中的页面集合 private List selectedPageList = new List(); /// /// 是否是下拉框选项改变引起的选项变更事件 /// private bool IsSelectFormSelf = false; public bool IsShowPageSize = false; public string Txt = Properties.Resources.txtex; public string Word = Properties.Resources.wordex; public string Ppt = Properties.Resources.pptex; public string Excel = Properties.Resources.excelex; public string Html = Properties.Resources.htmlex; public string Image = Properties.Resources.imageex; public string Pdf = Properties.Resources.pdf; #endregion 属性 #region 命令 public DelegateCommand SelectionChangedCommand { get; set; } /// /// 拦截键盘输入的事件 /// public DelegateCommand PreviewKeyDown { get; set; } /// /// 粘贴 /// public DelegateCommand PasteCommand { get; set; } /// /// 复制 /// public DelegateCommand CopyCommand { get; set; } /// /// 剪切 /// public DelegateCommand CutCommand { get; set; } /// /// 替换文件 /// public DelegateCommand ReplaceCommand { get; set; } /// /// 插入文件命令 /// public DelegateCommand InsertCommand { get; set; } /// /// 拆分文件 /// public DelegateCommand SplitCommand { get; set; } /// /// 提取文件 /// public DelegateCommand ExtractCommand { get; set; } /// /// 逆时针旋转 /// public DelegateCommand LeftRotateCommand { get; set; } /// /// 顺时针旋转 /// public DelegateCommand RightRotateCommand { get; set; } /// /// 删除 /// public DelegateCommand DeleteCommand { get; set; } /// /// 倒序 /// public DelegateCommand ReverseCommand { get; set; } /// /// 放大 /// public DelegateCommand ZoomInCommand { get; set; } /// /// 缩小 /// public DelegateCommand ZoomOutCommand { get; set; } /// /// 显示页面大小 /// public DelegateCommand ShowPageSizeCommand { get; set; } public DelegateCommand ClearSelectedCommand { get; set; } /// /// 进入页面编辑 /// public DelegateCommand EnterPageEditCommand { get; set; } #endregion 命令 public PageEditContentViewModel(IDialogService dialogService, IEventAggregator eventAggregator) { //变量初始化 dialogs = dialogService; eventor = eventAggregator; unicode = App.mainWindowViewModel.SelectedItem.Unicode; PageEditItems = new ObservableCollection(); PageRangeItems = new ObservableCollection(); //绑定命令 SelectionChangedCommand = new DelegateCommand(SelectionChangedEvent); PreviewKeyDown = new DelegateCommand(PreviewKeyDownEvent); SplitCommand = new DelegateCommand(SplitCommandEvent); InsertCommand = new DelegateCommand(InsertCommandEvent); ReplaceCommand = new DelegateCommand(ReplaceCommandEvent, CanFileCommandExcute).ObservesProperty(() => IsMouseRightButtonDown); ExtractCommand = new DelegateCommand(ExtractCommandEvent, CanFileCommandExcute).ObservesProperty(() => IsMouseRightButtonDown); DeleteCommand = new DelegateCommand(DeleteCommandEvent, CanFileCommandExcute).ObservesProperty(() => IsMouseRightButtonDown); LeftRotateCommand = new DelegateCommand(LeftRotateCommandEvent, CanFileCommandExcute).ObservesProperty(() => IsMouseRightButtonDown); RightRotateCommand = new DelegateCommand(RightRotateCommandEvent, CanFileCommandExcute).ObservesProperty(() => IsMouseRightButtonDown); ReverseCommand = new DelegateCommand(ReverseCommandEvent, CanReverseFileCommandExcute).ObservesProperty(() => IsMultiSelected); ZoomInCommand = new DelegateCommand(ZoomInCommandEvent, CanZoomIn).ObservesProperty(() => ZoomIndex); ZoomOutCommand = new DelegateCommand(ZoomOutCommandEvent, CanZoomOut).ObservesProperty(() => ZoomIndex); ShowPageSizeCommand = new DelegateCommand(ShowPageSize); CopyCommand = new DelegateCommand(copy); PasteCommand = new DelegateCommand(() => { Paste(); }, CanPasteExcute).ObservesProperty(() => CanPaste); CutCommand = new DelegateCommand(cut); ClearSelectedCommand = new DelegateCommand(clearSelected); EnterPageEditCommand = new DelegateCommand(enterpageeditr); //订阅页面刷新事件 eventAggregator.GetEvent().Subscribe(OnPageEditRefreshEvent, e => e.Unicode == unicode); eventAggregator.GetEvent().Subscribe(ViewContentChangedEvent, e => e.Unicode == unicode); CacheFilePath.Instance.PropertyChanged += Instance_PropertyChanged; RefreshPageRangeItem(); InitString(); } #region 事件 private void ViewContentChangedEvent(ViewContentEventArgs obj) { //只有在缩略图模式下响应刷新,进入页面编辑时 会刷新可见范围内图片,不需要响应这个事件 if (IsBOTAThumb == Visibility.Visible) { PageEditItems[PDFViewer.CurrentIndex].IsGetImage = false; PageEditItems[PDFViewer.CurrentIndex].Size = PDFViewer.Document.GetPageSize(PDFViewer.CurrentIndex); RefreshItemImage(PDFViewer.CurrentIndex, PDFViewer.CurrentIndex); } } /// /// 进入页面编辑 /// private void enterpageeditr() { viewContentViewModel.EnterPageEdit(); } private void Instance_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "CopyDoc") { if (CacheFilePath.Instance.CopyDoc != null) { CanPaste = true; } } } /// /// 替换功能的逻辑 /// 实现效果是,先删除后插入 /// 跨页多选后替换的位置是多选的第一页位置 /// private async void ReplaceCommandEvent() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Replace); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Replace"); //支持插入格式:PDF、图片、Office格式文件 string allfiles = Pdf + Txt + Word + Excel + Ppt + Image + Html; OpenFileDialog dialog = new OpenFileDialog(); //dialog.Multiselect = false; //dialog.Filter = PDF_Master.Properties.Resources.OpenDialogFilter; dialog.Filter = string.Format($"Files({allfiles.Replace(";", ",")}|{allfiles})|" + $"PDF({Pdf})|{Pdf}|" + $"Microsoft Office Word({Word})|{Word}|" + $"Microsoft Office Excel({Excel})|{Excel}|" + $"Microsoft Office PowerPoint({Ppt})|{Ppt}|" + $"Txt({Txt})|{Txt}|" + $"Picture({Image})|{Image}|" + $"Html({Html})|{Html}" ); List indexList = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { indexList.Add(i); } } //因为虚拟化 可能获取不到所有选中项的页码 需要结合选中项的集合判断一下 if (selectedPageList.Count > 0 && selectedPageList.Count > indexList.Count) { indexList = new List(); for (int j = 0; j < selectedPageList.Count; j++) { indexList.Add(selectedPageList[j] - 1); } } indexList.Sort(); //全选页面 提示不能全选,230711不要提示 //if (indexList.Count > 0 && indexList.Count == PDFViewer.Document.PageCount) //{ // AlertsMessage alertsMessage = new AlertsMessage(); // alertsMessage.ShowDialog("", App.MainPageLoader.GetString("PageEdit_DeleteAllPage"), App.ServiceLoader.GetString("Text_ok")); // return; //} if ((bool)dialog.ShowDialog()) { //付费锁 if (!ServiceHelper.IAPBeforeFunction()) { return; } IsLoading = Visibility.Visible; await Task.Delay(200); int pageCount = PDFViewer.Document.PageCount; int insertIndex = listSelecedIndex; string fileName = GetInsertFromFile(dialog.FileName); #region 历史版本 //从文件插入到指定位置 //var result = await InsertFromFile(listSelecedIndex + 1, fileName); //if (result) //{ // //插入成功后再删除原有页面 // //2023-06-05 索引需要-1,因为上面的listSelecedIndex + 1,需要还原 // //DoRemoveSelectedPages(new List() { ListSelectedIndex - 1 }); // DoRemoveSelectedPages(indexList); //} #endregion 历史版本 //先记录索引(第一个选定页面) int index = ListSelectedIndex; if (IsMouseRightButtonDown) { index = RightSelectedIndex; if (IsMultiSelected) { indexList = RightSelectedIndexs; } else { indexList = new List { index }; } } //替换页面 先看文件是否加密,如果加密,先解密后,再替换 //将文档验证是否为空,是否解密,置前,若为空直接退出 bool isDiscryptied = GetDocumentIsDiscryptied(fileName, null, out CPDFDocument doc, out string password); if (isDiscryptied) { //先删除 int flag = DoRemoveSelectedPages(indexList, false, true); if (flag == -1) { return; } if (PDFViewer.Document.PageCount == 0) { index = 0; } //再新增,避免索引串号的情况 var result = await InsertFromFile(index, fileName, doc, password); if (result) { ReloadAfterOption(true, false, Tuple.Create(insertIndex - 1, insertIndex + pageCount)); } } IsLoading = Visibility.Collapsed; } } /// /// 拆分功能的逻辑 /// private void SplitCommandEvent() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Split); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Split"); DialogParameters valuePairs = new DialogParameters(); valuePairs.Add(ParameterNames.PDFViewer, PDFViewer); valuePairs.Add(ParameterNames.PageEditSelectedIndex, ListSelectedIndex); valuePairs.Add(ParameterNames.PageEditSelectedItems, TbPageRange); dialogs.ShowDialog(DialogNames.SplitDialog, valuePairs, e => { if (e.Result == ButtonResult.OK && e.Parameters != null) { //付费锁 if (!ServiceHelper.IAPBeforeFunction()) { return; } //保存并继续,使用了高级功能则弹窗权益弹窗 if (!viewContentViewModel.saveFile(true)) { return; } var model = e.Parameters.GetValue(ParameterNames.DataModel); DoSplitPages(model); } }); } /// /// 提取功能的逻辑 /// private void ExtractCommandEvent() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Extract); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Extract"); DialogParameters keyValuePairs = new DialogParameters(); //因无法删除所有页面,若选中所有页面提取,则需要将「提取后删除页面」复选项置灰 if (selectedPageList.Count == PageEditItems.Count) { keyValuePairs.Add(ParameterNames.IsDeleteAfterExtract, false); } else { keyValuePairs.Add(ParameterNames.IsDeleteAfterExtract, true); } dialogs.ShowDialog(DialogNames.ExtractDialog, keyValuePairs, e => { if (e.Result == ButtonResult.OK && e.Parameters != null) { //付费锁 if (!ServiceHelper.IAPBeforeFunction()) { return; } //保存并继续,使用了高级功能则弹窗权益弹窗 if (!viewContentViewModel.saveFile(true)) { return; } var model = e.Parameters.GetValue(ParameterNames.DataModel); DoExtractPages(model.IsEveryPageToFile, model.IsDeleteAfterExtract); } }); } /// /// 插入功能的逻辑 /// private async void InsertCommandEvent(object type) { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Insert); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Insert"); if ((string)type == null) { return; } int pageIndex = 0; if (IsMouseRightButtonDown) { pageIndex = RightSelectedIndex; } else { pageIndex = ListSelectedIndex; } //获取插入位置 int insertIndex = 0; if (pageIndex < 0) { insertIndex = PageEditItems.Count; } else { insertIndex = pageIndex + 1; if (insertIndex >= PDFViewer.Document.PageCount) { insertIndex = PDFViewer.Document.PageCount; } if (isMultiSelected && maxSelectedIndex != -1) { insertIndex = maxSelectedIndex + 1; } } IsLoading = Visibility.Visible; await System.Threading.Tasks.Task.Delay(3); PageEditHistory history = new PageEditHistory(); history.InsertIndex = insertIndex; #region 插入空白页面 if ((string)type == ParameterNames.InsertType_Blank) { //付费锁 if (!ServiceHelper.IAPBeforeFunction()) { return; } history.Type = ActionType.InsertCustomPages; history.InsertFilePath = ""; //插入空白页面 bool result; if (insertIndex == 0) { result = PDFViewer.Document.InsertPage(insertIndex, PageEditItems[insertIndex].Size.Width, PageEditItems[insertIndex].Size.Height, null); history.PageSize = PageEditItems[insertIndex].Size; } else { result = PDFViewer.Document.InsertPage(insertIndex, PageEditItems[insertIndex - 1].Size.Width, PageEditItems[insertIndex - 1].Size.Height, null); history.PageSize = PageEditItems[insertIndex - 1].Size; } if (!result) { IsLoading = Visibility.Collapsed; ShowToast(); return; } //UI层插入Item var item = GetNewPageEditItem(insertIndex); PageEditItems.Insert(insertIndex, item); //插入后 滚动到 选中的页面 ReloadAfterOption(true, false, Tuple.Create(0, insertIndex + 1), true); await Task.Delay(10); //选中插入的页面 ListSelectedIndex = insertIndex; } #endregion 插入空白页面 #region 插入文件 else if ((string)type == ParameterNames.InsertType_File) { //支持插入格式:PDF、图片、Office格式文件 string allfiles = Pdf + Txt + Word + Excel + Ppt + Image + Html; OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = false; dialog.Filter = string.Format($"Files({allfiles.Replace(";", ",")}|{allfiles})|" + $"PDF({Pdf})|{Pdf}|" + $"Microsoft Office Word({Word})|{Word}|" + $"Microsoft Office Excel({Excel})|{Excel}|" + $"Microsoft Office PowerPoint({Ppt})|{Ppt}|" + $"Txt({Txt})|{Txt}|" + $"Picture({Image})|{Image}|" + $"Html({Html})|{Html}" ); //OpenFileDialog dialog = new OpenFileDialog(); //dialog.Multiselect = false; //dialog.Filter = PDF_Master.Properties.Resources.OpenDialogFilter; if ((bool)dialog.ShowDialog()) { //付费锁 if (!ServiceHelper.IAPBeforeFunction()) { return; } string fileName = GetInsertFromFile(dialog.FileName); //将文档验证是否为空,是否解密,置前,若为空直接退出 bool IsLocked = GetDocumentIsDiscryptied(fileName, null, out CPDFDocument doc, out string password); if (IsLocked == false) { return; } //ToolMethod.SetFileThumbImg(fileName); //插入文件 var result = await InsertFromFile(insertIndex, fileName, doc, password); if (!result) { IsLoading = Visibility.Collapsed; ShowToast(); return; } ReloadAfterOption(true, false, Tuple.Create(0, PDFViewer.Document.PageCount)); } IsLoading = Visibility.Collapsed; //里面附带了Undo栈记录,需要提前返回,避免重复记录 return; } #endregion 插入文件 #region 插入自定义页面 else { DialogParameters keyValuePairs = new DialogParameters(); Size size = new Size(); size.Width = CommonHelper.GetUnitsFromPageSize(PDFViewer.Document.GetPageSize(listSelecedIndex).Width); size.Height = CommonHelper.GetUnitsFromPageSize(PDFViewer.Document.GetPageSize(listSelecedIndex).Height); keyValuePairs.Add(ParameterNames.CurrentPageSize, size); keyValuePairs.Add(ParameterNames.PageEditSelectedIndex, pageIndex); //int o = ListSelectedIndex; //插入自定义页面 dialogs.ShowDialog(DialogNames.InsertDialog, keyValuePairs, e => { if (e.Result == ButtonResult.OK && e.Parameters != null) { //付费锁 if (!ServiceHelper.IAPBeforeFunction()) { return; } var model = e.Parameters.GetValue(ParameterNames.DataModel); var result = InsertFromCustomPage(insertIndex, model.width, model.height, model.filepath); if (!result) { return; } history.Type = ActionType.InsertCustomPages; history.InsertFilePath = model.filepath; history.PageSize = new Size(model.width, model.height); } }); } #endregion 插入自定义页面 IsLoading = Visibility.Collapsed; //添加记录到Undo栈,清除Redo栈 history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); } public string GetInsertFromFile(string file) { var fileType = System.IO.Path.GetExtension(file).ToLower(); string fileName = string.Empty; if (Pdf.Contains(fileType)) { fileName = file; } else if (Image.Contains(fileType)) { fileName = GetImageFile(file); } else { fileName = GetOfficeFile(file); } if (string.IsNullOrEmpty(fileName)) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("ErrorFile_Warning"), App.ServiceLoader.GetString("Text_ok")); IsLoading = Visibility.Collapsed; return fileName; } if (File.Exists(fileName) == false) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("ErrorFile_Warning"), App.ServiceLoader.GetString("Text_ok")); IsLoading = Visibility.Collapsed; return fileName; } return fileName; } private string GetOfficeFile(string sourcepath, Microsoft.Office.Interop.Word.WdPaperSize paperSize = Microsoft.Office.Interop.Word.WdPaperSize.wdPaperA4, double margin = 0) { try { string fileName = null; CPDFViewer pDFViewer = new CPDFViewer(); pDFViewer.CreateDocument(); string targetPath = ""; targetPath = ConverterHelper.ConvertOfficeToPDF(sourcepath, paperSize, margin); if (pDFViewer.Document == null) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("Create PDF failed"), App.ServiceLoader.GetString("Text_ok")); return null; } string file1 = sourcepath.Substring(sourcepath.LastIndexOf("\\") + 1, sourcepath.LastIndexOf(".") - sourcepath.LastIndexOf("\\") - 1) + ".pdf"; var tempdoc = CPDFDocument.InitWithFilePath(targetPath); if (tempdoc == null) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("Create PDF failed"), App.ServiceLoader.GetString("Text_ok")); return null; } pDFViewer.Document.ImportPages(tempdoc, ""); string tempfile = CacheFilePath.Instance.CreatedFilePath; fileName = CommonHelper.CreateFilePath(Path.Combine(tempfile, App.UntitledFileNmae)); pDFViewer.Document.WriteToFilePath(fileName); pDFViewer.CloseDocument(); pDFViewer.InitDocument(fileName); return fileName; } catch { string str = "没有安装"; //判断是否有安装office软件 var officeType = Type.GetTypeFromProgID("Word.Application"); if (officeType == null) { str += "Word;"; } officeType = Type.GetTypeFromProgID("Excel.Application"); if (officeType == null) { str += "Excel;"; } officeType = Type.GetTypeFromProgID("Powerpoint.Application"); if (officeType == null) { str += "Excel;"; } AlertsMessage alertsMessage = new AlertsMessage(); if (str != "没有安装") { alertsMessage.ShowDialog("", App.MainPageLoader.GetString("NoOffice_Warning"), App.ServiceLoader.GetString("Text_ok")); } else { alertsMessage.ShowDialog("", App.MainPageLoader.GetString("CreateFileFailedWarning"), App.ServiceLoader.GetString("Text_ok")); } return null; } } private string GetImageFile(string fileName) { CPDFViewer pDFViewer = new CPDFViewer(); pDFViewer.CreateDocument(); string path = fileName.Substring(fileName.LastIndexOf("\\") + 1, fileName.LastIndexOf(".") - fileName.LastIndexOf("\\") - 1) + ".pdf"; System.Drawing.Bitmap pic = new System.Drawing.Bitmap(fileName); int width = pic.Size.Width; int height = pic.Size.Height; string ex = System.IO.Path.GetExtension(fileName); //其他格式或者名称中含空格的图片 在本地先转存一下 if ((ex != ".jpg" && ex != ".jpeg") || !Uri.IsWellFormedUriString(fileName, UriKind.Absolute)) { //将其他格式图片转换成jpg string folderPath = Path.GetTempPath(); if (File.Exists(folderPath)) { File.Delete(folderPath); } DirectoryInfo tempfolder = new DirectoryInfo(folderPath); if (!tempfolder.Exists) { tempfolder.Create(); } string targetPath = System.IO.Path.Combine(folderPath, Guid.NewGuid().ToString()); fileName = targetPath; pic.Save(targetPath, System.Drawing.Imaging.ImageFormat.Jpeg); } pic.Dispose(); var result = pDFViewer.Document.InsertPage(0, width, height, fileName); if (!result) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("Create PDF failed"), App.ServiceLoader.GetString("Text_ok")); return null; } string tempfile = CacheFilePath.Instance.CreatedFilePath; string file = CommonHelper.CreateFilePath(Path.Combine(tempfile, App.UntitledFileNmae)); pDFViewer.Document.WriteToFilePath(file); pDFViewer.CloseDocument(); pDFViewer.InitDocument(file); return file; } /// /// 删除选中页面 /// private async void DeleteCommandEvent() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Delete); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Delete"); AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", T_DeleteLook, App.ServiceLoader.GetString("Text_no"), App.ServiceLoader.GetString("Text_ok")); if (alertsMessage.result == ContentResult.Ok) { IsLoading = Visibility.Visible; await Task.Delay(3); int pageIndex = 0; int index = 0; if (IsMouseRightButtonDown) { int count = RightSelectedIndexs.Count; pageIndex = RightSelectedIndex; if (IsMultiSelected) { index = DoRemoveSelectedPages(RightSelectedIndexs); } else { index = DoRemoveSelectedPages(new List { pageIndex }); } } else { index = DoRemoveSelectedPages(); } //删除后 选中项 if (index != -1) { if (index <= PDFViewer.Document.PageCount) { index = index + 1; } } else { index = 0; } if (IsBOTAThumb == Visibility.Visible) { GoToPage(new List() { index }); } ReloadAfterOption(true, true, Tuple.Create(0, PDFViewer.Document.PageCount)); //通知Xaml删除后 选中的页面,从VM设置选中项会有问题 NotifyUIToRefresh(new List() { index }); IsLoading = Visibility.Collapsed; } } /// /// 左旋转页面的逻辑 /// private void LeftRotateCommandEvent() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Rotate); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Rotate"); List pageitems = new List(); if (IsMouseRightButtonDown) { if (IsMultiSelected) { pageitems.AddRange(RightSelectedIndexs); } else { pageitems.Add(RightSelectedIndex); } RotateSelectedPages(false, pageitems); } else { RotateSelectedPages(false); } } /// /// 右旋转页面的逻辑 /// private void RightRotateCommandEvent() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Rotate); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Rotate"); List pageitems = new List(); if (IsMouseRightButtonDown) { if (IsMultiSelected) { pageitems.AddRange(RightSelectedIndexs); } else { pageitems.Add(RightSelectedIndex); } RotateSelectedPages(true, pageitems); } else { RotateSelectedPages(); } } /// /// 页面倒序的逻辑 /// private async void ReverseCommandEvent() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Reverse); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Reverse"); IsLoading = Visibility.Visible; await Task.Delay(3); List pages = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { pages.Add(i); } } DoReverse(pages); IsLoading = Visibility.Collapsed; } /// /// 将指定页面结合进行倒序 /// private async void DoReverse(List pages, bool isFromUndoRedo = false) { if (pages.Count <= 1) { ShowToast("请至少选择两个图片进行倒序操作。"); return; } //付费锁 if (!ServiceHelper.IAPBeforeFunction()) { return; } pages.Sort(); //记录原位置和目标位置 用于undo,redo Dictionary sourceTarget = new Dictionary(); for (int i = 0; i < pages.Count; i++) { int preindex = pages[i]; int laterIndex = pages[pages.Count - i - 1];//尾部的索引 if (laterIndex <= preindex)//交换完成 { //用于记录选中集合为奇数时,最中间Item的还原 sourceTarget.Add(preindex, preindex); break; } var result = ExchangeItem(preindex, laterIndex); if (!result) { ShowToast(); IsLoading = Visibility.Collapsed; return; } sourceTarget.Add(preindex, laterIndex); } await Task.Delay(20); //转换成页码数据集合,传递给UI,选中目标页面 //因虚拟化加载的问题,通过Selected来控制Item选中效果会有问题 List pageRange = new List(); for (int i = 0; i < pages.Count; i++) { pageRange.Add(pages[i] + 1); } NotifyUIToRefresh(pageRange); ReloadAfterOption(true, false, null); if (!isFromUndoRedo) { PageEditHistory history = new PageEditHistory(); history.Type = ActionType.Reverse; history.SourceTargetValue = sourceTarget; history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); } } /// /// 交换两个Item顺序 /// /// /// /// private bool ExchangeItem(int preiIndex, int laterIndex) { if (preiIndex == laterIndex) { return true; } var sourceitem = PageEditItems[preiIndex]; var targetitem = PageEditItems[laterIndex]; var result = PDFViewer.Document.ExchangePage(preiIndex, laterIndex); if (!result) { return false; } PageEditItems.Remove(sourceitem); PageEditItems.Remove(targetitem); PageEditItems.Insert(preiIndex, targetitem); PageEditItems.Insert(laterIndex, sourceitem); return true; } /// /// 是否可以执行文件操作命令 除插入、拆分外 /// /// private bool CanFileCommandExcute() { //增加是否有选中多页的判断 //修复问题:全选页面后,ctrl取消第一页的选中时,其余操作会因为ListSelectedIndex为-1被禁用的问题 if (IsMouseRightButtonDown) { if (RightSelectedIndex < 0 && !IsMultiSelected) { return false; } else { return true; } } else { if (ListSelectedIndex < 0 && !IsMultiSelected) { return false; } else { return true; } } } private bool CanReverseFileCommandExcute() { if (IsMouseRightButtonDown) { if (RightSelectedIndex >= 0 && IsMultiSelected) { return true; } else { return false; } } else { if (ListSelectedIndex >= 0 && IsMultiSelected) { return true; } else { return false; } } } /// /// 校验是否可以替换 /// /// private bool CanReplaceCommandExcute() { //return !IsMultiSelected; return true; } /// /// 放大页面 /// private void ZoomInCommandEvent() { ZoomIndex++; ChangeItemSize(ItemSizes[ZoomIndex + 1]); NotifyUIToRefresh(); } /// /// 缩小页面 /// private async void ZoomOutCommandEvent() { ZoomIndex--; ChangeItemSize(ItemSizes[ZoomIndex + 1]); //增加一定延时,计算页面显示范围时,用新的尺寸进行计算 await Task.Delay(3); NotifyUIToRefresh(); } /// /// /// /// public void ChangeItemSize(Size newsize) { for (int i = 0; i < PageEditItems.Count; i++) { PageEditItems[i].ItemSize = newsize; } RefreshPageNum(); List indexList = GetSelectedItemPageNumbers(); if (indexList.Count > 0) { //选中项集合 也需要 同步更新 selectedPageList.Clear(); selectedPageList.AddRange(indexList); } if (selectedPageList.Count > 0) { //缩略图模式 调整item大小的时候,更新选中项 //如果注释掉,调整BOTA宽度后,缩略图视图中不会显示选中项 if (selectedPageList.Count < 1) { NotifyUIToRefresh(new List() { PDFViewer.CurrentIndex + 1 }); } else { NotifyUIToRefresh(selectedPageList); } } } private bool CanZoomIn() { if (ZoomIndex >= 1) { return false; } else { return true; } } private bool CanZoomOut() { if (ZoomIndex <= -1) { return false; } else { return true; } } /// /// 响应UI发送刷新图片的事件 /// /// private void OnPageEditRefreshEvent(PageEditRefreshEventArgs e) { //UI发送事件过来通知刷新图片时 //调整逻辑,前后预加载5页 RefreshItemImage(e.PageRange.Item1 - 2, e.PageRange.Item2 + 2); } /// /// 选项改变事件 /// 虚拟化的时候不会触发选中事件 /// /// private void SelectionChangedEvent(object e) { if (IsSelectFormSelf) { //避免频繁的触发该事件 return; } var args = e as SelectionChangedEventArgs; //下下策 从UI控件获取所有选项的集合 var listbox = args.OriginalSource as ListBox; if (args != null) { selectedPageList = new List(); for (int i = 0; i < listbox.SelectedItems.Count; i++) { if (!selectedPageList.Contains((listbox.SelectedItems[i] as PageEditItem).PageNumber)) { selectedPageList.Add((listbox.SelectedItems[i] as PageEditItem).PageNumber); } } ////根据选中的范围 适配全部页面范围、奇数页面范围等 //if (pagelist.Count == PageEditItems.Count) //{ // ComboxSelectIndex = 0; // return; //} //只选中单个页面是,listselectedIndex 更准确 if (selectedPageList.Count == 1) { TbPageRange = (listSelecedIndex + 1).ToString(); //缩放 平移移动页面,页面大小出现不全的问题 listbox.ScrollIntoView(listbox.SelectedItems[0]); //需要刷新 startRefreshIndex 、endRefreshedIndex //这个方法 会有串联地方,然后不起作用 //NotifyUIToRefresh(); //保险起见,暂时只能用这个方法 if (listbox != null) { var itemSize = new Size((listbox.Items[0] as PageEditItem).ItemSize.Width + 32, (listbox.Items[0] as PageEditItem).ItemSize.Height + 30); Tuple range = (Tuple)GetRoughFromView(listbox, itemSize, new Thickness(5, 10, 5, 10)); //RefreshItemImage(range.Item1, range.Item2); startRefreshedIndex = range.Item1; endRefreshedIndex = range.Item2; } } else { //根据选中的页面转换成1,3-10类似的字符串 string pageparm = CommonHelper.GetPageParmFromList(selectedPageList); TbPageRange = pageparm; } } //Ctrl+A时让所有item选中 var isCtrlorShiftDown = ((Keyboard.IsKeyDown(Key.LeftCtrl) && Keyboard.IsKeyDown(Key.A)) || (Keyboard.IsKeyDown(Key.RightCtrl) && Keyboard.IsKeyDown(Key.A))); if (isCtrlorShiftDown) { for (int i = 0; i < PageEditItems.Count; i++) { PageEditItems[i].Selected = true; } } //判断是否有选中多项 if (listbox.SelectedItems.Count > 1) { IsMultiSelected = true; maxSelectedIndex = listbox.Items.IndexOf(listbox.SelectedItems[listbox.SelectedItems.Count - 1]); } else { IsMultiSelected = false; //非多选的时候需要重置多选页码的标志符 //否则会有多选页面复制后,粘贴位置不准确的问题 maxSelectedIndex = -1; } } private object GetRoughFromView(ListBox view, Size itemSize, Thickness itemMargin) { var scrollViewer = CommonHelper.FindVisualChild(view); if (scrollViewer == null || scrollViewer.ActualHeight == 0 || scrollViewer.ActualWidth == 0)//视图展开 return new Tuple(0, 0, 0); try { var currentHeight = scrollViewer.ActualHeight - view.Padding.Top; var currentWidth = scrollViewer.ActualWidth; //计算当前窗口大小能显示的行数和列数 var columnCount = (int)(currentWidth / (itemSize.Width + itemMargin.Left)); var rowCount = (int)Math.Ceiling(currentHeight / (itemSize.Height + itemMargin.Bottom)); var preItemCount = (int)((scrollViewer.VerticalOffset / scrollViewer.ExtentHeight) * ((view.Items.Count + columnCount - 1) / columnCount));//滑动百分比*行数 = 大概的垂直位置 preItemCount = preItemCount * columnCount; var preEnd = (int)(((scrollViewer.VerticalOffset + scrollViewer.ActualHeight) / scrollViewer.ExtentHeight) * ((view.Items.Count + columnCount - 1) / columnCount)); preEnd = preEnd * columnCount + columnCount - 1; var middle = (int)Math.Ceiling(preItemCount + preEnd / 2d); return new Tuple( Math.Max(preItemCount, 0), Math.Min(view.Items.Count, preEnd), middle); } catch { } return new Tuple(0, 0, 0); } /// /// 限制文本框输入内容 /// /// private void PreviewKeyDownEvent(object e) { var args = e as KeyEventArgs; if (args == null) { return; } ////枚举 过滤所有不合理的输入 //if (args.Key != Key.Enter && args.Key != Key.Back && args.Key != Key.OemComma && args.Key != Key.OemMinus && args.Key != Key.Subtract && !((args.Key >= Key.D0 && args.Key <= Key.D9) || (args.Key >= Key.NumPad0 && args.Key <= Key.NumPad9))) //{ // args.Handled = true; //} if (args.Key == Key.Enter) { if (PageRangeItems.Contains((args.OriginalSource as TextBox).Text)) { return; } List TargetPageIndexs = new List(); var result = CommonHelper.GetPagesInRange(ref TargetPageIndexs, (args.OriginalSource as TextBox).Text, PDFViewer.Document.PageCount, new char[] { ',', ',' }, new char[] { '-' }); if (!result) { ListSelectedIndex = -1; TbPageRange = string.Empty; AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("PageRangeWarning"), App.ServiceLoader.GetString("Text_ok")); return; } //选中输入的页面范围 List pageRange = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (TargetPageIndexs.Contains(PageEditItems[i].PageNumber - 1)) { pageRange.Add(i + 1); } } NotifyUIToRefresh(pageRange); } } /// /// 失去焦点后选中页面 /// /// public void lostfocus(object obj) { var args = obj as RoutedEventArgs; if (args == null || (args.OriginalSource as TextBox) == null) { return; } List TargetPageIndexs = new List(); if (PageRangeItems.Contains((args.OriginalSource as TextBox).Text) && ComboxSelectIndex != 5) { //选中其他项,失去焦点时不报错 return; } var result = CommonHelper.GetPagesInRange(ref TargetPageIndexs, (args.OriginalSource as TextBox).Text, PDFViewer.Document.PageCount, new char[] { ',', ',' }, new char[] { '-' }); if (!result) { ListSelectedIndex = -1; TbPageRange = string.Empty; AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("PageRangeWarning"), App.ServiceLoader.GetString("Text_ok")); return; } //选中输入的页面范围 List pageRange = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (TargetPageIndexs.Contains(PageEditItems[i].PageNumber - 1)) { pageRange.Add(i + 1); } } NotifyUIToRefresh(pageRange); } #endregion 事件 #region 方法 /// /// Esc退出多选 /// private void clearSelected() { //缩略图不支持esc取消选中; if (IsBOTAThumb == Visibility.Visible) { return; } else { ListSelectedIndex = -1; } } /// /// 调用打印机 /// public async void print(List SelectedPages) { //保存并继续,使用了高级功能则弹窗权益弹窗 if (!viewContentViewModel.saveFile(true)) { return; } if (ListSelectedIndex != -1) { await App.Current.Dispatcher.InvokeAsync(() => { PDFViewer.GoToPage(ListSelectedIndex); }); } DialogParameters printValue = new DialogParameters(); printValue.Add(ParameterNames.PDFViewer, PDFViewer); printValue.Add(ParameterNames.FilePath, PDFViewer.Document.FileName); printValue.Add(ParameterNames.PrintCurrentPage, PDFViewer.CurrentIndex); printValue.Add(ParameterNames.PageList, SelectedPages); dialogs.ShowDialog(DialogNames.HomePagePrinterDialog, printValue, e => { }); } /// /// 剪切 /// private void cut() { //没有权限时,拦截剪切操作 if (!viewContentViewModel.CheckPermissionBeforeOption()) { return; } CacheFilePath.Instance.CopyDoc = null; CacheFilePath.Instance.CopyDoc = CPDFDocument.CreateDocument(); List pages = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { pages.Add(i + 1); } } bool result = CacheFilePath.Instance.CopyDoc.ImportPages(PDFViewer.Document, String.Join(",", pages)); if (!result) { ShowToast(); return; } List pageitems = new List(); if (IsMouseRightButtonDown) { if (IsMultiSelected) { pageitems.AddRange(RightSelectedIndexs); } else { pageitems.Add(RightSelectedIndex); } DoRemoveSelectedPages(pageitems); } else { DoRemoveSelectedPages(); } ReloadAfterOption(true, true, Tuple.Create(0, PDFViewer.Document.PageCount)); } /// /// 复制 /// private void copy() { DataTrackingHelper.SetSendInformation(DataTrackingHelper.EventType.Purchase_PageEdit, DataTrackingHelper.EntryPathKeyType.SubTbr_PageEdit); DataTrackingHelper.AddFirstAndSecondaryPath(DataTrackingHelper.FirstPath.Reading, DataTrackingHelper.SecondaryPath.Copy); DataTrackingHelper.IsClearEntryPath = true; DataTrackingHelper.SendEvent(DataTrackingHelper.EventType.SubTbr_PageEdit, "SubTbr_Btn", "Btn_SubTbr_Copy"); if (!ServiceHelper.IAPBeforeFunction()) { return; } if (viewContentViewModel.CheckPermissionBeforeOption()) { int pageIndex = 0; if (IsMouseRightButtonDown) { pageIndex = RightSelectedIndex; } else { pageIndex = ListSelectedIndex; } CacheFilePath.Instance.CopyDoc?.Release(); CacheFilePath.Instance.CopyDoc = CPDFDocument.CreateDocument(); List pages = new List(); if (isMultiSelected) { //确认是多选了页面时,通过页面的选中状态获取选中页面 for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { pages.Add(i + 1); } } } else { //没有多选时,根据listbox的选中索引获取选中页面 pages.Add(pageIndex + 1); } bool result = CacheFilePath.Instance.CopyDoc.ImportPages(PDFViewer.Document, String.Join(",", pages)); if (!result) { ShowToast(); return; } } } /// /// 是否可以粘贴 /// /// private bool CanPasteExcute() { return this.CanPaste; } /// /// 粘贴 /// private void Paste(int Index = -1) { if (!ServiceHelper.IAPBeforeFunction()) { return; } int pageIndex = 0; if (IsMouseRightButtonDown) { pageIndex = RightSelectedIndex; } else { pageIndex = ListSelectedIndex; } IsLoading = Visibility.Visible; int insertindex = maxSelectedIndex > pageIndex ? maxSelectedIndex : pageIndex; insertindex++; if (Index >= 0) { insertindex = Index; } else if (pageIndex == -1) { insertindex = PageEditItems.Count; } if (CacheFilePath.Instance.CopyDoc == null) { return; } int pagecount = CacheFilePath.Instance.CopyDoc.PageCount; bool result = PDFViewer.Document.ImportPagesAtIndex(CacheFilePath.Instance.CopyDoc, "1-" + pagecount, insertindex); if (!result) { IsLoading = Visibility.Collapsed; ShowToast(); return; } //UI层插入 for (int i = 0; i < pagecount; i++) { var item = GetNewPageEditItem(i); PageEditItems.Insert(insertindex + i, item); } //加一点延时才能显示选中效果-2023.4.12,为解决卡顿问题,注释掉,注释掉未出现该选中问题 //await Task.Delay(200); List pageRange = new List(); for (int i = 0; i < pagecount; i++) { pageRange.Add(insertindex + i + 1); } PageEditHistory history = new PageEditHistory(); history.InsertIndex = insertindex; history.InsertPageCount = pagecount; history.Type = ActionType.Paste; history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); if (IsBOTAThumb == Visibility.Visible) { GoToPage(pageRange); } //刷新页码等 ReloadAfterOption(true, false, new Tuple(0, PDFViewer.Document.PageCount)); //通知Xaml选中新增的页面,从VM设置选中项会有问题 NotifyUIToRefresh(pageRange); IsLoading = Visibility.Collapsed; IsAddPages = true; } public void GoToPage(List pageRange) { int index = pageRange.Last() - 1; //跳转页面 需要写在ReloadAfterOption()之前,不然跳转失败的概率大 //插入页面需要重新加载 ,不然会有bug(bug:选中最后 一页,粘贴,跳转失败) PDFViewer.ReloadDocument(); //await Task.Delay(500); PDFViewer.GoToPage(index); } /// /// 页面编辑执行Undo操作的方法 /// public async void Undo(PageEditHistory history) { switch (history.Type) { case ActionType.RightRotate: var rightlist = history.SourceTargetValue.Keys.ToList(); RotateSelectedPages(false, rightlist, true); break; case ActionType.LeftRotate: var leftlist = history.SourceTargetValue.Keys.ToList(); RotateSelectedPages(true, leftlist, true); break; case ActionType.InsertFromFile: case ActionType.Paste: List pageList = new List(); for (int i = 0; i < history.InsertPageCount; i++) { pageList.Add(history.InsertIndex + i); } int index = DoRemoveSelectedPages(pageList, true); UndoPageOperations(index); break; case ActionType.InsertCustomPages: index = DoRemoveSelectedPages(new List { history.InsertIndex }, true); UndoPageOperations(index); break; case ActionType.DragSort: //将字典倒序后,将每个Source的值恢复到Key的位置 var SourceTargets = history.SourceTargetValue; var keys = SourceTargets.Keys.ToArray(); Array.Reverse(keys); foreach (var key in keys) { MoveItemToIndex(SourceTargets[key], key); } //刷新页码等 ReloadAfterOption(true, false, new Tuple(0, PDFViewer.Document.PageCount)); List selectedPages = new List(); //将索引集合转换成页码集合 foreach (var key in SourceTargets.Keys) { selectedPages.Add(key + 1); } //通知UI选中Item NotifyUIToRefresh(selectedPages); break; case ActionType.Reverse: //将字典倒序后,将每个Source的值恢复到Key的位置 var SourceTarget = history.SourceTargetValue; var pres = SourceTarget.Keys.ToArray(); foreach (var key in pres) { if (key != SourceTarget[key]) { ExchangeItem(key, SourceTarget[key]); } } await Task.Delay(20); //刷新页码等 ReloadAfterOption(true, false, null); List Pages = new List(); //将索引集合转换成页码集合 foreach (var key in SourceTarget.Keys) { Pages.Add(key + 1); } foreach (var key in SourceTarget.Values) { Pages.Add(key + 1); } //通知UI选中Item NotifyUIToRefresh(Pages); break; default: break; } } private void UndoPageOperations(int index) { //【页面编辑】插入页面后,undo,页码更新 ReloadAfterOption(true, false, new Tuple(0, PDFViewer.Document.PageCount)); //删除后 选中项 if (index != -1) { if (index <= PDFViewer.Document.PageCount) { index = index + 1; } } else { index = 0; } //通知Xaml删除后 选中的页面,从VM设置选中项会有问题 NotifyUIToRefresh(new List() { index }); } /// /// 页面编辑执行Redo操作的方法 /// public async void Redo(PageEditHistory history) { switch (history.Type) { case ActionType.RightRotate: var rightlist = history.SourceTargetValue.Keys.ToList(); RotateSelectedPages(true, rightlist, true); break; case ActionType.LeftRotate: var leftlist = history.SourceTargetValue.Keys.ToList(); RotateSelectedPages(false, leftlist, true); break; case ActionType.InsertFromFile: //将文档验证是否为空,是否解密,置前,若为空直接退出 bool IsLocked = GetDocumentIsDiscryptied(history.InsertFilePath, history.InsertFilePassWord, out CPDFDocument doc, out string password); if (IsLocked == false) { return; } await InsertFromFile(history.InsertIndex, history.InsertFilePath, doc, history.InsertFilePassWord, true); ReloadAfterOption(true, false, Tuple.Create(history.InsertIndex - 1, history.InsertIndex + history.InsertPageCount)); break; case ActionType.InsertCustomPages: InsertFromCustomPage(history.InsertIndex, history.PageSize.Width, history.PageSize.Height, history.InsertFilePath); ListSelectedIndex = history.InsertIndex; break; case ActionType.DragSort: DragToSort(history.InsertIndex, history.SourceTargetValue.Keys.ToList(), true); break; case ActionType.Reverse: var list = history.SourceTargetValue.Keys.ToList().Union(history.SourceTargetValue.Values.ToList()).ToList(); DoReverse(list, true); break; case ActionType.Paste: Paste(history.InsertIndex); break; default: break; } } /// /// 退出页面编辑面试,回到阅读页 /// public void BackToPDFViewer(int PageIndex) { PDFViewer.GoToPage(PageIndex); viewContentViewModel.ExitToolMode(); } /// /// 显示Toast提示 /// public void ShowToast(string content = "") { if (!string.IsNullOrEmpty(content)) { ToastText = content; } else { ToastText = App.MainPageLoader.GetString("OpentonFail_Warning"); } ShowTip = Visibility.Visible; } /// /// 通知UI刷新页面范围 /// 或通过xaml来设置选中项 /// vb nmjvcx private void NotifyUIToRefresh(List pageRange = null) { if (pageRange == null || pageRange.Count <= 0) { //通知UI刷新页面范围 eventor.GetEvent().Publish(new PageEditNotifyEventArgs(unicode)); } else { //通知UI刷新页面范围 eventor.GetEvent().Publish(new PageEditNotifyEventArgs(unicode, NotifyType.SelectItems, pageRange)); } } /// /// 获取已选中的页面集合 /// /// private List getSelectedPage() { List pages = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { pages.Add(i); } } return pages; } /// /// 删除选中项的方法 不带Reload操作 /// 方便其他逻辑中调用 /// private int DoRemoveSelectedPages(List pageList = null, bool isFromUndoRedo = false, bool isReplace = false) { PageEditItem pageEditItem = null; int index = -1; if (!ServiceHelper.IAPBeforeFunction()) { return index; } //删除后 的选中项 index = maxSelectedIndex; List indexList = new List(); if (pageList == null || pageList.Count == 0) { for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { indexList.Add(i); } } //因为虚拟化 可能获取不到所有选中项的页码 需要结合选中项的集合判断一下 if (selectedPageList.Count > 0 && selectedPageList.Count > indexList.Count) { indexList = new List(); for (int j = 0; j < selectedPageList.Count; j++) { indexList.Add(selectedPageList[j] - 1); } } } else { indexList = pageList; } if (indexList.Count > 0 && indexList.Count == PDFViewer.Document.PageCount) { // 全部替换 不显示 不能删除所有的弹窗 if (isReplace == false) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("PageEdit_DeleteAllPage"), App.ServiceLoader.GetString("Text_ok")); return -1; } } bool isLast = false; if (index == -1 && indexList.Count > 0) { if (isMultiSelected) { indexList.Sort(); index = indexList.First(); } else { index = indexList.Last(); } } if (index == PageEditItems.Count) { pageEditItem = PageEditItems[index - 1]; } else if (index < PageEditItems.Count) { if ((index + 1) >= PageEditItems.Count) { pageEditItem = PageEditItems[PageEditItems.Count - 1]; isLast = true; } else { pageEditItem = PageEditItems[index + 1]; } } var result = PDFViewer.Document.RemovePages(indexList.ToArray()); if (!result) { ShowToast(); return -1; } //文档层操作成功后再删除UI层 for (int i = indexList.Count - 1; i >= 0; i--) { PageEditItems.RemoveAt(indexList[i]); } if (!isFromUndoRedo) { ////清除页面编辑Undo,Redo栈 //UndoStack.Clear(); //RedoStack.Clear(); //this.CanUndo = false; //this.CanRedo = false; } index = PageEditItems.IndexOf(pageEditItem); if (index == -1 && indexList.Count > 0) { if (isLast) { index = PageEditItems.Count - 1; } else { index = indexList.Last(); } } return index; } /// /// 提取选中页面的方法 /// /// 是否每页生成一个文件 /// 是否提取后删除页面 private async void DoExtractPages(bool isEveryPageToFile, bool isDeleteAfterExtract) { System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog(); if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if (string.IsNullOrEmpty(dialog.SelectedPath)) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("OperationFailWarning"), App.ServiceLoader.GetString("Text_ok"));//补充提示文案 return; } } else return; string selectedfile = ""; IsLoading = Visibility.Visible; await Task.Delay(3); List pagenums = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { pagenums.Add(PageEditItems[i].PageNumber); } } if (IsMouseRightButtonDown) { if (IsMultiSelected) { for (int i = 0; i < RightSelectedIndexs.Count; i++) { RightSelectedIndexs[i] = RightSelectedIndexs[i] + 1; } pagenums = RightSelectedIndexs; } else { pagenums = new List() { RightSelectedIndex + 1 }; } } if (isEveryPageToFile) { //每页生成的单独的文件 for (int i = 0; i < pagenums.Count; i++) { string filename = PDFViewer.Document.FileName + " " + "pages " + pagenums[i] + ".pdf"; string path = System.IO.Path.Combine(dialog.SelectedPath, filename); path = CommonHelper.CreateFilePath(path); selectedfile = path; CPDFDocument savedoc = CPDFDocument.CreateDocument(); bool result = savedoc.ImportPages(PDFViewer.Document, pagenums[i].ToString()); if (!result) { savedoc.Release(); continue; } result = savedoc.WriteToFilePath(path); if (!result) { savedoc.Release(); continue; } savedoc.Release();//释放内存 } } else//全部生成一个文件 { string filename = PDFViewer.Document.FileName + " " + "pages " + CommonHelper.GetPageParmFromList(pagenums) + ".pdf"; string path = System.IO.Path.Combine(dialog.SelectedPath, filename); path = CommonHelper.CreateFilePath(path); selectedfile = path; CPDFDocument savedoc = CPDFDocument.CreateDocument(); string range = String.Join(",", pagenums); bool result = savedoc.ImportPages(PDFViewer.Document, range); if (!result) { ShowToast(); IsLoading = Visibility.Collapsed; return; } result = savedoc.WriteToFilePath(path); if (!result) { ShowToast(); } savedoc.Release();//释放内存 } if (isDeleteAfterExtract) { //先提取后删除,index和其他地方设置不一样 int index = DoRemoveSelectedPages() + 1; if (index > PDFViewer.Document.PageCount) { index = PDFViewer.Document.PageCount; } ReloadAfterOption(true, false, Tuple.Create(0, PDFViewer.Document.PageCount)); //通知Xaml删除后 选中的页面,从VM设置选中项会有问题 NotifyUIToRefresh(new List() { index }); } CommonHelper.ShowFileBrowser(selectedfile); IsLoading = Visibility.Collapsed; } private async void DoSplitPages(HomePageSplitDialogModel model) { try { var pdfViewer = PDFViewer; System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog(); //dialog.Description = App.MainPageLoader.GetString("Main_OpenFolderNoteWarning"); ; if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if (string.IsNullOrEmpty(dialog.SelectedPath)) { return; } } else return; var data = model; int PageCount = pdfViewer.Document.PageCount; string selectedfile = ""; string directory = System.IO.Path.Combine(dialog.SelectedPath, pdfViewer.Document.FileName); if (Directory.Exists(directory) == false) { Directory.CreateDirectory(directory); } App.mainWindowViewModel.ProcessCloseAction = PageSplitClear; string filename = ""; int index = 0; if (data.Mode == HomePageSplitDialogModel.SplitMode.AveragePages) { int perPages = Convert.ToInt32(data.GetModeCount); int splitCount = (int)Math.Ceiling((double)PageCount / (double)perPages); index = splitCount; ChatGTPAIHelper.SetIntProcess(true, "Splitting...", index, System.Windows.Visibility.Visible); //TODO:命名规则是否要调整 selectedfile = data.FileName + " " + "1.pdf"; for (int i = 0; i < splitCount; i++) { App.mainWindowViewModel.Value = i; await Task.Delay(50); // 模拟长时间操作 if (App.mainWindowViewModel.ProgressTitle == "Canceling") { return; } int startNum = i * perPages + 1; int endNum = Math.Min(PageCount, (i + 1) * perPages); string range = startNum.ToString() + "-" + endNum.ToString(); CPDFDocument savedoc = CPDFDocument.CreateDocument(); bool result = savedoc.ImportPages(pdfViewer.Document, range); if (!result) { savedoc.Release(); continue; } filename = GetFileName(data, i); string path = System.IO.Path.Combine(directory, filename); path = CommonHelper.CreateFilePath(path); result = savedoc.WriteToFilePath(path); if (!result) { savedoc.Release(); continue; } savedoc.Release(); selectedfile = path; } } else if (data.Mode == HomePageSplitDialogModel.SplitMode.AverageFiles) { int docCount = Convert.ToInt32(data.GetModeCount); int avePages = (int)Math.Floor((double)PageCount / (double)docCount); index = avePages; ChatGTPAIHelper.SetIntProcess(true, "Splitting...", index, System.Windows.Visibility.Visible); int remain = PageCount % docCount; int startNum = 1; //TODO:命名规则是否要调整 selectedfile = data.FileName + " " + "1.pdf"; for (int i = 0; i < docCount; i++) { App.mainWindowViewModel.Value = i; await Task.Delay(50); // 模拟长时间操作 if (App.mainWindowViewModel.ProgressTitle == "Canceling") { return; } int endNum = startNum + (avePages - 1); if (i < remain) endNum++; endNum = Math.Min(endNum, PageCount); string range = startNum + "-" + endNum; startNum = endNum + 1; filename = GetFileName(data, i); string path = System.IO.Path.Combine(directory, filename); path = CommonHelper.CreateFilePath(path); CPDFDocument savedoc = CPDFDocument.CreateDocument(); bool result = savedoc.ImportPages(pdfViewer.Document, range); if (!result) { savedoc.Release(); continue; } result = savedoc.WriteToFilePath(path); if (!result) { savedoc.Release(); continue; } savedoc.Release(); selectedfile = path; } } else//自定义页码范围 { string pageRange = ""; List pageList1 = new List(); if (data.PageMode == HomePageSplitDialogModel.PageRangeMode.OddPage) { int[] page = new int[(PageCount + 1) / 2]; index = page.Length; ChatGTPAIHelper.SetIntProcess(true, "Splitting...", index, System.Windows.Visibility.Visible); for (int i = 0; i < page.Length; i++) { App.mainWindowViewModel.Value = i; await Task.Delay(50); // 模拟长时间操作 if (App.mainWindowViewModel.ProgressTitle == "Canceling") { return; } page[i] = i * 2 + 1; } pageRange = string.Join(",", page); } else if (data.PageMode == HomePageSplitDialogModel.PageRangeMode.EvenPage) { int[] page = new int[PageCount / 2]; index = page.Length; ChatGTPAIHelper.SetIntProcess(true, "Splitting...", index, System.Windows.Visibility.Visible); for (int i = 0; i < page.Length; i++) { App.mainWindowViewModel.Value = i; await Task.Delay(50); // 模拟长时间操作 if (App.mainWindowViewModel.ProgressTitle == "Canceling") { return; } page[i] = i * 2 + 2; } pageRange = string.Join(",", page); } else if (data.PageMode == HomePageSplitDialogModel.PageRangeMode.CustomPage) { ChatGTPAIHelper.SetIntProcess(true, "Splitting...", PageCount, System.Windows.Visibility.Visible); pageRange = data.PageRange; } //如果是自定义输入页面范围的话,直接解析 CommonHelper.GetPagesInRange(ref pageList1, pageRange, PageCount, new char[] { ',' }, new char[] { '-' }); index = pageList1.Count; #region //part1 selectedfile = ""; CPDFDocument saveDoc1 = CPDFDocument.CreateDocument(); //string filepath = data.FileName + " " + "1.pdf"; filename = GetFileName(data, 0); string path1 = Path.Combine(directory, filename); path1 = CommonHelper.CreateFilePath(path1); bool result = saveDoc1.ImportPages(pdfViewer.Document, pageRange); if (!result) { saveDoc1.Release(); ShowToast(); ChatGTPAIHelper.clossProcess(index); return; } result = saveDoc1.WriteToFilePath(path1); if (!result) { saveDoc1.Release(); ShowToast(); ChatGTPAIHelper.clossProcess(index); return; } saveDoc1.Release(); selectedfile = path1; #endregion //part1 #region 方案二 //Part2 除了选定之外的页面 List pageList2 = new List(); for (int i = 1; i <= pdfViewer.Document.PageCount; i++) { if (!pageList1.Contains(i - 1))//pagelist1 存放的是index pageList2.Add(i); } string pageRange2 = string.Join(",", pageList2); CPDFDocument saveDoc2 = CPDFDocument.CreateDocument(); string filepath2 = /*data.FileName + " " + "2.pdf";*/ GetFileName(data, 1); string path2 = /*Path.Combine(dialog.SelectedPath, filepath2);*/Path.Combine(directory, filepath2); path2 = CommonHelper.CreateFilePath(path2); bool result1 = saveDoc2.ImportPages(pdfViewer.Document, pageRange2); if (!result1) { saveDoc2.Release(); ShowToast(); return; } result1 = saveDoc2.WriteToFilePath(path2); if (!result1) { saveDoc2.Release(); ShowToast(); return; } saveDoc2.Release(); //selectedfile = path2; } #endregion 方案二 //Part2 除了选定之外的页面 //显示文件夹,并选中一个文件 Process.Start("explorer", "/select,\"" + selectedfile + "\""); ChatGTPAIHelper.clossProcess(index); } catch { } } private void PageSplitClear() { App.mainWindowViewModel.ProgressTitle = "Canceling"; App.mainWindowViewModel.IsProcessVisible = System.Windows.Visibility.Collapsed; } private string GetFileName(HomePageSplitDialogModel model, int index) { string filename = ""; string label = model.HasLabel ? model.FileNameLabel : ""; string deimiter = model.HasDeimiter ? model.FileNameDeimiter : ""; if (model.IsSourceNameFront) { filename = model.SourceFileName + deimiter + label + (index + 1) + ".pdf"; } else { filename = label + (index + 1) + deimiter + model.SourceFileName + ".pdf"; } return filename; } /// /// 将文件插入到指定位置 /// /// public async Task InsertFromFile(int insertIndex, string filePath, CPDFDocument doc = null, string oldPassWord = null, bool isFromUndoRedo = false) { if (doc == null) { return false; } int pageCount = doc.PageCount; //插入整个新文档 //文档层插入 var insertresult = PDFViewer.Document.ImportPagesAtIndex(doc, "1-" + pageCount, insertIndex); if (!insertresult) { ShowToast(); return false; } //插入成功后释放临时Document对象 doc.Release(); //UI层插入 for (int i = 0; i < pageCount; i++) { var item = GetNewPageEditItem(i); PageEditItems.Insert(insertIndex + i, item); } //加一点延时才能显示选中效果 await Task.Delay(200); List pageRange = new List(); for (int i = 0; i < pageCount; i++) { pageRange.Add(insertIndex + i + 1); } if (IsBOTAThumb == Visibility.Visible) { GoToPage(pageRange); } NotifyUIToRefresh(pageRange); //如果是undo redo里调用本方法,则不需要添加到Undo栈 if (!isFromUndoRedo) { //添加记录到Undo栈,清空Redo栈 PageEditHistory history = new PageEditHistory(); history.Type = ActionType.InsertFromFile; history.InsertIndex = insertIndex; history.InsertFilePath = filePath; history.InsertFilePassWord = oldPassWord; history.InsertPageCount = pageCount; history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); } return true; } public bool GetDocumentIsDiscryptied(string filePath, string oldPassWord, out CPDFDocument doc, out string password) { doc = CPDFDocument.InitWithFilePath(filePath); password = ""; if (doc == null) { //文件损坏 AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("Main_OpenFileFailedWarning"), App.ServiceLoader.GetString("Text_ok")); return false; } if (doc.IsLocked) { if (!string.IsNullOrEmpty(oldPassWord)) { var result = doc.UnlockWithPassword(oldPassWord); if (result) { password = oldPassWord; } } //没有传入密码,或者用传入密码解密失败是,需要弹出界面弹窗 if (doc.IsLocked) { VerifyPasswordResult result = SecurityHelper.VerifyPasswordByPasswordKind(doc, EnumPasswordKind.StatusPermissionsPassword, dialogs); if (result.IsDiscryptied) { if (result.Password != null) { string filePath1 = doc.FilePath; if (doc.IsLocked) { doc.UnlockWithPassword(result.Password); } else { doc.CheckOwnerPassword(result.Password); } password = result.Password; } } else { return false; } } } return true; } /// /// 插入自定义页面 /// /// /// /// /// /// private bool InsertFromCustomPage(int insertIndex, double width, double height, string filePath) { try { bool result = false; //文档层插入 if (!string.IsNullOrEmpty(filePath)) { BitmapFrame frame = BitmapFrame.Create(new Uri(filePath)); byte[] imageData = new byte[frame.PixelWidth * frame.PixelHeight * 4]; frame.CopyPixels(imageData, frame.PixelWidth * 4, 0); result = PDFViewer.Document.InsertPage(insertIndex, frame.Width, frame.Height, imageData, CPDFDocumentImageMode.CPDFDocumentImageModeScaleToFill); } else { result = PDFViewer.Document.InsertPage(insertIndex, width, height, null); } if (!result) { ShowToast(); return false; } //UI层插入Item ,需要处理一下Item var item = GetNewPageEditItem(insertIndex); PageEditItems.Insert(insertIndex, item); ReloadAfterOption(true, false, Tuple.Create(insertIndex - 1, insertIndex + 1), true); //选中插入的页面 ListSelectedIndex = insertIndex; return true; } catch { return false; } } /// /// 根据索引创建新的Item /// /// /// private PageEditItem GetNewPageEditItem(int index) { PageEditItem item = new PageEditItem(); if (PDFViewer.Document.PageAtIndex(index).Rotation % 2 != 0) { ///标记为横向页面 item.isVertical = false; } item.PageNumber = index + 1; var pagesize = PDFViewer.Document.GetPageSize(index); item.Size = pagesize; //修复 缩放后粘贴的页面大小不一致的问题 item.ItemSize = ItemSizes[ZoomIndex + 1]; return item; } /// /// 进行文件操作后刷新PDFView /// 清除undo 栈 /// 重加载Document /// 设置保存状态 /// /// 是否需要刷新页码 /// 是否需要清空注释Undo栈 /// 需要刷新的页面范围图片 public void ReloadAfterOption(bool needRefreshPageNum = false, bool needClearUndoHistory = false, Tuple pageRange = null, bool isScrollIntoView = false) { if (needRefreshPageNum) { RefreshPageNum(); //从页面编辑退出的值,根据内容走,进页面编辑是这一页内容,退出来还是 if (CurrentPageEditItem != null && IsBOTAThumb != Visibility.Visible) { int pageIndex = CurrentPageEditItem.PageNumber - 1; if (pageIndex != PDFViewer.CurrentIndex) { PDFViewer.GoToPage(pageIndex); } } //插入、替换等更新页码,页码输入框的值未更新 RefreshTbPageRange(); } if (needClearUndoHistory) { //只有删除操作清空undo栈 //可能会引起注释模块联动问题 需要留意 PDFViewer.UndoManager.ClearHistory(); } if (pageRange != null) { if (pageRange.Item2 - pageRange.Item1 > 30) { if (isScrollIntoView) { //插入后 滚动到 选中的页面 List pageRanges = new List() { pageRange.Item2 }; NotifyUIToRefresh(pageRanges); } else { //范围较大时,通知UI获取更准确的刷新范围 NotifyUIToRefresh(); } } else { RefreshItemImage(pageRange.Item1, pageRange.Item2); if (isScrollIntoView) { if (ListSelectedIndex == -1) { //插入后 滚动到 选中的页面 List pageRanges = new List() { pageRange.Item2 }; NotifyUIToRefresh(pageRanges); } } } } PDFViewer.UndoManager.CanSave = true; PDFViewer.ReloadDocument(); //解决:阅读页放大到只能看到最后一页时,从缩略图删除最后一页,阅读页面没有联动刷新 if (PDFViewer.GetVerticalOffset() >= PDFViewer.GetExtendHeight()) { PDFViewer.ScrollToVerticalOffset(PDFViewer.GetExtendHeight()); } } /// /// 重新获取选中页码 /// /插入、替换等更新页码,页码输入框的值未更新 /// private void RefreshTbPageRange() { List indexList = GetSelectedItemPageNumbers(); if (indexList.Count > 0) { //选中项集合 也需要 同步更新 selectedPageList.Clear(); selectedPageList.AddRange(indexList); //只选中单个页面是,listselectedIndex 更准确 if (indexList.Count == 1) { TbPageRange = (listSelecedIndex + 1).ToString(); } else { //根据选中的页面转换成1,3-10类似的字符串 string pageparm = CommonHelper.GetPageParmFromList(indexList); TbPageRange = pageparm; } } } private List GetSelectedItemPageNumbers() { List indexList = new List(); for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { indexList.Add(PageEditItems[i].PageNumber); } } return indexList; } /// /// 旋转所有选中页面 /// /// private async void RotateSelectedPages(bool rightRotate = true, List pageitems = null, bool isFromUndoRedo = false) { if (!ServiceHelper.IAPBeforeFunction()) { return; } IsLoading = Visibility.Visible; await Task.Delay(2); Dictionary items = new Dictionary(); if (pageitems == null) { //旋转选中页面 items = SetRotateSelectedPagesEvent(rightRotate); } else { if (pageitems.Count == 0) { items = SetRotateSelectedPagesEvent(rightRotate); } else { //旋转对应Items集合 for (int i = 0; i < pageitems.Count; i++) { PDFViewer.RotatePage(ComPDFKitViewer.PageRotate.Rotate90, rightRotate, pageitems[i]); items.Add(pageitems[i], pageitems[i]); //重新拿图 if (PageEditItems.Count > pageitems[i]) { PageEditItems[pageitems[i]].IsGetImage = false; } } } } //旋转页面后取消选中 PDFViewer.ClearSelectPDFEdit(true); //如果是undo,Redo里调用的方法,则不记录到栈里 if (!isFromUndoRedo) { //记录进Undo栈 PageEditHistory history = new PageEditHistory(); history.Type = rightRotate ? ActionType.RightRotate : ActionType.LeftRotate; history.SourceTargetValue = items; history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); } //页面范围-横向页面,旋转90°后,输入框应当变成具体的页码,因为旋转后不是横向页面了(纵向页面同理) if (items.Count > 0) { ReloadAfterOption(true, false, Tuple.Create(items.Keys.First(), items.Keys.Last())); } IsLoading = Visibility.Collapsed; } private Dictionary SetRotateSelectedPagesEvent(bool rightRotate) { Dictionary items = new Dictionary(); for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].Selected) { //逆时针旋转传 - 1 顺时针旋转传1 //直接用PDFViewer的旋转接口,需要留意好,中间层不能有自动清空undo栈 PDFViewer.RotatePage(ComPDFKitViewer.PageRotate.Rotate90, rightRotate, i); items.Add(i, i); //重新拿图 PageEditItems[i].IsGetImage = false; } } return items; } /// /// 刷新页码 /// private void RefreshPageNum() { for (int i = 0; i < PageEditItems.Count; i++) { PageEditItems[i].PageNumber = i + 1; if (IsBOTAThumb == Visibility.Visible) { PageEditItems[i].FontSize = 12; } else { PageEditItems[i].FontSize = 14; } } } /// /// 刷新页面范围下拉框 /// private void RefreshPageRangeItem() { PageRangeItems.Clear(); PageRangeItems.Add(App.MainPageLoader.GetString("WritableComboBox_AllPage")); PageRangeItems.Add(App.MainPageLoader.GetString("WritableComboBox_OddPage")); PageRangeItems.Add(App.MainPageLoader.GetString("WritableComboBox_EvenPage")); PageRangeItems.Add("Horizontal Page"); PageRangeItems.Add("Vertical Page"); PageRangeItems.Add(App.MainPageLoader.GetString("WritableComboBox_CustomRangeEge")); } /// /// 选中目标页面范围的页面 /// /// 页面范围选中项索引 private async void SuitPageRange(int index) { List pageRange = new List(); switch (index) { case 0: for (int i = 0; i < PageEditItems.Count; i++) { pageRange.Add(i + 1); } break; case 1: //奇数页 //先清空所有选项 ListSelectedIndex = -1; for (int i = 0; i < PageEditItems.Count; i++) { if (i % 2 == 0) { pageRange.Add(i + 1); } } break; case 2: //偶数页 //先清空所有选项 ListSelectedIndex = -1; for (int i = 0; i < PageEditItems.Count; i++) { if (i % 2 != 0) { pageRange.Add(i + 1); } } break; case 3://横向页面 //先清空所有选项 ListSelectedIndex = -1; for (int i = 0; i < PageEditItems.Count; i++) { if (!PageEditItems[i].isVertical) { pageRange.Add(i + 1); } } break; case 4://纵向页面 for (int i = 0; i < PageEditItems.Count; i++) { if (PageEditItems[i].isVertical) { pageRange.Add(i + 1); } } break; case 5://自定义 TxtPageInputVisibility = Visibility.Visible; await Task.Delay(30); TbPageRange = ""; break; default: break; } if (pageRange.Count > 0) { //避免在下面的过程中频繁触发SelectionChanged事件 IsSelectFormSelf = true; NotifyUIToRefresh(pageRange); //为了避免重复选中,条件也符合而文本缺失的情况 TbPageRange = PageRangeItems[index]; RightSelectedIndexs.Clear(); foreach (var item in pageRange) { RightSelectedIndexs.Add(item - 1); } IsSelectFormSelf = false; } else { //选中了下拉框的选项 //增加条件,修复全选页面,但是ctrl点选取消后,选中状态不准确问题 if (index != -1) { //没有符合条件时 清空选中项 ListSelectedIndex = -1; //20230714 没有符合条件的页面时候,控件内容不清空 //没有符合条件的页面时,空间内容清空 //await Task.Delay(30); //TbPageRange = ""; } } } /// /// 是否显示页面尺寸 /// /// 是或否 private void ShowPageSize() { if (ShowedPageSize == Visibility.Visible) { IsShowPageSize = true; ShowedPageSize = Visibility.Collapsed; HidePageSize = Visibility.Visible; } else { IsShowPageSize = false; HidePageSize = Visibility.Collapsed; ShowedPageSize = Visibility.Visible; } ListSelectedIndex = -1; selectedPageList.Clear(); //显示显示当前范围的item的页面尺寸,其他的Item在刷新图片时,再显示尺寸 if (startRefreshedIndex <= endRefreshedIndex) { for (int i = startRefreshedIndex; i < endRefreshedIndex; i++) { if (i >= 0 && i <= PageEditItems.Count - 1) { PageEditItems[i].ShowPageSize = IsShowPageSize; } } } } /// /// 从PDFView获取所有Items集合 /// public void GetSourceItems(bool isFirstLoad) { if (isFirstLoad || IsBOTAThumb == Visibility.Visible) { PageEditItems.Clear(); for (int i = 0; i < PDFViewer.Document.PageCount; i++) { var item = GetNewPageEditItem(i); PageEditItems.Add(item); } } //else //{ // //后续进来仅刷新图片即可 // for (int i = 0; i < PageEditItems.Count; i++) // { // PageEditItems[i].IsGetImage = false; // } //} } /// /// 刷新书签列表 /// public void RefreshBookMarkList() { if (PDFViewer != null) { var booklist = PDFViewer.Document.GetBookmarkList(); if (booklist == null) { return; } //获取所有书签的Index集合 List marks = new List(); for (int i = 0; i < booklist.Count; i++) { marks.Add(booklist[i].PageIndex); } //不能只遍历marks集合,考虑书签集合元素删除的情况 for (int k = 0; k < PageEditItems.Count; k++) { if (marks.Contains(k)) PageEditItems[k].HaveBookMark = true; else PageEditItems[k].HaveBookMark = false; } } } /// /// 刷新指定范围的图片 /// /// /// private void RefreshItemImage(int startIndex, int endIndex) { startRefreshedIndex = startIndex; endRefreshedIndex = endIndex; if (PDFViewer == null || PDFViewer.Document == null) { return; } //一个拿图比例系数,减少拿图耗时,尽量确保缩放后图片清晰度不会很差 int rate = (int)ItemSizes[2].Height; //230628 缩略图需要根据当前 的缩略值 //int rate = (int)ItemSizes[ZoomIndex + 1].Height; for (int i = startIndex; i <= endIndex; i++) { if (i <= PageEditItems.Count - 1 && i >= 0 && PageEditItems.Count > 0 && PDFViewer.Document != null && rate > 0) { //先更新一次每个页面的尺寸 确保图的方向正确 PageEditItems[i].Size = PDFViewer.Document.GetPageSize(i); if (PageEditItems[i].Size.Width <= 0 || PageEditItems[i].Size.Height <= 0) { //补充判空逻辑,避免崩溃 continue; } //不能一次性显示页面大小,页数较多时会导致界面卡死 //每次刷新图片时,根据右键菜单状态(是否显示页面大小)来控制每个Item的页面尺寸显示 PageEditItems[i].ShowPageSize = IsShowPageSize; //宽高为样式中图片控件宽高 if (PageEditItems[i].isVertical) { //等比例缩小 if (PageEditItems[i].Size.Height > rate) { int index = Convert.ToInt32(PageEditItems[i].Size.Width / (PageEditItems[i].Size.Height / rate)); SetThumbnailImage(i, index, rate, true); } else { int index = Convert.ToInt32(PageEditItems[i].Size.Width * (rate / (int)PageEditItems[i].Size.Height)); //尺寸大小的图片 等比例放大 避免页面放大后内容模糊 SetThumbnailImage(i, index, rate, true); } } else { if (PageEditItems[i].Size.Width > rate) { int index = Convert.ToInt32(PageEditItems[i].Size.Height / (PageEditItems[i].Size.Width / rate)); SetThumbnailImage(i, index, rate, false); } else { int index = Convert.ToInt32(PageEditItems[i].Size.Height * (rate / (int)(PageEditItems[i].Size.Width))); SetThumbnailImage(i, index, rate, false); } } } } } private async void SetThumbnailImage(int i, int index, int rate, bool isVertical) { if (viewContentViewModel.IsHiddenAnnot) { if (isVertical) { //显示=1, 隐藏=0注释 await PDFViewer.GetThumbnail(i, index, rate, 0); } else { await PDFViewer.GetThumbnail(i, rate, index, 0); } } else { if (isVertical) { await PDFViewer.GetThumbnail(i, index, rate, 1); } else { await PDFViewer.GetThumbnail(i, rate, index, 1); } } } /// /// 拖拽排序功能 /// /// /// public void DragToSort(int targetIndex, List pageIndexs, bool IsFromUndoRedo = false) { //拖拽排序后需要重新选中项的集合 List selectedPages = new List(); //记录原位置和目标位置的字典,用于Undo,Redo恢复 Dictionary SourceTargetValue = new Dictionary(); bool result = false; //排序前,先对所有页码排序 pageIndexs.Sort(); //要考虑每一次交换都会导致局部页码发生改变 //每次整体往后移动时,先移动大页码;整体往前移动时,先移动小页码;往中间移动时,再按上述两种情况分别移动 if (targetIndex <= pageIndexs[0]) { for (int i = 0; i < pageIndexs.Count; i++) { // list.Add(PageEditListBox.Items[pageIndexs[i]] as ListBoxItem); //sourceindex.Add(pageIndexs[i]); result = MoveItemToIndex(pageIndexs[i], targetIndex + i); if (!result) { return; } SourceTargetValue.Add(pageIndexs[i], targetIndex + i); selectedPages.Add(targetIndex + i + 1); } } else if (targetIndex > pageIndexs[pageIndexs.Count - 1]) { //目标位置在所有选中内容右边 整体后移 for (int i = 0; i < pageIndexs.Count; i++) { result = MoveItemToIndex(pageIndexs[pageIndexs.Count - 1 - i], targetIndex - 1 - i); if (!result) { return; } SourceTargetValue.Add(pageIndexs[pageIndexs.Count - 1 - i], targetIndex - 1 - i); selectedPages.Add(targetIndex - i); } } else//目标位置在所有选中项中间 { int i, j, k; //找出PageEditListBox.Items中页码等于destpage的下标 for (k = 0; k < pageIndexs.Count - 1; k++) { //这里要算入K---即前面部分的页面个数 if (pageIndexs[k] < targetIndex && pageIndexs[k + 1] >= targetIndex) { break; } } //局部往后移动 for (i = 0; i <= k; i++) { result = MoveItemToIndex(pageIndexs[k - i], targetIndex - 1 - i); if (!result) { return; } SourceTargetValue.Add(pageIndexs[k - i], targetIndex - 1 - i); selectedPages.Add(targetIndex - i); } int newIndex = targetIndex; //局部往前移动 for (j = i; j < pageIndexs.Count; j++) { result = MoveItemToIndex(pageIndexs[j], newIndex); if (!result) { return; } SourceTargetValue.Add(pageIndexs[j], newIndex); selectedPages.Add(newIndex + 1); newIndex++; } } //刷新页码和图片 ReloadAfterOption(true, false, new Tuple(0, PDFViewer.Document.PageCount)); //先刷新页码再选中item,顶部的选中页面更准确 //通知UI选中Items NotifyUIToRefresh(selectedPages); if (!IsFromUndoRedo) { //存入Undo栈 PageEditHistory history = new PageEditHistory(); history.Type = ActionType.DragSort; history.SourceTargetValue = SourceTargetValue; //用于Redo恢复 history.InsertIndex = targetIndex; history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); } } /// /// 移动某个Item到指定位置 /// private bool MoveItemToIndex(int sourceindex, int targetindex) { if (targetindex == sourceindex || targetindex < 0) { return false; } //文档层移动 var result = PDFViewer.Document.MovePage(sourceindex, targetindex); if (!result) { return false; } //UI层移动 var source = PageEditItems[sourceindex]; PageEditItems.RemoveAt(sourceindex); PageEditItems.Insert(targetindex, source); if (PDFViewer.CurrentIndex == sourceindex) { PDFViewer.GoToPage(targetindex); } return true; } private void PDFViewer_InfoChanged(object sender, KeyValuePair e) { if (PDFViewer.Parent is ContentControl ui) { //判断鼠标焦点 是否在控件上 if (ui.IsMouseOver) { //缩略图 复制粘贴后会选择第一项的问题 if (e.Key == "PageNum" && !viewContentViewModel.isInPageEdit) { int index = (e.Value as ComPDFKitViewer.RenderData).PageIndex - 1; //注释掉 该方法有许多联动,避免联动影响 //NotifyUIToRefresh(new List { (e.Value as ComPDFKitViewer.RenderData).PageIndex }); eventor.GetEvent().Publish(new PageEditSelectedItemEventArgs() { Unicode = unicode, SelectedItemIndex = index, IsSingle = true }); } } } //不准确 有时候会触发两次,就无法判断 //if (IsAddPages == false) //{ // //缩略图 复制粘贴后会选择第一项的问题 // if (e.Key == "PageNum" && !viewContentViewModel.isInPageEdit) // { // int index = (e.Value as ComPDFKitViewer.RenderData).PageIndex - 1; // //注释掉 该方法有许多联动,避免联动影响 // //NotifyUIToRefresh(new List { (e.Value as ComPDFKitViewer.RenderData).PageIndex }); // eventor.GetEvent().Publish(new PageEditSelectedItemEventArgs() { Unicode = unicode, SelectedItemIndex = index, IsSingle = true }); // } //} //else //{ // IsAddPages = false; // return; //} } /// /// 从底层库获取对应页面的图片 /// /// /// /// /// private void PDFViewer_OnThumbnailGenerated(int pageIndex, byte[] thumb, int w, int h) { try { if (PageEditItems.Count >= pageIndex + 1) { PixelFormat fmt = PixelFormats.Bgra32; BitmapSource bps = BitmapSource.Create(w, h, 96.0, 96.0, fmt, null, thumb, (w * fmt.BitsPerPixel + 7) / 8); PageEditItems[pageIndex].Image = bps; PageEditItems[pageIndex].IsGetImage = true; } } catch { } } #endregion 方法 #region Navigate public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } public void OnNavigatedFrom(NavigationContext navigationContext) { } /// /// 从其他页面导航过来的时候会触发 /// 考虑只有在页面编辑的时候会进行页面的删减,可以尝试逻辑优化:仅第一次进入页面编辑时重新刷新页面 /// /// public void OnNavigatedTo(NavigationContext navigationContext) { navigationContext.Parameters.TryGetValue(ParameterNames.ViewContentViewModel, out viewContentViewModel); navigationContext.Parameters.TryGetValue(ParameterNames.PDFViewer, out PDFViewer); bool isBOTA = false; navigationContext.Parameters.TryGetValue(ParameterNames.BOTAThumb, out isBOTA); if (PDFViewer != null) { Initializing = true; if (isFirstLoad) { PDFViewer.OnThumbnailGenerated -= PDFViewer_OnThumbnailGenerated; PDFViewer.OnThumbnailGenerated += PDFViewer_OnThumbnailGenerated; PDFViewer.InfoChanged -= PDFViewer_InfoChanged; PDFViewer.InfoChanged += PDFViewer_InfoChanged; PDFViewer.AnnotEditHandler -= PDFViewer_AnnotEditHandler; PDFViewer.AnnotEditHandler += PDFViewer_AnnotEditHandler; ZoomIndex = 0; } //BOTA缩略图时,显示不同的菜单栏 if (isBOTA) { IsBOTAThumb = Visibility.Visible; //ShowedPageSize = Visibility.Collapsed; //HidePageSize = Visibility.Collapsed; } else { IsBOTAThumb = Visibility.Collapsed; //进入页面编辑 滚动到选中页面 //NotifyUIToRefresh(); } //每次进入页面编辑都刷新item个数,缩略图删减时,可以更新item //需要留意大文档性能 GetSourceItems(true); // 暂时 bota 和页面编辑不联动,切换后,是重新获取数据,不会获得之前的状态 IsShowPageSize = false; ShowedPageSize = Visibility.Visible; HidePageSize = Visibility.Collapsed; //清空一下选中项,修复进入页面编辑后仍然选中多页的问题 ListSelectedIndex = -1; ListSelectedIndex = PDFViewer.CurrentIndex; //页面编辑取消显示书签Icon //RefreshBookMarkList(); isFirstLoad = false; Initializing = false; if (PageEditItems.Count > 0) { if (PageEditItems.IndexOf(PageEditItems[PDFViewer.CurrentIndex]) > -1) { //记录 进页面编辑是这一页内容 CurrentPageEditItem = PageEditItems[PDFViewer.CurrentIndex]; } } } } private void PDFViewer_AnnotEditHandler(object sender, List e) { if (e != null && e.Count > 0 && IsBOTAThumb == Visibility.Visible) { //缩略图模式下 刷新页面 int pageIndex = e[0].PageIndex; RefreshItemImage(pageIndex, pageIndex); } } #endregion Navigate } }