|
@@ -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;
|
|
|
}
|
|
|
}
|
|
|
}
|