Selaa lähdekoodia

综合-搜索功能调整,右键菜单等相关内容实现

zhuyi 2 vuotta sitten
vanhempi
commit
1a2a4db2ac

+ 15 - 0
PDF Office/Helper/DpiHelpers.cs

@@ -78,6 +78,8 @@ namespace PDF_Office.Helper
             return new Rect(GetDpiUnrelatedNum(oldValue.Left), GetDpiUnrelatedNum(oldValue.Top),
                 GetDpiUnrelatedNum(oldValue.Width), GetDpiUnrelatedNum(oldValue.Height));
         }
+
+
         /// <summary>
         /// 转换到PDF矩形
         /// </summary>
@@ -100,6 +102,19 @@ namespace PDF_Office.Helper
             return new Rect(GetDpiRelatedNum(oldValue.Left), GetDpiRelatedNum(oldValue.Top),
                 GetDpiRelatedNum(oldValue.Width), GetDpiRelatedNum(oldValue.Height));
         }
+
+        /// <summary>
+        /// 将PDF矩形,转换为当前DPI时的矩形大小
+        /// </summary>
+        /// <param name="standRect"></param>
+        /// <returns></returns>
+        public static Rect GetRawRelatedRect(Rect standRect)
+        {
+            Rect newRect = new Rect(standRect.Left / 72D *96D, standRect.Top / 72D * 96D, standRect.Width / 72D * 96D, standRect.Height / 72D * 96D);
+            return GetDpiRelatedRect(newRect);
+        }
+
+
         /// <summary>
         /// 当前点转换成标准DPI时的大小
         /// </summary>

+ 71 - 0
PDF Office/Model/BOTA/SearchItem.cs

