Browse Source

【菜单】- 幻灯片选项

liujiajie 1 year ago
parent
commit
9e68e3a45f
19 changed files with 2208 additions and 3 deletions
  1. 1 0
      PDF Office/PDF Master/Class/ChromiumTabs/src/third_party/mozilla/NSString+Utils.h
  2. 23 0
      PDF Office/PDF Master/Class/ChromiumTabs/src/third_party/mozilla/NSString+Utils.m
  3. 56 0
      PDF Office/PDF Master/Class/Common/OC/KMTransitionController/NSGraphics_SKExtensions.h
  4. 155 0
      PDF Office/PDF Master/Class/Common/OC/KMTransitionController/NSGraphics_SKExtensions.m
  5. 100 0
      PDF Office/PDF Master/Class/Common/OC/KMTransitionController/SKTransitionController.h
  6. 604 0
      PDF Office/PDF Master/Class/Common/OC/KMTransitionController/SKTransitionController.m
  7. 4 0
      PDF Office/PDF Master/Class/DigtalSignature/CPDFDigtalView/Event/NSEvent+PDFListView.h
  8. 9 0
      PDF Office/PDF Master/Class/DigtalSignature/CPDFDigtalView/Event/NSEvent+PDFListView.m
  9. 417 0
      PDF Office/PDF Master/Class/PDFWindowController/MainWindowController/SKPresentationOptionsSheetController.swift
  10. 346 0
      PDF Office/PDF Master/Class/PDFWindowController/MainWindowController/TransitionSheet.xib
  11. 36 2
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMBotaTableView.swift
  12. 80 0
      PDF Office/PDF Master/Class/PDFWindowController/Tools/KMTransitionInfo.swift
  13. 267 0
      PDF Office/PDF Master/Class/PDFWindowController/Tools/SKTypeSelectHelper.swift
  14. 26 0
      PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMScroller.swift
  15. 5 0
      PDF Office/PDF Master/PDF_Reader_Pro DMG-Bridging-Header.h
  16. 5 0
      PDF Office/PDF Master/PDF_Reader_Pro Edition-Bridging-Header.h
  17. 5 0
      PDF Office/PDF Master/PDF_Reader_Pro-Bridging-Header.h
  18. 68 0
      PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj
  19. 1 1
      PDF Office/PDF Reader Pro.xcodeproj/xcshareddata/xcschemes/PDF Reader Pro Edition.xcscheme

+ 1 - 0
PDF Office/PDF Master/Class/ChromiumTabs/src/third_party/mozilla/NSString+Utils.h

@@ -73,6 +73,7 @@ typedef enum
 - (NSString *)stringByTrimmingWhitespace;
 - (NSString *)stringByRemovingAmpEscapes;
 - (NSString *)stringByAddingAmpEscapes;
+- (BOOL)containsStringStartingAtWord:(NSString *)string options:(NSInteger)mask range:(NSRange)range;
 
 @end
 

+ 23 - 0
PDF Office/PDF Master/Class/ChromiumTabs/src/third_party/mozilla/NSString+Utils.m

@@ -204,6 +204,29 @@
 	return [NSString stringWithString:dirtyStringMutant];
 }
 
+- (BOOL)containsStringStartingAtWord:(NSString *)string options:(NSInteger)mask range:(NSRange)range {
+    NSUInteger stringLength = [string length];
+    if (stringLength == 0 || stringLength > range.length)
+        return NO;
+    while (range.length >= stringLength) {
+        NSRange r = [self rangeOfString:string options:mask range:range];
+        if (r.location == NSNotFound)
+            return NO;
+        // see if we start at a "word boundary"
+        if (r.location == 0 || [[NSCharacterSet alphanumericCharacterSet] characterIsMember:[self characterAtIndex:r.location - 1]] == NO)
+            return YES;
+        // if it's anchored, we only should search once
+        if (mask & NSAnchoredSearch)
+            return NO;
+        // get the new range, shifted by one from the last match
+        if (mask & NSBackwardsSearch)
+            range = NSMakeRange(range.location, NSMaxRange(r) - range.location - 1);
+        else
+            range = NSMakeRange(r.location + 1, NSMaxRange(range) - r.location - 1);
+    }
+    return NO;
+}
+
 @end
 
 

+ 56 - 0
PDF Office/PDF Master/Class/Common/OC/KMTransitionController/NSGraphics_SKExtensions.h

