Ver código fonte

BOTA大纲-拖拽相关逻辑

zhuyi 2 anos atrás
pai
commit
54d2f16632

+ 23 - 0
PDF Office/Model/BOTA/OutlineNode.cs

@@ -80,5 +80,28 @@ namespace PDF_Office.Model.BOTA
             }
         }
 
+        private bool isExpanded = false;
+
+        public bool IsExpanded
+        {
+            get { return isExpanded; }
+            set
+            {
+                SetProperty(ref isExpanded, value);
+            }
+        }
+
+        private string pageIndex ="";
+
+        public string PageIndex
+        {
+            get { return pageIndex; }
+            set
+            {
+                SetProperty(ref pageIndex, value);
+            }
+        }
+
+
     }
 }

+ 1 - 0
PDF Office/Styles/OutLineItemStyle.xaml

@@ -63,6 +63,7 @@
     </Style>
 
     <Style x:Key="OutLineItemStyle" TargetType="{x:Type TreeViewItem}">
+        <Setter Property="IsExpanded" Value="{Binding IsExpanded,Mode=TwoWay}"/>
         <Setter Property="Background" Value="Transparent" />
         <Setter Property="HorizontalContentAlignment" Value="Center" />
         <Setter Property="VerticalContentAlignment" Value="Center" />

+ 179 - 3
PDF Office/ViewModels/BOTA/OutLineControlViewModel.cs

@@ -1,4 +1,5 @@
 using ComPDFKit.PDFDocument;
+using ComPDFKit.PDFDocument.Action;
 using ComPDFKitViewer.PdfViewer;
 using PDF_Office.Model;
 using PDF_Office.Model.BOTA;
@@ -16,6 +17,7 @@ namespace PDF_Office.ViewModels.BOTA
     class OutLineControlViewModel : BindableBase, INavigationAware
     {
         private CPDFViewer PDFViewer;
+
         public ObservableCollection<OutlineNode> Outlinelist { get; set; }
 
         private bool isInsertHead = false;
@@ -33,6 +35,7 @@ namespace PDF_Office.ViewModels.BOTA
         {
             Outlinelist = new ObservableCollection<OutlineNode>();
         }
+
         public bool IsNavigationTarget(NavigationContext navigationContext)
         {
             return true;
@@ -54,7 +57,7 @@ namespace PDF_Office.ViewModels.BOTA
             Outlinelist.Clear();
             foreach (CPDFOutline item in datasource)
             {
-                OutlineNode dto = ConvertCPDFToOutlineNode(item, null);
+                OutlineNode dto = ConvertCPDFToOutlineNode(item, null,false);
                 if (dto != null)
                 {
                     Outlinelist.Add(dto);
@@ -62,28 +65,201 @@ namespace PDF_Office.ViewModels.BOTA
             }
         }
 
-        private OutlineNode ConvertCPDFToOutlineNode(CPDFOutline outline, OutlineNode parent)
+        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;
+        }
+        public bool SetTitle(CPDFOutline cPDFOutline, string Title)
+        {
+            if (cPDFOutline == null)
+            {
+                return false;
+            }
+            return cPDFOutline.SetTitle(Title);
+        }
+        /// <summary>
+        /// 插入大纲到目标节点
+        /// </summary>
+        /// <param name="target">目标节点</param>
+        /// <param name="soure">需要插入的数据</param>
+        /// <returns></returns>
+        public bool InsertOutLine(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;
+        }
+        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.Outline = outline;
+                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();
+                        }
+                        else
+                        {
+                            node.PageIndex = "";
+                        }
+                    }
+                    else
+                    {
+                        node.PageIndex = "";
+                    }
+
+                }
+                else
+                {
+                    node.PageIndex = "";
+                }
+               
                 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.Chlidlist = new ObservableCollection<OutlineNode>();
                 if (outline.ChildList.Count > 0)
                 {
                     foreach (CPDFOutline item in outline.ChildList)
                     {
-                        node.Chlidlist.Add(ConvertCPDFToOutlineNode(item, node));
+                        node.Chlidlist.Add(ConvertCPDFToOutlineNode(item, node, IsMoveData));
                     }
                 }
             }
             return node;
         }
+
+        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;
+        }
+
+        private int GetIndexFromParent(List<CPDFOutline> parentlist, CPDFOutline outline)
+        {
+            for (int i = 0; i < parentlist.Count; i++)
+            {
+                if (parentlist[i] == outline)
+                {
+                    return i;
+                }
+            }
+            return -1;
+        }
     }
 }

