Prechádzať zdrojové kódy

PDFTools(iOS) - 注释模块串接

dinglingui 1 rok pred
rodič
commit
21a34a10b3

+ 15 - 0
Annotation-Ctrl-Demo/Annotation-Ctrl-Demo.xcodeproj/project.pbxproj

@@ -24,6 +24,7 @@
 		C9AF187F29F26ADF00EC4979 /* Quick Start Guide.pdf in Resources */ = {isa = PBXBuildFile; fileRef = C9AF187B29F26ADF00EC4979 /* Quick Start Guide.pdf */; };
 		F32776912A04A6D900C5F0A6 /* ComPDFKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C918CEBB29F904E400D43974 /* ComPDFKit.xcframework */; };
 		F32776922A04A6D900C5F0A6 /* ComPDFKit.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C918CEBB29F904E400D43974 /* ComPDFKit.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		F350B3502A09EFF500B4FC8F /* CPDFMediaManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F350B34F2A09EFF500B4FC8F /* CPDFMediaManager.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -64,6 +65,8 @@
 		C9AF187829F26ADF00EC4979 /* Form_Widgets_Test.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = Form_Widgets_Test.pdf; sourceTree = "<group>"; };
 		C9AF187929F26ADF00EC4979 /* PDF32000_2008.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = PDF32000_2008.pdf; sourceTree = "<group>"; };
 		C9AF187B29F26ADF00EC4979 /* Quick Start Guide.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Quick Start Guide.pdf"; sourceTree = "<group>"; };
+		F350B34D2A09EFF500B4FC8F /* CPDFMediaManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPDFMediaManager.h; sourceTree = "<group>"; };
+		F350B34F2A09EFF500B4FC8F /* CPDFMediaManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPDFMediaManager.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -116,6 +119,7 @@
 				C9AF185329F267DD00EC4979 /* SceneDelegate.m */,
 				4F06AB5B29F6852C007797E4 /* CPDFViewController.h */,
 				4F06AB5C29F6852C007797E4 /* CPDFViewController.m */,
+				F350B34C2A09EFF500B4FC8F /* PDFSound */,
 				C9AF185829F267DD00EC4979 /* Main.storyboard */,
 				C9AF185B29F267E000EC4979 /* Assets.xcassets */,
 				C9AF185D29F267E000EC4979 /* LaunchScreen.storyboard */,
@@ -149,6 +153,16 @@
 			path = ../TestFile;
 			sourceTree = "<group>";
 		};
+		F350B34C2A09EFF500B4FC8F /* PDFSound */ = {
+			isa = PBXGroup;
+			children = (
+				F350B34D2A09EFF500B4FC8F /* CPDFMediaManager.h */,
+				F350B34F2A09EFF500B4FC8F /* CPDFMediaManager.m */,
+			);
+			name = PDFSound;
+			path = "../../compdfkit-tools/compdfkit-tools/Annotation/PDFProperties/PDFSound";
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -229,6 +243,7 @@
 				C9AF185129F267DD00EC4979 /* AppDelegate.m in Sources */,
 				C9AF187629F26AD200EC4979 /* XMLParseManager.m in Sources */,
 				C9AF186229F267E000EC4979 /* main.m in Sources */,
+				F350B3502A09EFF500B4FC8F /* CPDFMediaManager.m in Sources */,
 				C9AF185429F267DD00EC4979 /* SceneDelegate.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 29 - 16
Annotation-Ctrl-Demo/Annotation-Ctrl-Demo/CPDFViewController.m

@@ -12,6 +12,8 @@
 
 #import "CPDFViewController.h"
 
+#import "CPDFMediaManager.h"
+
 #import <ComPDFKit/ComPDFKit.h>
 #import <compdfkit_tools/compdfkit_tools.h>
 
@@ -177,13 +179,6 @@
     [self.navigationController pushViewController:thumbnailViewController animated:NO];
 }
 
-- (void)menuItemClick_CopyAction:(id)sender {
-    if (self.pdfListView.currentSelection.string)
-        [[UIPasteboard generalPasteboard] setString:self.pdfListView.currentSelection.string];
-    
-    [self.pdfListView clearSelection];
-}
-
 #pragma mark - CPDFViewDelegate
 
 - (void)PDFViewDocumentDidLoaded:(CPDFView *)pdfView {
@@ -210,15 +205,6 @@
 
 #pragma mark - CPDFListViewDelegate
 
-- (NSArray<UIMenuItem *> *)PDFListView:(CPDFListView *)pdfListView customizeMenuForPage:(CPDFPage *)page forPagePoint:(CGPoint)pagePoint {
-    if (pdfListView.currentSelection) {
-        UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", nil)
-                                                          action:@selector(menuItemClick_CopyAction:)];
-        return @[copyItem];
-    }
-    return nil;
-}
-
 - (void)PDFListViewPerformTouchEnded:(CPDFListView *)pdfView {
     if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
         if (self.navigationController.navigationBarHidden) {
@@ -267,6 +253,33 @@
     self.annotationManage = [[CAnnotationManage alloc] initWithPDFView:pdfListView];
 }
 
+- (void)PDFListViewPerformAddStamp:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    
+}
+
+- (void)PDFListViewPerformAddImage:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    
+}
+
+- (BOOL)PDFListViewerTouchEndedIsAudioRecordMedia:(CPDFListView *)pdfListView {
+    if (CPDFMediaStateAudioRecord == [CPDFMediaManager shareManager].mediaState) {
+        return YES;
+    }
+    return NO;
+}
+
+- (void)PDFListViewPerformCancelMedia:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    [CPDFMediaManager shareManager].mediaState = CPDFMediaStateStop;
+    self.pdfListView.annotationMode = CPDFViewAnnotationModeNone;
+}
+
+- (void)PDFListViewPerformRecordMedia:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    NSInteger pageindex = [self.pdfListView.document indexForPage:page];
+    [CPDFMediaManager shareManager].mediaState = CPDFMediaStateAudioRecord;
+    [CPDFMediaManager shareManager].pageNum = pageindex;
+    [CPDFMediaManager shareManager].ptInPdf = point;    
+}
+
 #pragma mark - CPDFMorelistViewDelegate
 
 - (void)PDFMoreListViewController:(CPDFMoreListViewController *)moreVC didSelectRow:(CPDFMoreListViewType)row {

+ 25 - 0
compdfkit-tools/compdfkit-tools.xcodeproj/project.pbxproj

@@ -148,6 +148,8 @@
 		F32DA19129ED908800E19ECA /* CPDFMoreListViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = F32DA18F29ED908800E19ECA /* CPDFMoreListViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		F32DA19229ED908800E19ECA /* CPDFMoreListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F32DA19029ED908800E19ECA /* CPDFMoreListViewController.m */; };
 		F335EE4B29E430C800ACC72A /* compdfkit_tools.h in Headers */ = {isa = PBXBuildFile; fileRef = F335EE4A29E430C800ACC72A /* compdfkit_tools.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		F350B34A2A09EAF100B4FC8F /* CPDFMediaManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F350B3482A09EAF100B4FC8F /* CPDFMediaManager.m */; };