@@ -0,0 +1,56 @@
+//
+//  NSGraphics_SKExtensions.h
+//  Skim
+//
+//  Created by Christiaan Hofman on 10/20/11.
+/*
+ This software is Copyright (c) 2011-2018
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+extern void SKDrawResizeHandle(CGContextRef context, NSPoint point, CGFloat radius, BOOL active);
+extern void SKDrawResizeHandles(CGContextRef context, NSRect rect, CGFloat radius, BOOL active);
+
+#pragma mark -
+
+void SKDrawTextFieldBezel(NSRect rect, NSView *controlView);
+
+#pragma mark -
+
+extern void SKShiftAndResizeViews(NSArray *views, CGFloat dx, CGFloat dw);
+extern void SKShiftAndResizeView(NSView *view, CGFloat dx, CGFloat dw);
+void SKResizeWindow(NSWindow *window, CGFloat dw);
+extern void SKAutoSizeButtons(NSArray *buttons, BOOL rightAlign);
+extern CGFloat SKAutoSizeLabelFields(NSArray *labelFields, NSArray *controls, BOOL resizeControls);
+extern CGFloat SKAutoSizeLabelField(NSControl *labelField, NSControl *control, BOOL resizeControls);

+ 155 - 0
PDF Office/PDF Master/Class/Common/OC/KMTransitionController/NSGraphics_SKExtensions.m

@@ -0,0 +1,155 @@
+//
+//  NSGraphics_SKExtensions.m
+//  Skim
+//
+//  Created by Christiaan Hofman on 10/20/11.
+/*
+ This software is Copyright (c) 2011-2018
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "NSGraphics_SKExtensions.h"
+//#import "NSGeometry_SKExtensions.h"
+//#import "NSColor_SKExtensions.h"
+
+
+void SKDrawResizeHandle(CGContextRef context, NSPoint point, CGFloat radius, BOOL active)
+{
+    CGRect rect = CGRectMake(point.x - radius, point.y - radius, 2 * radius, 2 * radius);
+    NSColor *color = [[(active ? [NSColor colorWithRed:37/255.0 green:139/255.0 blue:251/255.0 alpha:1] : [NSColor secondarySelectedControlColor]) colorUsingColorSpaceName:NSCalibratedRGBColorSpace] colorWithAlphaComponent:1];
+    CGContextSetFillColorWithColor(context, [color CGColor]);
+    CGContextSetStrokeColorWithColor(context, [[NSColor whiteColor] CGColor]);
+    CGContextSetLineWidth(context, 0.25 * radius);
+    CGContextFillEllipseInRect(context, rect);
+    CGContextStrokeEllipseInRect(context, CGRectInset(rect, -0.25 *radius, -0.25 * radius));
+}
+
+void SKDrawResizeHandles(CGContextRef context, NSRect rect, CGFloat radius, BOOL active)
+{
+    SKDrawResizeHandle(context, NSMakePoint(NSMinX(rect), NSMidY(rect)), radius, active);
+    SKDrawResizeHandle(context, NSMakePoint(NSMidX(rect), NSMaxY(rect)), radius, active);
+    SKDrawResizeHandle(context, NSMakePoint(NSMidX(rect), NSMinY(rect)), radius, active);
+    SKDrawResizeHandle(context, NSMakePoint(NSMaxX(rect), NSMidY(rect)), radius, active);
+    SKDrawResizeHandle(context, NSMakePoint(NSMinX(rect), NSMaxY(rect)), radius, active);
+    SKDrawResizeHandle(context, NSMakePoint(NSMinX(rect), NSMinY(rect)), radius, active);
+    SKDrawResizeHandle(context, NSMakePoint(NSMaxX(rect), NSMaxY(rect)), radius, active);
+    SKDrawResizeHandle(context, NSMakePoint(NSMaxX(rect), NSMinY(rect)), radius, active);
+}
+
+#pragma mark -
+
+void SKDrawTextFieldBezel(NSRect rect, NSView *controlView) {
+    static NSTextFieldCell *cell = nil;
+    if (cell == nil) {
+        cell = [[NSTextFieldCell alloc] initTextCell:@""];
+        [cell setBezeled:YES];
+    }
+    [[NSColor controlColor] setFill];
+    NSRectFill(rect);
+    [cell drawWithFrame:rect inView:controlView];
+    [cell setControlView:nil];
+}
+
+#pragma mark -
+
+#define MIN_BUTTON_WIDTH 82.0
+#define MAX_BUTTON_WIDTH 100.0
+#define EXTRA_BUTTON_WIDTH 12.0
+
+void SKShiftAndResizeViews(NSArray *views, CGFloat dx, CGFloat dw) {
+    for (NSView *view in views)
+       SKShiftAndResizeView(view, dx, dw);
+}
+
+void SKShiftAndResizeView(NSView *view, CGFloat dx, CGFloat dw) {
+    NSRect frame = [view frame];
+    frame.origin.x += dx;
+    frame.size.width += dw;
+    [view setFrame:frame];
+}
+
+void SKResizeWindow(NSWindow *window, CGFloat dw) {
+    NSRect frame = [window frame];
+    frame.size.width += dw;
+    [window setFrame:frame display:NO];
+}
+
+void SKAutoSizeButtons(NSArray *buttons, BOOL rightAlign) {
+    if ([buttons count] == 0)
+        return;
+    NSButton *button = [buttons objectAtIndex:0];
+    CGFloat x = rightAlign ? NSMaxX([button frame]) : NSMinX([button frame]);
+    CGFloat width = 0.0;
+    for (button in buttons) {
+        [button sizeToFit];
+        width = fmax(width, NSWidth([button frame]) + EXTRA_BUTTON_WIDTH);
+    }
+    width = fmin(MAX_BUTTON_WIDTH, fmax(MIN_BUTTON_WIDTH, width));
+    for (button in buttons) {
+        NSRect frame = [button frame];
+        frame.size.width = fmax(width, NSWidth(frame) + EXTRA_BUTTON_WIDTH);
+        if (rightAlign) {
+            x -= NSWidth(frame);
+            frame.origin.x = x;
+        } else {
+            frame.origin.x = x;
+            x += NSWidth(frame);
+        }
+        [button setFrame:frame];
+    }
+}
+
+CGFloat SKAutoSizeLabelFields(NSArray *labelFields, NSArray *controls, BOOL resizeControls) {
+    if ([labelFields count] == 0)
+        return 0.0;
+    NSControl *control;
+    NSRect frame;
+    CGFloat left = CGFLOAT_MAX, width = 0.0, right, dw = -NSMaxX([[labelFields lastObject] frame]);
+    for (control in labelFields) {
+        [control sizeToFit];
+        frame = [control frame];
+        left = fmin(left, NSMinX(frame));
+        width = fmax(width, NSWidth(frame));
+    }
+    right = left + width;
+    for (control in labelFields) {
+        frame = [control frame];
+        frame.origin.x = right - NSWidth(frame);
+        [control setFrame:frame];
+    }
+    dw += right;
+    SKShiftAndResizeViews(controls, dw, resizeControls ? -dw : 0.0);
+    return dw;
+}
+
+extern CGFloat SKAutoSizeLabelField(NSControl *labelField, NSControl *control, BOOL resizeControls) {
+    return SKAutoSizeLabelFields([NSArray arrayWithObjects:labelField, nil], [NSArray arrayWithObjects:control, nil], resizeControls);
+}

+ 100 - 0
PDF Office/PDF Master/Class/Common/OC/KMTransitionController/SKTransitionController.h

@@ -0,0 +1,100 @@
+//
+//  SKTransitionController.h
+//  Skim
+//
+//  Created by Christiaan Hofman on 7/15/07.
+/*
+ This software is Copyright (c) 2007-2018
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+extern NSString *SKStyleNameKey;
+extern NSString *SKDurationKey;
+extern NSString *SKShouldRestrictKey;
+
+// this corresponds to the CGSTransitionType enum
+typedef NS_ENUM(NSUInteger, SKAnimationTransitionStyle) {
+	SKNoTransition,
+    // Core Graphics transitions
+	SKTransitionFade,
+	SKTransitionZoom,
+	SKTransitionReveal,
+	SKTransitionSlide,
+	SKTransitionWarpFade,
+	SKTransitionSwap,
+	SKTransitionCube,
+	SKTransitionWarpSwitch,
+	SKTransitionWarpFlip,
+    // Core Image transitions
+    SKCoreImageTransition
+};
+
+@class CIImage;
+
+@interface SKTransitionController : NSObject {
+    NSWindow *window;
+    CIImage *initialImage;
+    NSRect imageRect;
+    
+    SKAnimationTransitionStyle transitionStyle;
+    CGFloat duration;
+    BOOL shouldRestrict;
+    
+    SKAnimationTransitionStyle currentTransitionStyle;
+    CGFloat currentDuration;
+    BOOL currentShouldRestrict;
+    BOOL currentForward;
+    
+    NSArray *pageTransitions;
+}
+
+@property (nonatomic, strong) NSView *view;
+@property (nonatomic) SKAnimationTransitionStyle transitionStyle;
+@property (nonatomic) CGFloat duration;
+@property (nonatomic) BOOL shouldRestrict;
+@property (nonatomic, copy) NSArray *pageTransitions;
+@property (nonatomic) BOOL hasTransition;
+
++ (NSArray *)transitionNames;
+
++ (NSString *)nameForStyle:(SKAnimationTransitionStyle)style;
++ (SKAnimationTransitionStyle)styleForName:(NSString *)name;
+
++ (NSString *)localizedNameForStyle:(SKAnimationTransitionStyle)style;
+
+- (id)initForView:(NSView *)aView;
+
+- (void)prepareAnimationForRect:(NSRect)rect from:(NSUInteger)fromIndex to:(NSUInteger)toIndex;
+- (void)animateForRect:(NSRect)rect;
+
+@end

+ 604 - 0
PDF Office/PDF Master/Class/Common/OC/KMTransitionController/SKTransitionController.m

@@ -0,0 +1,604 @@
+//
+//  SKTransitionController.m
+//  Skim
+//
+//  Created by Christiaan Hofman on 7/15/07.
+/*
+ This software is Copyright (c) 2007-2018
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+/*
+ This code is based partly on Apple's AnimatingTabView example code
+ and Ankur Kothari's AnimatingTabsDemo application <http://dev.lipidity.com>
+*/
+
+#import "SKTransitionController.h"
+#import "NSBitmapImageRep_SKExtensions.h"
+//#import "NSView_SKExtensions.h"
+#import <CoreFoundation/CoreFoundation.h>
+#import <Quartz/Quartz.h>
+#include <unistd.h>
+#import <OpenGL/OpenGL.h>
+#import <OpenGL/gl.h>
+
+NSString *SKStyleNameKey = @"styleName";
+NSString *SKDurationKey = @"duration";
+NSString *SKShouldRestrictKey = @"shouldRestrict";
+
+#define kCIInputBacksideImageKey @"inputBacksideImage"
+#define kCIInputRectangleKey @"inputRectangle"
+
+#define WEAK_NULL NULL
+
+#pragma mark Private Core Graphics types and functions
+
+typedef int CGSConnection;
+typedef int CGSWindow;
+
+typedef enum _CGSTransitionType {
+    CGSNone,
+    CGSFade,
+    CGSZoom,
+    CGSReveal,
+    CGSSlide,
+    CGSWarpFade,
+    CGSSwap,
+    CGSCube,
+    CGSWarpSwitch,
+    CGSFlip
+} CGSTransitionType;
+
+typedef enum _CGSTransitionOption {
+    CGSDown,
+    CGSLeft,
+    CGSRight,
+    CGSInRight,
+    CGSBottomLeft = 5,
+    CGSBottomRight,
+    CGSDownTopRight,
+    CGSUp,
+    CGSTopLeft,
+    CGSTopRight,
+    CGSUpBottomRight,
+    CGSInBottom,
+    CGSLeftBottomRight,
+    CGSRightBottomLeft,
+    CGSInBottomRight,
+    CGSInOut
+} CGSTransitionOption;
+
+typedef struct _CGSTransitionSpec {
+    uint32_t unknown1;
+    CGSTransitionType type;
+    CGSTransitionOption option;
+    CGSWindow wid; // Can be 0 for full-screen
+    float *backColour; // Null for black otherwise pointer to 3 CGFloat array with RGB value
+} CGSTransitionSpec;
+
+extern CGSConnection _CGSDefaultConnection(void) __attribute__((weak_import));
+
+extern OSStatus CGSNewTransition(const CGSConnection cid, const CGSTransitionSpec* spec, int *pTransitionHandle) __attribute__((weak_import));
+extern OSStatus CGSInvokeTransition(const CGSConnection cid, int transitionHandle, float duration) __attribute__((weak_import));
+extern OSStatus CGSReleaseTransition(const CGSConnection cid, int transitionHandle) __attribute__((weak_import));
+
+#pragma mark Check whether the above functions are actually defined at run time
+
+static BOOL CoreGraphicsServicesTransitionsDefined() {
+    return _CGSDefaultConnection != WEAK_NULL &&
+           CGSNewTransition != WEAK_NULL &&
+           CGSInvokeTransition != WEAK_NULL &&
+           CGSReleaseTransition != WEAK_NULL;
+}
+
+#define SDK_BEFORE(_version) (!defined(MAC_OS_X_VERSION_ ## _version) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_ ## _version)
+
+#pragma mark -
+
+typedef void(^SKTransitionAnimationProgressHandler)(CGFloat);
+
+@interface SKTransitionAnimation : NSAnimation {
+    SKTransitionAnimationProgressHandler progressHandler;
+}
+@property (nonatomic, copy) SKTransitionAnimationProgressHandler progressHandler;
+@end
+
+#pragma mark -
+
+#if SDK_BEFORE(10_7)
+@interface NSOpenGLView (SKLionDeclarations)
+- (BOOL)wantsBestResolutionOpenGLSurface;
+- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
+@end
+#endif
+
+@interface SKTransitionView : NSOpenGLView {
+    CIImage *image;
+    CGFloat imageScale;
+    CIContext *context;
+    BOOL needsReshape;
+}
+@property (nonatomic, retain) CIImage *image;
+@property (nonatomic) CGFloat imageScale;
+@end
+
+#pragma mark -
+
+@implementation SKTransitionController
+
+@synthesize view, transitionStyle, duration, shouldRestrict, pageTransitions;
+@dynamic hasTransition;
+
++ (NSArray *)transitionNames {
+    static NSArray *transitionNames = nil;
+    
+    if (transitionNames == nil) {
+        transitionNames = [NSArray arrayWithObjects:
+            @"", 
+            @"CoreGraphics SKTransitionFade", 
+            @"CoreGraphics SKTransitionZoom", 
+            @"CoreGraphics SKTransitionReveal", 
+            @"CoreGraphics SKTransitionSlide", 
+            @"CoreGraphics SKTransitionWarpFade", 
+            @"CoreGraphics SKTransitionSwap", 
+            @"CoreGraphics SKTransitionCube", 
+            @"CoreGraphics SKTransitionWarpSwitch", 
+            @"CoreGraphics SKTransitionWarpFlip", nil];
+        // get all the transition filters
+		[CIPlugIn loadAllPlugIns];
+        transitionNames = [[transitionNames arrayByAddingObjectsFromArray:[CIFilter filterNamesInCategory:kCICategoryTransition]] copy];
+    }
+    
+    return transitionNames;
+}
+
++ (NSString *)nameForStyle:(SKAnimationTransitionStyle)style {
+    if (style > SKNoTransition && style < [[self transitionNames] count])
+        return [[self transitionNames] objectAtIndex:style];
+    else
+        return nil;
+}
+
++ (SKAnimationTransitionStyle)styleForName:(NSString *)name {
+    NSUInteger idx = [[self transitionNames] indexOfObject:name];
+    return idx == NSNotFound ? SKNoTransition : idx;
+}
+
++ (NSString *)localizedNameForStyle:(SKAnimationTransitionStyle)style {
+    switch (style) {
+        case SKNoTransition:         return NSLocalizedString(@"No Transition", @"Transition name");
+        case SKTransitionFade:       return NSLocalizedString(@"Fade", @"Transition name");
+        case SKTransitionZoom:       return NSLocalizedString(@"Zoom", @"Transition name");
+        case SKTransitionReveal:     return NSLocalizedString(@"Reveal", @"Transition name");
+        case SKTransitionSlide:      return NSLocalizedString(@"Slide", @"Transition name");
+        case SKTransitionWarpFade:   return NSLocalizedString(@"Warp Fade", @"Transition name");
+        case SKTransitionSwap:       return NSLocalizedString(@"Swap", @"Transition name");
+        case SKTransitionCube:       return NSLocalizedString(@"Cube", @"Transition name");
+        case SKTransitionWarpSwitch: return NSLocalizedString(@"Warp Switch", @"Transition name");
+        case SKTransitionWarpFlip:   return NSLocalizedString(@"Flip", @"Transition name");
+        default:                     return [CIFilter localizedNameForFilterName:[self nameForStyle:style]];
+    };
+}
+
+- (id)initForView:(NSView *)aView {
+    self = [super init];
+    if (self) {
+        view = aView; // don't retain as it may retain us
+        imageRect = NSZeroRect;
+        
+        transitionStyle = SKNoTransition;
+        duration = 1.0;
+        shouldRestrict = YES;
+        currentTransitionStyle = SKNoTransition;
+        currentDuration = 1.0;
+        currentShouldRestrict = YES;
+        currentForward = YES;
+    }
+    return self;
+}
+
+- (void)dealloc {
+    view = nil;
+   
+}
+
+- (NSRect)convertRectToScreen:(NSRect)rect view:(NSView *)view{
+    rect = [view convertRect:rect toView:nil];
+    rect.origin = [[view window] convertBaseToScreen:rect.origin];
+    return rect;
+}
+
+- (BOOL)hasTransition {
+    return transitionStyle != SKNoTransition || pageTransitions != nil;
+}
+
+static inline CGRect scaleRect(NSRect rect, CGFloat scale) {
+    return CGRectMake(scale * NSMinX(rect), scale * NSMinY(rect), scale * NSWidth(rect), scale * NSHeight(rect));
+}
+
+// rect and bounds are in pixels
+- (CIFilter *)transitionFilterForRect:(CGRect)rect bounds:(CGRect)bounds forward:(BOOL)forward initialCIImage:(CIImage *)initialCIImage finalCIImage:(CIImage *)finalCIImage {
+    NSString *filterName = [[self class] nameForStyle:currentTransitionStyle];
+    CIFilter *transitionFilter = [CIFilter filterWithName:filterName];
+    
+    [transitionFilter setDefaults];
+    
+    for (NSString *key in [transitionFilter inputKeys]) {
+        id value = nil;
+        if ([key isEqualToString:kCIInputExtentKey]) {
+            CGRect extent = currentShouldRestrict ? rect : bounds;
+            value = [CIVector vectorWithX:CGRectGetMinX(extent) Y:CGRectGetMinY(extent) Z:CGRectGetWidth(extent) W:CGRectGetHeight(extent)];
+        } else if ([key isEqualToString:kCIInputAngleKey]) {
+            CGFloat angle = forward ? 0.0 : M_PI;
+            if ([filterName isEqualToString:@"CIPageCurlTransition"] || [filterName isEqualToString:@"CIPageCurlWithShadowTransition"])
+                angle = forward ? -M_PI_4 : -3.0 * M_PI_4;
+            value = [NSNumber numberWithDouble:angle];
+        } else if ([key isEqualToString:kCIInputCenterKey]) {
+            value = [CIVector vectorWithX:CGRectGetMidX(rect) Y:CGRectGetMidY(rect)];
+        } else if ([key isEqualToString:kCIInputImageKey]) {
+            value = initialCIImage;
+            if (CGRectEqualToRect(rect, bounds) == NO)
+                value = [value imageByCroppingToRect:rect];
+        } else if ([key isEqualToString:kCIInputTargetImageKey]) {
+            value = finalCIImage;
+            if (CGRectEqualToRect(rect, bounds) == NO)
+                value = [value imageByCroppingToRect:rect];
+        } else if ([key isEqualToString:kCIInputShadingImageKey]) {
+            static CIImage *inputShadingImage = nil;
+            if (inputShadingImage == nil)
+                inputShadingImage = [[CIImage alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"TransitionShading" withExtension:@"tiff"]];
+            value = inputShadingImage;
+        } else if ([key isEqualToString:kCIInputBacksideImageKey]) {
+            value = initialCIImage;
+            if (CGRectEqualToRect(rect, bounds) == NO)
+                value = [value imageByCroppingToRect:rect];
+        } else if ([[[[transitionFilter attributes] objectForKey:key] objectForKey:kCIAttributeClass] isEqualToString:@"CIImage"]) {
+            // Scale and translate our mask image to match the transition area size.
+            static CIImage *inputMaskImage = nil;
+            if (inputMaskImage == nil)
+                inputMaskImage = [[CIImage alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"TransitionMask" withExtension:@"jpg"]];
+            CGRect extent = [inputMaskImage extent];
+            CGAffineTransform transform;
+            if ((CGRectGetWidth(extent) < CGRectGetHeight(extent)) != (CGRectGetWidth(rect) < CGRectGetHeight(rect))) {
+                transform = CGAffineTransformMake(0.0, 1.0, 1.0, 0.0, 0.0, 0.0);
+                transform = CGAffineTransformTranslate(transform, CGRectGetMinY(rect) - CGRectGetMinY(bounds), CGRectGetMinX(rect) - CGRectGetMinX(bounds));
+                transform = CGAffineTransformScale(transform, CGRectGetHeight(rect) / CGRectGetWidth(extent), CGRectGetWidth(rect) / CGRectGetHeight(extent));
+            } else {
+                transform = CGAffineTransformMakeTranslation(CGRectGetMinX(rect) - CGRectGetMinX(bounds), CGRectGetMinY(rect) - CGRectGetMinY(bounds));
+                transform = CGAffineTransformScale(transform, CGRectGetWidth(rect) / CGRectGetWidth(extent), CGRectGetHeight(rect) / CGRectGetHeight(extent));
+            }
+            value = [inputMaskImage imageByApplyingTransform:transform];
+        } else continue;
+        [transitionFilter setValue:value forKey:key];
+    }
+    
+    return transitionFilter;
+}
+
+- (CIImage *)newCurrentImage {
+    NSRect bounds = [view bounds];
+    NSBitmapImageRep *contentBitmap = [view bitmapImageRepForCachingDisplayInRect:bounds];
+    
+    [contentBitmap clear];
+    [view cacheDisplayInRect:bounds toBitmapImageRep:contentBitmap];
+    
+    return [[CIImage alloc] initWithBitmapImageRep:contentBitmap];
+}
+
+- (SKTransitionView *)transitionViewForRect:(NSRect)rect image:(CIImage *)image scale:(CGFloat)imageScale {
+    SKTransitionView *transitionView = nil;
+    
+    if (window == nil) {
+        transitionView = [[SKTransitionView alloc] init];
+        if ([transitionView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)])
+            [transitionView setWantsBestResolutionOpenGLSurface:YES];
+        window = [[NSWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+        [window setReleasedWhenClosed:NO];
+        [window setIgnoresMouseEvents:YES];
+        [window setContentView:transitionView];
+    } else {
+        transitionView = (SKTransitionView *)[window contentView];
+    }
+    
+    [transitionView setImageScale:imageScale];
+    [transitionView setImage:image];
+    [transitionView setNeedsDisplay:YES];
+    
+    [window setFrame:[self convertRectToScreen:rect view:view] display:NO];
+    [window orderBack:nil];
+    [[view window] addChildWindow:window ordered:NSWindowAbove];
+    
+    return transitionView;
+}
+
+- (void)prepareAnimationForRect:(NSRect)rect from:(NSUInteger)fromIndex to:(NSUInteger)toIndex {
+    currentTransitionStyle = transitionStyle;
+    currentDuration = duration;
+    currentShouldRestrict = shouldRestrict;
+    currentForward = (toIndex >= fromIndex);
+    
+    NSUInteger idx = MIN(fromIndex, toIndex);
+    if (fromIndex != NSNotFound && toIndex != NSNotFound && idx < [pageTransitions count]) {
+        NSDictionary *info = [pageTransitions objectAtIndex:idx];
+        id value;
+        if ((value = [info objectForKey:SKStyleNameKey]))
+            currentTransitionStyle = [[self class] styleForName:value];
+        if ((value = [info objectForKey:SKDurationKey]) && [value respondsToSelector:@selector(doubleValue)])
+            currentDuration = [value doubleValue];
+        if ((value = [info objectForKey:SKShouldRestrictKey]) && [value respondsToSelector:@selector(boolValue)])
+            currentShouldRestrict = [value boolValue];
+    }
+    
+	if (currentTransitionStyle >= SKCoreImageTransition) {
+        initialImage = [self newCurrentImage];
+        // We don't want the window to draw the next state before the animation is run
+        [[view window] disableFlushWindow];
+    } else if (currentTransitionStyle > SKNoTransition && CoreGraphicsServicesTransitionsDefined()) {
+        if (currentShouldRestrict) {
+            initialImage = [self newCurrentImage];
+        }
+        // We don't want the window to draw the next state before the animation is run
+        [[view window] disableFlushWindow];
+    }
+    imageRect = rect;
+}
+
+- (void)animateUsingCoreGraphics {
+    CIImage *finalImage = nil;
+    NSWindow *viewWindow = [view window];
+    SKTransitionView *transitionView = nil;
+    
+    if (currentShouldRestrict) {
+        NSRect bounds = [view bounds];
+        CGFloat imageScale = CGRectGetWidth([initialImage extent]) / NSWidth(bounds);
+        
+        finalImage = [self newCurrentImage];
+        
+        CGAffineTransform transform = CGAffineTransformMakeTranslation(-imageScale * NSMinX(imageRect), -imageScale * NSMinY(imageRect));
+        initialImage = [initialImage imageByApplyingTransform:transform];
+        finalImage = [finalImage imageByApplyingTransform:transform];
+        
+        transitionView = [self transitionViewForRect:imageRect image:initialImage scale:imageScale];
+        initialImage = nil;
+    }
+    
+    // declare our variables  
+    int handle = -1;
+    CGSTransitionSpec spec;
+    // specify our specifications
+    spec.unknown1 = 0;
+    spec.type =  currentTransitionStyle;
+    spec.option = currentForward ? CGSLeft : CGSRight;
+    spec.backColour = NULL;
+    spec.wid = [(currentShouldRestrict ? window : viewWindow) windowNumber];
+    
+    // Let's get a connection
+    CGSConnection cgs = _CGSDefaultConnection();
+    
+    // Create a transition
+    CGSNewTransition(cgs, &spec, &handle);
+    
+    if (currentShouldRestrict) {
+        [transitionView setImage:finalImage];
+        [transitionView display];
+    }
+    
+    // Redraw the window
+    [viewWindow display];
+    // Remember we disabled flushing in the previous method, we need to balance that.
+    [viewWindow enableFlushWindow];
+    [viewWindow flushWindow];
+    
+    CGSInvokeTransition(cgs, handle, currentDuration);
+    // We need to wait for the transition to finish before we get rid of it, otherwise we'll get all sorts of nasty errors... or maybe not.
+    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:currentDuration]];
+    
+    CGSReleaseTransition(cgs, handle);
+    handle = 0;
+    
+    if (currentShouldRestrict) {
+        [viewWindow removeChildWindow:window];
+        [window orderOut:nil];
+        [transitionView setImage:nil];
+    }
+}
+
+- (void)animateUsingCoreImage {
+    NSRect bounds = [view bounds];
+    CGFloat imageScale = CGRectGetWidth([initialImage extent]) / NSWidth(bounds);
+    
+    CIImage *finalImage = [self newCurrentImage];
+    
+    CIFilter *transitionFilter = [self transitionFilterForRect:scaleRect(imageRect, imageScale) bounds:scaleRect(bounds, imageScale) forward:currentForward initialCIImage:initialImage finalCIImage:finalImage];
+    
+    SKTransitionView *transitionView = [self transitionViewForRect:bounds image:initialImage scale:imageScale];
+    
+    initialImage = nil;
+    
+    SKTransitionAnimation *animation = [[SKTransitionAnimation alloc] initWithDuration:currentDuration animationCurve:NSAnimationEaseInOut];
+    [animation setProgressHandler:^(CGFloat value){
+            [transitionFilter setValue:[NSNumber numberWithDouble:value] forKey:kCIInputTimeKey];
+            [transitionView setImage:[transitionFilter valueForKey:kCIOutputImageKey]];
+            [transitionView display];
+        }];
+    [animation startAnimation];
+    
+    // Update the view and its window, so it shows the correct state when it is shown.
+    [view display];
+    // Remember we disabled flushing in the previous method, we need to balance that.
+    NSWindow *viewWindow = [view window];
+    [viewWindow enableFlushWindow];
+    [viewWindow flushWindow];
+    
+    [viewWindow removeChildWindow:window];
+    [window orderOut:nil];
+    [transitionView setImage:nil];
+}
+
+- (void)animateForRect:(NSRect)rect  {
+    if (NSEqualRects(imageRect, NSZeroRect))
+        [self prepareAnimationForRect:rect from:NSNotFound to:NSNotFound];
+    imageRect = NSIntegralRect(NSIntersectionRect(NSUnionRect(imageRect, rect), [view bounds]));
+	
+    if (currentTransitionStyle >= SKCoreImageTransition)
+        [self animateUsingCoreImage];
+	else if (currentTransitionStyle > SKNoTransition && CoreGraphicsServicesTransitionsDefined())
+        [self animateUsingCoreGraphics];
+    
+    currentTransitionStyle = transitionStyle;
+    currentDuration = duration;
+    currentShouldRestrict = shouldRestrict;
+    currentForward = YES;
+    
+    imageRect = NSZeroRect;
+}
+
+@end
+
+#pragma mark -
+
+@implementation SKTransitionAnimation
+
+@synthesize progressHandler;
+
+- (void)dealloc {
+    progressHandler = nil;
+}
+
+- (void)setCurrentProgress:(NSAnimationProgress)progress {
+    [super setCurrentProgress:progress];
+    if (progressHandler) progressHandler([self currentValue]);
+}
+
+@end
+
+#pragma mark -
+
+@implementation SKTransitionView
+
+@synthesize image, imageScale;
+
++ (NSOpenGLPixelFormat *)defaultPixelFormat {
+    static NSOpenGLPixelFormat *pf;
+
+    if (pf == nil) {
+        NSOpenGLPixelFormatAttribute attr[] = {
+            NSOpenGLPFAAccelerated,
+            NSOpenGLPFANoRecovery,
+            NSOpenGLPFAColorSize,
+            32,
+            0
+        };
+        
+        pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
+    }
+
+    return pf;
+}
+
+- (void)dealloc {
+    
+}
+
+- (void)reshape	{
+    needsReshape = YES;
+}
+
+- (void)prepareOpenGL {
+    // Enable beam-synced updates.
+    GLint parm = 1;
+    [[self openGLContext] setValues:&parm forParameter:NSOpenGLCPSwapInterval];
+    
+    // Make sure that everything we don't need is disabled.
+    // Some of these are enabled by default and can slow down rendering.
+    
+    glDisable(GL_ALPHA_TEST);
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_SCISSOR_TEST);
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    glDisable(GL_CULL_FACE);
+    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    glDepthMask(GL_FALSE);
+    glStencilMask(0);
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST);
+    
+    needsReshape = YES;
+}
+
+- (CGFloat)backingScaleNew {
+    if ([self respondsToSelector:@selector(convertSizeToBacking:)])
+        return [self convertSizeToBacking:NSMakeSize(1.0, 1.0)].width;
+    return 1.0;
+}
+
+- (void)updateMatrices {
+    NSRect bounds = [self bounds];
+    CGFloat scale = ([self respondsToSelector:@selector(wantsBestResolutionOpenGLSurface)] && [self wantsBestResolutionOpenGLSurface]) ? [self backingScaleNew] : 1.0;
+    
+    [[self openGLContext] update];
+    
+    glViewport(0, 0, scale * NSWidth(bounds), scale * NSHeight(bounds));
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(scale * NSMinX(bounds), scale * NSMaxX(bounds), scale * NSMinY(bounds), scale * NSMaxY(bounds), -1, 1);
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    
+    needsReshape = NO;
+}
+
+- (void)drawRect:(NSRect)rect {
+    [[self openGLContext] makeCurrentContext];
+    
+    if (needsReshape)
+        [self updateMatrices];
+    
+    glClearColor(0.0, 0.0, 0.0, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    if (image) {
+        CGFloat scale = ([self respondsToSelector:@selector(wantsBestResolutionOpenGLSurface)] && [self wantsBestResolutionOpenGLSurface]) ? [self backingScaleNew] : 1.0;
+        NSRect bounds = [self bounds];
+        if (context == nil) {
+            NSOpenGLPixelFormat *pf = [self pixelFormat] ?: [[self class] defaultPixelFormat];
+            context = [CIContext contextWithCGLContext:CGLGetCurrentContext() pixelFormat:[pf CGLPixelFormatObj] colorSpace:nil options:nil];
+        }
+        [context drawImage:image inRect:scaleRect(bounds, scale) fromRect:scaleRect(bounds, imageScale)];
+    }
+    
+    glFlush();
+}
+
+@end

+ 4 - 0
PDF Office/PDF Master/Class/DigtalSignature/CPDFDigtalView/Event/NSEvent+PDFListView.h

@@ -22,6 +22,10 @@
 
 - (unichar)PDFListViewFirstCharacter;
 
+- (NSUInteger)deviceIndependentModifierFlags;
+- (unichar)firstCharacter;
+
+
 + (NSPointingDeviceType)currentPointingDeviceType;
 + (void)setCurrentPointingDeviceType:(NSPointingDeviceType)newCurrentPointingDeviceType;
 

+ 9 - 0
PDF Office/PDF Master/Class/DigtalSignature/CPDFDigtalView/Event/NSEvent+PDFListView.m

@@ -33,6 +33,15 @@ static NSPointingDeviceType currentPointingDeviceType = NSUnknownPointingDevice;
     return [characters length] > 0 ? [characters characterAtIndex:0] : 0;
 }
 