@@ -0,0 +1,71 @@
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace PDF_Office.Model.BOTA
+{
+    public class TextBindProperty : BindableBase
+    {
+        public int PageIndex { get; set; }
+        public string TextContent { get; set; }
+        public Color HighLightColor { get; set; }
+        public string SearchWord { get; set; }
+        public Rect TextRect { get; set; }
+        public int PageRotate { get; set; }
+
+
+        private Visibility itemVisibility;
+        /// <summary>
+        /// 当前项的隐藏/显示状态
+        /// </summary>
+        public Visibility ItemVisibility
+        {
+            get { return itemVisibility; }
+            set
+            {
+                SetProperty(ref itemVisibility, value);
+            }
+        }
+    }
+    public class SearchItem : BindableBase
+    {
+        private TextBindProperty textProperty;
+
+        public TextBindProperty TextProperty
+        {
+            get { return textProperty; }
+            set
+            {
+                SetProperty(ref textProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// 用于分组的的名称
+        /// </summary>
+        public string ShowPageIndex
+        {
+            get { return "Page"+ (TextProperty.PageIndex + 1).ToString(); }
+            private set { }
+        }
+        /// <summary>
+        /// Pro抄过来的,用于切换为数量的模式使用的,以防万一先放着
+        /// </summary>
+        private int pageCount;
+
+        public int PageCount
+        {
+            get { return pageCount; }
+            set
+            {
+                SetProperty(ref pageCount, value);
+            }
+        }
+
+    }
+}

+ 2 - 0
PDF Office/PDF Office.csproj

@@ -340,6 +340,7 @@
     <Compile Include="Model\BOTA\AnnotationSortOrder.cs" />
     <Compile Include="Model\BOTA\AuthorItem.cs" />
     <Compile Include="Model\BOTA\OutlineNode.cs" />
+    <Compile Include="Model\BOTA\SearchItem.cs" />
     <Compile Include="Model\CloudDrive\CloudDriveItem.cs" />
     <Compile Include="Model\CloudDrive\CloudFiles.cs" />
     <Compile Include="Model\DialogNames.cs" />
@@ -2006,6 +2007,7 @@
     <Resource Include="Resources\BOTA\no_outline.png" />
     <Resource Include="Resources\PropertyPanel\nosign.png" />
     <Resource Include="Resources\Dialog\password.png" />
+    <Resource Include="Resources\BOTA\no search.png" />
     <Content Include="source\AnalysisWord\Res\word\_rels\document.xml.rels">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </Content>

BIN
PDF Office/Resources/BOTA/no search.png


+ 190 - 93
PDF Office/ViewModels/BOTA/SearchContentViewModel.cs

@@ -1,6 +1,9 @@
 using ComPDFKit.PDFPage;
+using ComPDFKitViewer.AnnotEvent;
 using ComPDFKitViewer.PdfViewer;
 using PDF_Office.Model;
+using PDF_Office.Model.BOTA;
+using PDF_Office.Properties;
 using PDF_Office.Views.BOTA;
 using Prism.Commands;
 using Prism.Mvvm;
@@ -12,6 +15,7 @@ using System.ComponentModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows;
 using System.Windows.Data;
 using System.Windows.Media;
 using System.Windows.Threading;
@@ -24,162 +28,256 @@ namespace PDF_Office.ViewModels.BOTA
 
         #region 属性
 
-        public PDFTextSearch textSearch;
-        private ObservableCollection<TextSearchBindItem> _searchResults = new ObservableCollection<TextSearchBindItem>();
+        private Visibility completed;
 
-        public ObservableCollection<TextSearchBindItem> searchResults
+        public Visibility Completed
         {
-            get { return _searchResults; }
-            set { SetProperty(ref _searchResults, value); }
+            get { return completed; }
+            set
+            {
+                SetProperty(ref completed, value);
+            }
         }
-        public List<TextSearchBindItem> lists;
 
-        private string _searchContent = "";
-        public string SearchContent
+        private string searchCount;
+
+        public string SearchCount
         {
-            get { return _searchContent; }
-            set { SetProperty(ref _searchContent, value); }
+            get { return searchCount; }
+            set
+            {
+                SetProperty(ref searchCount, value);
+            }
         }
 
 
-        private int _searchCount = 0;
-        public int SearchCount
-        {
-            get { return _searchCount; }
-            set { SetProperty(ref _searchCount, value); }
-        }
+        private ObservableCollection<SearchItem> searchItemList;
 
-        private bool _isEmpty = true;
-        public bool IsEmpty
+        public ObservableCollection<SearchItem> SearchItemList
         {
-            get { return _isEmpty; }
-            set { SetProperty(ref _isEmpty, value); }
+            get { return searchItemList; }
+            set
+            {
+                SetProperty(ref searchItemList, value);
+            }
         }
 
-        #endregion
-        #region  事件
-        public DelegateCommand<object> SearchTextCommand { get; set; }
-        public DelegateCommand<object> SearchChangedCommand { get; set; }
+        private PDFTextSearch textSearch;
 
-        #endregion
+        private CPDFViewer PDFViewer;
 
+        private string CurrentSearchText = "";
 
-        public SearchContentViewModel()
+        private ObservableCollection<string> myVar;
+
+        public ObservableCollection<string> MyProperty
         {
-           InitVariable();
-           InitCommand();
-           BindEvent();
-           lists = new List<TextSearchBindItem>();
+            get { return myVar; }
+            set
+            {
+                SetProperty(ref myVar, value);
+            }
         }
 
-        private void InitVariable()
+
+        /// <summary>
+        /// 历史记录数组
+        /// </summary>
+        List<string> HistorySearchText = new List<string>();
+        const int MaxHistoryCount = 10;
+
+        private bool caseInsensitive;
+
+        public bool CaseInsensitive
         {
-            textSearch = new PDFTextSearch();
-          
-            ICollectionView groupView = CollectionViewSource.GetDefaultView(searchResults);
-            groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(TextSearchBindItem.ShowPageIndex)));
+            get { return caseInsensitive; }
+            set
+            {
+                SetProperty(ref caseInsensitive, value);
+            }
         }
 
-        private  void InitCommand()
+        public DelegateCommand<object> SearchChangedCommand { get; set; }
+        public DelegateCommand CleanCommand { get; set; }
+
+        #endregion
+
+
+        public SearchContentViewModel()
         {
-            SearchTextCommand = new DelegateCommand<object>(SearchText);
+            textSearch = new PDFTextSearch();
+            SearchItemList = new ObservableCollection<SearchItem>();
+            MyProperty = new ObservableCollection<string>() { "1", "2"};
             SearchChangedCommand = new DelegateCommand<object>(SearchChanged);
-        }
+            CleanCommand = new DelegateCommand(clean);
+
+
+            ICollectionView groupView = CollectionViewSource.GetDefaultView(SearchItemList);
+            groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(SearchItem.ShowPageIndex)));
 