+		F350B34B2A09EAF100B4FC8F /* CPDFMediaManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F350B3492A09EAF100B4FC8F /* CPDFMediaManager.h */; };
 		F35DD18A2A067E7500B57F5B /* CPDFListView+UndoManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F35DD1882A067E7500B57F5B /* CPDFListView+UndoManager.h */; };
 		F35DD18B2A067E7500B57F5B /* CPDFListView+UndoManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F35DD1892A067E7500B57F5B /* CPDFListView+UndoManager.m */; };
 		F35DD1982A06850700B57F5B /* CPDFFreeTextAnnotation+PDFListView.m in Sources */ = {isa = PBXBuildFile; fileRef = F35DD18D2A06850700B57F5B /* CPDFFreeTextAnnotation+PDFListView.m */; };
@@ -339,6 +341,8 @@
 		F32DA19029ED908800E19ECA /* CPDFMoreListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPDFMoreListViewController.m; sourceTree = "<group>"; };
 		F335EE4729E430C800ACC72A /* compdfkit_tools.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = compdfkit_tools.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		F335EE4A29E430C800ACC72A /* compdfkit_tools.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = compdfkit_tools.h; sourceTree = "<group>"; };
+		F350B3482A09EAF100B4FC8F /* CPDFMediaManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPDFMediaManager.m; sourceTree = "<group>"; };
+		F350B3492A09EAF100B4FC8F /* CPDFMediaManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPDFMediaManager.h; sourceTree = "<group>"; };
 		F35DD1882A067E7500B57F5B /* CPDFListView+UndoManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CPDFListView+UndoManager.h"; sourceTree = "<group>"; };
 		F35DD1892A067E7500B57F5B /* CPDFListView+UndoManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CPDFListView+UndoManager.m"; sourceTree = "<group>"; };
 		F35DD18D2A06850700B57F5B /* CPDFFreeTextAnnotation+PDFListView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CPDFFreeTextAnnotation+PDFListView.m"; sourceTree = "<group>"; };
@@ -592,6 +596,7 @@
 		C9AF188829F4C65500EC4979 /* Annotation */ = {
 			isa = PBXGroup;
 			children = (
+				F350B3462A09EAAC00B4FC8F /* PDFSound */,
 				C918CE8F29F7C3FA00D43974 /* PDFAnnotationManage */,
 				C9AF188A29F4C7C900EC4979 /* PDFProperties */,
 				C9AF188929F4C68200EC4979 /* PDFAnnotationList */,
@@ -609,6 +614,7 @@
 		C9AF188A29F4C7C900EC4979 /* PDFProperties */ = {
 			isa = PBXGroup;
 			children = (
+				F350B3472A09EAD400B4FC8F /* PDFSound */,
 				C91BE7D12A0399F40038F2BC /* PDFSignature */,
 				C91BE7C02A0234CB0038F2BC /* PDFFreeText */,
 				C918CECB29FA432D00D43974 /* PDFShape */,
@@ -891,6 +897,23 @@
 			path = "compdfkit-tools";
 			sourceTree = "<group>";
 		};
+		F350B3462A09EAAC00B4FC8F /* PDFSound */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			name = PDFSound;
+			path = PDFProperties/PDFSound;
+			sourceTree = "<group>";
+		};
+		F350B3472A09EAD400B4FC8F /* PDFSound */ = {
+			isa = PBXGroup;
+			children = (
+				F350B3492A09EAF100B4FC8F /* CPDFMediaManager.h */,
+				F350B3482A09EAF100B4FC8F /* CPDFMediaManager.m */,
+			);
+			path = PDFSound;
+			sourceTree = "<group>";
+		};
 		F35DD18C2A06850700B57F5B /* PDFKit Categories */ = {
 			isa = PBXGroup;
 			children = (
@@ -978,6 +1001,7 @@
 				F32DA16A29ED904300E19ECA /* CPDFSearchViewCell.h in Headers */,
 				4F5986912A03411700F06A1B /* CPDFDropDownMenu.h in Headers */,
 				F32DA18529ED904300E19ECA /* CActivityIndicatorView.h in Headers */,
+				F350B34B2A09EAF100B4FC8F /* CPDFMediaManager.h in Headers */,
 				4F06AB5529F6792E007797E4 /* CPDFEditToolBar.h in Headers */,
 				F32DA17E29ED904300E19ECA /* CPDFBOTAViewController.h in Headers */,
 				F32DA16829ED904300E19ECA /* CPDFOutlineViewCell.h in Headers */,
@@ -1145,6 +1169,7 @@
 				C9B9EC5029F52DCC00C6A5D2 /* AAPLCustomPresentationController.m in Sources */,
 				4F1131BB29F911A800950564 /* CPDFTextPropertyCell.m in Sources */,
 				F35DD1A02A06850700B57F5B /* CPDFAnnotation+PDFListView.m in Sources */,
+				F350B34A2A09EAF100B4FC8F /* CPDFMediaManager.m in Sources */,
 				F32DA17F29ED904300E19ECA /* CNavigationController.m in Sources */,
 				F382636D29EFD0D9003F1DFD /* CPDFListView.m in Sources */,
 				F38F5B672A03D68100D0EEFD /* CPDFListMagnifierView.m in Sources */,

+ 33 - 0
compdfkit-tools/compdfkit-tools/Annotation/PDFProperties/PDFSound/CPDFMediaManager.h

@@ -0,0 +1,33 @@
+//
+//  CPDFMediaManager.h
+//  compdfkit-tools
+//
+//  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+//
+//  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+//  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+//  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+//  This notice may not be removed from this file.
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, CPDFMediaState) {
+    CPDFMediaStateStop = 0,
+    CPDFMediaStateRedayRecord,
+    CPDFMediaStateAudioRecord,
+    CPDFMediaStateVedioPlaying
+};
+
+@interface CPDFMediaManager : NSObject
+
++ (CPDFMediaManager*)shareManager;
+
+@property (nonatomic, assign)CPDFMediaState mediaState;
+
+@property (nonatomic, assign)NSInteger pageNum;
+
+@property (nonatomic, assign)CGPoint ptInPdf;
+
+@end

+ 26 - 0
compdfkit-tools/compdfkit-tools/Annotation/PDFProperties/PDFSound/CPDFMediaManager.m

@@ -0,0 +1,26 @@
+//
+//  CPDFMediaManager.m
+//  compdfkit-tools
+//
+//  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+//
+//  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+//  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+//  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+//  This notice may not be removed from this file.
+//
+
+#import "CPDFMediaManager.h"
+
+@implementation CPDFMediaManager
+
++ (CPDFMediaManager*)shareManager {
+    static CPDFMediaManager* mediaManager = nil;
+    static dispatch_once_t  predicate;
+    dispatch_once(&predicate, ^{
+        mediaManager = [[CPDFMediaManager alloc] init];
+    });
+    return mediaManager;
+}
+
+@end

+ 38 - 82
compdfkit-tools/compdfkit-tools/Common/Views/PDFAnnotationBar/CPDFAnnotationBar.m

@@ -24,6 +24,9 @@
 #import "CPDFInkTopToolBar.h"
 #import "CAnnotStyle.h"
 #import "CPDFListView.h"
+#import "CPDFListView+UndoManager.h"
+#import "CPDFListView+Private.h"
+
 #import "CAnnotationManage.h"
 #import "CPDFSignatureEditViewController.h"
 #import "CSignatureManager.h"
@@ -80,6 +83,10 @@
         [self initSubview];
         
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(annotationChangedNotification:) name:CPDFListViewActiveAnnotationsChangeNotification object:nil];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(annotationsOperationChangeNotification:) name:CPDFListViewAnnotationsOperationChangeNotification object:nil];
+        
+        [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewAnnotationsOperationChangeNotification object:annotationManage.pdfListView];
+
     }
     return self;
 }
