|
@@ -1,20 +1,21 @@
|
|
|
using ComPDFKit.Import;
|
|
|
+using ComPDFKit.PDFAnnotation;
|
|
|
+using ComPDFKit.PDFAnnotation.Form;
|
|
|
using ComPDFKit.Tool.DrawTool;
|
|
|
+using ComPDFKit.Tool.Help;
|
|
|
+using ComPDFKit.Tool.UndoManger;
|
|
|
using ComPDFKitViewer;
|
|
|
using ComPDFKitViewer.BaseObject;
|
|
|
using ComPDFKitViewer.Helper;
|
|
|
using ComPDFKitViewer.Layer;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
-using System.Diagnostics;
|
|
|
using System.Linq;
|
|
|
-using System.Net;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
+using System.Reflection;
|
|
|
using System.Windows;
|
|
|
-using System.Windows.Controls.Primitives;
|
|
|
using System.Windows.Input;
|
|
|
using System.Windows.Media;
|
|
|
+using static ComPDFKit.Tool.CPDFViewerTool;
|
|
|
|
|
|
namespace ComPDFKit.Tool
|
|
|
{
|
|
@@ -32,9 +33,10 @@ namespace ComPDFKit.Tool
|
|
|
private AnnotSelectAreaData AreaDrawData { get; set; } = new AnnotSelectAreaData();
|
|
|
private AnnotSelectAreaData AreaMoveData { get; set; } = new AnnotSelectAreaData();
|
|
|
private bool DrawSelect { get; set; } = true;
|
|
|
- private bool AllowMultiSelect { get; set; }
|
|
|
+ private bool AllowMultiSelect { get; set; } = false;
|
|
|
private bool IsMoved { get; set; } = false;
|
|
|
private Point OffsetPos { get; set; }=new Point(0,0);
|
|
|
+ private List<AnnotParam> AnnotParamList { get; set; }=new List<AnnotParam>();
|
|
|
private void AnnotSelectInsert()
|
|
|
{
|
|
|
Selector = new AnnotSelector();
|
|
@@ -188,7 +190,7 @@ namespace ComPDFKit.Tool
|
|
|
drawDC.Close();
|
|
|
}
|
|
|
|
|
|
- private void AnnotSelectAreaSelect()
|
|
|
+ private void AnnotSelectAreaSelect(bool onlyWidget=false,bool onlyAnnot = false)
|
|
|
{
|
|
|
if (!AllowMultiSelect)
|
|
|
{
|
|
@@ -214,6 +216,15 @@ namespace ComPDFKit.Tool
|
|
|
areaRect.Intersect(AreaDrawData.HitAreaBound);
|
|
|
foreach (AnnotData checkItem in PDFViewer.CurrentRenderFrame.AnnotDataList)
|
|
|
{
|
|
|
+ if (onlyWidget && checkItem.AnnotType != C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if(onlyAnnot && checkItem.AnnotType == C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
if (areaRect.IntersectsWith(checkItem.PaintRect))
|
|
|
{
|
|
|
Selector.AddItem(checkItem);
|
|
@@ -640,6 +651,8 @@ namespace ComPDFKit.Tool
|
|
|
|
|
|
private void AnnotSelectMoveSave()
|
|
|
{
|
|
|
+ GroupHistory historyGroup = new GroupHistory();
|
|
|
+
|
|
|
foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
{
|
|
|
if(checkItem.Annot==null || checkItem.Annot.IsValid()==false)
|
|
@@ -660,7 +673,22 @@ namespace ComPDFKit.Tool
|
|
|
saveRect.Height/checkItem.CurrentZoom);
|
|
|
Rect rawRect= DpiHelper.StandardRectToPDFRect(noZoomRect);
|
|
|
|
|
|
+ AnnotHistory historyItem = ParamConverter.CreateHistory(checkItem.Annot);
|
|
|
+ AnnotParam prevParam = ParamConverter.CPDFDataConverterToAnnotParam(PDFViewer.GetDocument(), checkItem.PageIndex, checkItem.Annot);
|
|
|
checkItem.Annot.SetRect(new CRect((float)rawRect.Left, (float)rawRect.Bottom, (float)rawRect.Right, (float)rawRect.Top));
|
|
|
+ AnnotParam currentParam = ParamConverter.CPDFDataConverterToAnnotParam(PDFViewer.GetDocument(), checkItem.PageIndex, checkItem.Annot);
|
|
|
+
|
|
|
+ historyItem.PreviousParam = prevParam;
|
|
|
+ historyItem.CurrentParam = currentParam;
|
|
|
+ historyItem.Action = HistoryAction.Update;
|
|
|
+ historyItem.PDFDoc = PDFViewer.GetDocument();
|
|
|
+ historyGroup.Histories.Add(historyItem);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (historyGroup.Histories.Count > 0 && PDFViewer != null)
|
|
|
+ {
|
|
|
+ PDFViewer.UndoManager?.AddHistory(historyGroup);
|
|
|
+ PDFViewer.UpdateAnnotFrame();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -715,6 +743,8 @@ namespace ComPDFKit.Tool
|
|
|
|
|
|
Rect newRect = new Rect(new Point(left, top), new Point(right, bottom));
|
|
|
|
|
|
+ GroupHistory historyGroup = new GroupHistory();
|
|
|
+
|
|
|
foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
{
|
|
|
if (checkItem.Annot == null || checkItem.Annot.IsValid() == false)
|
|
@@ -748,9 +778,359 @@ namespace ComPDFKit.Tool
|
|
|
saveRect.Height / checkItem.CurrentZoom);
|
|
|
Rect rawRect = DpiHelper.StandardRectToPDFRect(noZoomRect);
|
|
|
|
|
|
+ AnnotHistory historyItem = ParamConverter.CreateHistory(checkItem.Annot);
|
|
|
+ AnnotParam prevParam = ParamConverter.CPDFDataConverterToAnnotParam(PDFViewer.GetDocument(), checkItem.PageIndex, checkItem.Annot);
|
|
|
checkItem.Annot.SetRect(new CRect((float)rawRect.Left, (float)rawRect.Bottom, (float)rawRect.Right, (float)rawRect.Top));
|
|
|
+ AnnotParam currentParam = ParamConverter.CPDFDataConverterToAnnotParam(PDFViewer.GetDocument(), checkItem.PageIndex, checkItem.Annot);
|
|
|
+
|
|
|
+ historyItem.PreviousParam = prevParam;
|
|
|
+ historyItem.CurrentParam = currentParam;
|
|
|
+ historyItem.Action = HistoryAction.Update;
|
|
|
+ historyItem.PDFDoc = PDFViewer.GetDocument();
|
|
|
+ historyGroup.Histories.Add(historyItem);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (historyGroup.Histories.Count > 0 && PDFViewer != null)
|
|
|
+ {
|
|
|
+ PDFViewer.UndoManager?.AddHistory(historyGroup);
|
|
|
+ PDFViewer.UpdateAnnotFrame();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AnnotSelectClean()
|
|
|
+ {
|
|
|
+ Selector?.CleanDraw();
|
|
|
+ Selector?.ClearItem();
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool AnnotSelectCommandSupport(RoutedUICommand uiCmd)
|
|
|
+ {
|
|
|
+ if (!AllowMultiSelect)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uiCmd==null || PDFViewer == null || Selector == null)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (uiCmd.Name)
|
|
|
+ {
|
|
|
+ case "Copy":
|
|
|
+ case "Cut":
|
|
|
+ case "Delete":
|
|
|
+ return Selector.GetSelectCount() >= 2;
|
|
|
+ case "Paste":
|
|
|
+ return AnnotParamList.Count() >= 2;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ private void AnnotSelectCommandExecute(RoutedUICommand uiCmd)
|
|
|
+ {
|
|
|
+ if (!AllowMultiSelect)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uiCmd == null || string.IsNullOrEmpty(uiCmd.Name) || PDFViewer == null || Selector == null)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (uiCmd.Name)
|
|
|
+ {
|
|
|
+ case "Copy":
|
|
|
+ AnnotSelectCopy();
|
|
|
+ break;
|
|
|
+ case "Cut":
|
|
|
+ AnnotSelectCopy();
|
|
|
+ AnnotSelectDelete();
|
|
|
+ break;
|
|
|
+ case "Delete":
|
|
|
+ AnnotSelectDelete();
|
|
|
+ break;
|
|
|
+ case "Paste":
|
|
|
+ AnnotSelectPaste();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private void AnnotSelectCopy()
|
|
|
+ {
|
|
|
+ AnnotParamList?.Clear();
|
|
|
+ if (!AllowMultiSelect)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Selector.GetSelectCount()< 2)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
+ {
|
|
|
+ if (checkItem == null || checkItem.Annot == null || checkItem.Annot.IsValid() == false)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ AnnotParam prevParam = ParamConverter.CPDFDataConverterToAnnotParam(PDFViewer.GetDocument(), checkItem.PageIndex, checkItem.Annot);
|
|
|
+ if (prevParam == null)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
}
|
|
|
+ AnnotParamList.Add(prevParam);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private void AnnotSelectDelete()
|
|
|
+ {
|
|
|
+ if (!AllowMultiSelect)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Selector.GetSelectCount() < 2)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ GroupHistory historyGroup=new GroupHistory();
|
|
|
+ Dictionary<AnnotHistory, CPDFAnnotation> removeDict = new Dictionary<AnnotHistory, CPDFAnnotation>();
|
|
|
+ foreach (AnnotData checkItem in Selector.SelectAnnots)
|
|
|
+ {
|
|
|
+ if (checkItem == null || checkItem.Annot == null || checkItem.Annot.IsValid() == false)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ AnnotHistory historyItem = ParamConverter.CreateHistory(checkItem.Annot);
|
|
|
+ AnnotParam prevParam = ParamConverter.CPDFDataConverterToAnnotParam(PDFViewer.GetDocument(), checkItem.PageIndex, checkItem.Annot);
|
|
|
+ if (prevParam == null || historyItem==null)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ historyItem.CurrentParam = prevParam;
|
|
|
+ historyItem.Action = HistoryAction.Remove;
|
|
|
+ historyItem.PDFDoc = PDFViewer.GetDocument();
|
|
|
+ removeDict[historyItem]=checkItem.Annot;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach(AnnotHistory annotKey in removeDict.Keys)
|
|
|
+ {
|
|
|
+ CPDFAnnotation removeAnnot= removeDict[annotKey];
|
|
|
+ if (removeAnnot.RemoveAnnot())
|
|
|
+ {
|
|
|
+ historyGroup.Histories.Add(annotKey);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (historyGroup.Histories.Count > 0)
|
|
|
+ {
|
|
|
+ CleanSelectedRect();
|
|
|
+ AnnotSelectClean();
|
|
|
+ PDFViewer?.UndoManager.AddHistory(historyGroup);
|
|
|
+ PDFViewer?.UpdateAnnotFrame();
|
|
|
+ PDFViewer?.UpdateRenderFrame();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AnnotSelectPaste()
|
|
|
+ {
|
|
|
+ if (!AllowMultiSelect)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ double left = 0;
|
|
|
+ double right = 0;
|
|
|
+ double top = 0;
|
|
|
+ double bottom = 0;
|
|
|
+
|
|
|
+ Point point = rightPressPoint;
|
|
|
+ rightPressPoint = new Point(-1, -1);
|
|
|
+
|
|
|
+ for (int i = 0; i < AnnotParamList.Count; i++)
|
|
|
+ {
|
|
|
+ AnnotParam checkParam= AnnotParamList[i];
|
|
|
+ if(i==0)
|
|
|
+ {
|
|
|
+ left = checkParam.ClientRect.left;
|
|
|
+ top = checkParam.ClientRect.top;
|
|
|
+ bottom = checkParam.ClientRect.bottom;
|
|
|
+ right = checkParam.ClientRect.right;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ left = Math.Min(left, checkParam.ClientRect.left);
|
|
|
+ right = Math.Max(right, checkParam.ClientRect.right);
|
|
|
+ top = Math.Min(top, checkParam.ClientRect.top);
|
|
|
+ bottom = Math.Max(bottom, checkParam.ClientRect.bottom);
|
|
|
+ }
|
|
|
+
|
|
|
+ Point offsetPos = new Point(25, 25);
|
|
|
+
|
|
|
+ PDFViewer.GetPointPageInfo(point, out int pageIndex, out Rect paintRect, out Rect pageBound);
|
|
|
+ if (pageIndex >= 0)
|
|
|
+ {
|
|
|
+ Point zoomPoint = new Point((point.X - pageBound.X) / currentZoom, (point.Y - pageBound.Y) / currentZoom);
|
|
|
+ Point rawPoint = DpiHelper.StandardPointToPDFPoint(zoomPoint);
|
|
|
+ double rawWidth = DpiHelper.StandardNumToPDFNum(pageBound.Width / currentZoom);
|
|
|
+ double rawHeight = DpiHelper.StandardNumToPDFNum(pageBound.Height / currentZoom);
|
|
|
+
|
|
|
+ offsetPos = new Point(rawPoint.X, rawPoint.Y);
|
|
|
+
|
|
|
+ if (rawPoint.X + right - left > rawWidth)
|
|
|
+ {
|
|
|
+ offsetPos.X = rawWidth + left - right;
|
|
|
+ }
|
|
|
+ if (rawPoint.Y + bottom - top > rawHeight)
|
|
|
+ {
|
|
|
+ offsetPos.Y = rawHeight + top - bottom;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ GroupHistory historyGroup = new GroupHistory();
|
|
|
+ foreach (AnnotParam annotParam in AnnotParamList)
|
|
|
+ {
|
|
|
+ AnnotParam cloneItem = CloneAnnotParam(annotParam);
|
|
|
+ if(cloneItem==null)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Rect saveRect= new Rect(cloneItem.ClientRect.left,cloneItem.ClientRect.top,cloneItem.ClientRect.width(),cloneItem.ClientRect.height());
|
|
|
+ saveRect.X = saveRect.Left - left + offsetPos.X;
|
|
|
+ saveRect.Y = saveRect.Top - top + offsetPos.Y;
|
|
|
+
|
|
|
+ cloneItem.PageIndex= pageIndex;
|
|
|
+ cloneItem.ClientRect=new CRect((float)saveRect.Left, (float)saveRect.Bottom, (float)saveRect.Right, (float)saveRect.Top);
|
|
|
+ AnnotHistory historyItem = ParamConverter.CreateHistory(annotParam);
|
|
|
+ historyItem.CurrentParam = cloneItem;
|
|
|
+ historyItem.PDFDoc = PDFViewer.GetDocument();
|
|
|
+
|
|
|
+ historyItem.Add();
|
|
|
+ historyGroup.Histories.Add(historyItem);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (historyGroup.Histories.Count > 0 && PDFViewer != null)
|
|
|
+ {
|
|
|
+ CleanSelectedRect();
|
|
|
+ AnnotSelectClean();
|
|
|
+ PDFViewer.UndoManager?.AddHistory(historyGroup);
|
|
|
+ PDFViewer.UpdateAnnotFrame();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private AnnotParam CloneAnnotParam(AnnotParam oldParam)
|
|
|
+ {
|
|
|
+ if (oldParam != null)
|
|
|
+ {
|
|
|
+ AnnotParam newParam= new AnnotParam();
|
|
|
+ switch (oldParam.CurrentType)
|
|
|
+ {
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_CIRCLE:
|
|
|
+ newParam = new CircleParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_FREETEXT:
|
|
|
+ newParam=new FreeTextParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_HIGHLIGHT:
|
|
|
+ newParam=new HighlightParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_INK:
|
|
|
+ newParam=new InkParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_LINE:
|
|
|
+ newParam= new LineParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_LINK:
|
|
|
+ newParam=new LinkParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_CARET:
|
|
|
+ newParam=new RedactParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_SQUARE:
|
|
|
+ newParam=new SquareParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_SQUIGGLY:
|
|
|
+ newParam=new SquareParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_STAMP:
|
|
|
+ newParam=new StampParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_TEXT:
|
|
|
+ newParam=new StickyNoteParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_STRIKEOUT:
|
|
|
+ newParam=new StickyNoteParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_UNDERLINE:
|
|
|
+ newParam=new UnderlineParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET:
|
|
|
+ WidgetParm widgetParam=oldParam as WidgetParm;
|
|
|
+ if (widgetParam != null)
|
|
|
+ {
|
|
|
+ switch (widgetParam.WidgetType)
|
|
|
+ {
|
|
|
+ case C_WIDGET_TYPE.WIDGET_CHECKBOX:
|
|
|
+ newParam=new CheckBoxParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_WIDGET_TYPE.WIDGET_COMBOBOX:
|
|
|
+ newParam=new ComboBoxParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_WIDGET_TYPE.WIDGET_LISTBOX:
|
|
|
+ newParam=new ListBoxParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_WIDGET_TYPE.WIDGET_PUSHBUTTON:
|
|
|
+ newParam=new PushButtonParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_WIDGET_TYPE.WIDGET_RADIOBUTTON:
|
|
|
+ newParam=new RadioButtonParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_WIDGET_TYPE.WIDGET_SIGNATUREFIELDS:
|
|
|
+ newParam=new SignatureParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ case C_WIDGET_TYPE.WIDGET_TEXTFIELD:
|
|
|
+ newParam=new TextBoxParam();
|
|
|
+ oldParam.CopyTo(newParam);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return newParam;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|
|
|
}
|