+- (NSUInteger)deviceIndependentModifierFlags {
+    return [self modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
+}
+
+- (unichar)firstCharacter {
+    NSString *characters = [self charactersIgnoringModifiers];
+    return [characters length] > 0 ? [characters characterAtIndex:0] : 0;
+}
+
 + (NSPointingDeviceType)currentPointingDeviceType {
     return currentPointingDeviceType;
 }

+ 417 - 0
PDF Office/PDF Master/Class/PDFWindowController/MainWindowController/SKPresentationOptionsSheetController.swift

@@ -0,0 +1,417 @@
+//
+//  SKPresentationOptionsSheetController.swift
+//  PDF Reader Pro
+//
+//  Created by liujiajie on 2024/1/17.
+//
+
+import Cocoa
+
+let RIGHTARROW_CHARACTER: unichar = 0x2192
+
+let PAGE_COLUMNID = "page" 
+let IMAGE_COLUMNID = "image"
+let TRANSITIONSTYLE_KEY = "transitionStyle" 
+let DURATION_KEY = "duration"
+let SHOULDRESTRICT_KEY = "shouldRestrict"
+let PROPERTIES_KEY = "properties"
+let CONTENTOBJECT_BINDINGNAME = "contentObject"
+let MAX_PAGE_COLUMN_WIDTH: CGFloat = 100.0
+let TABLE_OFFSET: CGFloat = 8.0
+var SKTransitionPropertiesObservationContext = UnsafeMutableRawPointer(mutating: "SKTransitionPropertiesObservationContext")
+var SKPDFViewTransitionsObservationContext: CChar?
+
+class SKPresentationOptionsSheetController: NSWindowController, NSWindowDelegate, KMBotaTableViewDelegate, NSTableViewDataSource, NSTableViewDelegate{
+    @IBOutlet var notesDocumentPopUpButton: NSPopUpButton!
+    @IBOutlet var tableView: KMBotaTableView!
+    @IBOutlet var separateCheckButton: NSButton!
+    @IBOutlet var boxes, transitionLabels, transitionControls, buttons: NSArray!
+    @IBOutlet var arrayController: NSArrayController!
+    var separate = false{
+        willSet{
+            if newValue != separate {
+//                SKImageToolTipWindow.sharedToolTipWindow().orderOut(nil)
+                
+                let window = self.window
+                let isVisible = window?.isVisible ?? false
+                var frame = window?.frame ?? NSRect.zero
+                let scrollView = tableView?.enclosingScrollView
+                var extraWidth: CGFloat
+                var firstResponder = window?.firstResponder
+                var editor: NSTextView? = nil
+                
+                if let textView = firstResponder as? NSTextView {
+                    editor = textView
+                    if textView.isFieldEditor {
+//                        firstResponder = textView.delegate
+                    }
+                }
+                
+                if arrayController.commitEditing(), let editor = editor, window?.firstResponder != editor {
+                    window?.makeFirstResponder(firstResponder)
+                }
+                
+                if separate {
+                    makeTransitions()
+                    
+                    extraWidth = (scrollView?.frame.width ?? 0) + TABLE_OFFSET
+                    frame.size.width += extraWidth
+                    frame.origin.x -= floor(0.5 * extraWidth)
+                    window?.setFrame(frame, display: isVisible, animate: isVisible)
+                    scrollView?.isHidden = false
+                } else {
+                    scrollView?.isHidden = true
+                    extraWidth = (scrollView?.frame.width ?? 0) + TABLE_OFFSET
+                    frame.size.width -= extraWidth
+                    frame.origin.x += floor(0.5 * extraWidth)
+                    window?.setFrame(frame, display: isVisible, animate: isVisible)
+                }
+
+//                (undoRedoManager.prepare(withInvocationTarget: self) as AnyObject).separate = sparate == fasle
+            }
+        }
+        didSet{
+            
+        }
+    }
+    var transition: KMTransitionInfo!
+    var transitions: NSArray?{
+        willSet{
+            if newValue != transitions {
+//                (undoRedoManager?.prepare(withInvocationTarget: self) as AnyObject).transitions = transitions
+                stopObservingTransitions(infos: transitions as! [KMTransitionInfo])
+                startObservingTransitions(transitions as! [KMTransitionInfo])
+            }
+        }
+        didSet{
+            
+        }
+    }
+    var currentTransitions: NSArray?{
+        get{
+            return separate ? transitions : [transition as Any]
+        }
+        set{
+            
+        }
+    }
+    var pageTransitions: NSArray?{
+        get{
+            if separate && transitions?.count ?? 0 > 0 {
+                return [transitions?.value(forKey: PROPERTIES_KEY) as Any]
+            } else {
+                return nil
+            }
+        }
+        set{
+            
+        }
+    }
+    var notesDocument: NSDocument?{
+        get{
+            return notesDocumentPopUpButton.selectedItem?.representedObject as? NSDocument
+        }
+        set{
+            
+        }
+    }
+    var isScrolling: Bool{
+        get{
+            if let scroller = tableView?.enclosingScrollView?.verticalScroller as? KMScroller {
+                return scroller.isScrolling
+            }
+            return false
+        }
+        set{
+            
+        }
+    }
+    var undoRedoManager = UndoManager()
+    var controller: MainWindowController?
+    var transitionController: SKTransitionController!
+    
+    class func keyPathsForValuesAffectingCurrentTransitions() -> Set<String> { 
+        return Set<String>(["separate", "transitions", "transition"])
+    }
+    
+    convenience init(for aController: MainWindowController) {
+        self.init()
+        controller = aController
+        separate = false
+        transition = KMTransitionInfo()
+        transitions = nil
+    }
+    
+    @objc func handleDocumentsDidChangeNotification(notification: Notification?) {
+        guard let currentDoc = notesDocumentPopUpButton.selectedItem?.representedObject else { return }
+        while notesDocumentPopUpButton.numberOfItems > 1 {
+            notesDocumentPopUpButton.removeItem(at: notesDocumentPopUpButton.numberOfItems - 1)
+        }
+
+        guard let document = controller?.mainViewController?.document as? NSDocument,
+              let pageCount = controller?.mainViewController.listView.document?.pageCount else { return }
+
+        var documents = NSMutableArray()
+        for doc in NSDocumentController.shared.documents {
+            if let pdfDoc = doc as? CPDFDocument,
+                doc != document,
+                pdfDoc.pageCount == pageCount {
+                documents.add(doc)
+            }
+        }
+
+        let sortDescriptor = NSSortDescriptor(key: "displayName", ascending: true)
+        documents.sort(using: [sortDescriptor])
+
+        for doc in documents {
+            notesDocumentPopUpButton.addItem(withTitle: (doc as AnyObject).displayName)
+            notesDocumentPopUpButton.lastItem?.representedObject = doc
+        }
+
+        let docIndex = notesDocumentPopUpButton.indexOfItem(withRepresentedObject: currentDoc)
+        notesDocumentPopUpButton.selectItem(at: docIndex == -1 ? 0 : docIndex)
+    }
+    
+    func stopObservingTransitions(infos: [KMTransitionInfo]) {
+        for info in infos {
+            info.removeObserver(self, forKeyPath: TRANSITIONSTYLE_KEY) 
+            info.removeObserver(self, forKeyPath: DURATION_KEY)
+            info.removeObserver(self, forKeyPath: SHOULDRESTRICT_KEY)
+        }
+    }
+    
+    func creatTransitionController() {
+        transitionController = SKTransitionController(for: controller?.mainViewController.listView)//controller?.mainViewController.listView.transitionController
+        let options: NSKeyValueObservingOptions = [.new, .old]
+        transitionController?.addObserver(self, forKeyPath: "transitionStyle", options: options, context: &SKPDFViewTransitionsObservationContext)
+        transitionController?.addObserver(self, forKeyPath: "duration", options: options, context: &SKPDFViewTransitionsObservationContext)
+        transitionController?.addObserver(self, forKeyPath: "shouldRestrict", options: options, context: &SKPDFViewTransitionsObservationContext)
+        transitionController?.addObserver(self, forKeyPath: "pageTransitions", options: options, context: &SKPDFViewTransitionsObservationContext)
+    }
+    
+    override func windowDidLoad() {
+        super.windowDidLoad()
+        
+        let count = SKTransitionController.transitionNames().count
+        let transitionStylePopUpButton = transitionControls[0] as! NSPopUpButton
+        transitionStylePopUpButton.removeAllItems()
+        for i in 0..<count {
+            transitionStylePopUpButton.addItem(withTitle: SKTransitionController.localizedName(for: SKAnimationTransitionStyle(rawValue: UInt(i)) ?? .noTransition))
+            transitionStylePopUpButton.lastItem?.tag = i
+        }
+
+        notesDocumentPopUpButton.item(at: 0)?.title = NSLocalizedString("None", comment: "Menu item title")
+
+        creatTransitionController()
+        transition.transitionStyle = transitionController?.transitionStyle ?? .noTransition
+        transition.duration = Float(transitionController?.duration ?? 0)
+        transition.shouldRestrict = transitionController?.shouldRestrict ?? false
+        startObservingTransitions([transition])
+
+        separateCheckButton.sizeToFit()
+//        transitionControls.lastObject.sizeToFit()
+
+        SKAutoSizeButtons(buttons as? [Any], true)
+
+        let dw = SKAutoSizeLabelFields(transitionLabels as? [Any], transitionControls as? [Any], false)
+
+        if abs(dw) > 0.0 {
+            SKResizeWindow(window, dw)
+            SKShiftAndResizeViews(boxes as? [Any], -dw, dw)
+            SKShiftAndResizeView(separateCheckButton, -dw, 0.0)
+        }
+
+        // collapse the table
+        window?.setFrame(NSInsetRect(window?.frame ?? .zero, 0.5 * (NSWidth(tableView.enclosingScrollView!.frame) + TABLE_OFFSET), 0.0), display: false)
+
+        tableView.registerForDraggedTypes(KMTransitionInfo.readableTypesForPasteboard(pasteboard: NSPasteboard(name: NSPasteboard.Name.drag)) as! [NSPasteboard.PasteboardType])
+        
+        tableView.delegate = self
+        tableView.dataSource = self
+        tableView.botaDelegate = self
+
+        tableView.setTypeSelectHelper(SKTypeSelectHelper(matchOption: .SKFullStringMatch))
+
+        tableView.hasImageToolTips = true
+
+        tableView.backgroundColor = NSColor.mainSourceListBackgroundColor()
+
+        if (transitionController?.pageTransitions != nil && transitionController?.pageTransitions.count ?? 0 > 0) {
+            undoManager?.disableUndoRegistration()
+            separate = true
+            undoManager?.enableUndoRegistration()
+        }
+
+        // set the current notes document and observe changes for the popup
+        handleDocumentsDidChangeNotification(notification: nil)
+        let docIndex = notesDocumentPopUpButton.indexOfItem(withRepresentedObject: controller?.mainViewController.myDocument/*presentationNotesDocument*/)
+        notesDocumentPopUpButton.selectItem(at: docIndex > 0 ? docIndex : 0)
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(handleDocumentsDidChangeNotification(notification:)), name: NSNotification.Name("SKDocumentDidShowNotification"), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(handleDocumentsDidChangeNotification(notification:)), name: NSNotification.Name("SKDocumentControllerDidRemoveDocumentNotification"), object: nil)
+    }
+    
+    func startObservingTransitions(_ infos: [KMTransitionInfo]) {
+        for info in infos {
+            info.addObserver(self, forKeyPath: TRANSITIONSTYLE_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
+            info.addObserver(self, forKeyPath: DURATION_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
+            info.addObserver(self, forKeyPath: SHOULDRESTRICT_KEY, options: [.new, .old], context: &SKTransitionPropertiesObservationContext)
+        }
+    }
+    
+    func makeTransitions() { if transitions != nil { return }
+        let tableColumn = tableView?.tableColumn(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: PAGE_COLUMNID))
+        let cell = tableColumn?.dataCell
+        var labelWidth: CGFloat = 0.0
+        
+        var array = [Any]()
+        let dictionary = transition?.properties
+        let arr: NSArray = transitionController.pageTransitions! as NSArray
+        let ptEnum = arr.objectEnumerator()
+        var tn: KMThumbnail? = nil
+        
+        for next in (controller?.mainViewController.leftSideViewController.thumbnails)! {
+            if tn != nil {
+                let info = KMTransitionInfo()
+                info.thumbnail = tn
+                info.label = "\(tn!.label)\(RIGHTARROW_CHARACTER)\(next.label)"
+                info.properties = ptEnum.nextObject() as! NSDictionary
+                array.append(info)
+                (cell as AnyObject).setStringValue(info.label)
+                labelWidth = max(labelWidth, ceil(((cell as AnyObject).cellSize?.width)!))
+            }
+            tn = next
+        }
+        
+        labelWidth = min(labelWidth, MAX_PAGE_COLUMN_WIDTH)
+        tableColumn?.minWidth = labelWidth
+        tableColumn?.maxWidth = labelWidth
+        tableColumn?.width = labelWidth
+        
+        var frame: NSRect = tableView?.enclosingScrollView?.frame ?? .zero
+        let wi: CGFloat = tableColumn?.value(forKeyPath: "@sum.width") as! CGFloat
+        frame.size.width = 19.0 + wi
+        tableView?.enclosingScrollView?.frame = frame
+        
+        transitions = array as NSArray
+    }
+    override var windowNibName: NSNib.Name?{
+        return "TransitionSheet"
+    }
+   
+    override func dismissController(_ sender: Any?) {
+//        SKImageToolTipWindow.sharedToolTipWindow().orderOut(nil)
+        if (sender as? NSButton)?.tag == 0 {
+            super.dismissController(sender)
+        } else if arrayController.commitEditing() {
+            if ((undoManager?.canUndo) != nil) {
+                transitionController?.transitionStyle = transition?.transitionStyle ?? .noTransition
+                transitionController?.duration = CGFloat(transition?.duration ?? 0)
+                transitionController?.shouldRestrict = transition?.shouldRestrict ?? false
+                transitionController?.pageTransitions = pageTransitions as? [Any]
+                (controller?.undoManager)?.setActionName(NSLocalizedString("Change Transitions", comment: "Undo action name"))
+            }
+            controller?.mainViewController.myDocument/*presentationNotesDocument*/ = notesDocument
+            super.dismissController(sender)
+        }
+    }
+    func windowWillReturnUndoManager(_ window: NSWindow) -> UndoManager? {
+        return undoRedoManager
+    }
+    
+    func setValue(_ value: Any?, forKey key: String, ofTransition info: KMTransitionInfo) {
+        info.setValue(value, forKey: key)
+    }
+    override class func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
+        if context == &SKTransitionPropertiesObservationContext {
+            guard let info = object as? KMTransitionInfo else {
+                super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
+                return
+            }
+            let newValue = change?[.newKey]
+            let oldValue = change?[.oldKey]
+            
+            let newNonNullValue = newValue as? NSNull == nil ? newValue : nil
+            let oldNonNullValue = oldValue as? NSNull == nil ? oldValue : nil
+            
+//            if (newNonNullValue != nil || oldNonNullValue != nil) && newNonNullValue != oldNonNullValue {
+//                (undoManager?.prepare(withInvocationTarget: self) as AnyObject).setValue(oldNonNullValue, forKey: keyPath, ofTransition: info)
+//            }
+            if (newNonNullValue != nil || oldNonNullValue != nil){
+               
+            }
+        } else {
+            super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
+        }
+    }
+    func numberOfRows(in tableView: NSTableView) -> Int {
+        return 0
+    }
+    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
+        return nil
+    }
+    func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
+        if rowIndexes.count == 1 {
+            pboard.clearContents()
+            pboard.writeObjects([transitions?[rowIndexes.first ?? 0] as! NSPasteboardWriting])
+            return true
+        } else {
+            return false
+        }
+    }
+    
+    func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
+        if info.draggingPasteboard.canReadObject(forClasses: [KMTransitionInfo.self], options: [:]) {
+            if dropOperation == .above {
+                tableView.setDropRow(-1, dropOperation: .on)
+            }
+            return .every
+        }
+        return []
+    }
+   
+    func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
+        let pboard = info.draggingPasteboard
+        if dropOperation == .on {
+            guard let infos = pboard.readObjects(forClasses: [KMTransitionInfo.self], options: [:]) as? [KMTransitionInfo], infos.count > 0 else {
+                return false
+            }
+            let propertie: NSDictionary = infos[0].properties
+            
+            if row == -1 {
+                transitions?.setValue(propertie, forKey: PROPERTIES_KEY)
+            } else {
+                let transit: KMTransitionInfo = transitions?[row] as! KMTransitionInfo
+                transit.properties = propertie
+            }
+            return true
+        }
+        return false
+    }
+    func tableView(_ aTableView: NSTableView, imageContextForRow rowIndex: Int) -> AnyObject? {
+        return controller?.mainViewController.document?.page(at: UInt(rowIndex))
+    }
+    
+    func tableView(_ aTableView: NSTableView, copyRowsWithIndexes rowIndexes: IndexSet) {
+        let pboard = NSPasteboard.general
+        pboard.clearContents()
+        pboard.writeObjects([transitions?[rowIndexes.first ?? 0] as! NSPasteboardWriting])
+    }
+    func tableView(_ aTableView: NSTableView, canCopyRowsWithIndexes rowIndexes: IndexSet) -> Bool {
+        return true
+    }
+    func tableView(_ aTableView: NSTableView, pasteFromPasteboard pboard: NSPasteboard) {
+        guard let infos = pboard.readObjects(forClasses: [KMTransitionInfo.self], options: [:]) as? [KMTransitionInfo], infos.count > 0 else { return }
+        let arr: NSArray = transitions?.objects(at: tableView.selectedRowIndexes) as! NSArray
+        arr.setValue(infos[0].properties, forKey: PROPERTIES_KEY)
+    }
+    func tableView(_ aTableView: NSTableView, canPasteFromPasteboard pboard: NSPasteboard) -> Bool {
+        return (tableView.selectedRow != -1 && pboard.canReadObject(forClasses: [KMTransitionInfo.self], options: [:]))
+    }
+    func tableView(_ aTableView: NSTableView, typeSelectHelperSelectionStrings aTypeSelectHelper: SKTypeSelectHelper) -> NSArray {
+        return transitions?.value(forKeyPath: "thumbnail.label") as! NSArray
+    }
+}
+
+
+//