-        private void BindEvent()
-        {
             textSearch.SearchPercentHandler += TextSearch_SearchPercentHandler;
             textSearch.SearchCompletedHandler += TextSearch_SearchCompletedHandler;
+            Completed = Visibility.Collapsed;
         }
 
         private void TextSearch_SearchCompletedHandler(object sender, TextSearchResult e)
         {
-            issearched = true;
-            TotalCount = e.TotalCount;
+            App.Current.Dispatcher.Invoke(() =>
+            {
+                Completed = Visibility.Visible;
+                SearchCount = e.TotalCount.ToString();
+            });
         }
-        bool issearched = true;
-        int TotalCount = 0;
-        private bool cancelTask = false;
+
         private void TextSearch_SearchPercentHandler(object sender, TextSearchResult e)
         {
-
-            if (cancelTask == false)
+            App.Current.Dispatcher.Invoke(() =>
             {
-                string keywords = SearchContent;
                 if (e.Items.ContainsKey(e.CurrentPage))
                 {
+                    foreach (TextSearchItem item in e.Items[e.CurrentPage])
                     {
-                        TextSearchBindItem addItem = new TextSearchBindItem();
-                        addItem.PageCount = e.Items[e.CurrentPage].Count;
-                        addItem.ShowPageIndex = e.CurrentPage;
-                    }
-                    {
-                        foreach (TextSearchItem item in e.Items[e.CurrentPage])
-                        {
-                            TextSearchBindItem addItem = new TextSearchBindItem();
-                            addItem.BindProperty.PageIndex = item.PageIndex;
-                            addItem.BindProperty.TextContent = item.TextContent;
-                            addItem.BindProperty.TextRect = item.TextRect;
-                            addItem.BindProperty.SearchWord = keywords;
-                            addItem.BindProperty.HighLightColor = Color.FromArgb(0x99, 0xFF, 0xF7, 0x00);
-                            addItem.BindProperty.PageRotate = item.PageRotate;
-                            lists.Add(addItem);
-                        }
+                        SearchItem addItem = new SearchItem();
+                        addItem.TextProperty = new TextBindProperty();
+                        addItem.TextProperty.PageIndex = item.PageIndex;
+                        addItem.TextProperty.TextContent = item.TextContent;
+                        addItem.TextProperty.TextRect = item.TextRect;
+                        addItem.TextProperty.SearchWord = CurrentSearchText;
+                        addItem.TextProperty.HighLightColor = Color.FromArgb(0x99, 0xFF, 0xF7, 0x00);
+                        addItem.TextProperty.PageRotate = item.PageRotate;
+                        SearchItemList.Add(addItem);
                     }
                 }
-              
-            }
+                SearchCount = e.TotalCount.ToString();
+            });
         }
 
-        private async void SearchText(object obj)
+        /// <summary>
+        /// 文字搜索
+        /// </summary>
+        public async void SearchText(string Text)
         {
-
-            if (PDFViewer != null && textSearch != null)
+            //防止正在进行搜索,先取消一次。(若没有搜索,该方法不进行操作)
+            textSearch.CancleSearch();
+            //为了防止死循环,当超过十次,即0.1秒还是不能进行搜索,则取消本次搜索
+            int counter = 0;
+            while (!textSearch.CanDoSearch)
             {
-                issearched = false;
-                C_Search_Options option = C_Search_Options.Search_Case_Insensitive;
-                textSearch.TextSearchDocument = PDFViewer.Document;
-
-                searchResults.Clear();
-                lists.Clear();
-
-                textSearch.SearchText(SearchContent, option);
-            }
-            while (issearched == false)
                 await Task.Delay(10);
+                if (counter > 10)
+                {
+                    return;
+                }
+            }
+            //成功取消后,清除之前的结果,并搜索新内容
+            SearchItemList.Clear();
+            Completed = Visibility.Collapsed;
 