@@ -217,93 +224,21 @@
 #pragma mark - Action
 
 - (void)buttonItemClicked_Switch:(UIButton *)button {
-    self.propertiesBtn.userInteractionEnabled = YES;
-    self.propertiesBtn.tag = button.tag;
-    if (self.selectedIndex >= 0 && self.selectedIndex <= self.annotationBtns.count) {
-        UIButton *selectButton = [self.annotationBtns objectAtIndex:self.selectedIndex];
-        selectButton.backgroundColor = [UIColor clearColor];
-    }
-    
-    if (button.tag != self.selectedIndex) {
+    self.selectedIndex = button.tag;
+    if (self.pdfListView.annotationMode != self.selectedIndex) {
+        self.propertiesBtn.enabled = YES;
         button.backgroundColor = [UIColor colorWithRed:178.0/255.0 green:239.0/255.0 blue:253.0/255.0 alpha:1.0];
-        self.selectedIndex = button.tag;
         self.pdfListView.annotationMode = self.selectedIndex;
-
+        
+        [self.annotManage setAnnotStyleFromMode:self.selectedIndex];
     } else {
+        self.propertiesBtn.enabled = NO;
         self.pdfListView.annotationMode = CPDFViewAnnotationModeNone;
         self.selectedIndex = -1;
-        self.pdfListView.annotationMode = CPDFViewAnnotationModeNone;
+        button.backgroundColor = [UIColor clearColor];
     }
     
-    switch (self.selectedIndex) {
-        case CPDFToolbarNote:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeNote;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeNote];
-        }
-            break;
-        case CPDFToolbarHighlight:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeHighlight;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeNote];
-        }
-            break;
-        case CPDFToolbarUnderline:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeUnderline;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeHighlight];
-        }
-            break;
-        case CPDFToolbarStrikeout:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeStrikeout;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeStrikeout];
-        }
-            break;
-        case CPDFToolbarSquiggly:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeSquiggly;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeSquiggly];
-        }
-            break;
-        case CPDFToolbarFreehand:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeInk;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeInk];
-        }
-            break;
-        case CPDFToolbarShapeCircle:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeCircle;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeCircle];
-        }
-            break;
-        case CPDFToolbarShapeRectangle:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeSquare;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeSquare];
-        }
-            break;
-        case CPDFToolbarShapeArrow:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeArrow;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeArrow];
-        }
-            break;
-        case CPDFToolbarShapeLine:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeLine;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeLine];
-        }
-            break;
-            
-        default:
-        {
-            self.pdfListView.annotationMode = CPDFViewAnnotationModeNone;
-            [self.annotManage setAnnotStyleFromMode:CPDFViewAnnotationModeNone];
-        }
-            break;
-    }
+    self.propertiesBtn.tag = self.selectedIndex;
 }
 
 - (void)buttonItemClicked_open:(UIButton *)button {
@@ -430,11 +365,15 @@
 }
 
 - (void)buttonItemClicked_undo:(UIButton *)button {
-    
+    if(self.annotManage.pdfListView.undoPDFManager && [self.annotManage.pdfListView canUndo]) {
+        [self.annotManage.pdfListView.undoPDFManager undo];
+    }
 }
 
 - (void)buttonItemClicked_redo:(UIButton *)button {
-    
+    if(self.annotManage.pdfListView.undoPDFManager && [self.annotManage.pdfListView canUndo]) {
+        [self.annotManage.pdfListView.undoPDFManager redo];
+    }
 }
 
 #pragma mark - NotificationCenter