+ 346 - 0
PDF Office/PDF Master/Class/PDFWindowController/MainWindowController/TransitionSheet.xib

@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+    <dependencies>
+        <deployment version="1060" identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="SKPresentationOptionsSheetController" customModule="PDF_Reader_Pro" customModuleProvider="target">
+            <connections>
+                <outlet property="arrayController" destination="127" id="148"/>
+                <outlet property="boxes" destination="480" id="485"/>
+                <outlet property="buttons" destination="476" id="477"/>
+                <outlet property="notesDocumentPopUpButton" destination="69" id="99"/>
+                <outlet property="separateCheckButton" destination="138" id="346"/>
+                <outlet property="tableView" destination="279" id="287"/>
+                <outlet property="transitionControls" destination="466" id="475"/>
+                <outlet property="transitionLabels" destination="462" id="474"/>
+                <outlet property="window" destination="7" id="63"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="7" userLabel="SetupSheet" customClass="NSPanel">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES"/>
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+            <rect key="contentRect" x="282" y="439" width="426" height="280"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <value key="minSize" type="size" width="213" height="107"/>
+            <view key="contentView" id="8">
+                <rect key="frame" x="0.0" y="0.0" width="426" height="280"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <button tag="1" imageHugsTitle="YES" verticalHuggingPriority="750" id="27">
+                        <rect key="frame" x="330" y="12" width="82" height="32"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
+                        <buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" tag="1" inset="2" id="436">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+DQ
+</string>
+                        </buttonCell>
+                        <connections>
+                            <accessibilityConnection property="link" destination="31" id="461"/>
+                            <action selector="dismissSheet:" target="-2" id="490"/>
+                        </connections>
+                    </button>
+                    <button imageHugsTitle="YES" verticalHuggingPriority="750" id="31">
+                        <rect key="frame" x="248" y="12" width="82" height="32"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
+                        <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="437">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+Gw
+</string>
+                        </buttonCell>
+                        <connections>
+                            <action selector="dismissSheet:" target="-2" id="489"/>
+                        </connections>
+                    </button>
+                    <box borderType="line" id="67">
+                        <rect key="frame" x="123" y="120" width="286" height="118"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                        <view key="contentView" id="nHl-1V-Bnj">
+                            <rect key="frame" x="4" y="5" width="278" height="98"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                            <subviews>
+                                <textField verticalHuggingPriority="750" id="28">
+                                    <rect key="frame" x="216" y="42" width="50" height="22"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="442">
+                                        <numberFormatter key="formatter" formatterBehavior="custom10_4" positiveFormat="#,##0.0" negativeFormat="-#,##0.0" formatWidth="-1" minimumIntegerDigits="1" maximumIntegerDigits="2000000000" minimumFractionDigits="1" maximumFractionDigits="1" decimalSeparator="." groupingSeparator="," id="29">
+                                            <nil key="negativeInfinitySymbol"/>
+                                            <nil key="positiveInfinitySymbol"/>
+                                            <real key="minimum" value="0.0"/>
+                                        </numberFormatter>
+                                        <font key="font" metaFont="system"/>
+                                        <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                    </textFieldCell>
+                                    <connections>
+                                        <accessibilityConnection property="title" destination="25" id="48"/>
+                                        <binding destination="127" name="value" keyPath="selection.duration" id="504">
+                                            <dictionary key="options">
+                                                <real key="NSMultipleValuesPlaceholder" value="-1"/>
+                                                <real key="NSNoSelectionPlaceholder" value="-1"/>
+                                            </dictionary>
+                                        </binding>
+                                    </connections>
+                                </textField>
+                                <slider verticalHuggingPriority="750" id="30">
+                                    <rect key="frame" x="82" y="38" width="128" height="26"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <sliderCell key="cell" continuous="YES" alignment="left" maxValue="5" doubleValue="1" tickMarkPosition="above" numberOfTickMarks="6" sliderType="linear" id="443">
+                                        <font key="font" size="12" name="Helvetica"/>
+                                    </sliderCell>
+                                    <connections>
+                                        <accessibilityConnection property="link" destination="28" id="459"/>
+                                        <accessibilityConnection property="link" destination="10" id="460"/>
+                                        <accessibilityConnection property="title" destination="25" id="47"/>
+                                        <binding destination="127" name="value" keyPath="selection.duration" id="493"/>
+                                    </connections>
+                                </slider>
+                                <popUpButton imageHugsTitle="YES" verticalHuggingPriority="750" id="13">
+                                    <rect key="frame" x="81" y="68" width="188" height="26"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" id="439">
+                                        <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
+                                        <font key="font" metaFont="menu"/>
+                                        <menu key="menu" id="14"/>
+                                    </popUpButtonCell>
+                                    <connections>
+                                        <accessibilityConnection property="link" destination="30" id="458"/>
+                                        <accessibilityConnection property="title" destination="9" id="49"/>
+                                        <binding destination="127" name="selectedTag" keyPath="selection.transitionStyle" id="505">
+                                            <dictionary key="options">
+                                                <real key="NSMultipleValuesPlaceholder" value="-1"/>
+                                                <real key="NSNoSelectionPlaceholder" value="-1"/>
+                                            </dictionary>
+                                        </binding>
+                                    </connections>
+                                </popUpButton>
+                                <textField verticalHuggingPriority="750" id="9">
+                                    <rect key="frame" x="35" y="75" width="44" height="17"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Effect:" id="438">
+                                        <font key="font" metaFont="system"/>
+                                        <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                                    </textFieldCell>
+                                </textField>
+                                <textField verticalHuggingPriority="750" id="25">
+                                    <rect key="frame" x="15" y="44" width="64" height="17"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Duration:" id="440">
+                                        <font key="font" metaFont="system"/>
+                                        <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                                    </textFieldCell>
+                                </textField>
+                                <matrix verticalHuggingPriority="750" allowsEmptySelection="NO" autosizesCells="NO" id="10">
+                                    <rect key="frame" x="82" y="14" width="132" height="18"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                                    <size key="cellSize" width="64" height="18"/>
+                                    <size key="intercellSpacing" width="4" height="2"/>
+                                    <buttonCell key="prototype" type="radio" imagePosition="leading" alignment="left" inset="2" id="446">
+                                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                                        <font key="font" metaFont="system"/>
+                                    </buttonCell>
+                                    <cells>
+                                        <column>
+                                            <buttonCell type="radio" title="Screen" imagePosition="leading" alignment="left" state="on" inset="2" id="12">
+                                                <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                                                <font key="font" metaFont="system"/>
+                                                <connections>
+                                                    <accessibilityConnection property="title" destination="26" id="51"/>
+                                                </connections>
+                                            </buttonCell>
+                                        </column>
+                                        <column>
+                                            <buttonCell type="radio" title="Page" imagePosition="leading" alignment="left" tag="1" inset="2" id="11">
+                                                <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                                                <font key="font" metaFont="system"/>
+                                                <connections>
+                                                    <accessibilityConnection property="title" destination="26" id="52"/>
+                                                </connections>
+                                            </buttonCell>
+                                        </column>
+                                    </cells>
+                                    <connections>
+                                        <binding destination="127" name="selectedTag" keyPath="selection.shouldRestrict" id="506">
+                                            <dictionary key="options">
+                                                <real key="NSMultipleValuesPlaceholder" value="-1"/>
+                                                <real key="NSNoSelectionPlaceholder" value="-1"/>
+                                            </dictionary>
+                                        </binding>
+                                    </connections>
+                                </matrix>
+                                <textField verticalHuggingPriority="750" id="26">
+                                    <rect key="frame" x="30" y="15" width="49" height="17"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Extent:" id="441">
+                                        <font key="font" metaFont="system"/>
+                                        <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                        <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                                    </textFieldCell>
+                                </textField>
+                            </subviews>
+                        </view>
+                        <connections>
+                            <binding destination="127" name="displayPatternTitle2" keyPath="selection.label" previousBinding="512" id="513">
+                                <dictionary key="options">
+                                    <string key="NSDisplayPattern">%{title1}@ %{title2}@</string>
+                                </dictionary>
+                            </binding>
+                            <binding destination="127" name="displayPatternTitle1" keyPath="selection.title" id="512">
+                                <dictionary key="options">
+                                    <string key="NSDisplayPattern">%{title1}@ %{title2}@</string>
+                                </dictionary>
+                            </binding>
+                        </connections>
+                    </box>
+                    <box borderType="line" title="Synchronized Notes Document" id="68">
+                        <rect key="frame" x="123" y="56" width="286" height="60"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                        <view key="contentView" id="mnE-pI-3iK">
+                            <rect key="frame" x="4" y="5" width="278" height="40"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                            <subviews>
+                                <popUpButton imageHugsTitle="YES" verticalHuggingPriority="750" id="69">
+                                    <rect key="frame" x="15" y="10" width="242" height="26"/>
+                                    <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
+                                    <popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="81" id="444">
+                                        <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
+                                        <font key="font" metaFont="menu"/>
+                                        <menu key="menu" id="73">
+                                            <items>
+                                                <menuItem state="on" id="81"/>
+                                            </items>
+                                        </menu>
+                                    </popUpButtonCell>
+                                </popUpButton>
+                            </subviews>
+                        </view>
+                    </box>
+                    <button imageHugsTitle="YES" id="138">
+                        <rect key="frame" x="124" y="244" width="177" height="18"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                        <buttonCell key="cell" type="check" title="Distinct page transitions" bezelStyle="regularSquare" imagePosition="leading" alignment="left" inset="2" id="445">
+                            <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                            <font key="font" metaFont="system"/>
+                        </buttonCell>
+                        <connections>
+                            <binding destination="-2" name="value" keyPath="separate" id="143"/>
+                        </connections>
+                    </button>
+                    <scrollView hidden="YES" horizontalLineScroll="34" horizontalPageScroll="10" verticalLineScroll="34" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="276">
+                        <rect key="frame" x="20" y="20" width="98" height="240"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                        <clipView key="contentView" id="wPo-Zi-yxU">
+                            <rect key="frame" x="1" y="1" width="85" height="238"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                            <subviews>
+                                <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="32" id="279" customClass="KMBotaTableView" customModule="PDF_Reader_Pro" customModuleProvider="target">
+                                    <rect key="frame" x="0.0" y="0.0" width="85" height="238"/>
+                                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                    <size key="intercellSpacing" width="3" height="2"/>
+                                    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                    <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
+                                    <tableColumns>
+                                        <tableColumn identifier="image" editable="NO" width="32" minWidth="32" maxWidth="32" id="280">
+                                            <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+                                                <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                                <color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
+                                            </tableHeaderCell>
+                                            <imageCell key="dataCell" controlSize="small" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="283"/>
+                                            <connections>
+                                                <binding destination="127" name="value" keyPath="arrangedObjects.thumbnail.image" id="285"/>
+                                            </connections>
+                                        </tableColumn>
+                                        <tableColumn identifier="page" editable="NO" width="10" minWidth="10" maxWidth="1000" id="281">
+                                            <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
+                                                <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                                <color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
+                                            </tableHeaderCell>
+                                            <textFieldCell key="dataCell" controlSize="small" lineBreakMode="truncatingTail" alignment="left" id="282" customClass="SKCenteredTextFieldCell">
+                                                <font key="font" metaFont="smallSystem"/>
+                                                <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                            </textFieldCell>
+                                            <tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
+                                            <connections>
+                                                <binding destination="127" name="value" keyPath="arrangedObjects.label" id="397"/>
+                                            </connections>
+                                        </tableColumn>
+                                    </tableColumns>
+                                    <connections>
+                                        <outlet property="dataSource" destination="-2" id="311"/>
+                                        <outlet property="delegate" destination="-2" id="361"/>
+                                    </connections>
+                                </tableView>
+                            </subviews>
+                        </clipView>
+                        <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="448">
+                            <rect key="frame" x="-100" y="-100" width="128" height="15"/>
+                            <autoresizingMask key="autoresizingMask"/>
+                        </scroller>
+                        <scroller key="verticalScroller" verticalHuggingPriority="750" controlSize="small" horizontal="NO" id="447" userLabel="Vertical Scroller" customClass="SKScroller">
+                            <rect key="frame" x="86" y="1" width="11" height="238"/>
+                            <autoresizingMask key="autoresizingMask"/>
+                        </scroller>
+                    </scrollView>
+                </subviews>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="64"/>
+            </connections>
+            <point key="canvasLocation" x="117" y="-138"/>
+        </window>
+        <arrayController id="127" userLabel="Array Controller">
+            <declaredKeys>
+                <string>thumbnail.image</string>
+                <string>thumbnail.label</string>
+                <string>fromThumbnail.image</string>
+                <string>toThumbnail.image</string>
+                <string>fromThumbnail.label</string>
+                <string>nextThumbnail.image</string>
+                <string>label</string>
+                <string>title</string>
+            </declaredKeys>
+            <connections>
+                <binding destination="-2" name="contentArray" keyPath="currentTransitions" id="491"/>
+            </connections>
+        </arrayController>
+        <customObject id="462" userLabel="Transition Labels" customClass="SKIBArray">
+            <connections>
+                <outlet property="object1" destination="9" id="463"/>
+                <outlet property="object2" destination="25" id="464"/>
+                <outlet property="object3" destination="26" id="465"/>
+            </connections>
+        </customObject>
+        <customObject id="466" userLabel="Transition Controls" customClass="SKIBArray">
+            <connections>
+                <outlet property="object1" destination="13" id="470"/>
+                <outlet property="object2" destination="30" id="471"/>
+                <outlet property="object3" destination="28" id="472"/>
+                <outlet property="object4" destination="10" id="488"/>
+            </connections>
+        </customObject>
+        <customObject id="480" userLabel="Boxes" customClass="SKIBArray">
+            <connections>
+                <outlet property="object1" destination="67" id="486"/>
+                <outlet property="object2" destination="68" id="487"/>
+            </connections>
+        </customObject>
+        <customObject id="476" userLabel="Buttons" customClass="SKIBArray">
+            <connections>
+                <outlet property="object1" destination="27" id="478"/>
+                <outlet property="object2" destination="31" id="479"/>
+            </connections>
+        </customObject>
+    </objects>
+</document>

