using ComPDFKit.PDFDocument; using ComPDFKit.PDFDocument.Action; using ComPDFKit.PDFPage; using ComPDFKitViewer.PdfViewer; using PDF_Master.CustomControl; using PDF_Master.Model; using PDF_Master.Model.BOTA; using Prism.Commands; using Prism.Mvvm; using Prism.Regions; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; namespace PDF_Master.ViewModels.BOTA { class OutLineControlViewModel : BindableBase, INavigationAware { #region 文案 private string T_title; public string T_Title { get { return T_title; } set { SetProperty(ref T_title, value); } } private string T_expand; public string T_Expand { get { return T_expand; } set { SetProperty(ref T_expand, value); } } private string T_collapse; public string T_Collapse { get { return T_collapse; } set { SetProperty(ref T_collapse, value); } } private string T_removeAll; public string T_RemoveAll { get { return T_removeAll; } set { SetProperty(ref T_removeAll, value); } } private void InitString() { T_Title = App.MainPageLoader.GetString("Outline_Title"); T_Expand = App.MainPageLoader.GetString("Outline_Expand"); T_Collapse = App.MainPageLoader.GetString("Outline_Collapse"); T_RemoveAll = App.MainPageLoader.GetString("Outline_RemoveAll"); } #endregion private string PageDefaultName = ""; //缩略图相关全局变量,减少内存申请次数 private WriteableBitmap WirteBitmap; private byte[] bmpData; private CPDFViewer PDFViewer; public ObservableCollection Outlinelist { get; set; } private bool isInsertHead = false; /// /// 是否为插入最顶部 /// public bool IsInsertHead { get { return isInsertHead; } set { SetProperty(ref isInsertHead, value); } } private bool isOnDrop = false; public bool IsOnDrop { get { return isOnDrop; } set { isOnDrop = value; } } public DelegateCommand> CollapseAllCommand { get; set; } public DelegateCommand> ExpandAllCommand { get; set; } public DelegateCommand DeleteAllCommand { get; set; } public DelegateCommand DowngradeCommand { get; set; } public OutLineControlViewModel() { Outlinelist = new ObservableCollection(); DeleteAllCommand = new DelegateCommand(DeleteAll); CollapseAllCommand = new DelegateCommand>(CollapseAll); ExpandAllCommand = new DelegateCommand>(ExpandAll); InitString(); } public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } public void OnNavigatedFrom(NavigationContext navigationContext) { return; } public void OnNavigatedTo(NavigationContext navigationContext) { navigationContext.Parameters.TryGetValue(ParameterNames.PDFViewer, out PDFViewer); if (PDFViewer == null) { return; } List datasource = PDFViewer.Document.GetOutlineList(); Outlinelist.Clear(); foreach (CPDFOutline item in datasource) { OutlineNode dto = ConvertCPDFToOutlineNode(item, null, false); if (dto != null) { Outlinelist.Add(dto); } } if (Outlinelist.Count>0) { //如果是第一条数据不允许点击降级 Outlinelist[0].CanDown = false; } PDFViewer.GetCreateOutLineInfo(); } /// /// 更新大纲数据,并保存状态设置为true /// public void Updata(bool IsMoveData) { PDFViewer.Document.ReleaseOutlineList(); ObservableCollection list = new ObservableCollection(); List datasource = PDFViewer.Document.GetOutlineList(); //遍历,转换UI状态存入临时数组 foreach (CPDFOutline item in datasource) { OutlineNode dto = ConvertCPDFToOutlineNode(item, null, IsMoveData); if (dto != null) { list.Add(dto); } } if (list.Count>0) { //如果是第一条数据不允许点击降级 list[0].CanDown = false; } //清空绑定数组,并填充新数据 Outlinelist.Clear(); foreach (OutlineNode item in list) { Outlinelist.Add(item); } PDFViewer.UndoManager.CanSave = true; } /// /// 设置当前大纲对象的Title /// public bool SetTitle(CPDFOutline cPDFOutline, string Title) { if (cPDFOutline == null) { return false; } return cPDFOutline.SetTitle(Title); } /// /// 跳转到指定位置或者URL动作 /// public void GoToPage(TreeViewItem treeViewItem) { OutlineNode outline = treeViewItem.DataContext as OutlineNode; if (outline == null) { return; } CPDFAction action = outline.Outline.GetAction(); if (action != null && action.ActionType != C_ACTION_TYPE.ACTION_TYPE_UNKNOWN) { PDFViewer.ProcessAction(action); } else if(!string.IsNullOrEmpty(outline.PageIndex)) { Size size = PDFViewer.Document.GetPageSize(Convert.ToInt32(outline.PageIndex) - 1); if (outline.PositionX == -1) { outline.PositionX = 0; } if (outline.PositionY == -1) { outline.PositionY = size.Height; } PDFViewer.GoToPage(Convert.ToInt32(outline.PageIndex) - 1, new Point(outline.PositionX, size.Height - outline.PositionY)); } } /// /// 收起所有展开 /// public void CollapseAll(ObservableCollection outlineNodes) { foreach (var item in outlineNodes) { item.IsExpanded = false; if (item.Chlidlist.Count > 0) { CollapseAll(item.Chlidlist); } } } /// /// 展开所有大纲 /// public void ExpandAll(ObservableCollection outlineNodes) { foreach (var item in outlineNodes) { item.IsExpanded = true; if (item.Chlidlist.Count > 0) { ExpandAll(item.Chlidlist); } } } /// /// 更改目标位置 /// public void ChangeOutLineDestination(OutlineNode outline) { List textSelectNodes = PDFViewer.GetCreateOutLineInfo(); CPDFDestination info = new CPDFDestination(); info.PageIndex = textSelectNodes[0].PageIndex; Size size = PDFViewer.Document.GetPageSize(textSelectNodes[0].PageIndex); info.Position_X = (float)(size.Width - textSelectNodes[0].StartPoint.X); info.Position_Y = (float)(size.Height - textSelectNodes[0].StartPoint.Y); outline.Outline.SetDestination(PDFViewer.Document, info); Updata(false); } /// /// 添加大纲 /// public int AddOutLine(OutlineNode outline) { int ItemIndex = 0; List textSelectNodes = PDFViewer.GetCreateOutLineInfo(); CPDFDestination info = new CPDFDestination(); if (textSelectNodes.Count <= 0) { //SDK出错了 return -1; } info.PageIndex = textSelectNodes[0].PageIndex; Size size = PDFViewer.Document.GetPageSize(info.PageIndex); info.Position_X = (float)(textSelectNodes[0].StartPoint.X); info.Position_Y = (float)(size.Height - textSelectNodes[0].StartPoint.Y); CPDFOutline dto = null; //当前有选中大纲列表 if (outline != null) { CPDFOutline parentoutline = outline.Outline.GetParent(); if (parentoutline == null) { //获取父级失败,直接添加在根节点最下方 PDFViewer.Document.GetOutlineList(); CPDFOutline parent = PDFViewer.Document.GetOutlineRoot(); if (!parent.InsertChildAtIndex(PDFViewer.Document, parent.ChildList.Count, ref dto)) { //SDK出错了 return -1; } ItemIndex = parent.ChildList.Count; } else { //获取父节点成功,添加在父节点中选中项下方 int index = GetOutlinesIndexFormParent(parentoutline, outline.Outline); parentoutline.InsertChildAtIndex(PDFViewer.Document, index, ref dto); ItemIndex = index + 1; } } else { //未选中数据,直接添加在根节点最下方 PDFViewer.Document.GetOutlineList(); CPDFOutline parent = PDFViewer.Document.GetOutlineRoot(); if (!parent.InsertChildAtIndex(PDFViewer.Document, parent.ChildList.Count, ref dto)) { //SDK出错了 return -1; } ItemIndex = parent.ChildList.Count; } ///当前没有选中文字 if (string.IsNullOrEmpty(textSelectNodes[0].SelectText)) { string addPageName = PageDefaultName + (textSelectNodes[0].PageIndex + 1).ToString(); if (!dto.SetTitle(addPageName)) { //SDK出错了 return -1; } } else { string addPageName = PageDefaultName + textSelectNodes[0].SelectText; if (!dto.SetTitle(addPageName)) { //SDK出错了 return -1; } } dto.SetDestination(PDFViewer.Document, info); Updata(false); return ItemIndex; } /// /// 添加大纲到子节点的最后一位 /// public int InsertParentOutline(OutlineNode outline) { int ItemIndex = 0; List textSelectNodes = PDFViewer.GetCreateOutLineInfo(); CPDFDestination info = new CPDFDestination(); if (textSelectNodes.Count <= 0) { //SDK出错了 return -1; } info.PageIndex = textSelectNodes[0].PageIndex; info.Position_X = (float)textSelectNodes[0].StartPoint.X; info.Position_Y = (float)textSelectNodes[0].StartPoint.Y; CPDFOutline dto = null; CPDFOutline parent = outline.Outline.GetParent(); if (parent != null) { CPDFOutline trueparent = parent.GetParent(); if (trueparent != null) { ItemIndex = GetOutlinesIndexFormParent(trueparent, parent); if (!trueparent.InsertChildAtIndex(PDFViewer.Document, ItemIndex, ref dto)) { return -1; } ItemIndex = ItemIndex + 1; } } ///当前没有选中文字 if (string.IsNullOrEmpty(textSelectNodes[0].SelectText)) { string addPageName = PageDefaultName + (textSelectNodes[0].PageIndex + 1).ToString(); if (!dto.SetTitle(addPageName)) { //SDK出错了 return -1; } } else { string addPageName = PageDefaultName + textSelectNodes[0].SelectText; if (!dto.SetTitle(addPageName)) { //SDK出错了 return -1; } } dto.SetDestination(PDFViewer.Document, info); Updata(false); return ItemIndex; } /// /// 添加大纲到父节点的下一位 /// public int InsertChlidOutline(OutlineNode outline) { int ItemIndex = 0; if (outline == null) { return -1; } if (outline.Outline.ChildList != null) { ItemIndex = outline.Outline.ChildList.Count; } List textSelectNodes = PDFViewer.GetCreateOutLineInfo(); CPDFDestination info = new CPDFDestination(); if (textSelectNodes.Count <= 0) { //SDK出错了 return -1; } info.PageIndex = textSelectNodes[0].PageIndex; info.Position_X = (float)textSelectNodes[0].StartPoint.X; info.Position_Y = (float)textSelectNodes[0].StartPoint.Y; CPDFOutline dto = null; if (!outline.Outline.InsertChildAtIndex(PDFViewer.Document, ItemIndex, ref dto)) { return -1; } ///当前没有选中文字 if (string.IsNullOrEmpty(textSelectNodes[0].SelectText)) { string addPageName = PageDefaultName + (textSelectNodes[0].PageIndex + 1).ToString(); if (!dto.SetTitle(addPageName)) { //SDK出错了 return -1; } } else { string addPageName = PageDefaultName + textSelectNodes[0].SelectText; if (!dto.SetTitle(addPageName)) { //SDK出错了 return -1; } } dto.SetDestination(PDFViewer.Document, info); Updata(false); return ItemIndex; } /// /// 删除所有大纲 /// public void DeleteAll() { AlertsMessage alertsMessage = new AlertsMessage(); alertsMessage.ShowDialog("", "This action will permanently delete all outlines,Whether to continue?", "No", "Yes"); if (alertsMessage.result == ContentResult.Ok) { foreach (var item in Outlinelist) { item.Outline.RemoveFromParent(this.PDFViewer.Document); } Updata(false); } } /// /// 降级当前大纲 /// public void Downgrade(OutlineNode outline) { if (outline != null) { CPDFOutline parent = outline.Outline.GetParent(); int index = GetOutlinesIndexFormParent(parent, outline.Outline); CPDFOutline newparent = parent.ChildList[index - 2]; int insertindex = newparent.ChildList.Count; newparent.MoveChildAtIndex(PDFViewer.Document, outline.Outline, insertindex); Updata(false); } } /// /// 升级当前大纲 /// public void Upgrade(OutlineNode outline) { if (outline != null) { CPDFOutline parent = outline.Outline.GetParent(); CPDFOutline newparent = parent.GetParent(); int index = GetOutlinesIndexFormParent(parent.GetParent(), parent); newparent.MoveChildAtIndex(PDFViewer.Document, outline.Outline, index); Updata(false); } } /// /// 删除当前大纲 /// public void RemoveOutline(OutlineNode outline) { outline.Outline.RemoveFromParent(PDFViewer.Document); Updata(false); } /// /// 移动大纲到目标节点 /// /// 目标节点 /// 需要插入的数据 /// public bool MoveOutLine(OutlineNode target, OutlineNode soure) { bool Tag = true; if (IsInsertHead) { CPDFOutline root = PDFViewer.Document.GetOutlineRoot(); if (root != null) { Tag = root.MoveChildAtIndex(PDFViewer.Document, soure.Outline, 0); } } else { if (target.IsInsertNextLayer) { target.IsExpanded = true; Tag = target.Outline.MoveChildAtIndex(PDFViewer.Document, soure.Outline, target.Outline.ChildList.Count); } else { CPDFOutline parent = target.Outline.GetParent(); if (parent != null && parent.ChildList.Count > 0) { int index = parent.ChildList.IndexOf(target.Outline); int sourceindex = parent.ChildList.IndexOf(soure.Outline); //源数据不在目标节点树中的情况 if (sourceindex == -1) { Tag = parent.MoveChildAtIndex(PDFViewer.Document, soure.Outline, index + 1); } //分向上和向下移动 else if (sourceindex > index) { Tag = parent.MoveChildAtIndex(PDFViewer.Document, soure.Outline, index + 1); } else { Tag = parent.MoveChildAtIndex(PDFViewer.Document, soure.Outline, index); } } } } return Tag; } /// /// 获取对应大纲所需的缩略图数据 /// public WriteableBitmap LoadPreview(OutlineNode outlineNode,int Width,int Height) { CPDFPage page = PDFViewer.Document.PageAtIndex(Convert.ToInt32(outlineNode.PageIndex) - 1); Size size = PDFViewer.Document.GetPageSize(Convert.ToInt32(outlineNode.PageIndex) - 1); //当前对象添加时没创建默认对象,SDK会返回(-1,-1) if (outlineNode.PositionX == -1) { outlineNode.PositionX = 0; } if (outlineNode.PositionY == -1) { outlineNode.PositionY = size.Height; } Point zoomXY = new Point(outlineNode.PositionX * outlineNode.Zoom, outlineNode.PositionY * outlineNode.Zoom); Size zoomSize = new Size((int)(Width * outlineNode.Zoom), (int)(Height * outlineNode.Zoom)); bmpData = new byte[(int)(zoomSize.Width * zoomSize.Height * 4)]; WirteBitmap = new WriteableBitmap((int)zoomSize.Width, (int)zoomSize.Height, 96, 96, PixelFormats.Bgra32, null); if (!page.IsValid()) { return null; } page.RenderPageBitmapWithMatrix((float)outlineNode.Zoom, new Rect(outlineNode.PositionX, size.Height- outlineNode.PositionY, zoomSize.Width, zoomSize.Height), 0xFFFFFFFF, bmpData, 1, true); WirteBitmap.WritePixels(new Int32Rect(0, 0, (int)zoomSize.Width, (int)zoomSize.Height), bmpData, WirteBitmap.BackBufferStride, 0); WirteBitmap.Freeze(); return WirteBitmap; } /// /// 将PDF对象转换为自定义数据类型,并存储 /// private OutlineNode ConvertCPDFToOutlineNode(CPDFOutline outline, OutlineNode parent, bool IsMoveData) { OutlineNode node = new OutlineNode(); if (outline != null) { node.IsInsertNextLayer = false; node.IsInsertCurrentLayer = false; node.IsExpanded = false; node.IsSelected = false; node.Outline = outline; node.CanUp = outline.Level == 0 ? false : true; node.CanAddParent = outline.Level == 0 ? false : true; CPDFAction action = outline.GetAction(); if (action != null) { if (action.ActionType != C_ACTION_TYPE.ACTION_TYPE_URI) { CPDFDestination cPDFDestination = outline.GetDestination(PDFViewer.Document); if (cPDFDestination != null) { //存储大纲相关属性 node.PageIndex = (cPDFDestination.PageIndex + 1).ToString(); node.PositionX = cPDFDestination.Position_X; node.PositionY = cPDFDestination.Position_Y; if (cPDFDestination.Zoom <= 0) { node.Zoom = 1; } else { node.Zoom = cPDFDestination.Zoom; } } else { node.PageIndex = ""; node.PositionX = 0; node.PositionY = 0; node.Zoom = 1; } } else { node.PageIndex = ""; node.PositionX = 0; node.PositionY = 0; node.Zoom = 1; } } else { node.PageIndex = ""; node.PositionX = 0; node.PositionY = 0; node.Zoom = 1; } if (parent != null) { node.Parent = parent; } if (Outlinelist != null && Outlinelist.Count > 0) { OutlineNode oldnode = FindOutlineFromDto(Outlinelist, node.Outline, IsMoveData); if (oldnode != null) { node.IsExpanded = oldnode.IsExpanded; node.IsSelected = oldnode.IsSelected; } } node.Chlidlist = new ObservableCollection(); if (outline.ChildList.Count > 0) { foreach (CPDFOutline item in outline.ChildList) { node.Chlidlist.Add(ConvertCPDFToOutlineNode(item, node, IsMoveData)); } //如果是第一条数据不允许点击降级 node.Chlidlist[0].CanDown = false; } else { node.CanDown = false; } } return node; } /// /// 从当前列表中找到和SDK大纲对象相同的数据 /// public OutlineNode FindOutlineFromDto(ObservableCollection list, CPDFOutline outline, bool IsMoveData) { foreach (OutlineNode item in list) { CPDFOutline parent = outline.GetParent(); CPDFOutline PARENT = item.Outline.GetParent(); int i = GetIndexFromParent(parent.ChildList, outline); int I = GetIndexFromParent(PARENT.ChildList, item.Outline); if (IsMoveData) { if (item.Outline.Title == outline.Title) { return item; } else if (item.Chlidlist.Count > 0) { OutlineNode retdto = FindOutlineFromDto(item.Chlidlist, outline, IsMoveData); if (retdto != null) { return retdto; } } } else { if (item.Outline.Title == outline.Title && i == I && outline.Level == item.Outline.Level && ((parent.Title == PARENT.Title) || (parent.Title == null && PARENT.Title == null))) { return item; } else if (item.Chlidlist.Count > 0) { OutlineNode retdto = FindOutlineFromDto(item.Chlidlist, outline, IsMoveData); if (retdto != null) { return retdto; } } } } return null; } /// /// 从当前列表中找到对应的OutlineNode对象 /// public OutlineNode FindOutlineFromList(ObservableCollection list, OutlineNode outline, int outlineindex) { //如果传入比对数据为null,则返回最后一项 if (outline == null) { return list.Last(); } int index = list.IndexOf(outline); if (index >= 0) { if (outlineindex <= index) { return list[index]; } else { return list[outlineindex - 1]; } } else { foreach (var item in list) { OutlineNode node = FindOutlineFromList(item.Chlidlist, outline, outlineindex); if (node != null) { return node; } } } return null; } private int GetIndexFromParent(List parentlist, CPDFOutline outline) { for (int i = 0; i < parentlist.Count; i++) { if (parentlist[i] == outline) { return i; } } return -1; } private int GetOutlinesIndexFormParent(CPDFOutline parentoutline, CPDFOutline outline) { if (parentoutline != null) { if (parentoutline.ChildList.Count > 0) { for (int i = 0; i < parentoutline.ChildList.Count; i++) { if (parentoutline.ChildList[i] == outline) { return i + 1; } } } return parentoutline.ChildList.Count; } return 0; } } }