@@ -485,4 +424,21 @@
     }
 }
 
+#pragma mark - NSNotification
+
+- (void)annotationsOperationChangeNotification:(NSNotification *)notification {
+    CPDFListView *pdfListView = notification.object;
+    if(pdfListView == self.annotManage.pdfListView) {
+        if([pdfListView canUndo])
+            self.undoBtn.enabled = YES;
+         else
+            self.undoBtn.enabled = NO;
+        
+        if([pdfListView canRedo])
+            self.redoBtn.enabled = YES;
+         else
+            self.redoBtn.enabled = NO;
+    }
+}
+
 @end

+ 2 - 0
compdfkit-tools/compdfkit-tools/Common/Views/PDFView/PDFListView/CPDFListView+Annotation.h

@@ -26,6 +26,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 - (void)annotationDrawPage:(CPDFPage *)page toContext:(CGContextRef)context;
 
+- (NSArray<UIMenuItem *> *)annotationMenuItemsAtPoint:(CGPoint)point forPage:(CPDFPage *)page;
+
 - (void)updateScrollEnabled;
 
 @end

+ 296 - 55
compdfkit-tools/compdfkit-tools/Common/Views/PDFView/PDFListView/CPDFListView+Annotation.m

@@ -15,6 +15,8 @@
 #import "CPDFListView+Private.h"
 #import "CPDFListMagnifierView.h"
 
+#import <MobileCoreServices/UTCoreTypes.h>
+
 @implementation CPDFListView (Annotation)
 
 #pragma mark - Private method
@@ -44,6 +46,16 @@
     }
 }
 
+- (BOOL)isPasteboardValid {
+    NSString *textType = (NSString *)kUTTypeText;
+    NSString *urlType  = (NSString*)kUTTypeURL;
+    NSString *urlFileType  = (NSString*)kUTTypeFileURL;
+    NSString *jpegImageType = (NSString *)kUTTypeJPEG;
+    NSString *pngImageType = (NSString *)kUTTypePNG;
+    NSString *rawImageType = @"com.apple.uikit.image";
+    return [[UIPasteboard generalPasteboard] containsPasteboardTypes:[NSArray arrayWithObjects:textType, urlType, urlFileType, jpegImageType, pngImageType, rawImageType, nil]];
+}
+
 - (void)showMenuForAnnotation:(CPDFAnnotation *)annotation {
     if (!annotation) {
         [UIMenuController sharedMenuController].menuItems = nil;
@@ -51,71 +63,56 @@
         return;
     }
     
-    NSMutableArray *menuItems = [NSMutableArray array];
-    UIMenuItem *colorItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Color", nil)
-                                                       action:@selector(colorItemAction:)];
-    UIMenuItem *opacityItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Opacity", nil)
-                                                         action:@selector(opacityItemAction:)];
-    UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", nil)
-                                                      action:@selector(copyItemAction:)];
-    UIMenuItem *noteItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Note", nil)
-                                                      action:@selector(noteItemAction:)];
+    UIMenuItem *editNoteItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit", nil)
+                                                       action:@selector(menuItemClick_Edit:)];
+    
     UIMenuItem *deleteItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Delete", nil)
-                                                        action:@selector(deleteItemAction:)];
-    if ([annotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
-        UIMenuItem *shareItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Share", nil)
-                                                           action:@selector(shareItemAction:)];
-        [menuItems addObject:colorItem];
-        [menuItems addObject:opacityItem];
-        [menuItems addObject:copyItem];
-        [menuItems addObject:shareItem];
-        [menuItems addObject:noteItem];
-        [menuItems addObject:deleteItem];
-    } else if ([annotation isKindOfClass:[CPDFStampAnnotation class]]) {
-        if (CPDFStampTypeImage == [(CPDFStampAnnotation *)annotation stampType]) {
-            UIMenuItem *saveItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Save", nil)
-                                                              action:@selector(saveItemAction:)];
-            [menuItems addObject:saveItem];
-            [menuItems addObject:copyItem];
-        }
+                                                        action:@selector(menuItemClick_Delete:)];
+    
+    UIMenuItem *propertiesItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Properties", nil)
+                                                        action:@selector(menuItemClick_Properties:)];
+    
+    UIMenuItem *noteItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Note", nil)
+                                                        action:@selector(menuItemClick_Note:)];
+    
+    NSMutableArray *menuItems = [NSMutableArray array];
+    if([annotation isKindOfClass:[CPDFTextAnnotation class]]) {
+        [menuItems addObject:editNoteItem];
         [menuItems addObject:deleteItem];
-    } else if ([annotation isKindOfClass:[CPDFLinkAnnotation class]]) {
-        UIMenuItem *editItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit", nil)
-                                                          action:@selector(editItemAction:)];
-        [menuItems addObject:editItem];
+    } else if([annotation isKindOfClass:[CPDFMarkupAnnotation class]] ||
+              [annotation isKindOfClass:[CPDFInkAnnotation class]] ||
+              [annotation isKindOfClass:[CPDFCircleAnnotation class]] ||
+              [annotation isKindOfClass:[CPDFSquareAnnotation class]] ||
+              [annotation isKindOfClass:[CPDFLineAnnotation class]]) {
+        [menuItems addObject:propertiesItem];
+        [menuItems addObject:noteItem];
         [menuItems addObject:deleteItem];
     } else if ([annotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
-        UIMenuItem *editItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit", nil)
-                                                          action:@selector(editItemAction:)];
-        [menuItems addObject:editItem];
-        [menuItems addObject:copyItem];
+        [menuItems addObject:propertiesItem];
+        [menuItems addObject:editNoteItem];
+        [menuItems addObject:deleteItem];
+    } else if ([annotation isKindOfClass:[CPDFStampAnnotation class]]) {
+        [menuItems addObject:noteItem];
         [menuItems addObject:deleteItem];
     } else if ([annotation isKindOfClass:[CPDFSoundAnnotation class]] ||
-               [annotation isKindOfClass:[CPDFMovieAnnotation class]]) {
+               [annotation isKindOfClass:[CPDFMovieAnnotation  class]]) {
+        if ([annotation isKindOfClass:[CPDFSoundAnnotation class]]) {
+            UIMenuItem *playItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Play", nil)
+                                                              action:@selector(menuItemClick_Play:)];
+            [menuItems addObject:playItem];
+        }
+        [menuItems addObject:deleteItem];
+    }  else if ([annotation isKindOfClass:[CPDFLinkAnnotation class]]) {
+        [menuItems addObject:editNoteItem];
         [menuItems addObject:deleteItem];
     } else if ([annotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
-        UIMenuItem *cancelItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Cancel", nil)
-                                                            action:@selector(deleteItemAction:)];
-        UIMenuItem *addHereItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Add here", nil)
-                                                             action:@selector(addHereItemAction:)];
-        [menuItems addObject:cancelItem];
+        UIMenuItem *addHereItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Signature", nil)
+                                                            action:@selector(menuItemClick_Signature:)];
+        
         [menuItems addObject:addHereItem];
