using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media; using ComPDFKitViewer.PdfViewer; using PDF_Master.Model; using System.Collections.ObjectModel; using PDF_Master.Model.PageEdit; using Prism.Commands; using System.Windows; using System.Windows.Media.Imaging; using System.Windows.Controls.Primitives; using System.Diagnostics; using System.Windows.Controls; using System.Windows.Threading; using Prism.Events; using PDF_Master.EventAggregators; using System.Windows.Input; using PDF_Master.Helper; using Microsoft.Win32; using ComPDFKit.PDFDocument; using PDF_Master.CustomControl; using PDF_Master.Model.HomePageToolsDialogs; using System.IO; using System.Text.RegularExpressions; using static PDF_Master.Model.Dialog.ToolsDialogs.SaftyDialogs.DeleteSafetySettintgsModel; using PDF_Master.Model.Dialog.ToolsDialogs.SaftyDialogs; using PDF_Master.Properties; using PDF_Master.Views.PageEdit; 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 void InitString() { 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 ViewContentViewModel viewContentViewModel; private IDialogService dialogs; private IEventAggregator eventor; /// /// 用于筛选多窗体时间的唯一识别码 /// private string unicode = null; /// /// 项数据集合 /// public ObservableCollection PageEditItems { get; set; } /// /// 页面范围的项集合 /// public ObservableCollection PageRangeItems { get; set; } #region 属性 /// /// 是否是第一次加载 /// private bool isFirstLoad = true; /// /// 是否正在拖拽排序中 /// private bool DragSorting = false; /// /// 记录多选项中最后一项的索引 /// private 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 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; /// /// 隐藏页面尺寸 /// 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; #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, CanReplaceCommandExcute).ObservesProperty(() => IsMultiSelected); ExtractCommand = new DelegateCommand(ExtractCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex); DeleteCommand = new DelegateCommand(DeleteCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex); LeftRotateCommand = new DelegateCommand(LeftRotateCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex); RightRotateCommand = new DelegateCommand(RightRotateCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex); ReverseCommand = new DelegateCommand(ReverseCommandEvent, CanFileCommandExcute).ObservesProperty(() => ListSelectedIndex); 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() { OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = false; dialog.Filter = PDF_Master.Properties.Resources.OpenDialogFilter; if ((bool)dialog.ShowDialog()) { IsLoading = Visibility.Visible; await Task.Delay(200); int pageCount = PDFViewer.Document.PageCount; int insertIndex = listSelecedIndex; //从文件插入到指定位置 var result = await InsertFromFile(listSelecedIndex + 1, dialog.FileName); if (result) { //插入成功后再删除原有页面 //2023-06-05 索引需要-1,因为上面的listSelecedIndex + 1,需要还原 if (result) DoRemoveSelectedPages(new List() { listSelecedIndex - 1 }); } ReloadAfterOption(true, false, Tuple.Create(insertIndex - 1, insertIndex + pageCount)); IsLoading = Visibility.Collapsed; } } /// /// 拆分功能的逻辑 /// private void SplitCommandEvent() { DialogParameters valuePairs = new DialogParameters(); valuePairs.Add(ParameterNames.PDFViewer, PDFViewer); dialogs.ShowDialog(DialogNames.SplitDialog, valuePairs, e => { if (e.Result == ButtonResult.OK && e.Parameters != null) { var model = e.Parameters.GetValue(ParameterNames.DataModel); DoSplitPages(model); } }); } /// /// 提取功能的逻辑 /// private void ExtractCommandEvent() { dialogs.ShowDialog(DialogNames.ExtractDialog, null, e => { if (e.Result == ButtonResult.OK && e.Parameters != null) { var model = e.Parameters.GetValue(ParameterNames.DataModel); DoExtractPages(model.IsEveryPageToFile, model.IsDeleteAfterExtract); } }); } /// /// 插入功能的逻辑 /// private async void InsertCommandEvent(object type) { if ((string)type == null) { return; } //获取插入位置 int insertIndex = 0; if (listSelecedIndex < 0) { insertIndex = PageEditItems.Count; } else { insertIndex = listSelecedIndex + 1; if (isMultiSelected) { insertIndex = maxSelectedIndex + 1; } } IsLoading = Visibility.Visible; await Task.Delay(3); PageEditHistory history = new PageEditHistory(); history.InsertIndex = insertIndex; if ((string)type == ParameterNames.InsertType_Blank) { 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; } else if ((string)type == ParameterNames.InsertType_File) { OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = false; dialog.Filter = PDF_Master.Properties.Resources.OpenDialogFilter; if ((bool)dialog.ShowDialog()) { //插入文件 var result = await InsertFromFile(insertIndex, dialog.FileName); if (!result) { IsLoading = Visibility.Collapsed; ShowToast(); return; } ReloadAfterOption(true, false, Tuple.Create(0, PDFViewer.Document.PageCount)); } IsLoading = Visibility.Collapsed; //里面附带了Undo栈记录,需要提前返回,避免重复记录 return; } 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.ListSelectedIndex, ListSelectedIndex); //int o = ListSelectedIndex; //插入自定义页面 dialogs.ShowDialog(DialogNames.InsertDialog, keyValuePairs, e => { if (e.Result == ButtonResult.OK && e.Parameters != null) { 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); } }); } IsLoading = Visibility.Collapsed; //添加记录到Undo栈,清除Redo栈 history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); } /// /// 删除选中页面 /// private async void DeleteCommandEvent() { 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); DoRemoveSelectedPages(); ReloadAfterOption(true, true, Tuple.Create(0, PDFViewer.Document.PageCount)); IsLoading = Visibility.Collapsed; } } /// /// 左旋转页面的逻辑 /// private void LeftRotateCommandEvent() { RotateSelectedPages(false); } /// /// 右旋转页面的逻辑 /// private void RightRotateCommandEvent() { RotateSelectedPages(); } /// /// 页面倒序的逻辑 /// private async void ReverseCommandEvent() { 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; } 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 (ListSelectedIndex < 0 && !IsMultiSelected) { return false; } else { return true; } } /// /// 校验是否可以替换 /// /// 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; } 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(); } 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 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) { 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) { 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() { ListSelectedIndex = -1; } /// /// 调用打印机 /// public async void print(List SelectedPages) { await App.Current.Dispatcher.InvokeAsync(() => { PDFViewer.GoToPage(listSelecedIndex); }); 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; } DoRemoveSelectedPages(); ReloadAfterOption(true, true, Tuple.Create(0, PDFViewer.Document.PageCount)); } /// /// 复制 /// private void copy() { if (!viewContentViewModel.IAPBeforeFunction()) { return; } if (viewContentViewModel.CheckPermissionBeforeOption()) { 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(ListSelectedIndex + 1); } bool result = CacheFilePath.Instance.CopyDoc.ImportPages(PDFViewer.Document, String.Join(",", pages)); if (!result) { ShowToast(); return; } } } /// /// 是否可以粘贴 /// /// private bool CanPasteExcute() { return this.CanPaste; } /// /// 粘贴 /// private async void paste(int Index = -1) { if (!viewContentViewModel.IAPBeforeFunction()) { return; } IsLoading = Visibility.Visible; int insertindex = maxSelectedIndex > listSelecedIndex ? maxSelectedIndex : listSelecedIndex; insertindex++; if (Index >= 0) { insertindex = Index; } else if (listSelecedIndex == -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); //刷新页码等 ReloadAfterOption(true, false, new Tuple(0, PDFViewer.Document.PageCount)); //通知Xaml选中新增的页面,从VM设置选中项会有问题 NotifyUIToRefresh(pageRange); IsLoading = Visibility.Collapsed; } /// /// 页面编辑执行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); } DoRemoveSelectedPages(pageList, true); break; case ActionType.InsertCustomPages: DoRemoveSelectedPages(new List { history.InsertIndex }, true); 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; } } /// /// 页面编辑执行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: await InsertFromFile(history.InsertIndex, history.InsertFilePath, 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提示 /// private 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 void DoRemoveSelectedPages(List pageList = null, bool isFromUndoRedo = false) { if (!viewContentViewModel.IAPBeforeFunction()) { return; } 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) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("PageEdit_DeleteAllPage"), App.ServiceLoader.GetString("Text_ok")); return; } var result = PDFViewer.Document.RemovePages(indexList.ToArray()); if (!result) { ShowToast(); return; } //文档层操作成功后再删除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; } } /// /// 提取选中页面的方法 /// /// 是否每页生成一个文件 /// 是否提取后删除页面 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 (isEveryPageToFile) { //每页生成的单独的文件 for (int i = 0; i < pagenums.Count; i++) { string filename = PDFViewer.Document.FileName + " " + 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 + " " + 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) { DoRemoveSelectedPages(); ReloadAfterOption(true, false, Tuple.Create(0, PDFViewer.Document.PageCount)); } CommonHelper.ShowFileBrowser(selectedfile); IsLoading = Visibility.Collapsed; } private 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 = ""; if (data.Mode == HomePageSplitDialogModel.SplitMode.AveragePages) { int perPages = Convert.ToInt32(data.GetModeCount); int SplitCount = (int)Math.Ceiling((double)PageCount / (double)perPages); //TODO:命名规则是否要调整 selectedfile = data.FileName + " " + "1.pdf"; for (int i = 0; i < SplitCount; i++) { 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; } string filename = data.FileName + " " + (i + 1) + ".pdf"; string path = System.IO.Path.Combine(dialog.SelectedPath, 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); int remain = PageCount % docCount; int startNum = 1; //TODO:命名规则是否要调整 selectedfile = data.FileName + " " + "1.pdf"; for (int i = 0; i < docCount; i++) { int endNum = startNum + (avePages - 1); if (i < remain) endNum++; endNum = Math.Min(endNum, PageCount); string range = startNum + "-" + endNum; startNum = endNum + 1; string fileName = data.FileName + " " + (i + 1) + ".pdf"; string path = System.IO.Path.Combine(dialog.SelectedPath, 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 = ""; if (data.PageMode == HomePageSplitDialogModel.PageRangeMode.OddPage) { int[] page = new int[(PageCount + 1) / 2]; for (int i = 0; i < page.Length; i++) { page[i] = i * 2 + 1; } pageRange = string.Join(",", page); } else if (data.PageMode == HomePageSplitDialogModel.PageRangeMode.EvenPage) { int[] page = new int[PageCount / 2]; for (int i = 0; i < page.Length; i++) { page[i] = i * 2 + 2; } pageRange = string.Join(",", page); } List pageList1 = new List(); //如果是自定义输入页面范围的话,直接解析 CommonHelper.GetPagesInRange(ref pageList1, pageRange, PageCount, new char[] { ',' }, new char[] { '-' }); //part1 selectedfile = ""; CPDFDocument saveDoc1 = CPDFDocument.CreateDocument(); string filepath = data.FileName + " " + "1.pdf"; string path1 = Path.Combine(dialog.SelectedPath, filepath); path1 = CommonHelper.CreateFilePath(path1); bool result = saveDoc1.ImportPages(pdfViewer.Document, pageRange); if (!result) { saveDoc1.Release(); ShowToast(); return; } result = saveDoc1.WriteToFilePath(path1); if (!result) { saveDoc1.Release(); ShowToast(); return; } saveDoc1.Release(); //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"; string path2 = Path.Combine(dialog.SelectedPath, filepath2); path2 = CommonHelper.CreateFilePath(path2); result = saveDoc2.ImportPages(pdfViewer.Document, pageRange2); if (!result) { saveDoc2.Release(); ShowToast(); return; } result = saveDoc2.WriteToFilePath(path2); if (!result) { saveDoc2.Release(); ShowToast(); return; } selectedfile = path1; saveDoc2.Release(); } //显示文件夹,并选中一个文件 Process.Start("explorer", "/select,\"" + selectedfile + "\""); } catch (Exception ex) { } } /// /// 将文件插入到指定位置 /// /// public async Task InsertFromFile(int insertIndex, string filePath, string oldPassWord = null, bool isFromUndoRedo = false) { CPDFDocument doc = CPDFDocument.InitWithFilePath(filePath); if (doc == null) { ShowToast(); return false; } string password = ""; if (doc.IsLocked) { if (!string.IsNullOrEmpty(oldPassWord)) { var result = doc.UnlockWithPassword(oldPassWord); if (result) { password = oldPassWord; } } //没有传入密码,或者用传入密码解密失败是,需要弹出界面弹窗 if (doc.IsLocked) { DialogParameters value = new DialogParameters(); value.Add(ParameterNames.PDFDocument, doc); bool result = true; dialogs.ShowDialog(DialogNames.VerifyPassWordDialog, value, e => { if (e.Result != ButtonResult.OK) { result = false; } password = e.Parameters.GetValue(ParameterNames.PassWord); }); if (!result) { 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); } 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 = password; history.InsertPageCount = pageCount; history.viewmodel = this; PDFViewer.UndoManager.AddHistory(history); } 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; } PageEditItem item = new PageEditItem(); item.Size = PDFViewer.Document.GetPageSize(insertIndex); PageEditItems.Insert(insertIndex, item); ReloadAfterOption(true, false, Tuple.Create(insertIndex - 1, insertIndex + 1)); 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 (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(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 async void RotateSelectedPages(bool rightRotate = true, List pageitems = null, bool isFromUndoRedo = false) { if (!viewContentViewModel.IAPBeforeFunction()) { return; } IsLoading = Visibility.Visible; await Task.Delay(2); Dictionary items = new Dictionary(); if (pageitems == null) { //旋转选中页面 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; } } } else { //旋转对应Items集合 for (int i = 0; i < pageitems.Count; i++) { PDFViewer.RotatePage(ComPDFKitViewer.PageRotate.Rotate90, rightRotate, pageitems[i]); items.Add(pageitems[i], 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); } ReloadAfterOption(false, false, Tuple.Create(items.Keys.First(), items.Keys.Last())); IsLoading = Visibility.Collapsed; } /// /// 刷新页码 /// private void RefreshPageNum() { for (int i = 0; i < PageEditItems.Count; i++) { PageEditItems[i].PageNumber = i + 1; PageEditItems[i].ShowPageSize = ShowedPageSize == Visibility.Visible ? true : false; } } /// /// 刷新页面范围下拉框 /// 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); IsSelectFormSelf = false; } else { //选中了下拉框的选项 //增加条件,修复全选页面,但是ctrl点选取消后,选中状态不准确问题 if (index != -1) { //没有符合条件时 清空选中项 ListSelectedIndex = -1; } } } /// /// 是否显示页面尺寸 /// /// 是或否 private void ShowPageSize() { bool show = true; if (ShowedPageSize == Visibility.Visible) { show = false; ShowedPageSize = Visibility.Collapsed; } else { show = true; ShowedPageSize = Visibility.Visible; } for (int i = 0; i < PageEditItems.Count; i++) { PageEditItems[i].ShowPageSize = show; } } /// /// 从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 async void RefreshItemImage(int startIndex, int endIndex) { if (PDFViewer == null || PDFViewer.Document == null) { return; } //一个拿图比例系数,减少拿图耗时,尽量确保缩放后图片清晰度不会很差 int rate = (int)ItemSizes[2].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; } //宽高为样式中图片控件宽高 if (PageEditItems[i].isVertical) { //等比例缩小 if (PageEditItems[i].Size.Height > rate) { await PDFViewer.GetThumbnail(i, (int)(PageEditItems[i].Size.Width / (PageEditItems[i].Size.Height / rate)), rate); } else { //尺寸大小的图片 等比例放大 避免页面放大后内容模糊 await PDFViewer.GetThumbnail(i, (int)PageEditItems[i].Size.Width * (rate / (int)PageEditItems[i].Size.Height), rate); } } else { if (PageEditItems[i].Size.Width > rate) { await PDFViewer.GetThumbnail(i, rate, (int)(PageEditItems[i].Size.Height / (PageEditItems[i].Size.Width / rate))); } else { //获取横图 await PDFViewer.GetThumbnail(i, rate, (int)PageEditItems[i].Size.Height * (rate / (int)(PageEditItems[i].Size.Width))); } } } } } /// /// 拖拽排序功能 /// /// /// public void DragToSort(int targetIndex, List pageIndexs, bool IsFromUndoRedo = false) { DragSorting = true; //拖拽排序后需要重新选中项的集合 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) { DragSorting = false; 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) { DragSorting = false; 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) { DragSorting = false; 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) { DragSorting = false; return; } SourceTargetValue.Add(pageIndexs[j], newIndex); selectedPages.Add(newIndex + 1); newIndex++; } } DragSorting = false; //刷新页码和图片 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_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) { 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; } //每次进入页面编辑都刷新item个数,缩略图删减时,可以更新item //需要留意大文档性能 GetSourceItems(true); //清空一下选中项,修复进入页面编辑后仍然选中多页的问题 ListSelectedIndex = -1; ListSelectedIndex = PDFViewer.CurrentIndex; //页面编辑取消显示书签Icon //RefreshBookMarkList(); isFirstLoad = false; } } 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); } } private void PDFViewer_InfoChanged(object sender, KeyValuePair e) { if (e.Key == "PageNum" && !viewContentViewModel.isInPageEdit) { NotifyUIToRefresh(new List { (e.Value as ComPDFKitViewer.RenderData).PageIndex }); } } #endregion Navigate } }