+ 36 - 2
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMBotaTableView.swift

@@ -31,9 +31,14 @@ import Cocoa
     @objc optional func tableViewMoveRight(_ aTableView: NSTableView)
     
     @objc optional func tableView(_ aTableView: NSTableView, imageContextForRow rowIndex: Int) -> AnyObject?
+    
+    @objc optional func tableView(_ aTableView: NSTableView, typeSelectHelperSelectionStrings aTypeSelectHelper: SKTypeSelectHelper) -> NSArray
+    @objc optional func tableView(_ aTableView: NSTableView, typeSelectHelper aTypeSelectHelper: SKTypeSelectHelper, didFailToFindMatchForSearchString searchString: String)
+    @objc optional func tableView(_ aTableView: NSTableView, typeSelectHelper aTypeSelectHelper: SKTypeSelectHelper, updateSearchString searchString: String)
 }
 
-class KMBotaTableView: NSTableView {
+class KMBotaTableView: NSTableView, SKTypeSelectHelperDelegate {
+   
     var kmTrackingAreas: NSMutableSet?
     
     /*
@@ -43,7 +48,7 @@ class KMBotaTableView: NSTableView {
      @property (nonatomic) supportsQuickLook;
      @property (nonatomic, retain) SKTypeSelectHelper *typeSelectHelper;
      */
-    
+    var typeSelectHelper: SKTypeSelectHelper?
     weak var botaDelegate: KMBotaTableViewDelegate? {
         didSet {
             self._rebuildTrackingAreas()
@@ -68,6 +73,14 @@ class KMBotaTableView: NSTableView {
         }
     }
     
+    func setTypeSelectHelper(_ newTypeSelectHelper: SKTypeSelectHelper) {
+        if typeSelectHelper != newTypeSelectHelper {
+            typeSelectHelper?.delegate = nil
+            typeSelectHelper = newTypeSelectHelper
+            typeSelectHelper?.delegate = self
+        }
+    }
+    
     override func draw(_ dirtyRect: NSRect) {
         super.draw(dirtyRect)
 
@@ -79,6 +92,7 @@ class KMBotaTableView: NSTableView {
         
         self._rebuildTrackingAreas()
 //        [typeSelectHelper rebuildTypeSelectSearchCache];
+        typeSelectHelper?.rebuildTypeSelectSearchCache()
     }
     
     // MARK: - Tracking
@@ -246,6 +260,26 @@ class KMBotaTableView: NSTableView {
             self.noteHeightOfRows(withIndexesChanged: IndexSet(0..<self.numberOfRows))
         }
     }
+    func typeSelectHelperSelectionStrings(_ typeSelectHelper: SKTypeSelectHelper) -> NSArray {
+        return self.botaDelegate?.tableView?(self, typeSelectHelperSelectionStrings: typeSelectHelper) ?? NSArray()
+    }
+    
+    func typeSelectHelperCurrentlySelectedIndex(_ typeSelectHelper: SKTypeSelectHelper) -> Int {
+        return self.selectedRowIndexes.last ?? 0
+    }
+    
+    func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, selectItemAtIndex itemIndex: Int) {
+        self.selectRowIndexes(NSIndexSet(index: itemIndex) as IndexSet, byExtendingSelection: false)
+        self.scrollRowToVisible(itemIndex)
+    }
+    
+    func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, didFailToFindMatchForSearchString searchString: String) {
+        self.botaDelegate?.tableView?(self, typeSelectHelper: typeSelectHelper, didFailToFindMatchForSearchString: searchString)
+    }
+    
+    func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, updateSearchString searchString: String) {
+        self.botaDelegate?.tableView?(self, typeSelectHelper: typeSelectHelper, updateSearchString: searchString)
+    }
     
     /*
      - (void)setTypeSelectHelper:(SKTypeSelectHelper *)newTypeSelectHelper {

+ 80 - 0
PDF Office/PDF Master/Class/PDFWindowController/Tools/KMTransitionInfo.swift

@@ -0,0 +1,80 @@
+//
+//  KMTransitionInfo.swift
+//  PDF Reader Pro
+//
+//  Created by liujiajie on 2024/1/17.
+//
+
+import Foundation
+
+let SKPasteboardTypeTransition = "net.sourceforge.skim-app.pasteboard.transition"
+
+class KMTransitionInfo: NSObject{
+  
+    var transitionStyle: SKAnimationTransitionStyle = .noTransition
+    var duration: Float = 0.0
+    var shouldRestrict = false
+    var thumbnail: KMThumbnail?
+    var label: String = ""
+    var title: String {return NSLocalizedString("Page Transition", comment: "Box title")}
+    
+    var properties: NSDictionary{
+        get{
+            return [SKStyleNameKey: SKTransitionController.name(for: transitionStyle) ?? "", SKDurationKey: NSNumber(value: duration), SKShouldRestrictKey: NSNumber(value: shouldRestrict)] as [String : Any] as NSDictionary
+        }
+        set{
+            if let value = newValue[SKStyleNameKey] {
+                transitionStyle = SKTransitionController.style(forName: value as? String)
+            }
+            if let value = newValue[SKDurationKey] {
+                duration = value as! Float
+            }
+            if let value = newValue[SKShouldRestrictKey] {
+                shouldRestrict = value as! Bool
+            }
+        }
+    }
+    override init() {
+        super.init()
+        transitionStyle = .noTransition
+        duration = 1.0
+        shouldRestrict = false
+        thumbnail = nil
+        label = ""
+    }
+    
+    init(propertyList: NSDictionary, ofType: String) {
+        super.init()
+        if ofType == SKPasteboardTypeTransition {
+            self.properties = propertyList
+        } else {
+            
+        }
+    }
+    
+    override var description: String {
+        return "<\(type(of: self)) \(Unmanaged.passUnretained(self).toOpaque())> \(properties)"
+    }
+    
+    class func readableTypesForPasteboard(pasteboard: NSPasteboard) -> NSArray {
+        return NSArray(objects: SKPasteboardTypeTransition)
+    }
+    
+    class func readingOptionsForType(type: String, pasteboard: NSPasteboard) -> NSPasteboard.ReadingOptions {
+        if type == SKPasteboardTypeTransition {
+            return .asPropertyList
+        }
+        return .asData
+    }
+    
+    func writableTypesForPasteboard(pasteboard: NSPasteboard) -> NSArray {
+        return NSArray(objects: SKPasteboardTypeTransition)
+    }
+    
+    func pasteboardPropertyListForType(type: String) -> Any? {
+        if type == SKPasteboardTypeTransition {
+            return properties
+        }
+        return nil
+    }
+}

+ 267 - 0
PDF Office/PDF Master/Class/PDFWindowController/Tools/SKTypeSelectHelper.swift

@@ -0,0 +1,267 @@
+//
+//  SKTypeSelectHelper.swift
+//  PDF Reader Pro
+//
+//  Created by liujiajie on 2024/1/17.
+//
+
+import Foundation
+
+let SKWindowDidChangeFirstResponderNotification = "SKWindowDidChangeFirstResponderNotification"
+let REPEAT_CHARACTER: unichar = 0x2F
+let CANCEL_CHARACTER: unichar = 0x1B
+
+@objc enum SKTypeSelectMatchOption: Int {
+    case SKPrefixMatch = 0
+    case SKSubstringMatch
+    case SKFullStringMatch
+}
+
+
+@objc protocol SKTypeSelectHelperDelegate {
+    @objc func typeSelectHelperSelectionStrings(_ typeSelectHelper: SKTypeSelectHelper) -> NSArray
+    @objc func typeSelectHelperCurrentlySelectedIndex(_ typeSelectHelper: SKTypeSelectHelper) -> Int
+    @objc func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, selectItemAtIndex itemIndex: Int)
+    
+    @objc optional func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, didFailToFindMatchForSearchString searchString: String)
+    @objc optional func typeSelectHelper(_ typeSelectHelper: SKTypeSelectHelper, updateSearchString searchString: String)
+}
+
+
+class SKTypeSelectHelper: NSObject, NSTextDelegate{
+    var delegate: SKTypeSelectHelperDelegate?
+    var matchOption: SKTypeSelectMatchOption?
+    var isProcessing = false
+    var searchString: String = ""
+    var timer: Timer?
+    lazy var searchCache: NSArray? = {
+        var cache: NSArray = (self.delegate?.typeSelectHelperSelectionStrings(self))!
+        return cache
+    }()
+    
+    deinit {
+        NotificationCenter.default.removeObserver(self)
+    }
+
+    class func typeSelectHelper() -> Any? {
+        return SKTypeSelectHelper()
+    }
+
+    class func typeSelectHelper(withMatchOption aMatchOption: SKTypeSelectMatchOption) -> Any? {
+        return SKTypeSelectHelper(matchOption: aMatchOption)
+    }
+   
+    init(matchOption aMatchOption: SKTypeSelectMatchOption) {
+        super.init()
+        delegate = nil
+        searchCache = nil
+        searchString = ""
+        matchOption = aMatchOption
+        isProcessing = false
+        timer = nil
+    }
+    convenience override init() {
+        self.init(matchOption: .SKPrefixMatch)
+    }
+    
+    func rebuildTypeSelectSearchCache() {
+        searchCache = nil
+    }
+    
+    func handleEvent(_ keyEvent: NSEvent) -> Bool { 
+        guard keyEvent.type == .keyDown else { return false }
+        if isSearchEvent(keyEvent) {
+            searchWithEvent(keyEvent)
+            return true
+        } else if isRepeatEvent(keyEvent: keyEvent) {
+            repeatSearch()
+            return true
+        } else if isCancelEvent(keyEvent: keyEvent) {
+            cancelSearch()
+            return true
+        }
+        
+        return false
+    }
+    func isSearchEvent(_ keyEvent: NSEvent) -> Bool {
+        let validModifierFlags: NSEvent.ModifierFlags = [.shift, .option, .capsLock, .numericPad]
+        let invalidCharacters = isProcessing ? NSCharacterSet.controlCharacters : NSCharacterSet.alphanumerics
+        let eventModifierFlags = keyEvent.modifierFlags.intersection(.deviceIndependentFlagsMask)
+        let isModifierValid = eventModifierFlags.isSubset(of: validModifierFlags)
+        
+        let characters = keyEvent.characters ?? ""
+        let range = characters.rangeOfCharacter(from: invalidCharacters)
+        let isCharacterValid = range == nil
+        
+        return isModifierValid && isCharacterValid
+    }
+    func searchWithEvent(_ keyEvent: NSEvent) {
+        guard let keyWin = NSApp.keyWindow else { return }
+        let fieldEditor = keyWin.fieldEditor(true, for: self)
+        
+        if !isProcessing {
+            NotificationCenter.default.removeObserver(self)
+            NotificationCenter.default.addObserver(self, selector: #selector(typeSelectCleanTimeout(_:)), name: NSNotification.Name(SKWindowDidChangeFirstResponderNotification), object: keyWin)
+            NotificationCenter.default.addObserver(self, selector: #selector(typeSelectCleanTimeout(_:)), name: NSWindow.didResignKeyNotification, object: keyWin)
+            NotificationCenter.default.addObserver(self, selector: #selector(typeSelectCleanTimeout(_:)), name: NSWindow.willCloseNotification, object: keyWin)
+            fieldEditor?.delegate = self
+            fieldEditor?.string = ""
+        }
+        
+        fieldEditor?.interpretKeyEvents([keyEvent])
+        searchString = fieldEditor?.string ?? ""
+        updateSearchString(searchString)
+        
+        startTimer(for: #selector(typeSelectSearchTimeout(_:)))
+        
+        if matchOption != .SKFullStringMatch {
+            searchWithStickyMatch(isProcessing)
+        }
+        
+        isProcessing = true
+    }
+    func isRepeatEvent(keyEvent: NSEvent) -> Bool {
+        return keyEvent.deviceIndependentModifierFlags() == 0 && keyEvent.firstCharacter() == REPEAT_CHARACTER
+    }
+    func isCancelEvent(keyEvent: NSEvent) -> Bool {
+        return isProcessing && keyEvent.deviceIndependentModifierFlags() == 0 && keyEvent.firstCharacter() == CANCEL_CHARACTER
+    }
+    func repeatSearch() {
+        searchWithStickyMatch(false)
+        if searchString.count > 0 {
+            updateSearchString(searchString)
+        }
+        startTimer(for: #selector(typeSelectCleanTimeout(_:)))
+        isProcessing = false
+    }
+    func cancelSearch() {
+        if let timer = timer {
+            typeSelectCleanTimeout(timer)
+        }
+    }
+    @objc func typeSelectCleanTimeout(_ sender: Any) {
+        updateSearchString("")
+        NotificationCenter.default.removeObserver(self)
+        stopTimer()
+        isProcessing = false
+        guard let keyWin = NSApp.keyWindow else {
+            return
+        }
+        
+        let fieldEditor = keyWin.fieldEditor(true, for: self)
+        
+        if fieldEditor?.delegate === self {
+            let dummyKeyEvent: NSEvent = NSEvent.keyEvent(with: .keyDown, location: .zero, modifierFlags: [], timestamp: 0, windowNumber: 0, context: nil, characters: "", charactersIgnoringModifiers: "", isARepeat: false, keyCode: 0) ?? NSEvent()
+            fieldEditor?.interpretKeyEvents([dummyKeyEvent])
+            fieldEditor?.delegate = nil
+        }
+    }
+    @objc func typeSelectSearchTimeout(_ sender: Any) {
+        if matchOption == .SKFullStringMatch {
+            searchWithStickyMatch(false)
+        }
+        typeSelectCleanTimeout(sender)
+    }
+    func updateSearchString(_ string: String) {
+        if self.delegate != nil{
+            self.delegate?.typeSelectHelper?(self, updateSearchString: string)
+        }
+    }
+    func startTimer(for selector: Selector) { 
+        stopTimer()
+        timer = Timer(fire: Date(timeIntervalSinceNow: timeoutInterval()), interval: 0, repeats: false) { [weak self] _ in
+            self?.perform(selector)
+        } 
+        RunLoop.current.add(timer!, forMode: .default)
+    }
+    func stopTimer() {
+        timer?.invalidate()
+        timer = nil
+    }
+    func timeoutInterval() -> TimeInterval {
+        let keyThreshTicks = UserDefaults.standard.integer(forKey: "InitialKeyRepeat")
+        let defaultKeyThreshTicks = 35
+        let actualKeyThreshTicks = keyThreshTicks != 0 ? keyThreshTicks : defaultKeyThreshTicks
+        
+        let interval = min(2.0 / 60.0 * Double(actualKeyThreshTicks), 2.0)
+        return interval
+    }
+    func searchWithStickyMatch(_ sticky: Bool) {
+        if searchString.isEmpty { return }
+        var selectedIndex: Int?
+        var startIndex: Int?
+        var foundIndex: Int?
+        
+        if matchOption != .SKFullStringMatch {
+            selectedIndex = delegate?.typeSelectHelperCurrentlySelectedIndex(self)
+            if selectedIndex ?? 0 >= searchCache?.count ?? 0 {
+                selectedIndex = nil
+            }
+        } else {
+            selectedIndex = nil
+        }
+        
+        startIndex = selectedIndex
+        if sticky && selectedIndex != nil {
+            startIndex = startIndex! > 0 ? startIndex! - 1 : (searchCache?.count ?? 0) - 1
+        }
+        
+        foundIndex = indexOfMatchedItemAfterIndex(startIndex ?? 0)
+        
+        if foundIndex == nil {
+            delegate?.typeSelectHelper?(self, didFailToFindMatchForSearchString: searchString)
+        } else if foundIndex != selectedIndex {
+            delegate?.typeSelectHelper(self, selectItemAtIndex: foundIndex!)
+        }
+    }
+    func indexOfMatchedItemAfterIndex(_ selectedIndex: Int) -> Int? {
+        let labelCount = searchCache?.count
+        if labelCount == 0 {
+            return nil
+        }
+        
+        var labelIndex = selectedIndex
+        var looped = false
+        var options: String.CompareOptions = [.caseInsensitive]
+        
+        if matchOption == .SKPrefixMatch {
+            options.insert(.anchored)
+        }
+        
+        while looped == false {
+            if labelIndex == labelCount {
+                labelIndex = 0
+                looped = true
+            }
+            
+            if labelIndex == selectedIndex {
+                looped = true
+            }
+            
+            let label: String = searchCache?[labelIndex] as! String
+            
+            if matchOption == .SKFullStringMatch {
+                if label.caseInsensitiveCompare(searchString) == .orderedSame {
+                    return labelIndex
+                }
+            } else {
+                let str: NSString = label as NSString
+                let labelRange = NSRange(location: 0, length: label.count)
+                if str.containsStarting(atWord: searchString, options: Int(options.rawValue), range: labelRange) {
+                    return labelIndex
+                }
+            }
+            
+            labelIndex += 1
+        }
+        
+        return nil
+    }
+}
+
+
+extension String{
+    func isCaseInsensitiveEqual(_ aString: NSString) -> Bool {
+        return self.caseInsensitiveCompare(aString as String) == .orderedSame
+    }
+}

+ 26 - 0
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMScroller.swift

@@ -0,0 +1,26 @@
+//
+//  KMScroller.swift
+//  PDF Reader Pro
+//
+//  Created by liujiajie on 2024/1/18.
+//
+
+import Cocoa
+
+class KMScroller: NSScroller{
+    var isScrolling = false
+    
+    override class var isCompatibleWithOverlayScrollers: Bool{
+        return true
+    }
+    
+    override func trackKnob(with event: NSEvent) {
+        isScrolling = true
+        super.trackKnob(with: event)
+        isScrolling = false
+        superview?.needsDisplay = true
+    }
+    
+}
+
+

+ 5 - 0
PDF Office/PDF Master/PDF_Reader_Pro DMG-Bridging-Header.h

@@ -85,3 +85,8 @@
 #import "KMPurchaseCompareDMGWindowController.h"
 #import "KMVerificationWindowController.h"
 #import "KMVerificationMessageViewController.h"
+
+#import "SKTransitionController.h"
+#import "NSGraphics_SKExtensions.h"
+#import "NSString+Utils.h"
+#import "NSEvent+PDFListView.h"

+ 5 - 0
PDF Office/PDF Master/PDF_Reader_Pro Edition-Bridging-Header.h

@@ -81,3 +81,8 @@
 #import "KMPurchaseCompareDMGWindowController.h"
 #import "KMVerificationWindowController.h"
 #import "KMVerificationMessageViewController.h"
+
+#import "SKTransitionController.h"
+#import "NSGraphics_SKExtensions.h"
+#import "NSString+Utils.h"
+#import "NSEvent+PDFListView.h"

+ 5 - 0
PDF Office/PDF Master/PDF_Reader_Pro-Bridging-Header.h

@@ -81,3 +81,8 @@
 #import "KMPurchaseCompareDMGWindowController.h"
 #import "KMVerificationWindowController.h"
 #import "KMVerificationMessageViewController.h"
+
+#import "SKTransitionController.h"
+#import "NSGraphics_SKExtensions.h"
+#import "NSString+Utils.h"
+#import "NSEvent+PDFListView.h"

+ 68 - 0
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -3351,6 +3351,9 @@
 		BB6013902AD3AFF000A76FB2 /* NSPopover+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB60138F2AD3AFF000A76FB2 /* NSPopover+KMExtension.swift */; };
 		BB6013912AD3AFF000A76FB2 /* NSPopover+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB60138F2AD3AFF000A76FB2 /* NSPopover+KMExtension.swift */; };
 		BB6013922AD3AFF000A76FB2 /* NSPopover+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB60138F2AD3AFF000A76FB2 /* NSPopover+KMExtension.swift */; };