-    } else if ([annotation isKindOfClass:[CPDFLineAnnotation class]] ||
-               [annotation isKindOfClass:[CPDFSquareAnnotation class]] ||
-               [annotation isKindOfClass:[CPDFCircleAnnotation class]] ||
-               [annotation isKindOfClass:[CPDFInkAnnotation class]]) {
-        UIMenuItem *thicknessItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Thickness", nil)
-                                                               action:@selector(thicknessItemAction:)];
-        [menuItems addObject:noteItem];
-        [menuItems addObject:colorItem];
-        [menuItems addObject:thicknessItem];
-        [menuItems addObject:opacityItem];
-        [menuItems addObject:deleteItem];
-    } else if ([annotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) {
-        UIMenuItem *deleteItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Delete", nil)
-                                                            action:@selector(signatureWidgetDeleteItemAction:)];
         [menuItems addObject:deleteItem];
     }
+    
     if (menuItems.count <= 0) {
         return;
     }
@@ -129,6 +126,192 @@
     [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
 }
 
+- (void)showMenuForMediaAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    NSMutableArray *menuItems = [NSMutableArray array];
+    UIMenuItem *cancelItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Delete", nil)
+                                                        action:@selector(menuItemClick_MediaDelete:)];
+    
+    UIMenuItem *mediaRecordItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Record", nil)
+                                                         action:@selector(menuItemClick_MediaRecord:)];
+    [menuItems addObject:cancelItem];
+    [menuItems addObject:mediaRecordItem];
+    
+    CGRect bounds = CGRectMake(point.x-18, point.y-18, 37, 37);
+    CGRect rect = [self convertRect:bounds fromPage:page];
+    [self becomeFirstResponder];
+    [UIMenuController sharedMenuController].menuItems = menuItems;
+    [[UIMenuController sharedMenuController] setTargetRect:rect inView:self];
+    [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
+}
+
+#pragma mark - Action
+
+- (void)menuItemClick_Edit:(UIMenuItem *)menuItem {
+    if([self.activeAnnotation isKindOfClass:[CPDFTextAnnotation class]] || [self.activeAnnotation isKindOfClass:[CPDFLinkAnnotation class]]) {
+        if ([self.performDelegate respondsToSelector:@selector(PDFListViewEditNote:forAnnotation:)]) {
+            [self.performDelegate PDFListViewEditNote:self forAnnotation:self.activeAnnotation];
+        }
+    } else if([self.activeAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
+        [self editAnnotationFreeText:(CPDFFreeTextAnnotation *)self.activeAnnotation];
+    }
+}
+
+- (void)menuItemClick_Delete:(UIMenuItem *)menuItem {
+    [self updateActiveAnnotations:@[]];
+    [self.menuAnnotation.page removeAnnotation:self.activeAnnotation];
+    [self setNeedsDisplayForPage:self.activeAnnotation.page];
+    [self updateScrollEnabled];
+}
+
+- (void)menuItemClick_Note:(UIMenuItem *)menuItem {
+    if ([self.performDelegate respondsToSelector:@selector(PDFListViewEditNote:forAnnotation:)]) {
+        [self.performDelegate PDFListViewEditNote:self forAnnotation:self.activeAnnotation];
+    }
+}
+
+- (void)menuItemClick_Properties:(UIMenuItem *)menuItem {
+    if ([self.performDelegate respondsToSelector:@selector(PDFListViewEditProperties:forAnnotation:)]) {
+        [self.performDelegate PDFListViewEditProperties:self forAnnotation:self.activeAnnotation];
+    }
+}
+
+- (void)menuItemClick_Signature:(UIMenuItem *)menuItem {
+    if ([self.activeAnnotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
+        [(CPDFSignatureAnnotation *)self.activeAnnotation signature];
+        
+        [self updateActiveAnnotations:@[]];
+        [self setNeedsDisplayForPage:self.activeAnnotation.page];
+        [self updateScrollEnabled];
+    }
+}
+
+- (void)menuItemClick_Paste:(UIMenuItem *)menuItem {
+    NSString *textType = (NSString *)kUTTypeText;
+    NSString *utf8TextType = (NSString *)kUTTypeUTF8PlainText;
+    NSString *urlType  = (NSString*)kUTTypeURL;
+    NSString *urlFileType  = (NSString*)kUTTypeFileURL;
+    NSString *jpegImageType = (NSString *)kUTTypeJPEG;
+    NSString *pngImageType = (NSString *)kUTTypePNG;
+    NSString *rawImageType = @"com.apple.uikit.image";
+    
+    NSArray *pasteArray = [UIPasteboard generalPasteboard].items;
+    for (NSDictionary* dic in pasteArray) {
+        if ([dic objectForKey:textType] ||
+            [dic objectForKey:utf8TextType] ||
+            [dic objectForKey:urlType] ||
+            [dic objectForKey:urlFileType]) {
+            NSString *contents = nil;
+            if ([dic objectForKey:textType] ||
+                [dic objectForKey:utf8TextType]) {
+                contents = [UIPasteboard generalPasteboard].string;
+            } else {
+                contents = [[UIPasteboard generalPasteboard].URL absoluteString];
+            }
+            UIFont *font = [UIFont systemFontOfSize:12.0];
+            NSDictionary *attributes = @{NSFontAttributeName : font};
+            CGRect bounds = [contents boundingRectWithSize:CGSizeMake(280, MAXFLOAT)
+                                                   options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
+                                                attributes:attributes
+                                                   context:nil];
+            
+            CPDFFreeTextAnnotation *annotation = [[CPDFFreeTextAnnotation alloc] initWithDocument:self.document];
+            [annotation setContents:contents];
+            [annotation setModificationDate:[NSDate date]];
+            [annotation setUserName:[self annotationUserName]];
+            annotation.bounds = CGRectMake(self.menuPoint.x-bounds.size.width/2.0,
+                                           self.menuPoint.y-bounds.size.height/2.0,
+                                           bounds.size.width, bounds.size.height);
+            [self.menuPage addAnnotation:annotation];
+            [self setNeedsDisplayForPage:self.menuPage];
+        } else if ([dic objectForKey:jpegImageType] ||
+                   [dic objectForKey:pngImageType] ||
+                   [dic objectForKey:rawImageType]) {
+            UIImage *image = [UIPasteboard generalPasteboard].image;
+            UIImage *compressImage = [self compressImage:image size:CGSizeMake(240.0, 240.0)];
+            
+            CPDFStampAnnotation *annotation = [[CPDFStampAnnotation alloc] initWithDocument:self.document image:compressImage];
+            [annotation setModificationDate:[NSDate date]];
+            [annotation setUserName:[self annotationUserName]];
+            annotation.bounds = CGRectMake(self.menuPoint.x-compressImage.size.width/2.0,
+                                           self.menuPoint.y-compressImage.size.height/2.0,
+                                           compressImage.size.width, compressImage.size.height);
+            [self.menuPage addAnnotation:annotation];
+            [self setNeedsDisplayForPage:self.menuPage];
+        }
+    }
+}
+
+- (void)menuItemClick_TextNote:(UIMenuItem *)menuItem {
+    if (self.currentSelection) {
+        NSMutableArray *quadrilateralPoints = [NSMutableArray array];
+        CPDFMarkupAnnotation *annotation = [[CPDFMarkupAnnotation alloc] initWithDocument:self.document markupType:CPDFMarkupTypeHighlight];
+        for (CPDFSelection *selection in self.currentSelection.selectionsByLine) {
+            CGRect bounds = selection.bounds;
+            [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMaxY(bounds))]];
+            [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))]];
+            [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds))]];
+            [quadrilateralPoints addObject:[NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMinY(bounds))]];
+        }
+        [annotation setQuadrilateralPoints:quadrilateralPoints];
+        [annotation setMarkupText:self.currentSelection.string];
+        [annotation setModificationDate:[NSDate date]];
+        [annotation setUserName:[self annotationUserName]];
+        [self.currentSelection.page addAnnotation:annotation];
+        [annotation createPopup];
+        
+        [self clearSelection];
+        [self setNeedsDisplayForPage:annotation.page];
+    } else {
+        [self addAnnotation:CPDFViewAnnotationModeNote atPoint:self.menuPoint forPage:self.menuPage];
+    }
+}
+
+- (void)menuItemClick_FreeText:(UIMenuItem *)menuItem {
+    [self addAnnotationFreeTextAtPoint:self.menuPoint forPage:self.menuPage];
+}
+
+- (void)menuItemClick_Stamp:(UIMenuItem *)menuItem {
+    if ([self.performDelegate respondsToSelector:@selector(PDFListViewPerformAddStamp:atPoint:forPage:)]) {
+        [self.performDelegate PDFListViewPerformAddStamp:self atPoint:self.menuPoint forPage:self.menuPage];
+    }
+}
+
+- (void)menuItemClick_Image:(UIMenuItem *)menuItem {
+    if ([self.performDelegate respondsToSelector:@selector(PDFListViewPerformAddImage:atPoint:forPage:)]) {
+        [self.performDelegate PDFListViewPerformAddImage:self atPoint:self.menuPoint forPage:self.menuPage];
+    }
+}
+
+- (void)menuItemClick_Play:(UIMenuItem *)menuItem {
+    if ([self.activeAnnotation isKindOfClass:[CPDFSoundAnnotation class]]) {
+        [self updateActiveAnnotations:@[]];
+        [self setNeedsDisplayForPage:self.menuAnnotation.page];
+        if ([self.performDelegate respondsToSelector:@selector(PDFListViewPerformPlay:forAnnotation:)]) {
+            [self.performDelegate PDFListViewPerformPlay:self forAnnotation:(CPDFSoundAnnotation *)self.activeAnnotation];
+        }
+    }
+}
+
+- (void)menuItemClick_MediaDelete:(UIMenuItem *)menuItem  {
+    CGPoint point = CGPointMake(CGRectGetMidX(self.mediaSelectionRect), CGRectGetMidY(self.mediaSelectionRect));
+    CPDFPage *page = self.mediaSelectionPage;
+    if ([self.performDelegate respondsToSelector:@selector(PDFListViewPerformCancelMedia:atPoint:forPage:)]) {
+        [self.performDelegate PDFListViewPerformCancelMedia:self atPoint:point forPage:page];
+    }
+    
+    self.mediaSelectionPage = nil;
+    [self setNeedsDisplayForPage:page];
+}
+
+- (void)menuItemClick_MediaRecord:(UIMenuItem *)menuItem {
+    CGPoint point = CGPointMake(CGRectGetMidX(self.mediaSelectionRect), CGRectGetMidY(self.mediaSelectionRect));
+    CPDFPage *page = self.mediaSelectionPage;
+    if ([self.performDelegate respondsToSelector:@selector(PDFListViewPerformRecordMedia:atPoint:forPage:)]) {
+        [self.performDelegate PDFListViewPerformRecordMedia:self atPoint:point forPage:page];
+    }
+    self.mediaSelectionPage = nil;
+}
+
 #pragma mark - Magnifier
 
 - (void)addMagnifierAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