-            foreach (var item in lists)
-                searchResults.Add(item);
-
-            SearchCount = TotalCount;
-            if (TotalCount == 0)
-                IsEmpty = true;
+            if (CaseInsensitive)
+            {
+                textSearch.SearchText(Text, C_Search_Options.Search_Case_Insensitive);
+            }
             else
-                IsEmpty = false;
+            {
+                textSearch.SearchText(Text, C_Search_Options.Search_Case_Sensitive);
+            }
+            CurrentSearchText = Text;
+            if (HistorySearchText.Count >= MaxHistoryCount)
+            {
+                HistorySearchText.RemoveAt(0);
+            }
+            HistorySearchText.Add(CurrentSearchText);
         }
 
+        /// <summary>
+        /// 根据UI的Tag与绑定的对象来创建注释的方法
+        /// </summary>
+        public void CreateAnnotate(object item, string Tag)
+        {
+            SearchItem searchItem = item as SearchItem;
+            if (searchItem == null)
+            {
+                return;
+            }
+            switch (Tag)
+            {
+                case "Round":
+                    CircleAnnotArgs circleannotArgs = new CircleAnnotArgs();
+                    circleannotArgs.ClientRect = Helper.DpiHelpers.GetRawRelatedRect(searchItem.TextProperty.TextRect);
+                    circleannotArgs.Transparency = 1;
+                    circleannotArgs.BgColor = Colors.Transparent;
+                    circleannotArgs.LineColor = Colors.Red;
+                    circleannotArgs.LineWidth = 2;
+                    PDFViewer.CreatePageAnnot(searchItem.TextProperty.PageIndex, circleannotArgs);
+                    break;
+                case "Rectangle":
+                    SquareAnnotArgs squareAnnotArgs = new SquareAnnotArgs();
+                    squareAnnotArgs.ClientRect = Helper.DpiHelpers.GetRawRelatedRect(searchItem.TextProperty.TextRect);
+                    squareAnnotArgs.Transparency = 1;
+                    squareAnnotArgs.BgColor = Colors.Transparent;
+                    squareAnnotArgs.LineColor = Colors.Red;
+                    squareAnnotArgs.LineWidth = 2;
+                    PDFViewer.CreatePageAnnot(searchItem.TextProperty.PageIndex, squareAnnotArgs);
+                    break;
+                case "Highlight":
+                    TextHighlightAnnotArgs highlightAnnotArgs = new TextHighlightAnnotArgs();
+                    highlightAnnotArgs.Color = Settings.Default.AppProperties.Annotate.HighLightColor;
+                    highlightAnnotArgs.Transparency = 1;
+                    highlightAnnotArgs.PagesHiglightRectList[searchItem.TextProperty.PageIndex] = new List<Rect>();
+                    highlightAnnotArgs.PagesHiglightRectList[searchItem.TextProperty.PageIndex].Add(searchItem.TextProperty.TextRect);
+                    PDFViewer.CreatePageAnnot(searchItem.TextProperty.PageIndex, highlightAnnotArgs);
+                    break;
+                case "Underline":
+                    TextUnderlineAnnotArgs underlineAnnotArgs = new TextUnderlineAnnotArgs();
+                    underlineAnnotArgs.Color = Settings.Default.AppProperties.Annotate.UnderLineColor;
+                    underlineAnnotArgs.Transparency = 1;
+                    underlineAnnotArgs.PagesUnderlineRectList[searchItem.TextProperty.PageIndex] = new List<Rect>();
+                    underlineAnnotArgs.PagesUnderlineRectList[searchItem.TextProperty.PageIndex].Add(searchItem.TextProperty.TextRect);
+                    PDFViewer.CreatePageAnnot(searchItem.TextProperty.PageIndex, underlineAnnotArgs);
+                    break;
+                case "Strikethrough":
+                    TextStrikeoutAnnotArgs strikeoutAnnotArgs = new TextStrikeoutAnnotArgs();
+                    strikeoutAnnotArgs.Color = Settings.Default.AppProperties.Annotate.StrikethroughColor;
+                    strikeoutAnnotArgs.Transparency = 1;
+                    strikeoutAnnotArgs.PagesStrikeoutRectList[searchItem.TextProperty.PageIndex] = new List<Rect>();
+                    strikeoutAnnotArgs.PagesStrikeoutRectList[searchItem.TextProperty.PageIndex].Add(searchItem.TextProperty.TextRect);
+                    PDFViewer.CreatePageAnnot(searchItem.TextProperty.PageIndex, strikeoutAnnotArgs);
+                    break;
+                default:
+                    break;
+            }
+        }
 