+ 29 - 21
PDF Office/Views/BOTA/OutLineControl.xaml

@@ -66,45 +66,53 @@
             <Rectangle Margin="-1,0,0,2" Width="{Binding ElementName=Header,Path=ActualWidth}" HorizontalAlignment="Stretch" Height="1.5" StrokeDashArray="2" VerticalAlignment="Bottom" Fill="#FF0078D7"/>
         </StackPanel>
         <Grid Grid.Row="1"
-               DragOver="Grid_DragOver">
+               DragOver="Grid_DragOver"
+              DragLeave="Grid_DragLeave">
             <TreeView x:Name="OutlineView" Grid.Row="1" ItemsSource="{Binding Outlinelist}"
                 BorderThickness="0" AllowDrop="True"
                 VirtualizingPanel.ScrollUnit="Pixel"
-                PreviewMouseMove="OutlineView_PreviewMouseMove"      
+                Drop="OutlineView_Drop"
+                PreviewMouseMove="OutlineView_PreviewMouseMove" 
+                PreviewMouseLeftButtonDown="OutlineView_PreviewMouseLeftButtonDown"
+                PreviewMouseLeftButtonUp="OutlineView_PreviewMouseLeftButtonUp"
+                PreviewMouseDoubleClick="OutlineView_PreviewMouseDoubleClick"
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled">
                 <TreeView.ItemTemplate>
-                    <HierarchicalDataTemplate DataType="{x:Type model:OutlineNode}" ItemsSource="{Binding Path=Chlidlist}">
+                    <HierarchicalDataTemplate  DataType="{x:Type model:OutlineNode}" ItemsSource="{Binding Path=Chlidlist}">
                         <Grid>
-                            <Grid.ColumnDefinitions>
-                                <ColumnDefinition />
-                                <ColumnDefinition Width="auto" />
-                            </Grid.ColumnDefinitions>
                             <Grid.ContextMenu>
                                 <ContextMenu>
-                                    <MenuItem Header="1"/>
-                                    <MenuItem Header="2"/>
-                                    <MenuItem Header="3"/>
-                                    <MenuItem Header="4"/>
+                                    <MenuItem Header="添加条目"/>
+                                    <MenuItem Header="添加子条目"/>
+                                    <MenuItem Header="添加上一级条目"/>
+                                    
+                                    <MenuItem Header="删除"/>
 
-                                    <MenuItem Header="5"/>
-                                    <MenuItem Header="6"/>
-                                    <MenuItem Header="7"/>
+                                    <MenuItem Header="重命名"/>
+                                    <MenuItem Header="更改目标位置"/>
 
-                                    <MenuItem Header="8"/>
-                                    <MenuItem Header="9"/>
+                                    <MenuItem Header="升级"/>
+                                    <MenuItem Header="降级"/>
                                 </ContextMenu>
                             </Grid.ContextMenu>
-                            <DockPanel x:Name="ContentPanel">
+                            <Grid x:Name="ContentPanel">
+                                <Grid.ColumnDefinitions>
+                                    <ColumnDefinition />
+                                    <ColumnDefinition Width="auto" />
+                                </Grid.ColumnDefinitions>
                                 <TextBlock x:Name="Content" Text="{Binding Outline.Title}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
-                                <TextBlock x:Name="PageIndex" Grid.Column="1" HorizontalAlignment="Right"  VerticalAlignment="Center" Text="1"/>
-                            </DockPanel>
+                                <TextBlock x:Name="PageIndex" Grid.Column="1" HorizontalAlignment="Right"  VerticalAlignment="Center" Text="{Binding PageIndex}"/>
+                            </Grid>
 
                             <StackPanel  Orientation="Horizontal" HorizontalAlignment="Stretch" Visibility="{Binding IsInsertNextLayer, Converter={StaticResource BoolToVisible}}" >
                                 <Ellipse Margin="0,0,0,0" Width="8" Height="8" Fill="White" Stroke="#FF0078D7"  StrokeThickness="1.5" VerticalAlignment="Bottom"/>
                                 <Line Margin="-1,0,0,2" X1="0"  X2="{Binding ElementName=ContentPanel,Path=ActualWidth}" HorizontalAlignment="Stretch" StrokeThickness="1.5" StrokeDashArray="2" Stroke="#FF0078D7" VerticalAlignment="Bottom"/>
                             </StackPanel>