@@ -154,6 +337,41 @@
     self.magnifierView = nil;
 }
 
+#pragma mark - Menu
+
+- (NSArray<UIMenuItem *> *)annotationMenuItemsAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    self.menuPoint = point;
+    self.menuPage = page;
+
+    if(self.currentSelection) {
+        return [super menuItemsAtPoint:point forPage:page];
+    } else  {
+        NSMutableArray *menuItems = [NSMutableArray array];
+
+        UIMenuItem *pasteItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Paste", nil)
+                                                           action:@selector(menuItemClick_Paste:)];
+        if ([self isPasteboardValid]) {
+            [menuItems addObject:pasteItem];
+        }
+        UIMenuItem *textNoteItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Note", nil)
+                                                              action:@selector(menuItemClick_TextNote:)];
+        UIMenuItem *textItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Text", nil)
+                                                          action:@selector(menuItemClick_FreeText:)];
+        UIMenuItem *stampItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Stamp", nil)
+                                                           action:@selector(menuItemClick_Stamp:)];
+        UIMenuItem *imageItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Image", nil)
+                                                           action:@selector(menuItemClick_Image:)];
+        [menuItems addObject:textNoteItem];
+        [menuItems addObject:textItem];
+        [menuItems addObject:stampItem];
+        [menuItems addObject:imageItem];
+
+        return menuItems;
+    }
+    return nil;
+    
+}
+
 #pragma mark - Touch
 
 - (void)annotationTouchBeganAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