+		BB61F2122B59120F00777E27 /* KMScroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB61F2112B59120F00777E27 /* KMScroller.swift */; };
+		BB61F2132B59120F00777E27 /* KMScroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB61F2112B59120F00777E27 /* KMScroller.swift */; };
+		BB61F2142B59120F00777E27 /* KMScroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB61F2112B59120F00777E27 /* KMScroller.swift */; };
 		BB6347AE2AF1F0A500F5438E /* KMBatchOperateConvertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB6347AD2AF1F0A400F5438E /* KMBatchOperateConvertViewController.swift */; };
 		BB6347B02AF1F0BB00F5438E /* KMBatchOperateConvertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB6347AF2AF1F0BB00F5438E /* KMBatchOperateConvertViewController.xib */; };
 		BB6347B12AF1F0BB00F5438E /* KMBatchOperateConvertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB6347AF2AF1F0BB00F5438E /* KMBatchOperateConvertViewController.xib */; };
@@ -4128,6 +4131,24 @@
 		BBB9B330299A5D6D004F3235 /* GTMAppAuthFetcherAuthorization.m in Sources */ = {isa = PBXBuildFile; fileRef = BBB9B306299A5D6C004F3235 /* GTMAppAuthFetcherAuthorization.m */; };
 		BBB9B339299A5FD1004F3235 /* ObjectiveDropboxOfficial.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BBB9B335299A5F35004F3235 /* ObjectiveDropboxOfficial.framework */; };
 		BBB9B33A299A5FD1004F3235 /* ObjectiveDropboxOfficial.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BBB9B335299A5F35004F3235 /* ObjectiveDropboxOfficial.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		BBBAECF42B57672200266BD3 /* SKPresentationOptionsSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAECF32B57672200266BD3 /* SKPresentationOptionsSheetController.swift */; };