-                            <Grid x:Name="RenameGrid" Visibility="{Binding ElementName=Content,Path=Visibility,Mode=TwoWay,Converter={StaticResource UnVisivleConvert}}">
-                                <TextBox x:Name="ReName" HorizontalAlignment="Left" VerticalAlignment="Center"/>
+                            <Grid x:Name="RenameGrid"
+                                  LostFocus="RenameGrid_LostFocus"
+                                  Visibility="{Binding ElementName=Content,Path=Visibility,Mode=TwoWay,Converter={StaticResource UnVisivleConvert}}">
+                                <TextBox x:Name="ReName" HorizontalAlignment="Left" VerticalAlignment="Center" 
+                                         IsVisibleChanged="ReName_IsVisibleChanged"/>
                             </Grid>
                         </Grid>
                     </HierarchicalDataTemplate>

+ 182 - 19
PDF Office/Views/BOTA/OutLineControl.xaml.cs

@@ -1,6 +1,7 @@
 using ComPDFKit.PDFDocument;
 using PDF_Office.Helper;
 using PDF_Office.Model.BOTA;
+using PDF_Office.ViewModels.BOTA;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -23,6 +24,14 @@ namespace PDF_Office.Views.BOTA
     /// </summary>
     public partial class OutLineControl : UserControl
     {
+        /// <summary>
+        /// 当前显示了线段的Item
+        /// </summary>
+        private TreeViewItem Treeviewitem = null;
+        /// <summary>
+        /// 需要重命名的Item的DataContext
+        /// </summary>
+        private OutlineNode ReNameOutlineNode = null;
         public OutLineControl()
         {
             InitializeComponent();
@@ -36,7 +45,7 @@ namespace PDF_Office.Views.BOTA
         }
         private void OutlineView_PreviewMouseMove(object sender, MouseEventArgs e)
         {
-            if (e.LeftButton == MouseButtonState.Pressed )
+            if (e.LeftButton == MouseButtonState.Pressed)
             {
                 var pos = e.GetPosition(OutlineView);
                 HitTestResult result = VisualTreeHelper.HitTest(OutlineView, pos);
@@ -55,7 +64,11 @@ namespace PDF_Office.Views.BOTA
             }
         }
 
-        private TreeViewItem Treeviewitem = null;
+        /// <summary>
+        /// 拖拽判断区域以及显示什么线
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
         private void Grid_DragOver(object sender, DragEventArgs e)
         {
             TreeViewItem sourceitem = e.Data.GetData(typeof(TreeViewItem)) as TreeViewItem;
@@ -70,34 +83,184 @@ namespace PDF_Office.Views.BOTA
                 TreeViewItem treeviewitem = CommonHelper.FindVisualParent<TreeViewItem>(result.VisualHit);
                 if (treeviewitem != null)
                 {
-                    Point p = treeviewitem.TranslatePoint(new Point(0, 0), OutlineView);
-                    if (Treeviewitem==null)
-                    {
-                        Treeviewitem = treeviewitem;
-                    }
-                    else if (!Treeviewitem.Equals(treeviewitem))
-                    {
-                        (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
-                        (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
-                        Treeviewitem = treeviewitem;
-                    }
-                    else
+                    //控制最顶端的线
+                    if (pos.Y <= 9)
                     {
+                        if (Treeviewitem == null)
+                        {
+                            Treeviewitem = treeviewitem;
+                        }
+                        (DataContext as OutLineControlViewModel).IsInsertHead = true;
                         (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
                         (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
                     }
-                    if (pos.Y < p.Y + 16)
-                    {
-                        (treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = true;
-                    }
                     else
                     {
-                        (treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = true;
+                        (DataContext as OutLineControlViewModel).IsInsertHead = false;
+
+                        if (Treeviewitem == null)
+                        {
+                            Treeviewitem = treeviewitem;
+                        }
+                        else if (!Treeviewitem.Equals(treeviewitem))
+                        {
+                            (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
+                            (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
+                            Treeviewitem = treeviewitem;
+                        }
+                        else
+                        {
+                            (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
+                            (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
+                        }
+                        if (Treeviewitem.Equals(sourceitem))
+                        {
+                            return;
+                        }
+
+                        //鼠标位于上半部分显示实线,下半部分显示虚线
+                        Point p = treeviewitem.TranslatePoint(new Point(0, 0), OutlineView);
+                        if (pos.Y < p.Y + 16)
+                        {
+                            (treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = true;
+                        }
+                        else
+                        {
+                            (treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = true;
+                        }
                     }
                 }
+            }
+        }
+
+        private void Grid_DragLeave(object sender, DragEventArgs e)
+        {
+            HiddenaAllLine();
+        }
+
+        private void OutlineView_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
+        {
+            TextBlock text = e.OriginalSource as TextBlock;
+            if (text == null || text.Name == "PageIndex")
+            {
+                return;
+            }
+            TreeView tree = sender as TreeView;
+            if (tree == null)
+            {
+                return;
+            }
+            OutlineNode viewitem = tree.SelectedItem as OutlineNode;
+            if (viewitem == null)
+            {
+                return;
+            }
+            ReNameOutlineNode = viewitem;
+            text.Visibility = Visibility.Collapsed;
+            e.Handled = true;
+        }
+
+        private void OutlineView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+
+        }
+
+        private void OutlineView_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+        {
+            (DataContext as OutLineControlViewModel).IsInsertHead = false;
+            if (Treeviewitem != null)
+            {
+                (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
+                (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
+                Treeviewitem = null;
+            }
+        }
+
+        private void OutlineView_Drop(object sender, DragEventArgs e)
+        {
+            TreeViewItem souredata = e.Data.GetData(typeof(TreeViewItem)) as TreeViewItem;
+            OutlineNode soureoutlineNode = souredata.DataContext as OutlineNode;
+            Point pos = e.GetPosition(OutlineView);
+            HitTestResult result = VisualTreeHelper.HitTest(OutlineView, pos);
+            if (result==null)
+            {
+                HiddenaAllLine();
+                return;
+            }
+            TreeViewItem targetitem = CommonHelper.FindVisualParent<TreeViewItem>(result.VisualHit);
+            if (targetitem==null)
+            {
+                HiddenaAllLine();
+                return;
+            }
+            OutlineNode targetoutlineNode = targetitem.DataContext as OutlineNode;
+            if (soureoutlineNode.Equals(targetoutlineNode))
+            {
+                HiddenaAllLine();
+                return;
+            }
+           (DataContext as OutLineControlViewModel).InsertOutLine(targetoutlineNode, soureoutlineNode);
+
+            HiddenaAllLine();
+            (DataContext as OutLineControlViewModel).Updata(true);
+        }
+
+        private void HiddenaAllLine()
+        {
+            (DataContext as OutLineControlViewModel).IsInsertHead = false;
+            if (Treeviewitem != null)
+            {
+                (Treeviewitem.DataContext as OutlineNode).IsInsertCurrentLayer = false;
+                (Treeviewitem.DataContext as OutlineNode).IsInsertNextLayer = false;
+                Treeviewitem = null;
+            }
+        }
 
+        private void ReName_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
+        {
+            TextBox ReNameText = sender as TextBox;
+            if (ReNameText == null)
+            {
+                return;
+            }
+            if (ReNameText.Visibility == Visibility.Visible)
+            {
+                if (ReNameOutlineNode != null)
+                {
+                    ReNameText.Text = ReNameOutlineNode.Outline.Title;
+                }
+                ReNameText.Focus();
+                ReNameText.SelectAll();
             }
+        }
 
+        private void RenameGrid_LostFocus(object sender, RoutedEventArgs e)
+        {
+            TextBox newdto = e.OriginalSource as TextBox;
+            if (newdto == null)
+            {
+                return;
+            }
+            string newtitle = string.IsNullOrEmpty(newdto.Text) ? "" : newdto.Text;
+            Grid senderdto = sender as Grid;
+            if (senderdto == null)
+            {
+                return;
+            }
+            senderdto.Visibility = Visibility.Collapsed;
+            if (ReNameOutlineNode != null)
+            {
+                CPDFOutline result = ReNameOutlineNode.Outline;
+                if (result != null)
+                {
+                    if (newtitle == result.Title)
+                    {
+                        return;
+                    }
+                    (DataContext as OutLineControlViewModel).SetTitle(result, newtitle);
+                }
+                (DataContext as OutLineControlViewModel).Updata(false);
+            }
         }
     }
 }