@@ -299,6 +517,15 @@
                 } else {
                     [self addAnnotationLinkAtPoint:point forPage:page];
                 }
+            } else if (CPDFViewAnnotationModeSound == self.annotationMode) {
+                BOOL isAudioRecord  = NO;
+                if ([self.performDelegate respondsToSelector:@selector(PDFListViewerTouchEndedIsAudioRecordMedia:)]) {
+                    isAudioRecord = [self.performDelegate PDFListViewerTouchEndedIsAudioRecordMedia:self];
+                }
+                if (isAudioRecord) {
+                } else {
+                    [self addAnnotationMediaAtPoint:point forPage:page];
+                }
             } else if (CPDFViewAnnotationModeFreeText == self.annotationMode) {
                 [self addAnnotationFreeTextAtPoint:point forPage:page];
             } else if (CPDFViewAnnotationModeStamp == self.annotationMode) {
@@ -842,6 +1069,20 @@
     [self updateActiveAnnotations:@[]];
 }
 
+- (void)addAnnotationMediaAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    if (self.mediaSelectionPage) {
+        CPDFPage *selectionPage = self.mediaSelectionPage;
+        self.mediaSelectionPage = nil;
+        [self setNeedsDisplayForPage:selectionPage];
+    }
+    
+    self.mediaSelectionPage = page;
+    self.mediaSelectionRect = CGRectMake(point.x-20, point.y-20, 40, 40);
+    [self setNeedsDisplayForPage:page];
+    
+    [self showMenuForMediaAtPoint:point forPage:page];
+}
+
 - (void)addAnnotationLinkAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
     CPDFLinkAnnotation *annotation = [[CPDFLinkAnnotation alloc] initWithDocument:self.document]    ;
     annotation.bounds = self.addLinkRect;
@@ -854,7 +1095,7 @@
     [self setNeedsDisplayForPage:page];
     
     if(annotation)
-        [self updateActiveAnnotations:annotation];
+        [self updateActiveAnnotations:@[annotation]];
 
     if ([self.performDelegate respondsToSelector:@selector(PDFListViewEditNote:forAnnotation:)]) {
         [self.performDelegate PDFListViewEditNote:self forAnnotation:annotation];

+ 4 - 0
compdfkit-tools/compdfkit-tools/Common/Views/PDFView/PDFListView/CPDFListView+Private.h

@@ -69,6 +69,10 @@ typedef NS_ENUM(NSInteger, CPDFAnnotationDraggingType) {
 
 @property (nonatomic,retain) CPDFAnnotation *addAnnotation;
 
+@property (nonatomic,retain) CPDFPage *mediaSelectionPage;
+
+@property (nonatomic,assign) CGRect mediaSelectionRect;
+
 - (NSString *)annotationUserName;
 
 - (void)updateActiveAnnotations:(NSArray <CPDFAnnotation *> *)activeAnnotations;

+ 20 - 0
compdfkit-tools/compdfkit-tools/Common/Views/PDFView/PDFListView/CPDFListView+UndoManager.m

@@ -26,6 +26,13 @@ static NSString *CPDFAnnotationPropertiesObservationContext = @"CPDFAnnotationPr
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(PDFPageDidLoadAnnotationNotification:) name:@"CPDFPageDidLoadAnnotationNotification" object:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(PDFPageDidAddAnnotationNotification:) name:@"CPDFPageDidAddAnnotationNotification" object:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(PDFPageDidRemoveAnnotationNotification:) name:@"CPDFPageDidRemoveAnnotationNotification" object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(redoChangeNotification:)
+                                                 name:NSUndoManagerDidUndoChangeNotification object:[self undoPDFManager]];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(redoChangeNotification:)
+                                                 name:NSUndoManagerDidRedoChangeNotification object:[self undoPDFManager]];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(redoChangeNotification:)
+                                                 name:NSUndoManagerWillCloseUndoGroupNotification object:[self undoPDFManager]];
 }
 
 - (BOOL)canUndo {
@@ -187,4 +194,17 @@ static NSString *CPDFAnnotationPropertiesObservationContext = @"CPDFAnnotationPr
         }
     }
 }