+		BBBAECF52B57672200266BD3 /* SKPresentationOptionsSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAECF32B57672200266BD3 /* SKPresentationOptionsSheetController.swift */; };
+		BBBAECF62B57672200266BD3 /* SKPresentationOptionsSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAECF32B57672200266BD3 /* SKPresentationOptionsSheetController.swift */; };
+		BBBAECF82B57672C00266BD3 /* TransitionSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBBAECF72B57672C00266BD3 /* TransitionSheet.xib */; };
+		BBBAECF92B57672C00266BD3 /* TransitionSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBBAECF72B57672C00266BD3 /* TransitionSheet.xib */; };
+		BBBAECFA2B57672C00266BD3 /* TransitionSheet.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBBAECF72B57672C00266BD3 /* TransitionSheet.xib */; };
+		BBBAECFC2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAECFB2B57713F00266BD3 /* KMTransitionInfo.swift */; };
+		BBBAECFD2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAECFB2B57713F00266BD3 /* KMTransitionInfo.swift */; };
+		BBBAECFE2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAECFB2B57713F00266BD3 /* KMTransitionInfo.swift */; };
+		BBBAED0B2B57D55300266BD3 /* SKTransitionController.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED092B57D55100266BD3 /* SKTransitionController.m */; };
+		BBBAED0C2B57D55300266BD3 /* SKTransitionController.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED092B57D55100266BD3 /* SKTransitionController.m */; };
+		BBBAED0D2B57D55300266BD3 /* SKTransitionController.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED092B57D55100266BD3 /* SKTransitionController.m */; };
+		BBBAED102B57E76400266BD3 /* NSGraphics_SKExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED0F2B57E76400266BD3 /* NSGraphics_SKExtensions.m */; };
+		BBBAED112B57E76400266BD3 /* NSGraphics_SKExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED0F2B57E76400266BD3 /* NSGraphics_SKExtensions.m */; };
+		BBBAED122B57E76400266BD3 /* NSGraphics_SKExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED0F2B57E76400266BD3 /* NSGraphics_SKExtensions.m */; };
+		BBBAED142B57E97000266BD3 /* SKTypeSelectHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED132B57E97000266BD3 /* SKTypeSelectHelper.swift */; };
+		BBBAED152B57E97000266BD3 /* SKTypeSelectHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED132B57E97000266BD3 /* SKTypeSelectHelper.swift */; };
+		BBBAED162B57E97000266BD3 /* SKTypeSelectHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBAED132B57E97000266BD3 /* SKTypeSelectHelper.swift */; };
 		BBBB6CCA2AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CC92AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift */; };
 		BBBB6CCB2AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CC92AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift */; };
 		BBBB6CCC2AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CC92AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift */; };
@@ -6154,6 +6175,7 @@
 		BB6013872AD3A3CB00A76FB2 /* CPDFWidgetAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFWidgetAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BB60138B2AD3A94200A76FB2 /* CPDFSignatureAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFSignatureAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BB60138F2AD3AFF000A76FB2 /* NSPopover+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSPopover+KMExtension.swift"; sourceTree = "<group>"; };
+		BB61F2112B59120F00777E27 /* KMScroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMScroller.swift; sourceTree = "<group>"; };
 		BB6347AD2AF1F0A400F5438E /* KMBatchOperateConvertViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBatchOperateConvertViewController.swift; sourceTree = "<group>"; };
 		BB6347AF2AF1F0BB00F5438E /* KMBatchOperateConvertViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMBatchOperateConvertViewController.xib; sourceTree = "<group>"; };
 		BB6347B32AF224D600F5438E /* KMConvertCollectionViewHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMConvertCollectionViewHeader.swift; sourceTree = "<group>"; };
@@ -6462,6 +6484,14 @@
 		BBB9B305299A5D6C004F3235 /* GTMOAuth2KeychainCompatibility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2KeychainCompatibility.m; sourceTree = "<group>"; };
 		BBB9B306299A5D6C004F3235 /* GTMAppAuthFetcherAuthorization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMAppAuthFetcherAuthorization.m; sourceTree = "<group>"; };
 		BBB9B335299A5F35004F3235 /* ObjectiveDropboxOfficial.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ObjectiveDropboxOfficial.framework; sourceTree = "<group>"; };
+		BBBAECF32B57672200266BD3 /* SKPresentationOptionsSheetController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKPresentationOptionsSheetController.swift; sourceTree = "<group>"; };
+		BBBAECF72B57672C00266BD3 /* TransitionSheet.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TransitionSheet.xib; sourceTree = "<group>"; };
+		BBBAECFB2B57713F00266BD3 /* KMTransitionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMTransitionInfo.swift; sourceTree = "<group>"; };
+		BBBAED092B57D55100266BD3 /* SKTransitionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKTransitionController.m; sourceTree = "<group>"; };
+		BBBAED0A2B57D55200266BD3 /* SKTransitionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKTransitionController.h; sourceTree = "<group>"; };
+		BBBAED0E2B57E76300266BD3 /* NSGraphics_SKExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSGraphics_SKExtensions.h; sourceTree = "<group>"; };
+		BBBAED0F2B57E76400266BD3 /* NSGraphics_SKExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSGraphics_SKExtensions.m; sourceTree = "<group>"; };
+		BBBAED132B57E97000266BD3 /* SKTypeSelectHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKTypeSelectHelper.swift; sourceTree = "<group>"; };
 		BBBB6CC92AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BBBB6CCD2AD13E210035AA66 /* CPDFButtonWidgetAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFButtonWidgetAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BBBB6CD12AD14A5F0035AA66 /* CPDFChoiceWidgetAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFChoiceWidgetAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
@@ -7017,6 +7047,8 @@
 				899700E728F3E4D3009AF911 /* MainWindowController.xib */,
 				BB78EAA92B561F9700121691 /* KMFullScreenWindow.swift */,
 				BBB3FF972B567D0300145C4A /* KMApplication.swift */,
+				BBBAECF32B57672200266BD3 /* SKPresentationOptionsSheetController.swift */,
+				BBBAECF72B57672C00266BD3 /* TransitionSheet.xib */,
 			);
 			path = MainWindowController;
 			sourceTree = "<group>";
@@ -7845,6 +7877,7 @@
 				BBE0BDF229A22EF300440583 /* KMMainViewController+MenuAction.swift */,
 				9FCFEC8B2AD10A4400EAD2CB /* KMTextFieldSheetController.swift */,
 				896933D329AEEE3D0055327F /* PageSheet.xib */,
+				BB61F2112B59120F00777E27 /* KMScroller.swift */,
 			);
 			path = ViewController;
 			sourceTree = "<group>";
@@ -8588,6 +8621,8 @@
 			isa = PBXGroup;
 			children = (
 				ADA08A8929F21A53009B2A7B /* KMPDFViewAnnotationOnceModeStore.swift */,
+				BBBAECFB2B57713F00266BD3 /* KMTransitionInfo.swift */,
+				BBBAED132B57E97000266BD3 /* SKTypeSelectHelper.swift */,
 			);
 			path = Tools;
 			sourceTree = "<group>";