+        /// <summary>
+        /// 选项改变时,跳转并且高亮搜索内容
+        /// </summary>
         private void SearchChanged(object obj)
         {
 
             if (PDFViewer != null && textSearch != null)
             {
-                TextSearchBindItem currentItem = obj as TextSearchBindItem;
+                SearchItem currentItem = obj as SearchItem;
                 if (currentItem != null && PDFViewer != null)
                 {
                     List<TextSearchItem> pageTextList = new List<TextSearchItem>();
                     pageTextList.Add(new TextSearchItem()
                     {
-                        PageIndex = currentItem.BindProperty.PageIndex,
-                        TextRect = currentItem.BindProperty.TextRect,
-                        TextContent = currentItem.BindProperty.TextContent,
-                        PageRotate = currentItem.BindProperty.PageRotate
+                        PageIndex = currentItem.TextProperty.PageIndex,
+                        TextRect = currentItem.TextProperty.TextRect,
+                        TextContent = currentItem.TextProperty.TextContent,
+                        PageRotate = currentItem.TextProperty.PageRotate
                     });
                     PDFViewer.SetPageSelectText(pageTextList, new SolidColorBrush(Color.FromArgb(0x99, 0xFF, 0xF7, 0x00)));
                 }
             }
         }
 
+        private void clean()
+        {
+            SearchItemList.Clear();
+            HistorySearchText.Clear();
+        }
+
         public bool IsNavigationTarget(NavigationContext navigationContext)
         {
             return true;
@@ -190,13 +288,12 @@ namespace PDF_Office.ViewModels.BOTA
             return;
         }
 
-        private CPDFViewer PDFViewer;
         public void OnNavigatedTo(NavigationContext navigationContext)
         {
             navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
             if (PDFViewer != null)
             {
-
+                textSearch.TextSearchDocument = PDFViewer.Document;
             }
         }
     }

+ 2 - 3
PDF Office/Views/BOTA/OutLineControl.xaml.cs

@@ -79,10 +79,9 @@ namespace PDF_Office.Views.BOTA
                     return;
                 }
                 DataObject dataObj = new DataObject(treeViewItem);
-                Dispatcher.BeginInvoke(new Action(() =>
-                {
+         
                     DragDrop.DoDragDrop(OutlineView, dataObj, DragDropEffects.Move);
-                }));
+               
                 return;
             }
         }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 94 - 25
PDF Office/Views/BOTA/SearchContent.xaml


+ 57 - 52
PDF Office/Views/BOTA/SearchContent.xaml.cs

@@ -1,4 +1,6 @@
 using PDF_Office.CustomControl;
