RedactionContentViewModel.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. using ComPDFKit.Import;
  2. using ComPDFKit.PDFAnnotation;
  3. using ComPDFKit.PDFPage;
  4. using ComPDFKitViewer;
  5. using ComPDFKitViewer.AnnotEvent;
  6. using ComPDFKitViewer.PdfViewer;
  7. using PDF_Master.CustomControl;
  8. using PDF_Master.EventAggregators;
  9. using PDF_Master.Model;
  10. using PDF_Master.Properties;
  11. using Prism.Commands;
  12. using Prism.Events;
  13. using Prism.Mvvm;
  14. using Prism.Regions;
  15. using Prism.Services.Dialogs;
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Windows;
  20. using System.Windows.Controls;
  21. using System.Windows.Input;
  22. using System.Windows.Media;
  23. namespace PDF_Master.ViewModels.EditTools.Redaction
  24. {
  25. public class RedactionContentViewModel : BindableBase, INavigationAware
  26. {
  27. public IEventAggregator eventAggregator;
  28. public IRegionManager redactionRegion;
  29. public IDialogService dialogs;
  30. private CPDFViewer PDFViewer;
  31. private ViewContentViewModel viewContentViewModel;
  32. private RedactionAnnotArgs redactionArgs = new RedactionAnnotArgs();
  33. public string RedactionDocumentRegionName { get; set; }
  34. public string RedactionBottomBarRegionName { get; set; }
  35. public string RedactionDocumentName = "RedactionDocumentContent";
  36. public string Unicode = null;
  37. public DelegateCommand CloseEditToolCommand { get; set; }
  38. public DelegateCommand<string> ApplyCommmand { get; set; }
  39. public DelegateCommand PageRedactionCommand { get; set; }
  40. public DelegateCommand<string> EraseCommand { get; set; }
  41. public RedactionCommandEventArgs TempArgs { get; set; }
  42. private int currentPage = 0;
  43. /// <summary>
  44. /// 是否因为本身传递值 防止循环调用
  45. /// </summary>
  46. private bool isFromSelf = false;
  47. public int CurrentPage
  48. {
  49. get { return currentPage; }
  50. set
  51. {
  52. SetProperty(ref currentPage, value);
  53. if (value >= 1 && value <= PDFViewer.Document.PageCount && !isFromSelf)
  54. {
  55. PDFViewer.GoToPage(value - 1);
  56. }
  57. }
  58. }
  59. private int pageCount = 0;
  60. public int PageCount
  61. {
  62. get { return pageCount; }
  63. set
  64. {
  65. SetProperty(ref pageCount, value);
  66. }
  67. }
  68. private bool isEnable = false;
  69. /// <summary>
  70. /// 按钮是否启用
  71. /// </summary>
  72. public bool IsEnable
  73. {
  74. get { return isEnable; }
  75. set
  76. {
  77. SetProperty(ref isEnable, value);
  78. }
  79. }
  80. public RedactionContentViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IDialogService dialogService)
  81. {
  82. this.redactionRegion = regionManager;
  83. this.eventAggregator = eventAggregator;
  84. this.dialogs = dialogService;
  85. RedactionDocumentRegionName = Guid.NewGuid().ToString();
  86. Unicode = App.mainWindowViewModel.SelectedItem.Unicode;
  87. CloseEditToolCommand = new DelegateCommand(CloseEditTool);
  88. ApplyCommmand = new DelegateCommand<string>(apply,CanExcute).ObservesProperty(() => IsEnable);
  89. EraseCommand = new DelegateCommand<string>(erase, CanExcute).ObservesProperty(() => IsEnable);
  90. PageRedactionCommand = new DelegateCommand(pageMark);
  91. eventAggregator.GetEvent<RedactionCommandEvent>().Subscribe(SetContextMenu, e => e.UniCode == Unicode);
  92. }
  93. private void SetContextMenu(RedactionCommandEventArgs obj)
  94. {
  95. var contextmenu = App.Current.FindResource("RedactionContextMenu") as ContextMenu;
  96. obj.args.PopupMenu = contextmenu;
  97. TempArgs = obj;
  98. for(int i=0;i<contextmenu.Items.Count;i++)
  99. {
  100. if(contextmenu.Items[i] is MenuItem)
  101. {
  102. var item = contextmenu.Items[i] as MenuItem;
  103. switch (item.Name)
  104. {
  105. case "MenuDelete":
  106. item.Command = ApplicationCommands.Delete;
  107. item.CommandParameter = (UIElement)obj.Sender;
  108. break;
  109. case "MenuSetDeufalt":
  110. item.Command = new DelegateCommand<RedactionCommandEventArgs>(SetDefualtProperty);
  111. item.CommandParameter = obj;
  112. break;
  113. case "MenuProperties":
  114. item.Command = new DelegateCommand<RedactionCommandEventArgs>(ShowProperty);
  115. item.CommandParameter = obj;
  116. break;
  117. case "MenuRepeat":
  118. item.Command = new DelegateCommand<RedactionCommandEventArgs>(RepreatMark);
  119. item.CommandParameter = obj;
  120. break;
  121. case "MenuApply":
  122. item.Command = this.ApplyCommmand;
  123. item.CommandParameter = "Single";
  124. break;
  125. case "MenuErase":
  126. item.Command = this.EraseCommand;
  127. item.CommandParameter = "Single";
  128. break;
  129. default:
  130. break;
  131. }
  132. }
  133. }
  134. }
  135. /// <summary>
  136. /// 设置当前为默认属性
  137. /// </summary>
  138. /// <param name="args"></param>
  139. private void SetDefualtProperty(RedactionCommandEventArgs args)
  140. {
  141. var annoteargs = args.args.AnnotEventArgsList[0] as RedactionAnnotArgs;
  142. DialogParameters keyValues = new DialogParameters();
  143. keyValues.Add(ParameterNames.DataModel,args.args.AnnotEventArgsList[0] as RedactionAnnotArgs);
  144. Settings.Default.RedactionsSettings.SetDefualtValue(
  145. annoteargs.Content,
  146. annoteargs.LineColor,
  147. annoteargs.BgColor,
  148. annoteargs.FontColor,
  149. (int)annoteargs.FontSize,
  150. string.IsNullOrEmpty(annoteargs.Content) ? false : true,
  151. annoteargs.Align,
  152. annoteargs.FontName,
  153. annoteargs.FontWeight);
  154. PDFViewer.SetMouseMode(MouseModes.AnnotCreate);
  155. PDFViewer.SetToolParam(annoteargs);
  156. }
  157. /// <summary>
  158. /// 显示属性弹窗
  159. /// </summary>
  160. /// <param name="args"></param>
  161. private void ShowProperty(RedactionCommandEventArgs args)
  162. {
  163. DialogParameters keyValues = new DialogParameters();
  164. keyValues.Add(ParameterNames.DataModel, args.args.AnnotEventArgsList[0] as RedactionAnnotArgs);
  165. dialogs.ShowDialog(DialogNames.MarkSettingDialog,keyValues,null);
  166. }
  167. /// <summary>
  168. /// 显示跨页标记弹窗
  169. /// </summary>
  170. /// <param name="args"></param>
  171. private void RepreatMark(RedactionCommandEventArgs args)
  172. {
  173. DialogParameters keyValues = new DialogParameters();
  174. keyValues.Add(ParameterNames.PageCount,PDFViewer.Document.PageCount);
  175. dialogs.ShowDialog(DialogNames.RepeatMarkDialog, keyValues, e=> {
  176. if (e.Result == ButtonResult.OK)
  177. {
  178. PDFViewer.AddRedaction(e.Parameters.GetValue<List<int>>(ParameterNames.PageList), args.args);
  179. }
  180. });
  181. }
  182. /// <summary>
  183. /// 应用
  184. /// </summary>
  185. private void apply(string type)
  186. {
  187. AlertsMessage alertsMessage = new AlertsMessage();
  188. alertsMessage.ShowDialog("Apply Redactions", "Use blank blocks to remove selected sensitive content." +
  189. "This action will permanently delete the marked ciphertext information from this document and you will not be able to retrieve the marked ciphertext information.", "Cancel", "Apply & Save As");
  190. if (alertsMessage.result == ContentResult.Ok)
  191. {
  192. if (!string.IsNullOrEmpty(type) && type == "All")
  193. {
  194. viewContentViewModel.saveAsFile(applyAll);
  195. }
  196. else
  197. {
  198. viewContentViewModel.saveAsFile(applySingle);
  199. }
  200. }
  201. }
  202. /// <summary>
  203. /// 擦除
  204. /// </summary>
  205. private void erase(string type)
  206. {
  207. AlertsMessage alertsMessage = new AlertsMessage();
  208. alertsMessage.ShowDialog("","Replace selected sensitive content with color blocks."+
  209. "This action will permanently delete the marked ciphertext information from this document and you will not be able to retrieve the marked ciphertext information.", "Cancel", "Apply & Save As");
  210. if (alertsMessage.result == ContentResult.Ok)
  211. {
  212. if (!string.IsNullOrEmpty(type) && type == "All")
  213. {
  214. viewContentViewModel.saveAsFile(eraseAll);
  215. }
  216. else
  217. {
  218. viewContentViewModel.saveAsFile(eraseSingle);
  219. }
  220. }
  221. }
  222. /// <summary>
  223. /// 应用所有密文块
  224. /// </summary>
  225. private void applyAll()
  226. {
  227. PDFViewer.Document.ApplyRedaction();
  228. PDFViewer.Document.ReleasePages();
  229. PDFViewer.ReloadDocument();
  230. }
  231. /// <summary>
  232. /// 擦除所有密文块
  233. /// </summary>
  234. private void eraseAll()
  235. {
  236. for (int i = 0; i < PDFViewer.Document.PageCount; i++)
  237. {
  238. //获取页面Page对象
  239. var page = PDFViewer.Document.PageAtIndex(i);
  240. var annots = PDFViewer.GetAnnotCommentList(i, PDFViewer.Document);
  241. //循环擦除当前页的标记密文
  242. for (int j = 0; j < annots.Count; j++)
  243. {
  244. if (annots[j].EventType == AnnotArgsType.AnnotRedaction)
  245. {
  246. foreach (var rect in (annots[j] as RedactionAnnotArgs).QuardRects)
  247. {
  248. page.ErasureRedaction(rect);
  249. }
  250. }
  251. }
  252. }
  253. }
  254. /// <summary>
  255. /// 应用选中的密文块
  256. /// </summary>
  257. private void applySingle()
  258. {
  259. AnnotCommandArgs annotCommand =TempArgs.args;
  260. if (annotCommand != null)
  261. {
  262. List<RedactionAnnotArgs> redactionList = new List<RedactionAnnotArgs>();
  263. foreach (AnnotHandlerEventArgs annotArgs in annotCommand.AnnotEventArgsList)
  264. {
  265. if (annotArgs.EventType == AnnotArgsType.AnnotRedaction)
  266. {
  267. redactionList.Add((RedactionAnnotArgs)annotArgs);
  268. }
  269. }
  270. PDFViewer.ApplyRedaction(redactionList);
  271. }
  272. }
  273. /// <summary>
  274. /// 擦除选中的密文块
  275. /// </summary>
  276. private void eraseSingle()
  277. {
  278. AnnotCommandArgs annotCommand = TempArgs.args;
  279. if (annotCommand != null)
  280. {
  281. List<RedactionAnnotArgs> redactionList = new List<RedactionAnnotArgs>();
  282. foreach (AnnotHandlerEventArgs annotArgs in annotCommand.AnnotEventArgsList)
  283. {
  284. if (annotArgs.EventType == AnnotArgsType.AnnotRedaction)
  285. {
  286. foreach (var rect in (annotArgs as RedactionAnnotArgs).QuardRects)
  287. {
  288. var page = PDFViewer.Document.PageAtIndex((annotArgs as RedactionAnnotArgs).PageIndex);
  289. page.ErasureRedaction(rect);
  290. }
  291. }
  292. }
  293. }
  294. }
  295. private bool CanExcute(string type)
  296. {
  297. return IsEnable;
  298. }
  299. private void pageMark()
  300. {
  301. DialogParameters valuePairs = new DialogParameters();
  302. valuePairs.Add(ParameterNames.PageCount,PDFViewer.Document.PageCount);
  303. valuePairs.Add(ParameterNames.CurrentPageIndex,PDFViewer.CurrentIndex);
  304. dialogs.ShowDialog(DialogNames.PageMarkDialog,valuePairs,e=> {
  305. if(e.Result == ButtonResult.OK)
  306. {
  307. var pagelist = e.Parameters.GetValue<List<int>>(ParameterNames.PageList);
  308. addMarkToPages(pagelist);
  309. }
  310. });
  311. }
  312. private void addMarkToPages(List<int> list)
  313. {
  314. foreach (var page in list)
  315. {
  316. //根据页面大小,创建标记密文注释
  317. CPDFPage docPage = PDFViewer.Document.PageAtIndex(page);
  318. CPDFRedactAnnotation redactionAnnot = docPage.CreateAnnot(C_ANNOTATION_TYPE.C_ANNOTATION_REDACT) as CPDFRedactAnnotation;
  319. if (redactionAnnot == null)
  320. {
  321. //TODO 操作失败
  322. return;
  323. }
  324. redactionAnnot.SetQuardRects(new List<CRect>() { new CRect(0, (float)docPage.PageSize.Height, (float)docPage.PageSize.Width,0)});
  325. if (redactionArgs == null)
  326. return;
  327. byte[] lineColor = { redactionArgs.LineColor.R, redactionArgs.LineColor.G, redactionArgs.LineColor.B };
  328. redactionAnnot.SetOutlineColor(lineColor);
  329. if (redactionArgs.BgColor != Colors.Transparent)
  330. {
  331. byte[] bgColor = { redactionArgs.BgColor.R, redactionArgs.BgColor.G, redactionArgs.BgColor.B };
  332. redactionAnnot.SetFillColor(bgColor);
  333. }
  334. else
  335. {
  336. // redactionAnnot.ClearBgColor();
  337. }
  338. CTextAttribute textAttr = new CTextAttribute();
  339. byte[] fontColor = { redactionArgs.FontColor.R, redactionArgs.FontColor.G, redactionArgs.FontColor.B };
  340. textAttr.FontColor = fontColor;
  341. textAttr.FontSize = (float)redactionArgs.FontSize;
  342. redactionAnnot.SetTextAttribute(textAttr);
  343. switch (redactionArgs.Align)
  344. {
  345. case TextAlignment.Left:
  346. redactionAnnot.SetTextAlignment(C_TEXT_ALIGNMENT.ALIGNMENT_LEFT);
  347. break;
  348. case TextAlignment.Center:
  349. redactionAnnot.SetTextAlignment(C_TEXT_ALIGNMENT.ALIGNMENT_CENTER);
  350. break;
  351. case TextAlignment.Right:
  352. redactionAnnot.SetTextAlignment(C_TEXT_ALIGNMENT.ALIGNMENT_RIGHT);
  353. break;
  354. default:
  355. redactionAnnot.SetTextAlignment(C_TEXT_ALIGNMENT.ALIGNMENT_LEFT);
  356. break;
  357. }
  358. //byte transparency = (byte)Math.Round(redactionArgs.Transparency * 255);
  359. //redactionAnnot.SetTransparency(transparency);
  360. redactionAnnot.SetBorderWidth(1);
  361. //redactionAnnot.SetRect(new CRect(Left, Bottom, Right, Top));
  362. //redactionAnnot.SetCreationDate(Helpers.GetCurrentPdfTime());
  363. if (string.IsNullOrEmpty(Settings.Default.AppProperties.Description.Author))
  364. {
  365. redactionAnnot.SetAuthor(Settings.Default.AppProperties.Description.Author);
  366. }
  367. if (redactionArgs.Content != null && redactionArgs.Content != string.Empty)
  368. {
  369. redactionAnnot.SetOverlayText(redactionArgs.Content);
  370. }
  371. if (redactionAnnot.GetIsLocked() != redactionArgs.Locked)
  372. {
  373. redactionAnnot.SetIsLocked(redactionArgs.Locked);
  374. }
  375. redactionAnnot.UpdateAp();
  376. redactionAnnot.ReleaseAnnot();
  377. }
  378. }
  379. public void CloseEditTool()
  380. {
  381. bool isClose = true;
  382. if (CheckHasRedactionAnnote())
  383. {
  384. AlertsMessage alertsMessage = new AlertsMessage();
  385. alertsMessage.ShowDialog("", "There are unapplied redactions in this file. Exit will not save redaction.", "Cancel", "Exit");
  386. if (alertsMessage.result != ContentResult.Ok)
  387. {
  388. isClose = false;
  389. }
  390. }
  391. if(isClose)
  392. {
  393. PDFViewer.SetMouseMode(MouseModes.PanTool);
  394. redactionRegion.Regions[RegionNames.ViwerRegionName].Remove(PDFViewer);
  395. redactionRegion.Regions[RedactionDocumentRegionName].Remove(PDFViewer);
  396. this.eventAggregator.GetEvent<CloseEditToolEvent>().Publish(new EnumCloseModeUnicode { Unicode = this.Unicode, Status = EnumCloseMode.StatusCancel });
  397. App.mainWindowViewModel.SelectedItem.IsInReadctonMode = false;
  398. }
  399. }
  400. /// <summary>
  401. /// 检查是否有未应用的标记密文
  402. /// </summary>
  403. private bool CheckHasRedactionAnnote()
  404. {
  405. for (int i = 0; i < PDFViewer.Document.PageCount; i++)
  406. {
  407. var items = PDFViewer.GetAnnotCommentList(i, PDFViewer.Document);
  408. for (int j = 0; j < items.Count; j++)
  409. {
  410. if (items[j].EventType == AnnotArgsType.AnnotRedaction)
  411. {
  412. return true;
  413. }
  414. }
  415. }
  416. return false;
  417. }
  418. #region Navigation
  419. public bool IsNavigationTarget(NavigationContext navigationContext)
  420. {
  421. return true;
  422. }
  423. public void OnNavigatedFrom(NavigationContext navigationContext)
  424. {
  425. }
  426. public void OnNavigatedTo(NavigationContext navigationContext)
  427. {
  428. App.mainWindowViewModel.SelectedItem.IsInReadctonMode = true;
  429. navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
  430. navigationContext.Parameters.TryGetValue<ViewContentViewModel>(ParameterNames.ViewContentViewModel, out viewContentViewModel);
  431. PDFViewer.InfoChanged -= PDFViewer_InfoChanged;
  432. PDFViewer.InfoChanged += PDFViewer_InfoChanged;
  433. PDFViewer.AnnotEditHandler -= PDFViewer_AnnotEditHandler;
  434. PDFViewer.AnnotEditHandler += PDFViewer_AnnotEditHandler;
  435. CurrentPage = PDFViewer.CurrentIndex + 1;
  436. PageCount = PDFViewer.Document.PageCount;
  437. if (!redactionRegion.Regions[RedactionDocumentRegionName].Views.Contains(PDFViewer))
  438. {
  439. redactionArgs = new RedactionAnnotArgs();
  440. AnnotHandlerEventArgs annotArgs = null;
  441. redactionArgs.LineColor = Settings.Default.RedactionsSettings.LineColor;
  442. redactionArgs.BgColor = Settings.Default.RedactionsSettings.BgColor;
  443. redactionArgs.FontColor = Settings.Default.RedactionsSettings.FontColor;
  444. redactionArgs.Align = Settings.Default.RedactionsSettings.Align;
  445. redactionArgs.FontSize = Settings.Default.RedactionsSettings.FontSize;
  446. redactionArgs.Content = Settings.Default.RedactionsSettings.Content;
  447. if (!Settings.Default.RedactionsSettings.isUseText)
  448. {
  449. redactionArgs.Content = "";
  450. }
  451. annotArgs = redactionArgs;
  452. if (annotArgs != null)
  453. {
  454. //设置注释作者
  455. annotArgs.Author = Settings.Default.AppProperties.Description.Author;
  456. PDFViewer.SetMouseMode(MouseModes.AnnotCreate);
  457. PDFViewer.SetToolParam(annotArgs);
  458. }
  459. redactionRegion.AddToRegion(RedactionDocumentRegionName, PDFViewer);
  460. }
  461. }
  462. private void PDFViewer_AnnotEditHandler(object sender, List<AnnotEditEvent> e)
  463. {
  464. //添加注释后检测是否有未应用的标记密文注释
  465. IsEnable = false;
  466. for(int i=0;i<PDFViewer.Document.PageCount;i++)
  467. {
  468. var annotes = PDFViewer.GetAnnotCommentList(i,PDFViewer.Document);
  469. for(int j=0;j<annotes.Count;j++)
  470. {
  471. if(annotes[j].EventType == AnnotArgsType.AnnotRedaction)
  472. {
  473. IsEnable = true;
  474. return;
  475. }
  476. }
  477. }
  478. }
  479. private void PDFViewer_InfoChanged(object sender, KeyValuePair<string, object> e)
  480. {
  481. isFromSelf = true;
  482. if(e.Key=="PageNum")
  483. {
  484. var data = e.Value as RenderData;
  485. CurrentPage = data.PageIndex;
  486. }
  487. isFromSelf = false;
  488. }
  489. #endregion
  490. }
  491. }