@@ -10806,6 +10841,7 @@
 		BB5F8A0329BB04EF00365ADB /* OC */ = {
 			isa = PBXGroup;
 			children = (
+				BBBAED082B57D52D00266BD3 /* KMTransitionController */,
 				BB8810D32B4F984000AFA63E /* JSONKit */,
 				BB8810CD2B4F980E00AFA63E /* NSNULL+Filtration */,
 				BB8810C12B4F95A900AFA63E /* NSObject+DeviceInfo */,
@@ -11637,6 +11673,17 @@
 			path = GTMOAuth2KeychainCompatibility;
 			sourceTree = "<group>";
 		};
+		BBBAED082B57D52D00266BD3 /* KMTransitionController */ = {
+			isa = PBXGroup;
+			children = (
+				BBBAED0A2B57D55200266BD3 /* SKTransitionController.h */,
+				BBBAED092B57D55100266BD3 /* SKTransitionController.m */,
+				BBBAED0E2B57E76300266BD3 /* NSGraphics_SKExtensions.h */,
+				BBBAED0F2B57E76400266BD3 /* NSGraphics_SKExtensions.m */,
+			);
+			path = KMTransitionController;
+			sourceTree = "<group>";
+		};
 		BBBC08812B2AC845009B237F /* Model */ = {
 			isa = PBXGroup;
 			children = (
@@ -12718,6 +12765,7 @@
 				ADDF835C2B391A5C00A81A4E /* CDSignatureCertificateStateViewController.xib in Resources */,
 				ADC63E432A49817400854E02 /* KMSubscribeSuccessView.xib in Resources */,
 				ADE86AF22B0AF56C00414DFA /* KMCompareCoveringSettingView.xib in Resources */,
+				BBBAECF82B57672C00266BD3 /* TransitionSheet.xib in Resources */,
 				BB65A0822AF8FEA1003A27A0 /* KMBatchOperateRemoveHeaderFooterViewController.xib in Resources */,
 				ADE86AB12B03438400414DFA /* KMWatermarkWindowController.xib in Resources */,
 				ADEC7A84299397F8009A8256 /* SF-Pro-Text-Semibold.otf in Resources */,
@@ -13311,6 +13359,7 @@
 				ADDF833F2B391A5C00A81A4E /* KMPDFDigitalSignViewController.xib in Resources */,
 				BBEC00DD295C39FD00A26C98 /* KMBatesPropertyInfoController.xib in Resources */,
 				BBA8B7B4293635D80097D183 /* KMPasswordInputWindow.xib in Resources */,
+				BBBAECF92B57672C00266BD3 /* TransitionSheet.xib in Resources */,
 				9F78EFBF28F7C1CC001E66F4 /* KMHomeViewController.xib in Resources */,
 				BBB376A52B10A7FD009539CC /* a_4b.png in Resources */,
 				BB0B2CD92B04AE560088FFD8 /* LeftSideView.xib in Resources */,
@@ -13690,6 +13739,7 @@
 				BB1BFF672AE9FBA8003EB179 /* KMBatchOperateWindowController.xib in Resources */,
 				ADDF835E2B391A5C00A81A4E /* CDSignatureCertificateStateViewController.xib in Resources */,
 				ADD1B6FE2946C0D400C3FFF7 /* KMPrintChoosePageSizePamphletView.xib in Resources */,
+				BBBAECFA2B57672C00266BD3 /* TransitionSheet.xib in Resources */,
 				BBFDFAA42AF3815C00E08AA2 /* KMTextHintWindowController.xib in Resources */,
 				9FF94F1629A7476000B1EF69 /* KMDesignPropertySelector.xib in Resources */,
 				ADE8BC3529F9261900570F89 /* KMSearchCellView.xib in Resources */,
@@ -14147,6 +14197,7 @@
 				9FA607DE28FD4C9F00B46586 /* KMHomePopViewController.swift in Sources */,
 				BBDA8A692A31B50C006A2C4E /* KMCustomStepperView.swift in Sources */,
 				BBD512A12B0DE86C005BFE8A /* KMBotaLeftView.swift in Sources */,
+				BBBAED142B57E97000266BD3 /* SKTypeSelectHelper.swift in Sources */,
 				BB162E9B295073B40088E9D1 /* KMWatermarkManager.swift in Sources */,
 				BB4BD9CC2909026500A66A65 /* KMRightSideViewController.swift in Sources */,
 				AD2D74B529F0D39500EDC5E4 /* KMCancellationSuccessView.swift in Sources */,
@@ -14345,6 +14396,7 @@
 				9FB220FF2B18866E00A5B208 /* KMAnnotationSelfSignViewController.swift in Sources */,
 				ADDEEA7A2AD3F4C800EF675D /* KMPopUpButton.swift in Sources */,
 				AD58F4162B1DAC0900299EE0 /* KMPrintSettingView.swift in Sources */,
+				BBBAED102B57E76400266BD3 /* NSGraphics_SKExtensions.m in Sources */,
 				BB1BFF792AEA0B8E003EB179 /* KMBatchOperateRightViewController.swift in Sources */,
 				ADAFDA282AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */,
 				BB3A66902B07099F00575343 /* KMFindTableviewCell.swift in Sources */,
@@ -14877,6 +14929,7 @@
 				BB671A012AD2D2A0003D44D5 /* CPDFStampAnnotation+PDFListView.swift in Sources */,
 				BBF729BF2B19783600576AC5 /* KMBatchRemoveHeaderFooterOperation.swift in Sources */,
 				9F0CB4F5298655D500007028 /* KMDesignToken+Fill.swift in Sources */,
+				BB61F2122B59120F00777E27 /* KMScroller.swift in Sources */,
 				ADDF83652B391A5C00A81A4E /* DSignatureFromFileViewController.swift in Sources */,
 				BBB7B48D2A0384E100B58A5A /* NSCollectionViewItem+KMExtension.swift in Sources */,
 				F3732323292DFFFE0013862C /* CPDFListView+Extension.m in Sources */,
@@ -15028,7 +15081,9 @@
 				BB146FAB299DC0D000784A6A /* GTLRBatchQuery.m in Sources */,
 				BB897218294AED6C0045787C /* KMWatermarkAdjectivePreViewBaseController.swift in Sources */,
 				ADAFDA162AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */,
+				BBBAECF42B57672200266BD3 /* SKPresentationOptionsSheetController.swift in Sources */,
 				ADE8BC2F29F8CD7200570F89 /* KMPDFThumbnailModel.swift in Sources */,
+				BBBAECFC2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */,
 				BB4EEF4029764FCC003A3537 /* KMWatermarkColorView.swift in Sources */,
 				BB146FC9299DC0D100784A6A /* GTMSessionFetcher.m in Sources */,
 				9F8DDF342924DA6B006CDC73 /* KMPDFToolsCollectionView.swift in Sources */,
@@ -15043,6 +15098,7 @@
 				BB3D97162B3023C5007094C8 /* KMCustomButton.swift in Sources */,
 				BB49ECDD293EED6100C82CA2 /* KMConvertWordWindowController.swift in Sources */,
 				BBC4F9FA2AEB9E200098A1A8 /* KMBatchTableCellView.swift in Sources */,
+				BBBAED0B2B57D55300266BD3 /* SKTransitionController.m in Sources */,
 				BB1969D72B2842AD00922736 /* KMSnapshotWindowController.swift in Sources */,
 				AD0FA4F929A8DD6F00EDEB50 /* KMRegisterSuccessView.swift in Sources */,
 				BB146FF9299DC0D100784A6A /* OIDExternalUserAgentMac.m in Sources */,
@@ -15262,6 +15318,7 @@
 				ADAFDA772AEB5FCD00F084BC /* KMHomeHistoryCollectionItem.swift in Sources */,
 				BB1969D82B2842AD00922736 /* KMSnapshotWindowController.swift in Sources */,
 				BB897242294C028A0045787C /* KMWatermarkAdjectiveSegementControl.swift in Sources */,
+				BBBAED0C2B57D55300266BD3 /* SKTransitionController.m in Sources */,
 				BB4A949C2B04B77F00940F8B /* KMOCROperation.swift in Sources */,
 				9F1FE4B529406E4700E952CA /* CTBrowser.m in Sources */,
 				BB6719E62AD28527003D44D5 /* CPDFLineAnnotation+PDFListView.swift in Sources */,
@@ -15458,6 +15515,7 @@
 				BB3AD6FA29935483004FC1AE /* Reachability.m in Sources */,
 				BBEC00C0295C306400A26C98 /* KMBatesPropertyController.swift in Sources */,
 				BB0A55222A30968900B6E84B /* KMDesignBaseView.swift in Sources */,
+				BB61F2132B59120F00777E27 /* KMScroller.swift in Sources */,
 				9FCFEC992AD14EEF00EAD2CB /* KMMailHelper.swift in Sources */,
 				89E4E6ED2963D1B7002DBA6F /* KMColorPickerViewController.m in Sources */,
 				ADAFDA172AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.swift in Sources */,
@@ -15682,6 +15740,7 @@
 				9FF816EF2AFA5D840087EFC5 /* KMTableDataManager.swift in Sources */,
 				ADDEEA872AD7805200EF675D /* KMGeneralButton.swift in Sources */,
 				BB5BE4EE2B060E2F00D51BF2 /* KMLanguageViewController.swift in Sources */,
+				BBBAECFD2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */,
 				BB1B0AED2B4FC6E900889528 /* KMGuideCoverView.swift in Sources */,
 				9F1FE4EE29406E4700E952CA /* ThrobberView.m in Sources */,
 				BB2F18472A0C7E250003F65E /* KMConvertBaseView.swift in Sources */,
@@ -16114,11 +16173,13 @@
 				BB03D69D2B0249A2008C9976 /* KMPDFEditInsertPageWindow.swift in Sources */,
 				BB147042299DC0D200784A6A /* OIDClientMetadataParameters.m in Sources */,
 				ADDF83572B391A5C00A81A4E /* DSignatureCreateViewController.swift in Sources */,
+				BBBAECF52B57672200266BD3 /* SKPresentationOptionsSheetController.swift in Sources */,
 				9F1FE4CA29406E4700E952CA /* CTTabContents.m in Sources */,
 				9FCFECA52AD237B500EAD2CB /* KMBatchTableRowView.swift in Sources */,
 				BB1A34A9295EA30100B80B3E /* NSBitmapImageRep_SKExtensions.m in Sources */,
 				9F0CB4FE298655F600007028 /* KMDesignToken+BorderColor.swift in Sources */,
 				BBB1A3A729F6B66400E54E47 /* NSPanel+KMExtension.swift in Sources */,
+				BBBAED152B57E97000266BD3 /* SKTypeSelectHelper.swift in Sources */,
 				BB1B0AD22B4FC6E900889528 /* KMFunctionGuideSingleController.swift in Sources */,
 				BB4F7E962B0C857D0077EC8C /* KMNoteTypeCollectionViewItem.swift in Sources */,
 				BB147048299DC0D200784A6A /* OIDServiceConfiguration.m in Sources */,
@@ -16194,6 +16255,7 @@
 				BBBE20942B21B18900509C4E /* KMPDFInsertWindowController.swift in Sources */,
 				89D2D309295A83B500BFF5FE /* KMEditPDFTextPropertyViewController.swift in Sources */,
 				9F0CB4DE2986554D00007028 /* KMDesignToken+HorizontalPadding.swift in Sources */,
+				BBBAED112B57E76400266BD3 /* NSGraphics_SKExtensions.m in Sources */,
 				9F1FE49A29406E4700E952CA /* NewTabButton.m in Sources */,
 				9F512CD02B469A7700EC0BC3 /* KMPageDisplayThemeCollectionViewItem.swift in Sources */,
 				BBF2455E2AE78FF900037D08 /* KMBatchWindow.swift in Sources */,
@@ -16375,6 +16437,7 @@
 				BB1B0A9F2B4FB88100889528 /* IAPProductsManager.m in Sources */,
 				9F0CB4B72977BC1000007028 /* KMPropertiesPanelPreviewSubVC.swift in Sources */,
 				BB3A81B72AC2C0F4006FC66C /* NSObject+KMExtension.swift in Sources */,
+				BBBAECF62B57672200266BD3 /* SKPresentationOptionsSheetController.swift in Sources */,
 				BB88106F2B4F771D00AFA63E /* KMVerificationInfoViewController.m in Sources */,
 				BB9E2F752A495BCD000DC68D /* KMConvertSettingLimitTipView.swift in Sources */,
 				9FCFEC8A2AD0EF9900EAD2CB /* KMPopMenuButton.swift in Sources */,
@@ -16525,6 +16588,7 @@
 				9FF94F0B29A62B5000B1EF69 /* KMDesignSelect.swift in Sources */,
 				BB4F7E832B0C4E140077EC8C /* KMNoteFilterCollevtionViewItem.swift in Sources */,
 				BB60138E2AD3A94200A76FB2 /* CPDFSignatureAnnotation+PDFListView.swift in Sources */,
+				BBBAED162B57E97000266BD3 /* SKTypeSelectHelper.swift in Sources */,
 				BB6347B62AF224D600F5438E /* KMConvertCollectionViewHeader.swift in Sources */,
 				ADBC2D2A299DCA76006280C8 /* NSTextField+Layer.swift in Sources */,
 				AD867FB529DFBB2700F00440 /* KMAnnotationOutlineSectionView.swift in Sources */,
@@ -16545,6 +16609,7 @@
 				BB146FBF299DC0D100784A6A /* GTMGatherInputStream.m in Sources */,
 				BB8116012992682F0008F536 /* KMSecureLimitAlertView.swift in Sources */,
 				AD3A3589294C11ED00D72802 /* KMPrintPreviewPresenter.swift in Sources */,
+				BB61F2142B59120F00777E27 /* KMScroller.swift in Sources */,
 				AD1CA4322A0640F20070541F /* KMAnnotationScreenHeadView.swift in Sources */,
 				BB49ED1B293F4D4E00C82CA2 /* KMConvertCSVSettingView.swift in Sources */,
 				BB8810782B4F785200AFA63E /* KMUnlockAlertViewController.m in Sources */,
@@ -16850,6 +16915,7 @@
 				BB49ECF8293F44DC00C82CA2 /* KMConvertExcelWindowController.swift in Sources */,
 				9FBC48BA299B44C600CA39D7 /* KMSecondaryViewController.m in Sources */,
 				AD1CA3F92A05FCB60070541F /* KMAnnotationScreenViewController.swift in Sources */,
+				BBBAECFE2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */,
 				9F1FE4EC29406E4700E952CA /* NSBezierPath+MCAdditions.m in Sources */,
 				BB1B0AFA2B4FC6E900889528 /* KMOpenFileFunctionView.swift in Sources */,
 				9F5664892988B16F00020985 /* KMTextfieldVC.swift in Sources */,
@@ -16923,6 +16989,7 @@
 				AD3AAD1D2B0B5B4400DE5FE7 /* KMCompareCoveringWindowController.swift in Sources */,
 				ADDEEA4B2AD38BDB00EF675D /* KMSignatureHelpViewController.swift in Sources */,
 				AD58F4102B1DAAA800299EE0 /* KMPrintDefaultView.swift in Sources */,
+				BBBAED0D2B57D55300266BD3 /* SKTransitionController.m in Sources */,
 				BBB3FF9E2B56852700145C4A /* NSDocument+KMExtensions.swift in Sources */,
 				9FDD0F7E2952F2D8000C4DAD /* KMBaseParser.swift in Sources */,
 				BBC8A75E2B05B55200FA9377 /* KMSegmentedControl.swift in Sources */,
@@ -17246,6 +17313,7 @@
 				ADE86AA62B031FF000414DFA /* KMCompareView.swift in Sources */,
 				BB5DF1F32959C9F00025CDA1 /* KMHeaderFooterPropertyMainController.swift in Sources */,
 				ADC63E4A2A49BEDD00854E02 /* KMSubscribeWaterMarkCollectionItem.swift in Sources */,
+				BBBAED122B57E76400266BD3 /* NSGraphics_SKExtensions.m in Sources */,
 				9F8DDF2829237910006CDC73 /* Array+KMExtensions.swift in Sources */,
 				9F0CB5172986566D00007028 /* KMDesignToken+BorderRadiusTopLeft.swift in Sources */,
 				BBBB6CCC2AD109F30035AA66 /* CPDFAnnotation+PDFListView.swift in Sources */,

+ 1 - 1
PDF Office/PDF Reader Pro.xcodeproj/xcshareddata/xcschemes/PDF Reader Pro Edition.xcscheme

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
    LastUpgradeVersion = "1520"
-   version = "1.8">
+   version = "1.7">
    <BuildAction
       parallelizeBuildables = "YES"
       buildImplicitDependencies = "YES">