123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736 |
- using ComPDFKit.PDFDocument;
- using ComPDFKit.PDFDocument.Action;
- using ComPDFKit.PDFPage;
- using ComPDFKitViewer.PdfViewer;
- using PDF_Office.Model;
- using PDF_Office.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_Office.ViewModels.BOTA
- {
- class OutLineControlViewModel : BindableBase, INavigationAware
- {
- private string PageDefaultName = "";
- //缩略图相关全局变量,减少内存申请次数
- private WriteableBitmap WirteBitmap;
- private byte[] bmpData;
- private CPDFViewer PDFViewer;
- public ObservableCollection<OutlineNode> Outlinelist { get; set; }
- private bool isInsertHead = false;
- /// <summary>
- /// 是否为插入最顶部
- /// </summary>
- 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<ObservableCollection<OutlineNode>> CollapseAllCommand { get; set; }
- public DelegateCommand<ObservableCollection<OutlineNode>> ExpandAllCommand { get; set; }
- public DelegateCommand DeleteAllCommand { get; set; }
- public DelegateCommand<OutlineNode> DowngradeCommand { get; set; }
- public OutLineControlViewModel()
- {
- Outlinelist = new ObservableCollection<OutlineNode>();
- DeleteAllCommand = new DelegateCommand(DeleteAll);
- CollapseAllCommand = new DelegateCommand<ObservableCollection<OutlineNode>>(CollapseAll);
- ExpandAllCommand = new DelegateCommand<ObservableCollection<OutlineNode>>(ExpandAll);
- }
- public bool IsNavigationTarget(NavigationContext navigationContext)
- {
- return true;
- }
- public void OnNavigatedFrom(NavigationContext navigationContext)
- {
- return;
- }
- public void OnNavigatedTo(NavigationContext navigationContext)
- {
- navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
- if (PDFViewer == null)
- {
- return;
- }
- List<CPDFOutline> datasource = PDFViewer.Document.GetOutlineList();
- Outlinelist.Clear();
- foreach (CPDFOutline item in datasource)
- {
- OutlineNode dto = ConvertCPDFToOutlineNode(item, null, false);
- if (dto != null)
- {
- Outlinelist.Add(dto);
- }
- }
- PDFViewer.GetCreateOutLineInfo();
- }
- /// <summary>
- /// 更新大纲数据,并保存状态设置为true
- /// </summary>
- public void Updata(bool IsMoveData)
- {
- PDFViewer.Document.ReleaseOutlineList();
- ObservableCollection<OutlineNode> list = new ObservableCollection<OutlineNode>();
- List<CPDFOutline> datasource = PDFViewer.Document.GetOutlineList();
- //遍历,转换UI状态存入临时数组
- foreach (CPDFOutline item in datasource)
- {
- OutlineNode dto = ConvertCPDFToOutlineNode(item, null, IsMoveData);
- if (dto != null)
- {
- list.Add(dto);
- }
- }
- //清空绑定数组,并填充新数据
- Outlinelist.Clear();
- foreach (OutlineNode item in list)
- {
- Outlinelist.Add(item);
- }
- PDFViewer.UndoManager.CanSave = true;
- }
- /// <summary>
- /// 设置当前大纲对象的Title
- /// </summary>
- public bool SetTitle(CPDFOutline cPDFOutline, string Title)
- {
- if (cPDFOutline == null)
- {
- return false;
- }
- return cPDFOutline.SetTitle(Title);
- }
- /// <summary>
- /// 跳转到指定位置或者URL动作
- /// </summary>
- 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
- {
- Size size = PDFViewer.Document.GetPageSize(Convert.ToInt32(outline.PageIndex) - 1);
- PDFViewer.GoToPage(Convert.ToInt32(outline.PageIndex) - 1, new Point(size.Width - outline.PositionX, size.Height - outline.PositionY));
- }
- }
- /// <summary>
- /// 收起所有展开
- /// </summary>
- public void CollapseAll(ObservableCollection<OutlineNode> outlineNodes)
- {
- foreach (var item in outlineNodes)
- {
- item.IsExpanded = false;
- if (item.Chlidlist.Count > 0)
- {
- CollapseAll(item.Chlidlist);
- }
- }
- }
- /// <summary>
- /// 展开所有大纲
- /// </summary>
- public void ExpandAll(ObservableCollection<OutlineNode> outlineNodes)
- {
- foreach (var item in outlineNodes)
- {
- item.IsExpanded = true;
- if (item.Chlidlist.Count > 0)
- {
- ExpandAll(item.Chlidlist);
- }
- }
- }
- /// <summary>
- /// 更改目标位置
- /// </summary>
- public void ChangeOutLineDestination(OutlineNode outline)
- {
- List<TextSelectNode> 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);
- }
- /// <summary>
- /// 添加大纲
- /// </summary>
- public int AddOutLine(OutlineNode outline)
- {
- int ItemIndex = 0;
- List<TextSelectNode> 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)(size.Width - 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;
- }
- /// <summary>
- /// 添加大纲到子节点的最后一位
- /// </summary>
- public int InsertParentOutline(OutlineNode outline)
- {
- int ItemIndex = 0;
- List<TextSelectNode> 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;
- }
- /// <summary>
- /// 添加大纲到父节点的下一位
- /// </summary>
- public int InsertChlidOutline(OutlineNode outline)
- {
- int ItemIndex = 0;
- if (outline == null)
- {
- return -1;
- }
- if (outline.Outline.ChildList != null)
- {
- ItemIndex = outline.Outline.ChildList.Count;
- }
- List<TextSelectNode> 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;
- }
- /// <summary>
- /// 删除所有大纲
- /// </summary>
- public void DeleteAll()
- {
- foreach (var item in Outlinelist)
- {
- item.Outline.RemoveFromParent(this.PDFViewer.Document);
- }
- Updata(false);
- }
- /// <summary>
- /// 升级当前大纲
- /// </summary>
- 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);
- }
- }
- /// <summary>
- /// 降级当前大纲
- /// </summary>
- 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);
- }
- }
- /// <summary>
- /// 删除当前大纲
- /// </summary>
- public void RemoveOutline(OutlineNode outline)
- {
- outline.Outline.RemoveFromParent(PDFViewer.Document);
- Updata(false);
- }
- /// <summary>
- /// 移动大纲到目标节点
- /// </summary>
- /// <param name="target">目标节点</param>
- /// <param name="soure">需要插入的数据</param>
- /// <returns></returns>
- 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;
- }
- /// <summary>
- /// 获取对应大纲所需的缩略图数据
- /// </summary>
- public WriteableBitmap LoadPreview(OutlineNode outlineNode)
- {
- CPDFPage page = PDFViewer.Document.PageAtIndex(Convert.ToInt32(outlineNode.PageIndex) - 1);
- Size size = PDFViewer.Document.GetPageSize(Convert.ToInt32(outlineNode.PageIndex) - 1);
- Point zoomXY = new Point(outlineNode.PositionX * outlineNode.Zoom, outlineNode.PositionY * outlineNode.Zoom);
- //数据校验,暂不确定SDK会不会给垃圾值。说是从底层返回的。
- if (zoomXY.X > size.Width || zoomXY.X < 0)
- {
- zoomXY.X = 0;
- }
- if (zoomXY.Y > size.Height || zoomXY.Y < 0)
- {
- zoomXY.Y = 0;
- }
- Size zoomSize = new Size((int)(size.Width * outlineNode.Zoom), (int)(size.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(zoomXY.X, zoomXY.Y, 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;
- }
- /// <summary>
- /// 将PDF对象转换为自定义数据类型,并存储
- /// </summary>
- 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<OutlineNode>();
- if (outline.ChildList.Count > 0)
- {
- foreach (CPDFOutline item in outline.ChildList)
- {
- node.Chlidlist.Add(ConvertCPDFToOutlineNode(item, node, IsMoveData));
- }
- }
- else
- {
- node.CanDown = false;
- }
- }
- return node;
- }
- /// <summary>
- /// 从当前列表中找到和SDK大纲对象相同的数据
- /// </summary>
- public OutlineNode FindOutlineFromDto(ObservableCollection<OutlineNode> 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;
- }
- /// <summary>
- /// 从当前列表中找到对应的OutlineNode对象
- /// </summary>
- public OutlineNode FindOutlineFromList(ObservableCollection<OutlineNode> 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<CPDFOutline> 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;
- }
- }
- }
|