|
@@ -14,12 +14,10 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
get {
|
|
|
if (self._scalePopUpButton == nil) {
|
|
|
|
|
|
-// NSScrollView *scrollView = [self scrollView];
|
|
|
- let scrollView = self.enclosingScrollView
|
|
|
+ let scrollView = self.documentView()
|
|
|
scrollView?.hasHorizontalScroller = true
|
|
|
|
|
|
// create it
|
|
|
-// scalePopUpButton = [[NSPopUpButton allocWithZone:[self zone]] initWithFrame:NSMakeRect(0.0, 0.0, 1.0, 1.0) pullsDown:NO];
|
|
|
let scalePopUpButton_ = NSPopUpButton(frame: NSMakeRect(0.0, 0.0, 1.0, 1.0), pullsDown: false)
|
|
|
scalePopUpButton_.cell?.controlSize = .small
|
|
|
self._scalePopUpButton = scalePopUpButton_
|
|
@@ -45,9 +43,7 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
|
|
|
// fill it
|
|
|
for i in 0 ..< numberOfDefaultItems {
|
|
|
-// for (cnt = 0; cnt < numberOfDefaultItems; cnt++) {
|
|
|
label = Bundle.main.localizedString(forKey: self._SKDefaultScaleMenuLabels[i], value: "", table: "ZoomValues")
|
|
|
-// width = NSWidth([label boundingRectWithSize:size options:0 attributes:attrs]);
|
|
|
width = NSWidth(label.boundingRect(with: size, options: NSString.DrawingOptions(rawValue: 0), attributes: attrs))
|
|
|
if (width > maxWidth) {
|
|
|
maxWidth = width
|
|
@@ -67,7 +63,6 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
// Make sure the popup is big enough to fit the largest cell
|
|
|
scalePopUpButton_.selectItem(at: maxIndex)
|
|
|
scalePopUpButton_.sizeToFit()
|
|
|
-// [scalePopUpButton setFrameSize:];
|
|
|
scalePopUpButton_.setFrameSize(NSMakeSize(NSWidth(scalePopUpButton_.frame) - CONTROL_WIDTH_OFFSET, CONTROL_HEIGHT))
|
|
|
//
|
|
|
// // select the appropriate item, adjusting the scaleFactor if necessary
|
|
@@ -105,6 +100,8 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
private let _SKMinDefaultScaleMenuFactor = 0.1
|
|
|
private let _SKDefaultScaleMenuFactorsCount = 23
|
|
|
|
|
|
+ private let SKPDFContentViewChangedNotification = "SKPDFContentViewChangedNotification"
|
|
|
+
|
|
|
deinit {
|
|
|
KMPrint("KMSnapshotPDFView deinit.")
|
|
|
|
|
@@ -123,84 +120,174 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
self._commonInitialization()
|
|
|
}
|
|
|
|
|
|
+ override func layout() {
|
|
|
+ super.layout()
|
|
|
+
|
|
|
+ let scrollView = self.documentView()
|
|
|
+ let clipView = scrollView?.contentView
|
|
|
+// KMPrint(scrollView?.frame)
|
|
|
+// KMPrint(clipView?.frame)
|
|
|
+ scrollView?.frame = self.bounds
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
override func draw(_ dirtyRect: NSRect) {
|
|
|
super.draw(dirtyRect)
|
|
|
|
|
|
// Drawing code here.
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ @objc func handlePDFViewFrameChangedNotification(_ notification: NSNotification) {
|
|
|
+ if self.autoFits {
|
|
|
+ let clipView = self.documentView().contentView
|
|
|
+ let clipRect = self.convert(clipView.visibleRect, from: clipView)
|
|
|
+ var rect = self.convert(self.autoFitRect, from: self.autoFitPage)
|
|
|
+
|
|
|
+ let factor = fmin(NSWidth(clipRect) / NSWidth(rect), NSHeight(clipRect) / NSHeight(rect))
|
|
|
+ rect = self.convert(NSInsetRect(rect, 0.5 * (NSWidth(rect) - NSWidth(clipRect) / factor), 0.5 * (NSHeight(rect) - NSHeight(clipRect) / factor)), to: self.autoFitPage)
|
|
|
+ super.scaleFactor = factor * self.scaleFactor
|
|
|
+ self.go(to: rect, on: self.autoFitPage)
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- /*
|
|
|
- #define SKPDFContentViewChangedNotification @"SKPDFContentViewChangedNotification"
|
|
|
-
|
|
|
- - (void)handlePDFViewFrameChangedNotification:(NSNotification *)notification {
|
|
|
- if ([self autoFits]) {
|
|
|
- NSView *clipView = [[self scrollView] contentView];
|
|
|
- NSRect clipRect = [self convertRect:[clipView visibleRect] fromView:clipView];
|
|
|
- NSRect rect = [self convertRect:autoFitRect fromPage:autoFitPage];
|
|
|
- CGFloat factor = fmin(NSWidth(clipRect) / NSWidth(rect), NSHeight(clipRect) / NSHeight(rect));
|
|
|
- rect = [self convertRect:NSInsetRect(rect, 0.5 * (NSWidth(rect) - NSWidth(clipRect) / factor), 0.5 * (NSHeight(rect) - NSHeight(clipRect) / factor)) toPage:autoFitPage];
|
|
|
- [super setScaleFactor:factor * [self scaleFactor]];
|
|
|
- [self goToRect:rect onPage:autoFitPage];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- - (void)handlePDFContentViewFrameChangedDelayedNotification:(NSNotification *)notification {
|
|
|
- if ([self inLiveResize] == NO && [[self window] isZoomed] == NO)
|
|
|
- [self resetAutoFitRectIfNeeded];
|
|
|
- }
|
|
|
-
|
|
|
- - (void)handlePDFContentViewFrameChangedNotification:(NSNotification *)notification {
|
|
|
- if ([self inLiveResize] == NO && [[self window] isZoomed] == NO) {
|
|
|
- NSNotification *note = [NSNotification notificationWithName:SKPDFContentViewChangedNotification object:self];
|
|
|
- [[NSNotificationQueue defaultQueue] enqueueNotification:note postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- - (void)handlePDFViewScaleChangedNotification:(NSNotification *)notification {
|
|
|
- if ([self autoFits] == NO)
|
|
|
- [self setScaleFactor:fmax([self scaleFactor], SKMinDefaultScaleMenuFactor) adjustPopup:YES];
|
|
|
- }
|
|
|
- - (void)setAutoScales:(BOOL)newAuto {}
|
|
|
-
|
|
|
- - (IBAction)zoomIn:(id)sender{
|
|
|
- if([self autoFits]){
|
|
|
- [super zoomIn:sender];
|
|
|
- [self setAutoFits:NO adjustPopup:YES];
|
|
|
- }else{
|
|
|
- NSUInteger numberOfDefaultItems = SKDefaultScaleMenuFactorsCount;
|
|
|
- NSUInteger i = [self lowerIndexForScaleFactor:[self scaleFactor]];
|
|
|
- if (i < numberOfDefaultItems - 1) i++;
|
|
|
- [self setScaleFactor:SKDefaultScaleMenuFactors[i]];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- - (IBAction)zoomOut:(id)sender{
|
|
|
- if([self autoFits]){
|
|
|
- [super zoomOut:sender];
|
|
|
- [self setAutoFits:NO adjustPopup:YES];
|
|
|
- }else{
|
|
|
- NSUInteger i = [self upperIndexForScaleFactor:[self scaleFactor]];
|
|
|
- if (i > 1) i--;
|
|
|
- [self setScaleFactor:SKDefaultScaleMenuFactors[i]];
|
|
|
- }
|
|
|
- }
|
|
|
+ @objc func handlePDFContentViewFrameChangedDelayedNotification(_ notification: NSNotification) {
|
|
|
+ if self.inLiveResize == false && (self.window?.isZoomed ?? false) == false {
|
|
|
+ self._resetAutoFitRectIfNeeded()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func handlePDFContentViewFrameChangedNotification(_ notification: NSNotification) {
|
|
|
+ if self.inLiveResize == false && (self.window?.isZoomed ?? false) == false {
|
|
|
+ let note = Notification(name: Notification.Name(SKPDFContentViewChangedNotification), object: self)
|
|
|
+ NotificationQueue.default.enqueue(note, postingStyle: .whenIdle, coalesceMask: .onName, forModes: nil)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func handlePDFViewScaleChangedNotification(_ notification: NSNotification) {
|
|
|
+ if self.autoFits == false {
|
|
|
+ self._setScaleFactor(fmax(self.scaleFactor, _SKMinDefaultScaleMenuFactor), adjustPopup: true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func setAutoScales() {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction override func zoomIn(_ sender: Any?) {
|
|
|
+ if self.autoFits {
|
|
|
+ super.zoomIn(sender)
|
|
|
+ self._setAutoFits(false, adjustPopup: true)
|
|
|
+ } else {
|
|
|
+ let numberOfDefaultItems = _SKDefaultScaleMenuFactorsCount
|
|
|
+ var i = self._lowerIndex(for: self.scaleFactor)
|
|
|
+ if i < numberOfDefaultItems-1 {
|
|
|
+ i += 1
|
|
|
+ }
|
|
|
+ self._setScaleFactor(_SKDefaultScaleMenuFactors[Int(i)])
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction override func zoomOut(_ sender: Any?) {
|
|
|
+ if self.autoFits {
|
|
|
+ super.zoomOut(sender)
|
|
|
+ self._setAutoFits(false, adjustPopup: true)
|
|
|
+ } else {
|
|
|
+ var i = self._upperIndex(for: self.scaleFactor)
|
|
|
+ if i > 1 {
|
|
|
+ i -= 1
|
|
|
+ }
|
|
|
+ self._setScaleFactor(_SKDefaultScaleMenuFactors[Int(i)])
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override var canZoomIn: Bool {
|
|
|
+ if super.canZoomIn == false {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ let numberOfDefaultItems = _SKDefaultScaleMenuFactorsCount
|
|
|
+ let i = self._lowerIndex(for: self.scaleFactor)
|
|
|
+ return i < numberOfDefaultItems - 1
|
|
|
+ }
|
|
|
+
|
|
|
+ override var canZoomOut: Bool {
|
|
|
+ if super.canZoomOut == false {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ let i = self._upperIndex(for: self.scaleFactor)
|
|
|
+ return i > 1
|
|
|
+ }
|
|
|
+
|
|
|
+ override func go(to page: CPDFPage!) {
|
|
|
+ super.go(to: page)
|
|
|
+
|
|
|
+ self._resetAutoFitRectIfNeeded()
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func doAutoFit(_ sender: Any?) {
|
|
|
+ self.autoFits = true
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func doActualSize(_ sender: Any?) {
|
|
|
+ self.scaleFactor = 1.0
|
|
|
+ }
|
|
|
+
|
|
|
+ override func menu(for event: NSEvent) -> NSMenu? {
|
|
|
+ let selectionActions: NSSet = NSSet(objects: ["copy:", "_searchInSpotlight:", "_searchInGoogle:", "_searchInDictionary:", "_revealSelection:"])
|
|
|
+ var menu = super.menu(for: event)
|
|
|
+ if menu == nil {
|
|
|
+ menu = NSMenu()
|
|
|
+ }
|
|
|
+
|
|
|
+ menu?.insertItem(.separator(), at: 0)
|
|
|
+ menu?.insertItem(withTitle: KMLocalizedString("Print", "Menu item title"), action: #selector(menuItemClick_Print), target: self, at: 0)
|
|
|
|
|
|
- - (BOOL)canZoomIn{
|
|
|
- if ([super canZoomIn] == NO)
|
|
|
- return NO;
|
|
|
- NSUInteger numberOfDefaultItems = SKDefaultScaleMenuFactorsCount;
|
|
|
- NSUInteger i = [self lowerIndexForScaleFactor:[self scaleFactor]];
|
|
|
- return i < numberOfDefaultItems - 1;
|
|
|
- }
|
|
|
+ var item = menu?.insertItem(withTitle: KMLocalizedString("Export", "Menu item title"), action: nil, target: self, at: 0)
|
|
|
+ let subMenu = NSMenu()
|
|
|
+
|
|
|
+ subMenu.addItem(title: KMLocalizedString("PNG", "Menu item title"), action: #selector(menuItemClick_ExportPNG), target: self)
|
|
|
+ subMenu.addItem(title: KMLocalizedString("JPG", "Menu item title"), action: #selector(menuItemClick_ExportJPG), target: self)
|
|
|
+ subMenu.addItem(title: KMLocalizedString("PDF", "Menu item title"), action: #selector(menuItemClick_ExportPDF), target: self)
|
|
|
+ item?.submenu = subMenu
|
|
|
|
|
|
- - (BOOL)canZoomOut{
|
|
|
- if ([super canZoomOut] == NO)
|
|
|
- return NO;
|
|
|
- NSUInteger i = [self upperIndexForScaleFactor:[self scaleFactor]];
|
|
|
- return i > 1;
|
|
|
- }
|
|
|
+ menu?.insertItem(.separator(), at: 0)
|
|
|
+ menu?.insertItem(withTitle: KMLocalizedString("Copy", "Menu item title"), action: #selector(menuItemClick_Copy), target: self, at: 0)
|
|
|
+
|
|
|
+// [self setCurrentSelection:RUNNING_AFTER(10_11) ? [[[PDFSelection alloc] initWithDocument:[self document]] autorelease] : nil];
|
|
|
+ self.currentSelection = CPDFSelection(document: self.document)
|
|
|
+ if let _menu = menu {
|
|
|
+ while (_menu.numberOfItems > 0) {
|
|
|
+ if let item = _menu.item(at: 0), item.action != nil {
|
|
|
+ if item.isSeparatorItem || self.validateMenuItem(item) == false || selectionActions.contains(NSStringFromSelector(item.action!)) {
|
|
|
+ menu?.removeItem(at: 0)
|
|
|
+ } else {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if let i = menu?.indexOfItem(withTarget: self, andAction: NSSelectorFromString("_setAutoSize:")), i != -1 {
|
|
|
+ menu?.item(at: i)?.action = #selector(doAutoFit)
|
|
|
+ }
|
|
|
+ if let i = menu?.indexOfItem(withTarget: self, andAction: NSSelectorFromString("_setActualSize:")), i != -1 {
|
|
|
+ menu?.item(at: i)?.action = #selector(doActualSize)
|
|
|
+ var item = menu?.insertItem(withTitle: KMLocalizedString("Physical Size", "Menu item title"), action: #selector(doPhysicalSize), target: self, at: i + 1)
|
|
|
+// item?.keyEquivalentModifierMask = [.alternate]
|
|
|
+// [item setKeyEquivalentModifierMask:NSAlternateKeyMask];
|
|
|
+// [item setAlternate:YES];
|
|
|
+ item?.isAlternate = true
|
|
|
+ }
|
|
|
+
|
|
|
+ return menu
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func doPhysicalSize(_ sender: Any?) {
|
|
|
+// [self setPhysicalScaleFactor:1.0];
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
|
|
|
- (BOOL)canGoBack {
|
|
|
if ([self respondsToSelector:@selector(currentHistoryIndex)] && minHistoryIndex > 0)
|
|
@@ -209,23 +296,6 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
return [super canGoBack];
|
|
|
}
|
|
|
|
|
|
- - (void)goToPage:(PDFPage *)aPage {
|
|
|
- [super goToPage:aPage];
|
|
|
- [self resetAutoFitRectIfNeeded];
|
|
|
- }
|
|
|
-
|
|
|
- - (void)doAutoFit:(id)sender {
|
|
|
- [self setAutoFits:YES];
|
|
|
- }
|
|
|
-
|
|
|
- - (void)doActualSize:(id)sender {
|
|
|
- [self setScaleFactor:1.0];
|
|
|
- }
|
|
|
-
|
|
|
- - (void)doPhysicalSize:(id)sender {
|
|
|
- [self setPhysicalScaleFactor:1.0];
|
|
|
- }
|
|
|
-
|
|
|
// we don't want to steal the printDocument: action from the responder chain
|
|
|
- (void)printDocument:(id)sender{}
|
|
|
|
|
@@ -233,65 +303,6 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
return aSelector != @selector(printDocument:) && [super respondsToSelector:aSelector];
|
|
|
}
|
|
|
|
|
|
- - (NSMenu *)menuForEvent:(NSEvent *)theEvent {
|
|
|
- static NSSet *selectionActions = nil;
|
|
|
- if (selectionActions == nil)
|
|
|
- selectionActions = [[NSSet alloc] initWithObjects:@"copy:", @"_searchInSpotlight:", @"_searchInGoogle:", @"_searchInDictionary:", @"_revealSelection:", nil];
|
|
|
- NSMenu *menu = [super menuForEvent:theEvent];
|
|
|
-
|
|
|
- [menu insertItem:[NSMenuItem separatorItem] atIndex:0];
|
|
|
- [menu insertItemWithTitle:NSLocalizedString(@"Print", @"Menu item title") action:@selector(menuItemClick_Print:) target:self atIndex:0];
|
|
|
-
|
|
|
- NSMenuItem * item = [menu insertItemWithTitle:NSLocalizedString(@"Export", @"Menu item title") action:nil target:self atIndex:0];
|
|
|
- NSMenu *subMenu = [NSMenu menu];
|
|
|
-
|
|
|
- [subMenu addItemWithTitle:NSLocalizedString(@"PNG", @"Menu item title") action:@selector(menuItemClick_ExportPNG:) target:self];
|
|
|
- [subMenu addItemWithTitle:NSLocalizedString(@"JPG", @"Menu item title") action:@selector(menuItemClick_ExportJPG:) target:self];
|
|
|
- [subMenu addItemWithTitle:NSLocalizedString(@"PDF", @"Menu item title") action:@selector(menuItemClick_ExportPDF:) target:self];
|
|
|
- item.submenu = subMenu;
|
|
|
-
|
|
|
- [menu insertItem:[NSMenuItem separatorItem] atIndex:0];
|
|
|
- [menu insertItemWithTitle:NSLocalizedString(@"Copy", @"Menu item title") action:@selector(menuItemClick_Copy:) target:self atIndex:0];
|
|
|
-
|
|
|
- [self setCurrentSelection:RUNNING_AFTER(10_11) ? [[[PDFSelection alloc] initWithDocument:[self document]] autorelease] : nil];
|
|
|
- while ([menu numberOfItems]) {
|
|
|
- NSMenuItem *item = [menu itemAtIndex:0];
|
|
|
- if ([item isSeparatorItem] || [self validateMenuItem:item] == NO || [selectionActions containsObject:NSStringFromSelector([item action])])
|
|
|
- [menu removeItemAtIndex:0];
|
|
|
- else
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- NSInteger i = [menu indexOfItemWithTarget:self andAction:NSSelectorFromString(@"_setAutoSize:")];
|
|
|
- if (i != -1)
|
|
|
- [[menu itemAtIndex:i] setAction:@selector(doAutoFit:)];
|
|
|
- i = [menu indexOfItemWithTarget:self andAction:NSSelectorFromString(@"_setActualSize:")];
|
|
|
- if (i != -1) {
|
|
|
- [[menu itemAtIndex:i] setAction:@selector(doActualSize:)];
|
|
|
- NSMenuItem *item = [menu insertItemWithTitle:NSLocalizedString(@"Physical Size", @"Menu item title") action:@selector(doPhysicalSize:) target:self atIndex:i + 1];
|
|
|
- [item setKeyEquivalentModifierMask:NSAlternateKeyMask];
|
|
|
- [item setAlternate:YES];
|
|
|
- }
|
|
|
-
|
|
|
- return menu;
|
|
|
- }
|
|
|
-
|
|
|
- - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
|
|
|
- if ([menuItem action] == @selector(doAutoFit:)) {
|
|
|
- [menuItem setState:[self autoFits] ? NSOnState : NSOffState];
|
|
|
- return YES;
|
|
|
- } else if ([menuItem action] == @selector(doActualSize:)) {
|
|
|
- [menuItem setState:fabs([self scaleFactor] - 1.0) < 0.1 ? NSOnState : NSOffState];
|
|
|
- return YES;
|
|
|
- } else if ([menuItem action] == @selector(doPhysicalSize:)) {
|
|
|
- [menuItem setState:([self autoScales] || fabs([self physicalScaleFactor] - 1.0 ) > 0.01) ? NSOffState : NSOnState];
|
|
|
- return YES;
|
|
|
- } else if ([[SKSnapshotPDFView superclass] instancesRespondToSelector:_cmd]) {
|
|
|
- return [super validateMenuItem:menuItem];
|
|
|
- }
|
|
|
- return YES;
|
|
|
- }
|
|
|
-
|
|
|
#pragma mark Gestures
|
|
|
|
|
|
- (void)beginGestureWithEvent:(NSEvent *)theEvent {
|
|
@@ -340,52 +351,57 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
else
|
|
|
[[NSCursor openHandCursor] set];
|
|
|
}
|
|
|
-
|
|
|
- - (NSImage *)thumbnailWithSize:(CGFloat)size {
|
|
|
- NSView *clipView = [[[self documentView] enclosingScrollView] contentView];
|
|
|
- NSRect bounds = [self convertRect:[clipView bounds] fromView:clipView];
|
|
|
- NSBitmapImageRep *imageRep = [self bitmapImageRepForCachingDisplayInRect:bounds];
|
|
|
- NSAffineTransform *transform = nil;
|
|
|
- NSSize thumbnailSize = thumbnailSize = bounds.size;
|
|
|
- CGFloat shadowBlurRadius = 0.0;
|
|
|
- CGFloat shadowOffset = 0.0;
|
|
|
- NSImage *image;
|
|
|
-
|
|
|
- [self cacheDisplayInRect:bounds toBitmapImageRep:imageRep];
|
|
|
-
|
|
|
- bounds.origin = NSZeroPoint;
|
|
|
-
|
|
|
- if (size > 0.0) {
|
|
|
- shadowBlurRadius = round(size / 32.0);
|
|
|
- shadowOffset = -ceil(shadowBlurRadius * 0.75);
|
|
|
- if (NSHeight(bounds) > NSWidth(bounds))
|
|
|
- thumbnailSize = NSMakeSize(round((size - 2.0 * shadowBlurRadius) * NSWidth(bounds) / NSHeight(bounds) + 2.0 * shadowBlurRadius), size);
|
|
|
- else
|
|
|
- thumbnailSize = NSMakeSize(size, round((size - 2.0 * shadowBlurRadius) * NSHeight(bounds) / NSWidth(bounds) + 2.0 * shadowBlurRadius));
|
|
|
- transform = [NSAffineTransform transform];
|
|
|
- [transform translateXBy:shadowBlurRadius yBy:shadowBlurRadius - shadowOffset];
|
|
|
- [transform scaleXBy:(thumbnailSize.width - 2.0 * shadowBlurRadius) / NSWidth(bounds) yBy:(thumbnailSize.height - 2.0 * shadowBlurRadius) / NSHeight(bounds)];
|
|
|
- }
|
|
|
-
|
|
|
- image = [[[NSImage alloc] initWithSize:thumbnailSize] autorelease];
|
|
|
-
|
|
|
- [image lockFocus];
|
|
|
- [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
|
|
|
- [transform concat];
|
|
|
- [NSGraphicsContext saveGraphicsState];
|
|
|
- [[PDFView defaultPageBackgroundColor] set];
|
|
|
- if (shadowBlurRadius > 0.0)
|
|
|
- [NSShadow setShadowWithColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.5] blurRadius:shadowBlurRadius yOffset:shadowOffset];
|
|
|
- NSRectFill(bounds);
|
|
|
- [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationDefault];
|
|
|
- [NSGraphicsContext restoreGraphicsState];
|
|
|
- [imageRep drawInRect:bounds];
|
|
|
- [image unlockFocus];
|
|
|
-
|
|
|
- return image;
|
|
|
- }
|
|
|
*/
|
|
|
|
|
|
+ func thumbnailWithSize(_ size: CGFloat) -> NSImage? {
|
|
|
+// NSView *clipView = [[[self documentView] enclosingScrollView] contentView];
|
|
|
+ let clipView = self.documentView().contentView
|
|
|
+ var bounds = self.convert(clipView.bounds, from: clipView)
|
|
|
+ guard let imageRep = self.bitmapImageRepForCachingDisplay(in: bounds) else {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ var transform: NSAffineTransform?
|
|
|
+ var thumbnailSize = bounds.size
|
|
|
+ var shadowBlurRadius = 0.0
|
|
|
+ var shadowOffset = 0.0
|
|
|
+ var image: NSImage?
|
|
|
+
|
|
|
+ self.cacheDisplay(in: bounds, to: imageRep)
|
|
|
+
|
|
|
+ bounds.origin = .zero
|
|
|
+
|
|
|
+ if (size > 0.0) {
|
|
|
+ shadowBlurRadius = round(size / 32.0)
|
|
|
+ shadowOffset = -ceil(shadowBlurRadius * 0.75)
|
|
|
+ if (NSHeight(bounds) > NSWidth(bounds)) {
|
|
|
+ thumbnailSize = NSMakeSize(round((size - 2.0 * shadowBlurRadius) * NSWidth(bounds) / NSHeight(bounds) + 2.0 * shadowBlurRadius), size)
|
|
|
+ } else {
|
|
|
+ thumbnailSize = NSMakeSize(size, round((size - 2.0 * shadowBlurRadius) * NSHeight(bounds) / NSWidth(bounds) + 2.0 * shadowBlurRadius))
|
|
|
+ }
|
|
|
+ transform = NSAffineTransform()
|
|
|
+ transform?.translateX(by: shadowBlurRadius, yBy: shadowBlurRadius - shadowOffset)
|
|
|
+ transform?.scaleX(by: (thumbnailSize.width - 2.0 * shadowBlurRadius) / NSWidth(bounds), yBy: (thumbnailSize.height - 2.0 * shadowBlurRadius) / NSHeight(bounds))
|
|
|
+ }
|
|
|
+
|
|
|
+ image = NSImage(size: thumbnailSize)
|
|
|
+
|
|
|
+ image?.lockFocus()
|
|
|
+ NSGraphicsContext.current?.imageInterpolation = .high
|
|
|
+ transform?.concat()
|
|
|
+ NSGraphicsContext.saveGraphicsState()
|
|
|
+// [[PDFView defaultPageBackgroundColor] set];
|
|
|
+// if (shadowBlurRadius > 0.0) {
|
|
|
+// [NSShadow setShadowWithColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.5] blurRadius:shadowBlurRadius yOffset:shadowOffset];
|
|
|
+// }
|
|
|
+ __NSRectFill(bounds)
|
|
|
+ NSGraphicsContext.current?.imageInterpolation = .default
|
|
|
+ NSGraphicsContext.restoreGraphicsState()
|
|
|
+ imageRep.draw(in: bounds)
|
|
|
+ image?.unlockFocus()
|
|
|
+
|
|
|
+ return image
|
|
|
+ }
|
|
|
+
|
|
|
func resetHistory() {
|
|
|
// if ([self respondsToSelector:@selector(currentHistoryIndex)])
|
|
|
// minHistoryIndex = [self currentHistoryIndex];
|
|
@@ -395,7 +411,7 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
}
|
|
|
|
|
|
// MARK: - Menu
|
|
|
- func menuItemClick_Print(_ sender: AnyObject?) {
|
|
|
+ @objc func menuItemClick_Print(_ sender: AnyObject?) {
|
|
|
// NSImage * image = [self thumbnailWithSize:0.0];
|
|
|
//
|
|
|
// PDFPage *page = [[[PDFPage alloc] initWithImage:image] autorelease];
|
|
@@ -413,78 +429,52 @@ class KMSnapshotPDFView: CPDFView {
|
|
|
// [printOperation runOperationModalForWindow:self.window delegate:self didRunSelector:nil contextInfo:NULL];
|
|
|
}
|
|
|
|
|
|
- func menuItemClick_ExportPDF(_ sender: NSMenuItem) {
|
|
|
-// NSImage * image = [self thumbnailWithSize:0.0];
|
|
|
-//
|
|
|
-// PDFPage *page = [[[PDFPage alloc] initWithImage:image] autorelease];
|
|
|
-// PDFDocument *pdfDocument = [[[PDFDocument alloc] init] autorelease];
|
|
|
-// [pdfDocument insertPage:page atIndex:0];
|
|
|
-//
|
|
|
-// NSSavePanel *savePanel = [NSSavePanel savePanel];
|
|
|
-// savePanel.allowedFileTypes = @[@"pdf"];
|
|
|
-// [savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
|
|
|
-// if (result) {
|
|
|
-// if ([pdfDocument writeToURL:savePanel.URL]) {
|
|
|
-// [[NSWorkspace sharedWorkspace] selectFile:savePanel.URL.path
|
|
|
-// inFileViewerRootedAtPath:@""];
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }];
|
|
|
+ @objc func menuItemClick_ExportPDF(_ sender: NSMenuItem) {
|
|
|
+ guard let image = self.thumbnailWithSize(0) else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let document = CPDFDocument()
|
|
|
+ document?.km_insert(image: image, at: 0)
|
|
|
+
|
|
|
+ NSPanel.savePanel_pdf_success(self.window!, document: document) { url in
|
|
|
+ NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "")
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- func menuItemClick_ExportJPG(_ sender: NSMenuItem) {
|
|
|
-// NSImage * image = [self thumbnailWithSize:0.0];
|
|
|
-// NSData *data = image.TIFFRepresentation;
|
|
|
-// NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:data];
|
|
|
-// [imageRep setSize:image.size];
|
|
|
-// NSData *imageData = [imageRep representationUsingType:NSJPEGFileType properties:@{}];
|
|
|
-//
|
|
|
-// NSSavePanel *savePanel = [NSSavePanel savePanel];
|
|
|
-// savePanel.allowedFileTypes = @[@"jpg"];
|
|
|
-// [savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
|
|
|
-// if (result) {
|
|
|
-// if ([imageData writeToURL:savePanel.URL atomically:YES]) {
|
|
|
-// [[NSWorkspace sharedWorkspace] selectFile:savePanel.URL.path
|
|
|
-// inFileViewerRootedAtPath:@""];
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }];
|
|
|
- }
|
|
|
-
|
|
|
- func menuItemClick_Copy(_ sender: AnyObject?) {
|
|
|
-// NSPasteboardItem *pasteboardItem = [[[NSPasteboardItem alloc] init] autorelease];
|
|
|
-// NSImage * image = [self thumbnailWithSize:0.0];
|
|
|
-// NSData *tiffData = [image TIFFRepresentation];
|
|
|
-// if (tiffData) {
|
|
|
-// [pasteboardItem setData:tiffData forType:NSPasteboardTypeTIFF];
|
|
|
-// if (pasteboardItem){
|
|
|
-// NSPasteboard *pboard = [NSPasteboard generalPasteboard];
|
|
|
-// [pboard clearContents];
|
|
|
-//
|
|
|
-// [pboard writeObjects:[NSArray arrayWithObject:pasteboardItem]];
|
|
|
-// }
|
|
|
-// }
|
|
|
+ @objc func menuItemClick_ExportJPG(_ sender: NSMenuItem) {
|
|
|
+ guard let image = self.thumbnailWithSize(0) else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ NSPanel.savePanel_data_success(self.window!, imageData: image.jpgData(), allowedTypes: ["jpg"]) { url in
|
|
|
+ NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func menuItemClick_Copy(_ sender: AnyObject?) {
|
|
|
+ guard let image = self.thumbnailWithSize(0) else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if let tiffData = image.tiffRepresentation {
|
|
|
+ let pasteboardItem = NSPasteboardItem()
|
|
|
+ pasteboardItem.setData(tiffData, forType: .tiff)
|
|
|
+ let pboard = NSPasteboard.general
|
|
|
+ pboard.clearContents()
|
|
|
+ pboard.writeObjects([pasteboardItem])
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- func menuItemClick_ExportPNG(_ sender: NSMenuItem) {
|
|
|
-// NSImage * image = [self thumbnailWithSize:0.0];
|
|
|
-//
|
|
|
-// NSData *data = image.TIFFRepresentation;
|
|
|
-// NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:data];
|
|
|
-// [imageRep setSize:image.size];
|
|
|
-// NSData *imageData = [imageRep representationUsingType:NSPNGFileType properties:@{}];
|
|
|
-//
|
|
|
-// NSSavePanel *savePanel = [NSSavePanel savePanel];
|
|
|
-// savePanel.allowedFileTypes = @[@"png"];
|
|
|
-// [savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
|
|
|
-// if (result) {
|
|
|
-// if ([imageData writeToURL:savePanel.URL atomically:YES]) {
|
|
|
-// [[NSWorkspace sharedWorkspace] selectFile:savePanel.URL.path
|
|
|
-// inFileViewerRootedAtPath:@""];
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }];
|
|
|
+ @objc func menuItemClick_ExportPNG(_ sender: NSMenuItem) {
|
|
|
+ guard let image = self.thumbnailWithSize(0) else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ NSPanel.savePanel_data_success(self.window!, imageData: image.pngData(), allowedTypes: ["png"]) { url in
|
|
|
+ NSWorkspace.shared.selectFile(url.path, inFileViewerRootedAtPath: "")
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// MARK: - Private Methods
|
|
@@ -495,14 +485,10 @@ extension KMSnapshotPDFView {
|
|
|
self.autoFitPage = nil
|
|
|
self.autoFitRect = .zero
|
|
|
|
|
|
-// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:)
|
|
|
-// name:NSViewFrameDidChangeNotification object:self];
|
|
|
-// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewFrameChangedNotification:)
|
|
|
-// name:NSViewBoundsDidChangeNotification object:self];
|
|
|
-// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFContentViewFrameChangedNotification:)
|
|
|
-// name:NSViewBoundsDidChangeNotification object:[[self scrollView] contentView]];
|
|
|
-// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFContentViewFrameChangedDelayedNotification:)
|
|
|
-// name:SKPDFContentViewChangedNotification object:self];
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(handlePDFViewFrameChangedNotification), name: NSView.frameDidChangeNotification, object: self)
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(handlePDFViewFrameChangedNotification), name: NSView.boundsDidChangeNotification, object: self)
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(handlePDFContentViewFrameChangedNotification), name: NSView.boundsDidChangeNotification, object: self.documentView()?.contentView)
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(handlePDFContentViewFrameChangedDelayedNotification), name: NSNotification.Name(SKPDFContentViewChangedNotification), object: self)
|
|
|
// if ([PDFView instancesRespondToSelector:@selector(magnifyWithEvent:)] == NO || [PDFView instanceMethodForSelector:@selector(magnifyWithEvent:)] == [NSView instanceMethodForSelector:@selector(magnifyWithEvent:)])
|
|
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePDFViewScaleChangedNotification:)
|
|
|
// name:PDFViewScaleChangedNotification object:self];
|
|
@@ -580,10 +566,9 @@ extension KMSnapshotPDFView {
|
|
|
|
|
|
private func _resetAutoFitRectIfNeeded() {
|
|
|
if self.autoFits {
|
|
|
- let clipView = self.enclosingScrollView?.contentView
|
|
|
+ let clipView = self.documentView().contentView
|
|
|
self.autoFitPage = self.currentPage()
|
|
|
-// autoFitRect = [self convertRect:[self convertRect:[clipView visibleRect] fromView:clipView] toPage:autoFitPage];
|
|
|
- let rect = self.convert(clipView?.visibleRect ?? .zero, from: clipView)
|
|
|
+ let rect = self.convert(clipView.visibleRect, from: clipView)
|
|
|
self.autoFitRect = self.convert(rect, to: self.autoFitPage)
|
|
|
}
|
|
|
}
|
|
@@ -598,3 +583,23 @@ extension KMSnapshotPDFView {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+extension KMSnapshotPDFView: NSMenuItemValidation {
|
|
|
+ func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
|
|
|
+ if (menuItem.action == #selector(doAutoFit)) {
|
|
|
+ menuItem.state = self.autoFits ? .on : .off
|
|
|
+ return true
|
|
|
+ } else if (menuItem.action == #selector(doActualSize)) {
|
|
|
+ menuItem.state = fabs(self.scaleFactor - 1.0) < 0.1 ? .on : .off
|
|
|
+ return true
|
|
|
+ }
|
|
|
+// else if (menuItem.action == #selector(doPhysicalSize)) {
|
|
|
+// [menuItem setState:([self autoScales] || fabs([self physicalScaleFactor] - 1.0 ) > 0.01) ? NSOffState : NSOnState];
|
|
|
+// return true
|
|
|
+// }
|
|
|
+// } else if ([[SKSnapshotPDFView superclass] instancesRespondToSelector:_cmd]) {
|
|
|
+// return [super validateMenuItem:menuItem];
|
|
|
+// }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+}
|