+using PDF_Office.Model.BOTA;
+using PDF_Office.ViewModels.BOTA;
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
@@ -19,57 +21,32 @@ using System.Windows.Shapes;
 
 namespace PDF_Office.Views.BOTA
 {
-    public class TextSearchBindItem : INotifyPropertyChanged
-    {
-        public int ShowPageIndex { get { return BindProperty.PageIndex + 1; } set { BindProperty.PageIndex = value; } }
-        public TextBindProperty BindProperty { get; set; }
-        public TextSearchBindItem()
-        {
-            BindProperty = new TextBindProperty();
-        }
-
-        public int PageCount { get; set; }
-        private int _pageMaxCount;
-        public int PageMaxCount { get { return _pageMaxCount; } set { _pageMaxCount = value; OnPropertyChanged("Percent"); } }
-
-        public double Percent { get { if (PageMaxCount > 0 && PageCount >= 0) return (double)PageCount / (double)PageMaxCount; return 0; } }
-
-        public event PropertyChangedEventHandler PropertyChanged;
-        protected void OnPropertyChanged([CallerMemberName] string name = null)
-        {
-            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
-        }
-    }
-
-
-    public class TextBindProperty
-    {
-        public int PageIndex { get; set; }
-        public string TextContent { get; set; }
-        public Color HighLightColor { get; set; }
-        public string SearchWord { get; set; }
-        public Rect TextRect { get; set; }
-        public int PageRotate { get; set; }
-    }
     /// <summary>
     /// SearchContent.xaml 的交互逻辑
     /// </summary>
     public partial class SearchContent : UserControl
     {
-       // private ObservableCollection<TextSearchBindItem> searchResults;
         public SearchContent()
         {
             InitializeComponent();
-       //     searchResults = new ObservableCollection<TextSearchBindItem>();
-        //    ICollectionView groupView = CollectionViewSource.GetDefaultView(searchResults);
-        //    groupView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(TextSearchBindItem.ShowPageIndex)));
         }
 
-        private void SearchResultList_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        private void TextBox_KeyDown(object sender, KeyEventArgs e)
         {
-
+            if (e.Key==Key.Enter)
+            {
+                TextBox text = e.Source as TextBox;
+                if (text==null)
+                {
+                    return;
+                }
+                (DataContext as SearchContentViewModel).SearchText(text.Text);
+            }
         }
 
+        /// <summary>
+        /// 控制收起与展开
+        /// </summary>
         private void BtnExptend_Click(object sender, RoutedEventArgs e)
         {
             var btn = sender as CustomIconToggleBtn;
@@ -77,26 +54,54 @@ namespace PDF_Office.Views.BOTA
 
 
             var item = (sender as FrameworkElement).DataContext as CollectionViewGroup;
-            if(item != null)
+            if (item != null)
             {
-                foreach (var item2 in item.Items)
+                foreach (object item2 in item.Items)
                 {
-                    var item3 = item2 as TextSearchBindItem;
-
-                    var listBoxItem = SearchResultList.ItemContainerGenerator.ContainerFromItem(item3) as ListViewItem;
-                    if (listBoxItem != null)
+                    SearchItem searchItem = item2 as SearchItem;
+                    if (searchItem.TextProperty.ItemVisibility==Visibility.Visible)
                     {
-                       if(btn.IsChecked == true)
-                        {
-                            listBoxItem.Visibility = Visibility.Collapsed;
-                        }
-                       else
-                        {
-                            listBoxItem.Visibility = Visibility.Visible;
-                        }
+                        searchItem.TextProperty.ItemVisibility = Visibility.Collapsed;
+                    }
+                    else
+                    {
+                        searchItem.TextProperty.ItemVisibility = Visibility.Visible;
                     }
                 }
             }
         }
+
+        private void Create_Click(object sender, RoutedEventArgs e)
+        {
+            MenuItem menuItem= sender as MenuItem;
+            if (menuItem==null)
+            {
+                return;
+            }
+            foreach (object item in SearchResultList.SelectedItems)
+            {
+                (DataContext as SearchContentViewModel).CreateAnnotate(item, menuItem.Tag.ToString());
+            }
+        }
+
+        private void TextBoxEx_Initialized(object sender, EventArgs e)
+        {
+            var btn = sender as TextBoxEx;
+            if (btn != null)
+            {
+                btn.ContextMenu = null;
+            }
+        }
+
+        private void PathButton_Click(object sender, RoutedEventArgs e)
+        {
+            ContextSearchText.PlacementTarget = SearchText;
+            ContextSearchText.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
+            ContextSearchText.IsOpen = true;
+        }
+
+        private void MenuItem_Click(object sender, RoutedEventArgs e)
+        {
+        }
     }
 }