using ComPDFKit.PDFDocument; using ComPDFKit.PDFPage; using ComPDFKitViewer.PdfViewer; using Dropbox.Api.TeamLog; using Microsoft.Office.Interop.Word; using Microsoft.Win32; using PDF_Master.CustomControl; using PDF_Master.EventAggregators; using PDF_Master.Helper; using PDF_Master.Model; using PDF_Master.Model.Dialog.ToolsDialogs; using PDF_Master.Properties; using PDF_Master.Views.Dialog; using Prism.Commands; using Prism.Events; using Prism.Mvvm; 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.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; using static Dropbox.Api.TeamLog.PaperDownloadFormat; using static PDF_Master.Model.Dialog.ToolsDialogs.SaftyDialogs.DeleteSafetySettintgsModel; namespace PDF_Master.ViewModels.Dialog.ToolsDialogs { internal class MergeDialogViewModel : BindableBase, IDialogAware { // Fix:存储当前程序加载的文档的路径和tag, //如果路径相同则用tag里的密码解锁, //解锁失败再另行提权 private string CurrentFilePath = string.Empty; private string currentLoadedPassword = string.Empty; private IEventAggregator eventAggregator; private enum PageSizeType { kDefault = 0, A4 = 1, A3 = 2, Letter = 3, Legal = 4, Customized = 5, } #region 框架内容 public string Title => ""; public event Action RequestClose; public bool CanCloseDialog() { return true; } public void OnDialogClosed() { } public void OnDialogOpened(IDialogParameters parameters) { CPDFViewer pdfViewer = null; if (parameters.TryGetValue(ParameterNames.PDFViewer, out pdfViewer) && pdfViewer != null && pdfViewer.Document != null) { VerifyPasswordResult condition = SecurityHelper.VerifyPasswordByPasswordKind(pdfViewer.Document, EnumPasswordKind.StatusPermissionsPassword, dialogs); if (condition.IsDiscryptied) { if (!string.IsNullOrEmpty(condition.Password)) { if (pdfViewer.Document.UnlockWithPassword(condition.Password)) { pdfViewer.Document.CheckOwnerPassword(condition.Password); } } string unicode; if (parameters.TryGetValue(ParameterNames.Unicode, out unicode)) { this.eventAggregator.GetEvent().Publish(new ShowTipEventArgs() { enumTipKind = EnumTipKind.StatusNone, Unicode = unicode }); } } currentLoadedPassword = pdfViewer.Document.Password; if (Settings.Default.UserDate.subscribestatus != 1) { LimitationsConvertVisible = Visibility.Visible; } } if (pdfViewer != null && pdfViewer.Document != null) { CurrentFilePath = pdfViewer.Document.FilePath; List list = new List(); list.Add(CurrentFilePath); AddFiles(list.ToArray()); } string[] Paths; parameters.TryGetValue(ParameterNames.FilePath, out Paths); if (Paths != null) { AddFiles(Paths); } } #endregion 框架内容 #region 定义与初始化 public ObservableCollection MergeObjectlist { get; set; } public DelegateCommand CancelCommand { get; set; } public DelegateCommand PreviewCancelDownCommand { get; set; } public DelegateCommand MergeCommand { get; set; } public DelegateCommand AddFilesCommand { get; set; } public DelegateCommand ClearCommand { get; set; } public DelegateCommand UnlockMouseDownCommand { get; set; } public DelegateCommand SetPageSizeTypeCommand { get; set; } public DelegateCommand CancelAddFileCommand { get; set; } public IDialogService dialogs; private PageSizeType pageSizeType = PageSizeType.kDefault; private string inputWidth; public string InputWidth { get { return inputWidth; } set { SetProperty(ref inputWidth, value); } } private Visibility processVisible = Visibility.Collapsed; /// /// 是否显示进度条 /// public Visibility ProcessVisible { get { return processVisible; } set { SetProperty(ref processVisible, value); } } private bool _AddOpenFileIsEn = false; /// /// 添加已打开文件是否置灰 /// public bool AddOpenFileIsEn { get { return _AddOpenFileIsEn; } set { SetProperty(ref _AddOpenFileIsEn, value); } } private string inputHeight; public string InputHeight { get { return inputHeight; } set { SetProperty(ref inputHeight, value); } } private double maxValue; /// /// 最大文件数 用于显示进度条 /// public double MaxValue { get { return maxValue; } set { SetProperty(ref maxValue, value); } } private double currentvalue; /// /// 当前进度值 /// public double CurrentValue { get { return currentvalue; } set { SetProperty(ref currentvalue, value); } } /// /// 订阅按钮 /// private string _TextUpgrade; public string TextUpgrade { get { return _TextUpgrade; } set { _TextUpgrade = value; } } /// /// 是否显示限制字段 /// private Visibility limitationsConvertVisible = Visibility.Hidden; public Visibility LimitationsConvertVisible { get { return limitationsConvertVisible; } set { SetProperty(ref limitationsConvertVisible, value); } } /// /// 是否取消添加文件 /// private bool CancelAddFiles = false; public MergeDialogViewModel(IDialogService dialogService, IEventAggregator eventAggregator) { IntString(); this.eventAggregator = eventAggregator; dialogs = dialogService; MergeObjectlist = new ObservableCollection(); CancelCommand = new DelegateCommand(Cancel); PreviewCancelDownCommand = new DelegateCommand(PreviewCancelDown); AddFilesCommand = new DelegateCommand(ButtonAddFiles); MergeCommand = new DelegateCommand(Merge); ClearCommand = new DelegateCommand(Clear); SetPageSizeTypeCommand = new DelegateCommand(SetPageSizeType); CancelAddFileCommand = new DelegateCommand(CancelAddFileOpention); UnlockMouseDownCommand = new DelegateCommand(UnlockMouseDown); } /// /// 多语 /// private void IntString() { TextUpgrade = App.ServiceLoader.GetString("TextUpgrade"); } #endregion 定义与初始化 #region 私有方法 private void UnlockMouseDown() { ConverterHelper.convertUnlock(); } private void CancelAddFileOpention() { CancelAddFiles = true; } private void UpDataMergeObjectIndex() { for (int i = 0; i < MergeObjectlist.Count; i++) { MergeObjectlist[i].ItemIndex = i + 1; } AddOpenFileIsEnChange(); } private void Cancel() { Clear(); RequestClose.Invoke(new DialogResult(ButtonResult.Cancel)); } /// /// 点击取消页面范围控件使失去焦点不生效 /// private void PreviewCancelDown(object e) { var listView = e as ListView; if (listView != null) { if (listView.ItemsSource != null) { foreach (var item in listView.ItemsSource) { var pagerange = listView.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem; if (pagerange != null) { var pagerangecombobox = CommonHelper.FindVisualChild(pagerange); if (pagerangecombobox != null) pagerangecombobox.IsloseFocus = false; } } } } } public void ButtonAddFiles(object data) { int index = Convert.ToInt32(data); CancelAddFiles = false; switch (index) { case 0: //打开文件 AddFiles(OpenFile()); break; case 1: //打开文件夹 AddFiles(OpenFileFolder()); break; case 2: //打开当前文件 List list = new List(); for (int i = 0; i < App.OpenedFileList.Count; i++) { list.Add(App.OpenedFileList[i]); } AddFiles(list.ToArray()); break; default: break; } } /// /// 改变添加已打开文件按钮置灰状态 /// private void AddOpenFileIsEnChange() { AddOpenFileIsEn = false; if (MergeObjectlist.Count > App.OpenedFileList.Count) { AddOpenFileIsEn = true; return; } for (int i = 0; i < App.OpenedFileList.Count; i++) { bool found = false; for (int j = 0; j < MergeObjectlist.Count; j++) { if (App.OpenedFileList[i] == MergeObjectlist[j].FilePath) { found = true; break; } } if (!found) { AddOpenFileIsEn = true; break; } } } private string[] OpenFileFolder() { System.Windows.Forms.FolderBrowserDialog openFile = new System.Windows.Forms.FolderBrowserDialog(); if (openFile.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) { return null; } DirectoryInfo tempfolder = new DirectoryInfo(openFile.SelectedPath); FileInfo[] fileInfos = tempfolder.GetFiles(); List list = new List(); foreach (FileInfo item in fileInfos) { list.Add(item.FullName); } DirectoryInfo[] directoryInfos = tempfolder.GetDirectories(); foreach (DirectoryInfo fileInfo in directoryInfos) { FileInfo[] fileinfo = fileInfo.GetFiles(); foreach (FileInfo item in fileinfo) { list.Add(item.FullName); } } return list.ToArray(); } private string[] OpenFile() { OpenFileDialog openFile = new OpenFileDialog(); openFile.Multiselect = true; openFile.Filter = Properties.Resources.imageex.ToLower() + "|*"; if (openFile.ShowDialog() == false) { return null; } return openFile.FileNames; } private void Merge() { bool result = true; CPDFDocument SaveDoc = CPDFDocument.CreateDocument(); int sum = MergeObjectlist.Count; if (Settings.Default.UserDate.subscribestatus != 1) { sum = 2; } for (int i = 0; i < sum; i++) { List listnum = new List(); if (MergeObjectlist[i].SetPageRange == null || MergeObjectlist[i].SetPageRange.Count == 0) { if (MergeObjectlist[i].SDKPageCount == 0) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("PageRangeWarning"), App.ServiceLoader.GetString("Text_ok")); return; } List pageRangeList = new List(); for (int page1 = 0; page1 < MergeObjectlist[i].SDKPageCount; page1++) { pageRangeList.Add(page1); } MergeObjectlist[i].SetPageRange = pageRangeList; } } for (int i = 0; i < sum; i++) { if (MergeObjectlist[i].SetPageRange == null) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("PageRangeWarning"), App.ServiceLoader.GetString("Text_ok")); } //图片 if (Path.GetExtension(MergeObjectlist[i].FilePath).Trim().ToLower() != ".pdf") { if (Path.GetExtension(MergeObjectlist[i].FilePath).Trim().ToLower() == ".gif") {//GIF下面方法产生虚影改成与图片转PDF一致 try { System.Drawing.Image img = System.Drawing.Image.FromFile(MergeObjectlist[i].FilePath); string tempFileName = Path.GetTempPath() + "pngtemp.jpg"; if (!PictureConverter.SaveJpeg(MergeObjectlist[i].FilePath, tempFileName)) { MessageBoxEx.Show("图片格式有问题"); } // 之前插入位置为零点导致插入为第一页,改为尾插 2023/5/24 result = SaveDoc.InsertPage(SaveDoc.PageCount, img.Width, img.Height, tempFileName); try { if (File.Exists(tempFileName)) File.Delete(tempFileName); } catch { } if (!result) { SaveDoc.Release(); return; } continue; } catch { continue; } } else { try { BitmapSource frame = MergeObjectlist[i].DocThumbnail; byte[] imageData = new byte[frame.PixelWidth * frame.PixelHeight * 4]; if (frame.Format != PixelFormats.Bgra32) { FormatConvertedBitmap covert = new FormatConvertedBitmap(frame, PixelFormats.Bgra32, frame.Palette, 0); covert.CopyPixels(imageData, frame.PixelWidth * 4, 0); } else { frame.CopyPixels(imageData, frame.PixelWidth * 4, 0); } frame.CopyPixels(imageData, frame.PixelWidth * 4, 0); // 之前插入位置为零点导致插入为第一页,改为尾插 2023/5/24 result = SaveDoc.InsertPage(SaveDoc.PageCount, frame.PixelWidth, frame.PixelHeight, imageData, CPDFDocumentImageMode.CPDFDocumentImageModeScaleToFill); if (!result) { SaveDoc.Release(); return; } continue; } catch { continue; } } } else { CPDFDocument tempDoc = CPDFDocument.InitWithFilePath(MergeObjectlist[i].FilePath); if (!string.IsNullOrEmpty(MergeObjectlist[i].Password)) { tempDoc.UnlockWithPassword(MergeObjectlist[i].Password); } if (!string.IsNullOrEmpty(MergeObjectlist[i].SetPageRangeStr)) { result = SaveDoc.ImportPages(tempDoc, MergeObjectlist[i].SetPageRangeStr); } else { //下拉框控件传出来的list是页面索引集合, //此处传给SDK的合并接口的是页码集合,因此需要将集合项遍历+1,只有合并接口是接收页码集合,其余接口是接受页面索引集合 List pageIndexs = new List(); for (int j = 0; j < MergeObjectlist[i].SetPageRange.Count; j++) { pageIndexs.Add(MergeObjectlist[i].SetPageRange[j] + 1); } result = SaveDoc.ImportPages(tempDoc, CommonHelper.GetPageParmFromList(pageIndexs)); } if (!result) { SaveDoc.Release(); tempDoc.Release(); return; } tempDoc.Release(); } } SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FileName = "Untitle"; saveFileDialog.Filter = "PDF|*.pdf;"; if (saveFileDialog.ShowDialog() == false) { return; } string path = saveFileDialog.FileName; System.Windows.Rect rect = new System.Windows.Rect(); switch (pageSizeType) { case PageSizeType.kDefault: break; case PageSizeType.A4: rect.Width = CommonHelper.GetPageSizeFomrUnit(210); rect.Height = CommonHelper.GetPageSizeFomrUnit(297); break; case PageSizeType.A3: rect.Width = CommonHelper.GetPageSizeFomrUnit(297); rect.Height = CommonHelper.GetPageSizeFomrUnit(420); break; case PageSizeType.Letter: rect.Width = CommonHelper.GetPageSizeFomrUnit(216); rect.Height = CommonHelper.GetPageSizeFomrUnit(279); break; case PageSizeType.Legal: rect.Width = CommonHelper.GetPageSizeFomrUnit(216); rect.Height = CommonHelper.GetPageSizeFomrUnit(356); break; case PageSizeType.Customized: if (!string.IsNullOrEmpty(InputWidth) && !string.IsNullOrEmpty(InputHeight)) { rect.Width = CommonHelper.GetPageSizeFomrUnit(Convert.ToInt32(InputWidth)); rect.Height = CommonHelper.GetPageSizeFomrUnit(Convert.ToInt32(InputHeight)); } else { rect.Width = CommonHelper.GetPageSizeFomrUnit(595); rect.Height = CommonHelper.GetPageSizeFomrUnit(841); } break; default: break; } if (rect.Width > 0 && rect.Height > 0) { //裁剪 for (int i = 0; i < SaveDoc.PageCount; i++) { CPDFPage page = SaveDoc.PageAtIndex(i); page.CropPage(CPDFDisplayBox.MediaBox, rect); } } bool saveResult = SaveDoc.WriteToFilePath(path); SaveDoc.Release(); CommonHelper.ShowFileBrowser(path); DialogParameters valuePairs = new DialogParameters(); valuePairs.Add(ParameterNames.FilePath, path); RequestClose.Invoke(new DialogResult(ButtonResult.OK, valuePairs)); } private void Clear() { MergeObjectlist.Clear(); AddOpenFileIsEn = false; } private void SetPageSizeType(object button) { if (button is RadioButton) { pageSizeType = (PageSizeType)Convert.ToInt32((button as RadioButton).Tag); } } #endregion 私有方法 #region 公开方法 public void DeleteItem(MergeObject merge) { MergeObjectlist.Remove(merge); UpDataMergeObjectIndex(); } /// /// 拖拽插入 /// public void MoveMerge(MergeObject targetNode, MergeObject soureNode) { int targetindex = MergeObjectlist.IndexOf(targetNode); MergeObjectlist.Remove(soureNode); if (targetNode.IsForward) { if (targetindex + 1 < MergeObjectlist.Count) { MergeObjectlist.Insert(targetindex + 1, soureNode); } else { MergeObjectlist.Add(soureNode); } } else { MergeObjectlist.Insert(targetindex, soureNode); } UpDataMergeObjectIndex(); } public async void AddFiles(string[] FilePath) { if (FilePath == null) { return; } // 免费用户 限制只选两个文件的逻辑 //if (Settings.Default.UserDate.subscribestatus != 1 && MergeObjectlist.Count >= 2) //{ // return; //} bool showDialog = false; ProcessVisible = Visibility.Visible; MaxValue = FilePath.Length; // 免费用户 限制只选两个文件的逻辑 //int sum = SetFilesLength(FilePath); for (int i = 0; i < FilePath.Length; i++) { //加入异步语句,防止UI卡死,显示加载进度条 await System.Threading.Tasks.Task.Delay(1); //如果中断了文件添加,则取消循环 if (CancelAddFiles) { break; } MergeObject mergeObject = new MergeObject(); mergeObject.FilePath = FilePath[i]; //通过路径判断文件是否已添加 bool IsExists = false; for (int j = 0; j < MergeObjectlist.Count; j++) { if (MergeObjectlist[j].FilePath == mergeObject.FilePath) { IsExists = true; } } if (IsExists) { continue; } string FileType = Path.GetExtension(mergeObject.FilePath).Trim().ToLower(); if (string.IsNullOrEmpty(FileType)) { showDialog = true; //获取不到文件类型 continue; } if (FileType != ".pdf") { string imagetype = "*" + FileType; string[] x = Properties.Resources.imageex.ToLower().Split(';'); List list = x.ToList(); int imageindex = list.IndexOf(imagetype); if (imageindex < 0) { showDialog = true; //图片格式不支持 continue; }; mergeObject.DocName = Path.GetFileName(mergeObject.FilePath); mergeObject.DocPageCount = 1 + " " + App.MainPageLoader.GetString("Merge_ItemPages"); mergeObject.SDKPageCount = 1; mergeObject.SetPageRange = new List() { 0 }; mergeObject.DocSize = CommonHelper.GetFileSize(mergeObject.FilePath); try { mergeObject.DocThumbnail = new BitmapImage(new Uri(mergeObject.FilePath)); } catch (Exception) { showDialog = true; //解码错误 continue; } } else { CPDFDocument doc = CPDFDocument.InitWithFilePath(mergeObject.FilePath); if (doc == null) { showDialog = true; //PDF打开失败 continue; } ///Fix: ///情况分为: ///开启路径是当前路径: ///已解锁或本身就无密码->直接加入 ///未解锁-> release /// /// 不是当前路径 ///解锁或取消-> /// if (CurrentFilePath == doc.FilePath) { if ((!(!doc.IsLocked && (SecurityHelper.CheckHaveAllPermissions(doc)))) && (!(!string.IsNullOrEmpty(currentLoadedPassword) && doc.UnlockWithPassword(currentLoadedPassword) && (doc.CheckOwnerPassword(currentLoadedPassword) || SecurityHelper.CheckHaveAllPermissions(doc))))) { doc.Release(); continue; } //添加的第一个文档有权限密码时,保存密码,避免合并时因没有密码导致合并失败 //表现为在首页打开一个带权限的文档进入合并,点击合并按钮没有反应 if (!string.IsNullOrEmpty(currentLoadedPassword)) { mergeObject.Password = currentLoadedPassword; } } else { VerifyPasswordResult condition = new VerifyPasswordResult(); App.Current.Dispatcher.Invoke(() => { //切换一下UI线程,避免解密弹窗异常 condition = SecurityHelper.VerifyPasswordByPasswordKind(doc, EnumPasswordKind.StatusPermissionsPassword, dialogs); }); if (condition.IsDiscryptied) { if (condition.Password != null) { mergeObject.Password = condition.Password; if (doc.UnlockWithPassword(condition.Password) && doc.CheckOwnerPassword(condition.Password)) { } } } else { doc.Release(); continue; } } mergeObject.DocName = doc.FileName; if (doc.PageCount > 1) { mergeObject.DocPageCount = doc.PageCount.ToString() + " " + App.MainPageLoader.GetString("Merge_ItemPages"); mergeObject.IsEvenPageIsEnabled = true; } else { mergeObject.DocPageCount = doc.PageCount.ToString() + " " + App.MainPageLoader.GetString("Merge_ItemPage"); mergeObject.IsEvenPageIsEnabled = false; } mergeObject.SDKPageCount = doc.PageCount; mergeObject.DocSize = CommonHelper.GetFileSize(mergeObject.FilePath); //获取第一页缩略图 CPDFPage page = doc.PageAtIndex(0); Size size = doc.GetPageSize(0); byte[] bmpData = new byte[(int)(size.Width * size.Height * 4)]; WriteableBitmap WirteBitmap = new WriteableBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Bgra32, null); page.RenderPageBitmap(0, 0, (int)size.Width, (int)size.Height, 0xFFFFFFFF, bmpData, 1); WirteBitmap.WritePixels(new Int32Rect(0, 0, (int)size.Width, (int)size.Height), bmpData, WirteBitmap.BackBufferStride, 0); WirteBitmap.Freeze(); mergeObject.DocThumbnail = WirteBitmap; doc.Release(); } App.Current.Dispatcher.Invoke(() => { MergeObjectlist.Add(mergeObject); }); CurrentValue = i; UpDataMergeObjectIndex(); } ProcessVisible = Visibility.Collapsed; if (showDialog) { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", App.MainPageLoader.GetString("ErrorFile_Warning"), App.ServiceLoader.GetString("Text_ok")); if (alertsMessage.result == ContentResult.Ok) { } } } /// /// 未购买的用户 设置文件数量 /// /// /// private int SetFilesLength(string[] filePath) { int sum = filePath.Length; if (Settings.Default.UserDate.subscribestatus != 1 && sum >= 2) { if (MergeObjectlist.Count >= 1) { sum = 1; } else { sum = 2; } } return sum; } #endregion 公开方法 } }