// // CPDFDigtalView.m // PDF Reader Pro Edition // // Created by Niehaoyu on 2023/10/10. // #import "CPDFDigtalView.h" #import "CPDFAnnotation+PDFListView.h" #import "NSGeometry+PDFListView.h" #import "CPDFListViewConfig.h" #define HANDLE_SIZE 4.0 #define MIN_NOTE_SIZE 8.0 @implementation CPDFDigtalView - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; // Drawing code here. } - (id)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; if (self) { [self setUp]; } return self; } - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (self) { [self setUp]; } return self; } - (void)setUp { self.annotationType = CAnnotationTypeSignature; self.activeAnnotations = [NSMutableArray array]; } - (void)setDocument:(CPDFDocument *)document { [super setDocument:document]; NSArray *signatures = document.signatures; NSMutableArray *tempArr = [NSMutableArray array]; for (CPDFSignature *signature in signatures) { if(signature.signers.count > 0) { [signature verifySignatureWithDocument:document]; [tempArr addObject:signature]; } } self.signatures = tempArr; } - (CPDFPage *)pageAndPoint:(NSPoint *)point forEvent:(NSEvent *)event nearest:(BOOL)nearest { NSPoint p = [self convertPoint:[event locationInWindow] fromView:nil]; CPDFPage *page = [self pageForPoint:p nearest:nearest]; if (page && point) *point = [self convertPoint:p toPage:page]; return page; } - (void)setCursorForMouse:(NSEvent *)theEvent { if (theEvent == nil) theEvent = [NSEvent mouseEventWithType:NSEventTypeMouseMoved location:[[self window] mouseLocationOutsideOfEventStream] modifierFlags:[NSEvent standardPDFListViewModifierFlags] timestamp:0 windowNumber:[[self window] windowNumber] context:nil eventNumber:0 clickCount:1 pressure:0.0]; [self setCursorForAreaOfInterest:[self areaOfInterestForMouse:theEvent]]; } - (CPDFAnnotation *)activeAnnotation { return self.activeAnnotations.lastObject; } - (void)mouseDown:(NSEvent *)theEvent { [self setCursorForMouse:theEvent]; NSPoint point = NSZeroPoint; CPDFAreaOfInterest area = [self areaOfInterestForMouse:theEvent]; NSPoint newpoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; area = [self areaOfInterestForPoint:newpoint]; CPDFAnnotation *newActiveAnnotation = nil; if ([[self document] isLocked]) { [super mouseDown:theEvent]; } else if ([self doClickAnnotationWithEvent:theEvent forAnnotation:&newActiveAnnotation]) { [self doDragAnnotationWithEvent:theEvent forAnnotation:newActiveAnnotation]; } else { [self doDragAddAnnotationWithEvent:theEvent]; } } - (BOOL)doClickAnnotationWithEvent:(NSEvent *)theEvent forAnnotation:(CPDFAnnotation **)annotation{ CPDFAnnotation *newActiveAnnotation = nil; NSPoint point = NSZeroPoint; CPDFPage *page = [self pageAndPoint:&point forEvent:theEvent nearest:YES]; NSMutableArray *currentActiveAnnotations = [NSMutableArray array]; for (CPDFAnnotation *an in self.activeAnnotations) { if([an.page isEqual:page]) { if(!([an isKindOfClass:[CPDFMarkupAnnotation class]] || [an isKindOfClass:[CPDFTextAnnotation class]])) { [currentActiveAnnotations addObject:an]; } } } newActiveAnnotation = [self doSelectAnnotationWithEvent:theEvent]; *annotation = newActiveAnnotation; return !!newActiveAnnotation; } - (CPDFAnnotation *)doSelectAnnotationWithEvent:(NSEvent *)theEvent { CPDFAnnotation *newActiveAnnotation = nil; NSPoint point = NSZeroPoint; CPDFPage *page = [self pageAndPoint:&point forEvent:theEvent nearest:YES]; id annotations = [page annotations]; for (CPDFAnnotation *annotation in annotations) { if ([annotation hitTest:point] && [annotation annotationShouldDisplay] ) { newActiveAnnotation = annotation; break; } } return newActiveAnnotation; } - (void)doDragAnnotationWithEvent:(NSEvent *)theEvent forAnnotation:(CPDFAnnotation *)newActiveAnnotation { BOOL isContains = YES; if (self.activeAnnotations.count == 0 || ![self.activeAnnotations containsObject:newActiveAnnotation]) { isContains = NO; } NSRect originalBounds = [newActiveAnnotation bounds]; BOOL isLine = [newActiveAnnotation isKindOfClass:[CPDFLineAnnotation class]]; NSPoint pagePoint = NSZeroPoint; CPDFPage *page = [self pageAndPoint:&pagePoint forEvent:theEvent nearest:YES]; NSPoint originalStartPoint = NSZeroPoint; NSPoint originalEndPoint = NSZeroPoint; BOOL draggedAnnotation = NO; NSEvent *lastMouseEvent = theEvent; NSPoint offset = CPDFListViewSubstractPoints(pagePoint, originalBounds.origin); NSUInteger eventMask = NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged; CGFloat mouseOffset = [self unitWidthOnPage:page]; while (YES) { theEvent = [[self window] nextEventMatchingMask:eventMask]; if ([theEvent type] == NSEventTypeLeftMouseUp) { if(draggedAnnotation) { if (!isContains) [self.selectAnnotations removeAllObjects]; } else { if(self.activeAnnotations.count == 1 && self.activeAnnotation == newActiveAnnotation && ([newActiveAnnotation isKindOfClass:[CPDFTextAnnotation class]] || [newActiveAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]])) { [self editAnnotation:newActiveAnnotation]; break; } if(!isContains) { [self updateActiveAnnotations:@[newActiveAnnotation]]; } [self editAnnotation:newActiveAnnotation]; } [self setNeedsDisplayAnnotationViewForPage:page]; break; } else if ([theEvent type] == NSEventTypeLeftMouseDragged) { NSPoint point = NSZeroPoint; [self pageAndPoint:&point forEvent:theEvent nearest:YES]; CGRect zRect = CGRectMake(pagePoint.x-2*mouseOffset, pagePoint.y-2*mouseOffset, 4*mouseOffset, 4*mouseOffset); if (CGRectContainsPoint(zRect, point)) {continue;} lastMouseEvent = theEvent; draggedAnnotation = YES; if(!isContains) { [self dragAnnotationReferenceLine:newActiveAnnotation]; [self.selectAnnotations removeAllObjects]; [self.selectAnnotations addObject:newActiveAnnotation]; [self doMoveAnnotation:newActiveAnnotation withEvent:lastMouseEvent offset:offset]; } else { if ([newActiveAnnotation isKindOfClass:[CPDFStampAnnotation class]] || [newActiveAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]] || [newActiveAnnotation isKindOfClass:[CPDFSignatureAnnotation class]] || [newActiveAnnotation isKindOfClass:[CPDFWidgetAnnotation class]]) { [newActiveAnnotation updateAppearanceStream]; } } [self dragAnnotationReferenceLine:newActiveAnnotation]; [self setNeedsDisplayAnnotationViewForPage:page]; } } [self performSelector:@selector(setCursorForMouse:) withObject:theEvent afterDelay:0]; } - (void)doMoveAnnotation:(CPDFAnnotation *)activeAnnotation withEvent:(NSEvent *)theEvent offset:(NSPoint)offset { // Move annotation. [[[self documentView] contentView] autoscroll:theEvent]; NSPoint point = NSZeroPoint; CPDFPage *newActivePage = [self pageAndPoint:&point forEvent:theEvent nearest:YES]; if (newActivePage) { // newActivePage should never be nil, but just to be sure if (newActivePage != [activeAnnotation page]) { return; } NSRect newBounds = [activeAnnotation bounds]; newBounds.origin = CPDFListViewIntegralPoint(CPDFListViewSubstractPoints(point, offset)); // constrain bounds inside page bounds } } - (void)dragAnnotationReferenceLine:(CPDFAnnotation *)annotation { // if ([self isAlignedWithOtherForms:annotation] && annotation) { // CGRect bounds = annotation.bounds; // NSRect rect = [self convertRect:bounds fromPage:self.currentPage]; // [self drawLineOfDashByCAShapeLayer:rect]; // } } - (void)editAnnotation:(CPDFAnnotation *)annotation { if ([annotation isKindOfClass:[CPDFFreeTextAnnotation class]]) { [self editAnnotationFreeText:(CPDFFreeTextAnnotation *)annotation]; [[self window] makeFirstResponder:self]; [self setNeedsDisplayAnnotation:annotation]; } else { if([annotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) { if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewEditAnnotation:forAnnotation:)]) { [self.pdfListViewDelegate PDFListViewEditAnnotation:self forAnnotation:annotation]; } } } } - (void)doDragAddAnnotationWithEvent:(NSEvent *)theEvent { NSPoint pagePoint = NSZeroPoint; CPDFPage *page = [self pageAndPoint:&pagePoint forEvent:theEvent nearest:YES]; NSRect originalBounds = CGRectZero; CGFloat mouseOffset = [self unitWidthOnPage:page]; // [self setCursorForAreaOfInterest:CAreaOfInterestForResizeHandle(CMaxXEdgeMask | CMinYEdgeMask, page)]; CPDFAnnotation *annotation = nil; originalBounds = CPDFListViewRectFromCenterAndSquareSize(CPDFListViewIntegralPoint(pagePoint), 0.0); CRectEdges resizeHandle = CMaxXEdgeMask | CMinYEdgeMask; BOOL draggedAnnotation = NO; NSEvent *lastMouseEvent = theEvent; NSUInteger eventMask = NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged; while (YES) { theEvent = [[self window] nextEventMatchingMask:eventMask]; if ([theEvent type] == NSEventTypeLeftMouseUp) { if (!draggedAnnotation) { if (annotation) { break; } if(CAnnotationTypeLine == self.annotationType || CAnnotationTypeArrow == self.annotationType) { } else { CGFloat defaultWidth = 72; CGFloat defaultHeight = 32; NSSize defaultSize = ([page rotation] % 180 == 0) ? NSMakeSize(defaultWidth, defaultHeight) : NSMakeSize(defaultHeight, defaultWidth); CGRect bounds = CGRectZero; bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize); bounds = CPDFListViewConstrainRect(bounds, page.bounds,[CPDFListViewConfig defaultManager].annotationBorderOffset.floatValue); annotation = [self addAnnotationWithType:self.annotationType selection:nil page:page bounds:bounds]; originalBounds = [annotation bounds]; if(annotation) { [self updateActiveAnnotations:@[annotation]]; [self setNeedsDisplayAnnotation:annotation]; } else if(self.activeAnnotations.count >0) { [self updateActiveAnnotations:@[]]; [self setNeedsDisplayAnnotationViewForPage:page]; } } } else { } break; } else if ([theEvent type] == NSEventTypeLeftMouseDragged) { CGPoint zPoint = pagePoint; [self pageAndPoint:&zPoint forEvent:theEvent nearest:YES]; CGRect zRect = CGRectMake(pagePoint.x-2*mouseOffset, pagePoint.y-2*mouseOffset, 4*mouseOffset, 4*mouseOffset); if (CGRectContainsPoint(zRect, zPoint)) {continue;} if (annotation == nil) annotation = [self addAnnotationWithType:self.annotationType selection:nil page:page bounds:CPDFListViewRectFromCenterAndSquareSize(originalBounds.origin, 0.0)]; if(annotation) { [self updateActiveAnnotations:@[annotation]]; } else if(self.activeAnnotations.count >0) { [self updateActiveAnnotations:@[]]; [self setNeedsDisplayAnnotationViewForPage:page]; } lastMouseEvent = theEvent; draggedAnnotation = YES; [self setNeedsDisplayAnnotationViewForPage:page]; } [self doResizeAnnotationWithEvent:lastMouseEvent fromPoint:pagePoint originalBounds:originalBounds resizeHandle:&resizeHandle]; } if (annotation) { [self setNeedsDisplayAnnotation:annotation]; if ([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewAddAnnotation:forAddAnnotation:inPage:)]) { [self.pdfListViewDelegate PDFListViewAddAnnotation:self forAddAnnotation:annotation inPage:page]; } } [self performSelector:@selector(setCursorForMouse:) withObject:theEvent afterDelay:0]; } - (void)setNeedsDisplayAnnotation:(CPDFAnnotation *)annotation { if (annotation) { [self setNeedsDisplayAnnotationViewForPage:annotation.page]; } else { [self setNeedsDisplayAnnotationViewForVisiblePages]; } } - (CGFloat)unitWidthOnPage:(CPDFPage *)page { return NSWidth([self convertRect:NSMakeRect(0.0, 0.0, 1.0, 1.0) toPage:page]); } - (CPDFAnnotation *)addAnnotationWithType:(CAnnotationType)annotationType selection:(CPDFSelection *)selection page:(CPDFPage *)page bounds:(NSRect)bounds { CPDFAnnotation *annotation = nil; NSString *text = [selection PDFListViewCleanedString]; BOOL isInitial = NO; if(selection) { CGRect noteRect = selection.bounds; isInitial = NSEqualSizes(noteRect.size, NSZeroSize); } else { isInitial = NSEqualSizes(bounds.size, NSZeroSize); } if (isInitial) bounds = CPDFListViewRectFromCenterAndSquareSize(bounds.origin, 8.0); switch (annotationType) { case CAnnotationTypeSignature: annotation = [[CPDFSignatureWidgetAnnotation alloc] initPDFListViewNoteWithDocument:self.document]; annotation.bounds = bounds; break; default: break; } if (annotation) { if (annotationType != CAnnotationTypeLine && annotationType != CAnnotationTypeArrow && annotationType != CAnnotationTypeInk && [text length] > 0) [annotation setString:text]; [self addAnnotation:annotation toPage:page]; } return annotation; } - (void)updateActiveAnnotations:(NSArray *)activeAnnotations { [self refreshActiveAnnotations:activeAnnotations isRight:NO]; } - (void)addAnnotation:(CPDFAnnotation *)annotation toPage:(CPDFPage *)page { // [[[self undoManager] prepareWithInvocationTarget:self] removeAnnotation:annotation]; [annotation setModificationDate:[NSDate date]]; //widget设置作者与fieldName冲突 if (![annotation isKindOfClass:[CPDFWidgetAnnotation class]]) { [annotation setUserName:CPDFKitShareConfig.annotationAuthor?:NSFullUserName()]; } [page addAnnotation:annotation]; [self setNeedsDisplayAnnotation:annotation]; [[self undoManager] setActionName:NSLocalizedString(@"Add Note", @"Undo action name")]; } - (void)refreshActiveAnnotations:(NSArray *)activeAnnotations isRight:(BOOL)isRight { if(activeAnnotations) { NSArray *selectTure = [activeAnnotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF in %@", self.activeAnnotations]]; BOOL isSame = NO; if(self.activeAnnotations.count == activeAnnotations.count && self.activeAnnotations.count == selectTure.count) isSame = YES; if(!isSame) { self.activeAnnotations = [NSMutableArray arrayWithArray:activeAnnotations]; } } else if (!activeAnnotations && self.activeAnnotations.count > 0) { [self.activeAnnotations removeAllObjects]; } } - (void)doResizeAnnotationWithEvent:(NSEvent *)theEvent fromPoint:(NSPoint)originalPagePoint originalBounds:(NSRect)originalBounds resizeHandle:(CRectEdges *)resizeHandlePtr { CPDFAnnotation *activeAnnotation = self.activeAnnotation; NSPoint pagePoint = NSZeroPoint; CPDFPage *page = activeAnnotation?activeAnnotation.page:[self pageAndPoint:&pagePoint forEvent:theEvent nearest:YES]; NSRect newBounds = originalBounds; NSRect pageBounds = [page boundsForBox:[self displayBox]]; NSPoint currentPagePoint = [self convertPoint:[theEvent locationInPDFListView:self] toPage:page]; NSPoint relPoint = CPDFListViewSubstractPoints(currentPagePoint, originalPagePoint); CRectEdges resizeHandle = *resizeHandlePtr; if (NSEqualSizes(originalBounds.size, NSZeroSize)) { CRectEdges currentResizeHandle = (relPoint.x < 0.0 ? CMinXEdgeMask : CMaxXEdgeMask) | (relPoint.y <= 0.0 ? CMinYEdgeMask : CMaxYEdgeMask); if (currentResizeHandle != resizeHandle) { *resizeHandlePtr = resizeHandle = currentResizeHandle; // [self setCursorForAreaOfInterest:CAreaOfInterestForResizeHandle(resizeHandle, page)]; } } BOOL isRadioOrCheckButton = NO; if ([activeAnnotation isKindOfClass:[CPDFButtonWidgetAnnotation class]]) { CPDFButtonWidgetAnnotation *annotation = (CPDFButtonWidgetAnnotation *)activeAnnotation; if (CPDFWidgetRadioButtonControl == annotation.controlType || CPDFWidgetCheckBoxControl == annotation.controlType) { isRadioOrCheckButton = YES; } } CGFloat minWidth = MIN_NOTE_SIZE; CGFloat minHeight = MIN_NOTE_SIZE; CGFloat offsetPageSet = 2; if ((resizeHandle & CMaxXEdgeMask)) { newBounds.size.width += relPoint.x; if (NSMaxX(newBounds)+offsetPageSet > NSMaxX(pageBounds)) newBounds.size.width = NSMaxX(pageBounds) - NSMinX(newBounds)-offsetPageSet; if (NSWidth(newBounds) < minWidth) { newBounds.size.width = minWidth; } } else if ((resizeHandle & CMinXEdgeMask)) { newBounds.origin.x += relPoint.x; newBounds.size.width -= relPoint.x; if (NSMinX(newBounds)-offsetPageSet < NSMinX(pageBounds)) { newBounds.size.width = NSMaxX(newBounds) - NSMinX(pageBounds)-offsetPageSet; newBounds.origin.x = NSMinX(pageBounds)+offsetPageSet; } if (NSWidth(newBounds) < minWidth) { newBounds.origin.x = NSMaxX(newBounds) - minWidth; newBounds.size.width = minWidth; } } if ((resizeHandle & CMaxYEdgeMask)) { newBounds.size.height += relPoint.y; if (NSMaxY(newBounds)+ offsetPageSet > NSMaxY(pageBounds)) { newBounds.size.height = NSMaxY(pageBounds) - NSMinY(newBounds)- offsetPageSet; } if (NSHeight(newBounds) < minHeight) { newBounds.size.height = minHeight; } } else if ((resizeHandle & CMinYEdgeMask)) { newBounds.origin.y += relPoint.y; newBounds.size.height -= relPoint.y; if (NSMinY(newBounds)-offsetPageSet < NSMinY(pageBounds)) { newBounds.size.height = NSMaxY(newBounds) - NSMinY(pageBounds)-offsetPageSet; newBounds.origin.y = NSMinY(pageBounds)+offsetPageSet; } if (NSHeight(newBounds) < minHeight) { newBounds.origin.y = NSMaxY(newBounds) - minHeight; newBounds.size.height = minHeight; } } [activeAnnotation setBounds:NSIntegralRect(newBounds)]; if ([activeAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]]) { [self updateAnnotationFreeTextBounds:(CPDFFreeTextAnnotation *)activeAnnotation]; } } #pragma mark - NSMenu - (NSMenu *)menuForEvent:(NSEvent *)event { if (self.annotationType == CAnnotationTypeInk || self.annotationType == CAnnotationTypeEraser) { return nil; } NSMenu *menu = [super menuForEvent:event]; if(!menu) menu = [[NSMenu alloc] init]; NSPoint pagePoint = NSZeroPoint; CPDFPage *page = [self pageAndPoint:&pagePoint forEvent:event nearest:YES]; NSMenuItem * copyItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", @"PDFListView") action:@selector(copy:) keyEquivalent:@"c"]; NSMenuItem * pasteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Paste", @"PDFListView") action:@selector(menuItemClick_Paste:) keyEquivalent:@"v"]; pasteItem.representedObject = event; NSMenuItem * cutItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Cut", @"PDFListView") action:@selector(cut:) keyEquivalent:@"x"]; NSMenuItem * deleteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Delete", @"PDFListView") action:@selector(delete:) keyEquivalent:@""]; NSMenu *subMenu = nil; NSMenuItem * arrangementItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Arrangement", @"PDFListView") action:nil keyEquivalent:@""]; subMenu = [[NSMenu alloc] init]; NSMenuItem * bringForwardItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Bring Forward", @"PDFListView") action:@selector(menuItemClick_BringForward:) keyEquivalent:@""]; NSMenuItem * sendBackForwardItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Send Backward", @"PDFListView") action:@selector(menuItemClick_SendBackward:) keyEquivalent:@""]; NSMenuItem * bringFrontItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Bring to Front", @"PDFListView") action:@selector(menuItemClick_BringFront:) keyEquivalent:@""]; NSMenuItem * sendBackItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Send to Back", @"PDFListView") action:@selector(menuItemClick_SendBack:) keyEquivalent:@""]; [subMenu addItem:bringForwardItem]; [subMenu addItem:sendBackForwardItem]; [subMenu addItem:bringFrontItem]; [subMenu addItem:sendBackItem]; arrangementItem.submenu = subMenu; NSMenuItem * editNoteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit Note", @"PDFListView") action:@selector(menuItemClick_EditNote:) keyEquivalent:@""]; if(0) { } else { CPDFAnnotation *annotation = nil; for (CPDFAnnotation *tAnnotation in page.annotations) { if ([tAnnotation hitTest:pagePoint]) { annotation = tAnnotation; break; } } if (annotation && [annotation isKindOfClass:[CPDFWidgetAnnotation class]] ){ } if(annotation) { if(![self.activeAnnotations containsObject:annotation]) { [self updateIsRightActiveAnnotations:@[annotation]]; [self setNeedsDisplayAnnotation:annotation]; } } if(annotation && [annotation isKindOfClass:[CPDFWidgetAnnotation class]]) { annotation = nil; } else if(annotation && [annotation isKindOfClass:[CPDFRedactAnnotation class]]) { annotation = nil; } else if (annotation && [annotation isKindOfClass:[CPDFInkAnnotation class]] && [self annotationType] == CAnnotationTypeInk) { annotation = nil; } CPDFSelection *selection = [self creatImageCurrentSelectionForPoint:[event locationInPDFListView:self]]; if(selection && CPDFSelectionTypeImage == [selection selectionType] && !self.activeAnnotation){ self.currentSelection = selection; } NSMenu *subMenu = [[NSMenu alloc] init]; if(self.activeAnnotations.count == 1) { // NSMenuItem * lineStyleItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Line Style", @"PDFListView") action:@selector(menuItemClick_LineStyle:) keyEquivalent:@""]; // // subMenu = [[NSMenu alloc] init]; // NSMenuItem * lineSolidItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Solid", @"PDFListView") action:@selector(menuItemClick_LineStyle:) keyEquivalent:@""]; // lineSolidItem.tag = CPDFBorderStyleSolid; // NSMenuItem * lineDashedItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Dashed", @"PDFListView") action:@selector(menuItemClick_LineStyle:) keyEquivalent:@""]; // lineDashedItem.tag = CPDFBorderStyleDashed; // // [subMenu addItem:lineSolidItem]; // [subMenu addItem:lineDashedItem]; // lineStyleItem.submenu = subMenu; // // NSMenuItem * changeColorItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Color...", @"PDFListView") action:@selector(menuItemClick_ChangeColor:) keyEquivalent:@""]; // [menu insertItem:arrangementItem atIndex:0]; // [menu insertItem:[NSMenuItem separatorItem] atIndex:0]; // if([self.activeAnnotation isKindOfClass:[CPDFMarkupAnnotation class]] || // [self.activeAnnotation isKindOfClass:[CPDFStampAnnotation class]] || // [self.activeAnnotation isKindOfClass:[CPDFSignatureAnnotation class]]) { // [menu insertItem:editNoteItem atIndex:0]; // } else if ([self.activeAnnotation isKindOfClass:[CPDFInkAnnotation class]]) { // [menu insertItem:editNoteItem atIndex:0]; // [menu insertItem:lineStyleItem atIndex:0]; // [menu insertItem:changeColorItem atIndex:0]; // } else if ([self.activeAnnotation isKindOfClass:[CPDFTextAnnotation class]]) { // [menu insertItem:editNoteItem atIndex:0]; // [menu insertItem:changeColorItem atIndex:0]; // } else if ([self.activeAnnotation isKindOfClass:[CPDFSquareAnnotation class]] || // [self.activeAnnotation isKindOfClass:[CPDFCircleAnnotation class]] || // [self.activeAnnotation isKindOfClass:[CPDFLineAnnotation class]]) { // [menu insertItem:editNoteItem atIndex:0]; // if([self.activeAnnotation isKindOfClass:[CPDFLineAnnotation class]]) { // NSMenuItem * directionItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Direction", @"PDFListView") action:nil keyEquivalent:@""]; // subMenu = [[NSMenu alloc]init]; // // NSMenuItem * lineHorizontalItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Horizontal", @"PDFListView") action:@selector(menuItemClick_LineHorizontal:) keyEquivalent:@""]; // NSMenuItem * lineVerticalItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Vertical", @"PDFListView") action:@selector(menuItemClick_LineVertical:) keyEquivalent:@""]; // [subMenu addItem:lineHorizontalItem]; // [subMenu addItem:lineVerticalItem]; // directionItem.submenu = subMenu; // // [menu insertItem:directionItem atIndex:0]; // } // [menu insertItem:lineStyleItem atIndex:0]; // [menu insertItem:changeColorItem atIndex:0]; // } if ([self.activeAnnotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) { CPDFSignatureWidgetAnnotation *aa = (CPDFSignatureWidgetAnnotation *)self.activeAnnotation; CPDFSignature *aaa = aa.signature; [menu insertItem:[NSMenuItem separatorItem] atIndex:0]; [menu insertItem:deleteItem atIndex:0]; } // if(![self.activeAnnotation isKindOfClass:[CPDFMarkupAnnotation class]]) { // if ([[NSPasteboard generalPasteboard] canReadObjectForClasses:[NSArray arrayWithObjects:[CPDFAnnotation class], [NSString class],[NSImage class], nil] options:[NSDictionary dictionary]]) { // [menu insertItem:pasteItem atIndex:0]; // } // [menu insertItem:cutItem atIndex:0]; // } // [menu insertItem:copyItem atIndex:0]; __block typeof(self) blockSelf = self; } else if (self.activeAnnotations.count > 1) { BOOL isMarkupAn = NO; for (CPDFAnnotation *annotation in self.activeAnnotations) { if([annotation isKindOfClass:[CPDFMarkupAnnotation class]]) { isMarkupAn = YES; break; } } // [menu insertItem:arrangementItem atIndex:0]; [menu insertItem:[NSMenuItem separatorItem] atIndex:0]; [menu insertItem:deleteItem atIndex:0]; if(!isMarkupAn) { [menu insertItem:cutItem atIndex:0]; [menu insertItem:copyItem atIndex:0]; } } else if (self.currentSelection) { if(CPDFSelectionTypeImage == [self.currentSelection selectionType]) { NSMenuItem * exportImageItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Export…", nil) action:@selector(menuItemClick_ExportImage:) keyEquivalent:@""]; [menu insertItem:exportImageItem atIndex:0]; [menu insertItem:[NSMenuItem separatorItem] atIndex:0]; } if ([[NSPasteboard generalPasteboard] canReadObjectForClasses:[NSArray arrayWithObjects:[CPDFAnnotation class], [NSString class],[NSImage class], nil] options:[NSDictionary dictionary]]) { [menu insertItem:pasteItem atIndex:0]; } [menu insertItem:copyItem atIndex:0]; } else if (!self.activeAnnotation) { // NSMenuItem * pageDisplayItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Page Display", @"PDFListView") action:nil keyEquivalent:@""]; // subMenu = [[NSMenu alloc] init]; // // NSMenuItem * twoPagesContinuousItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Two Pages Continuous", @"PDFListView") action:@selector(menuItemClick_TwoPagesContinuous:) keyEquivalent:@""]; // NSMenuItem * twoPagesItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Two Pages", @"PDFListView") action:@selector(menuItemClick_TwoPages:) keyEquivalent:@""]; // NSMenuItem * singlePageContinuousItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Single Page Continuous", @"PDFListView") action:@selector(menuItemClick_SinglePagesContinuous:) keyEquivalent:@""]; // NSMenuItem * singlePageItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Single Page", @"PDFListView") action:@selector(menuItemClick_SinglePage:) keyEquivalent:@""]; // NSMenuItem * bookModeItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Book Mode", @"PDFListView") action:@selector(menuItemClick_BookMode:) keyEquivalent:@""]; // switch (self.displayViewMode) { // case CPDFDisplayViewSinglePageContinuous: // singlePageContinuousItem.state = NSControlStateValueOn; // break; // case CPDFDisplayViewTwoUp: // if (self.displaysAsBook) // bookModeItem.state = NSControlStateValueOn; // else // twoPagesItem.state = NSControlStateValueOn; // break; // case CPDFDisplayViewTwoUpContinuous: // if (self.displaysAsBook) // bookModeItem.state = NSControlStateValueOn; // else // twoPagesContinuousItem.state = NSControlStateValueOn; // break; // default: // case CPDFDisplayViewSinglePage: // singlePageItem.state = NSControlStateValueOn; // break; // } // // [subMenu addItem:singlePageItem]; // [subMenu addItem:singlePageContinuousItem]; // [subMenu addItem:twoPagesItem]; // [subMenu addItem:twoPagesContinuousItem]; // [subMenu addItem:bookModeItem]; // pageDisplayItem.submenu = subMenu; // // [menu insertItem:pageDisplayItem atIndex:0]; // // NSMenuItem *zoomItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Zoom", @"PDFListView") action:nil keyEquivalent:@""]; // subMenu = [[NSMenu alloc]init]; // // NSMenuItem * fitWidthItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Fit Width", @"PDFListView") action:@selector(menuItemClick_FitWidth:) keyEquivalent:@""]; // NSMenuItem * automaticallyItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Automatically Resize", @"PDFListView") action:@selector(menuItemClick_AutomaticallyResize:) keyEquivalent:@""]; // NSMenuItem * actualSizeItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Actual Size", @"PDFListView") action:@selector(menuItemClick_ActualSize:) keyEquivalent:@""]; // NSMenuItem * zoomInItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Zoom In", @"PDFListView") action:@selector(menuItemClick_ZoomIn:) keyEquivalent:@""]; // NSMenuItem * zoomOutItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Zoom Out", @"PDFListView") action:@selector(menuItemClick_ZoomOut:) keyEquivalent:@""]; // // NSMenuItem * hidenShowNoteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Hide Notes", @"PDFListView") action:@selector(menuItemClick_HidenorShowNote:) keyEquivalent:@""]; // // if (self.autoScales) { // automaticallyItem.state = NSControlStateValueOn; // } else if (self.scaleFactor == 1.0) { // actualSizeItem.state = NSControlStateValueOn; // } // // // // [subMenu addItem:fitWidthItem]; // [subMenu addItem:automaticallyItem]; // [subMenu addItem:actualSizeItem]; // [subMenu addItem:zoomInItem]; // [subMenu addItem:zoomOutItem]; // zoomItem.submenu = subMenu; // [menu insertItem:zoomItem atIndex:0]; // // [menu insertItem:[NSMenuItem separatorItem] atIndex:0]; // [menu insertItem:hidenShowNoteItem atIndex:0]; // [menu insertItem:[NSMenuItem separatorItem] atIndex:0]; // [menu insertItem:pasteItem atIndex:0]; } } // if ([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewMenuForEvent:forEvent:clickMenu:)]) { // [self.pdfListViewDelegate PDFListViewMenuForEvent:self forEvent:event clickMenu:&menu]; // } return menu; } - (void)updateIsRightActiveAnnotations:(NSArray *)activeAnnotations { [self refreshActiveAnnotations:activeAnnotations isRight:YES]; } - (IBAction)delete:(id)sender { if (self.activeAnnotations.count > 0 ) { NSMutableArray *tarr = [NSMutableArray arrayWithArray:self.activeAnnotations]; for (CPDFAnnotation * an in tarr) { // if(self.hoverAnnotation == an) { // self.hoverAnnotation = nil; // } [self removeAnnotation:an]; [[self undoManager] setActionName:NSLocalizedString(@"Remove Note", @"Undo action name")]; if([an isKindOfClass:[CPDFFreeTextAnnotation class]]) { CPDFFreeTextAnnotation *freeTextAn = (CPDFFreeTextAnnotation *)an; if ([self isEditWithCurrentFreeText:freeTextAn]) { [self commitEditAnnotationFreeText:freeTextAn]; } } } [self removeActiveAnnotations:tarr]; } else { NSBeep(); } } - (void)removeAnnotation:(CPDFAnnotation *)annotation { CPDFAnnotation *wasAnnotation = annotation; CPDFPage *page = wasAnnotation.page; [[[self undoManager] prepareWithInvocationTarget:self] addAnnotation:wasAnnotation toPage:page]; [page removeAnnotation:wasAnnotation]; [self annotationsChangedOnPage:page]; [self setNeedsDisplayAnnotation:wasAnnotation]; // dispatch_async(dispatch_get_main_queue(), ^{ // [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewDidRemoveAnnotationNotification object:self // userInfo:[NSDictionary dictionaryWithObjectsAndKeys:wasAnnotation, CPDFListViewAnnotationKey, page, CPDFListViewPageKey, nil]]; // }); // // if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewRemoveAnnotations:forRemoveAnnotations:inPage:)]) // [self.pdfListViewDelegate PDFListViewRemoveAnnotations:self forRemoveAnnotations:@[annotation] inPage:page]; } - (void)removeActiveAnnotations:(NSArray *)removeAnnotations { BOOL isContains = NO; NSMutableArray *tarr = [NSMutableArray arrayWithArray:self.activeAnnotations]; [tarr removeObjectsInArray:removeAnnotations]; self.activeAnnotations = tarr; isContains = YES; if(isContains) { if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewDeleteAnnotation:forAnnotation:)]) [self.pdfListViewDelegate PDFListViewDeleteAnnotation:self forAnnotation:removeAnnotations.firstObject]; dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewActiveAnnotationsChangeNotification object:self]; }); } // if(isContains) { // if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewChangeatioActiveAnnotations:forActiveAnnotations:isRightMenu:)]) // [self.pdfListViewDelegate PDFListViewChangeatioActiveAnnotations:self forActiveAnnotations:self.activeAnnotations isRightMenu:NO]; // // dispatch_async(dispatch_get_main_queue(), ^{ // [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewActiveAnnotationsChangeNotification object:self]; // }); // } } @end