+
+- (void)redoChangeNotification:(NSNotification *)notification {
+    if([self canUndo] || [self canRedo]) {
+        
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewAnnotationsOperationChangeNotification object:self];
+            
+            if([self.performDelegate respondsToSelector:@selector(PDFListViewAnnotationsOperationChange:)]) {
+                [self.performDelegate PDFListViewAnnotationsOperationChange:self];
+            }
+        });
+    }
+}
 @end

+ 17 - 0
compdfkit-tools/compdfkit-tools/Common/Views/PDFView/PDFListView/CPDFListView.h

@@ -47,6 +47,8 @@ extern NSNotificationName const CPDFListViewAnnotationModeChangeNotification;
 
 extern NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification;
 
+extern NSNotificationName const CPDFListViewAnnotationsOperationChangeNotification;
+
 #pragma mark - CPDFListViewDelegate
 
 @class CPDFListView;
@@ -60,6 +62,8 @@ extern NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification;
 
 - (void)PDFListViewEditNote:(CPDFListView *)pdfListView forAnnotation:(CPDFAnnotation *)annotation;
 
+- (void)PDFListViewEditProperties:(CPDFListView *)pdfListView forAnnotation:(CPDFAnnotation *)annotation;
+
 - (void)PDFListViewPerformTouchEnded:(CPDFListView *)pdfListView;
 
 - (void)PDFListViewCustomMenuClick:(CPDFListView *)pdfListView identifier:(NSString *)menuIdentifier;
@@ -70,6 +74,19 @@ extern NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification;
 
 - (void)PDFListViewChangeatioActiveAnnotations:(CPDFListView *)pdfListView forActiveAnnotations:(NSArray<CPDFAnnotation *> *)annotations;
 
+- (void)PDFListViewAnnotationsOperationChange:(CPDFListView *)pdfListView;
+
+- (BOOL)PDFListViewerTouchEndedIsAudioRecordMedia:(CPDFListView *)pdfListView;
+
+- (void)PDFListViewPerformPlay:(CPDFListView *)pdfView forAnnotation:(CPDFSoundAnnotation *)annotation;
+
+- (void)PDFListViewPerformCancelMedia:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page;
+
+- (void)PDFListViewPerformRecordMedia:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page;
+
+- (void)PDFListViewPerformAddStamp:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page;
+
+- (void)PDFListViewPerformAddImage:(CPDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page;
 
 @end
 

+ 27 - 2
compdfkit-tools/compdfkit-tools/Common/Views/PDFView/PDFListView/CPDFListView.m

@@ -25,6 +25,8 @@ NSNotificationName const CPDFListViewAnnotationModeChangeNotification = @"CPDFLi
 
 NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification = @"CPDFListViewActiveAnnotationsChangeNotification";
 
+NSNotificationName const CPDFListViewAnnotationsOperationChangeNotification = @"CPDFListViewAnnotationsOperationChangeNotification";
+
 @interface  CPDFListView()
 
 @property (nonatomic, strong) CPDFPageIndicatorView * pageIndicatorView;
@@ -132,6 +134,15 @@ NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification = @"CPD
     return self.activeAnnotations.firstObject;
 }
 
+#pragma mark - Action
+
+- (void)menuItemClick_CopyAction:(id)sender {
+    if (self.currentSelection.string)
+        [[UIPasteboard generalPasteboard] setString:self.currentSelection.string];
+    
+    [self clearSelection];
+}
+
 #pragma mark - Touch
 
 - (void)touchBeganAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
@@ -183,10 +194,25 @@ NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification = @"CPD
 }
 
 - (NSArray<UIMenuItem *> *)menuItemsAtPoint:(CGPoint)point forPage:(CPDFPage *)page {
+    NSMutableArray *menuItems = [NSMutableArray array];
+
+    if (CToolModelAnnotation == self.toolModel) {
+        [menuItems addObjectsFromArray:[self annotationMenuItemsAtPoint:point forPage:page]];
+    } else if (CToolModelForm == self.toolModel) {
+        
+    } else if (CToolModelEdit == self.toolModel) {
+        
+    } else {
+        if (self.currentSelection) {
+            UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", nil)
+                                                              action:@selector(menuItemClick_CopyAction:)];
+            [menuItems addObject:copyItem];
+        }
+    }
     if([self.performDelegate respondsToSelector:@selector(PDFListView:customizeMenuForPage:forPagePoint:)])
         return [self.performDelegate PDFListView:self customizeMenuForPage:page forPagePoint:point];
 
-    return [super menuItemsAtPoint:point forPage:page];
+    return menuItems;
 }
 
 #pragma mark - Private method
@@ -253,7 +279,6 @@ NSNotificationName const CPDFListViewActiveAnnotationsChangeNotification = @"CPD
     [self.pageIndicatorView updatePageCount:weakSelf.document.pageCount currentPageIndex:self.currentPageIndex + 1];
 }
 
-
 - (NSString *)annotationUserName {
     NSString *annotationUserName = CPDFKitShareConfig.annotationAuthor;
     if (!annotationUserName || [annotationUserName length] <= 0) {

+ 0 - 9
viewer-ctrl-demo/viewer-ctrl-demo/CPDFViewController.m

@@ -181,15 +181,6 @@
 
 #pragma mark - CPDFListViewDelegate
 
-- (NSArray<UIMenuItem *> *)PDFListView:(CPDFListView *)pdfListView customizeMenuForPage:(CPDFPage *)page forPagePoint:(CGPoint)pagePoint {
-    if (pdfListView.currentSelection) {
-        UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", nil)
-                                                          action:@selector(menuItemClick_CopyAction:)];
-        return @[copyItem];
-    }
-    return nil;
-}
-
 - (void)PDFListViewPerformTouchEnded:(CPDFListView *)pdfView {
     if (CPDFViewAnnotationModeNone != self.pdfListView.annotationMode) {
         self.pdfListView.annotationMode = CPDFViewAnnotationModeNone;