Parcourir la source

【系统设置】- 同步

liujiajie il y a 1 an
Parent
commit
fa25844f4f

+ 72 - 0
PDF Office/PDF Master/Class/Common/OC/CheckFileUpdate/SKFileUpdateChecker.h

@@ -0,0 +1,72 @@
+//
+//  SKFileUpdateChecker.h
+//  Skim
+//
+//  Created by Christiaan Hofman on 12/23/10.
+/*
+ This software is Copyright (c) 2010-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>
+
+
+@interface SKFileUpdateChecker : NSObject {
+    NSDocument *document;
+    
+    struct _fucFlags {
+        unsigned int enabled:1;
+        unsigned int autoUpdate:1;
+        unsigned int isUpdatingFile:1;
+        unsigned int fileWasUpdated:1;
+        unsigned int fileWasMoved:1;
+        unsigned int fileChangedOnDisk:1;
+    } fucFlags;
+    
+    dispatch_source_t source;
+    
+    NSDate *lastModifiedDate;
+    NSTimer *fileUpdateTimer;
+}
+
+@property (nonatomic, getter=isEnabled) BOOL enabled;
+@property (nonatomic, readonly) BOOL fileChangedOnDisk, isUpdatingFile;
+
+- (id)initForDocument:(NSDocument *)aDocument;
+
+- (void)terminate;
+
+- (void)reset;
+- (void)stop;
+
+- (void)didUpdateFromURL:(NSURL *)fileURL;
+
+@end

+ 386 - 0
PDF Office/PDF Master/Class/Common/OC/CheckFileUpdate/SKFileUpdateChecker.m

@@ -0,0 +1,386 @@
+//
+//  SKFileUpdateChecker.m
+//  Skim
+//
+//  Created by Christiaan Hofman on 12/23/10.
+/*
+ This software is Copyright (c) 2010-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 "SKFileUpdateChecker.h"
+//#import "NSDocument_SKExtensions.h"
+//#import "NSData_SKExtensions.h"
+//#import <SkimNotes/SkimNotes.h>
+//#import "NSUserDefaultsController_SKExtensions.h"
+//#import "NSString_SKExtensions.h"
+//#import "NSError_SKExtensions.h"
+
+#import <PDF_Reader_Pro-Swift.h>
+
+#define PATH_KEY @"path"
+
+static char SKFileUpdateCheckerObservationContext;
+
+static BOOL isURLOnHFSVolume(NSURL *fileURL);
+static BOOL canUpdateFromURL(NSURL *fileURL);
+
+@interface SKFileUpdateChecker (SKPrivate)
+- (void)fileUpdated;
+- (void)noteFileUpdated;
+- (void)noteFileMoved;
+- (void)noteFileRemoved;
+@end
+
+@implementation SKFileUpdateChecker
+
+@dynamic enabled, fileChangedOnDisk, isUpdatingFile;
+
+- (id)initForDocument:(NSDocument *)aDocument {
+    self = [super init];
+    if (self) {
+        document = aDocument;
+        // hidden pref to always auto update without first asking the user
+        memset(&fucFlags, 0, sizeof(fucFlags));
+        fucFlags.autoUpdate = [[NSUserDefaults standardUserDefaults] boolForKey:@"SKAutoReloadFileUpdate"];
+//        [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKey:@"SKAutoCheckFileUpdate" context:&SKFileUpdateCheckerObservationContext];
+        [[NSUserDefaultsController sharedUserDefaultsController]addObserver:self forKeyPath:@"SKAutoCheckFileUpdate" options:0 context:&SKFileUpdateCheckerObservationContext];
+        [document addObserver:self forKeyPath:@"fileURL" options:0 context:&SKFileUpdateCheckerObservationContext];
+    }
+    return self;
+}
+
+//self.addObserver(anObserver, forKeyPath: "values.\(key)", options: .init(rawValue: 0), context: context as! UnsafeMutableRawPointer)
+
+- (void)dealloc {
+    @try { [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKey:@"SKAutoCheckFileUpdate"]; }
+    @catch (id) {}
+    document = nil;
+    [self stop];
+}
+
+- (void)terminate {
+    [self stop];
+    @try { [document removeObserver:self forKeyPath:@"fileURL"]; }
+    @catch (id) {}
+    document = nil;
+}
+
+- (void)stop {
+    // remove file monitor and invalidate timer; maybe we've changed filesystems
+    if (source) {
+        dispatch_source_cancel(source);
+        source = nil;
+    }
+    if (fileUpdateTimer) {
+        [fileUpdateTimer invalidate];
+        fileUpdateTimer = nil;
+    }
+    fucFlags.fileWasMoved = NO;
+}
+
+- (void)checkForFileModification:(NSTimer *)timer {
+    NSDate *currentFileModifiedDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:[[[document fileURL] URLByResolvingSymlinksInPath] path] error:NULL] fileModificationDate];
+    if (nil == lastModifiedDate) {
+        lastModifiedDate = [currentFileModifiedDate copy];
+    } else if ([lastModifiedDate compare:currentFileModifiedDate] == NSOrderedAscending) {
+        // Always reset mod date to prevent repeating messages; note that the kqueue also notifies only once
+        lastModifiedDate = [currentFileModifiedDate copy];
+        [self noteFileUpdated];
+    }
+}
+
+- (void)checkForFileReplacement:(NSTimer *)timer {
+    if ([[[document fileURL] URLByResolvingSymlinksInPath] checkResourceIsReachableAndReturnError:NULL]) {
+        // the deleted file was replaced at the old path, restart the file updating for the replacement file and note the update
+        [self reset];
+        [self noteFileUpdated];
+    }
+}
+
+- (void)startTimerWithSelector:(SEL)aSelector {
+    fileUpdateTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.1] interval:2.0 target:self selector:aSelector userInfo:nil repeats:YES];
+    [[NSRunLoop currentRunLoop] addTimer:fileUpdateTimer forMode:NSDefaultRunLoopMode];
+}
+
+- (void)reset {
+    [self stop];
+    NSURL *fileURL = [[document fileURL] URLByResolvingSymlinksInPath];
+    if (fileURL) {
+        if (fucFlags.enabled && [[NSUserDefaults standardUserDefaults] boolForKey:@"SKAutoCheckFileUpdate"]) {
+            
+            // AFP, NFS, SMB etc. don't support kqueues, so we have to manually poll and compare mod dates
+            if (isURLOnHFSVolume(fileURL)) {
+                int fd = open([[fileURL path] fileSystemRepresentation], O_EVTONLY);
+                
+                if (fd >= 0) {
+                    dispatch_queue_t queue = dispatch_get_main_queue();
+                    source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_WRITE, queue);
+                    
+                    if (source) {
+                        
+                        dispatch_source_set_event_handler(source, ^{
+                            unsigned long flags = dispatch_source_get_data(self->source);
+                            if ((flags & DISPATCH_VNODE_DELETE))
+                                [self noteFileRemoved];
+                            else if ((flags & DISPATCH_VNODE_RENAME))
+                                [self noteFileMoved];
+                            else if ((flags & DISPATCH_VNODE_WRITE))
+                                [self noteFileUpdated];
+                        });
+                        
+                        dispatch_source_set_cancel_handler(source, ^{ close(fd); });
+                        
+                        dispatch_resume(source);
+                        
+                    } else {
+                        close(fd);
+                    }
+                }
+            } else if (nil == fileUpdateTimer) {
+                // Use a fairly long delay since this is likely a network volume.
+                [self startTimerWithSelector:@selector(checkForFileModification:)];
+            }
+        }
+    }
+}
+
+- (void)fileUpdateAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
+    
+    if (returnCode == NSAlertSecondButtonReturn) {
+        // if we don't reload now, we should not do it automatically next
+        fucFlags.autoUpdate = NO;
+    } else {
+        // should we reset autoUpdate to YES on NSAlertFirstButtonReturn when SKAutoReloadFileUpdateKey is set?
+        if (returnCode == NSAlertThirdButtonReturn)
+            fucFlags.autoUpdate = YES;
+        
+        [[alert window] orderOut:nil];
+        NSError *error = nil;
+        BOOL didRevert = [document revertToContentsOfURL:[document fileURL] ofType:[document fileType] error:&error];
+        if (didRevert == NO && error != nil && [self isUserCancelledError:error] == NO)
+            [document presentError:error modalForWindow:[document windowForSheet] delegate:nil didPresentSelector:NULL contextInfo:NULL];
+        
+        if (didRevert == NO && fucFlags.fileWasUpdated)
+            [self performSelector:@selector(fileUpdated) withObject:nil afterDelay:0.0];
+    }
+    fucFlags.isUpdatingFile = NO;
+    fucFlags.fileWasUpdated = NO;
+}
+
+- (BOOL)isUserCancelledError: (NSError *)error {
+    return [[error domain] isEqualToString:NSCocoaErrorDomain] && [error code] == NSUserCancelledError;
+}
+
+- (void)handleWindowDidEndSheetNotification:(NSNotification *)notification {
+    // This is only called to delay a file update handling
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidEndSheetNotification object:[notification object]];
+    // Make sure we finish the sheet event first. E.g. the documentEdited status may need to be updated.
+    [self performSelector:@selector(fileUpdated) withObject:nil afterDelay:0.0];
+}
+
+- (void)fileUpdated {
+    NSURL *fileURL = [[document fileURL] URLByResolvingSymlinksInPath];
+    
+    // should never happen
+    if (fucFlags.isUpdatingFile)
+        NSLog(@"*** already busy updating file %@", [fileURL path]);
+    
+    if (fucFlags.enabled &&
+        [[NSUserDefaults standardUserDefaults] boolForKey:@"SKAutoCheckFileUpdate"] &&
+        [fileURL checkResourceIsReachableAndReturnError:NULL]) {
+        
+        fucFlags.fileChangedOnDisk = YES;
+        
+        fucFlags.isUpdatingFile = YES;
+        fucFlags.fileWasUpdated = NO;
+        
+        NSWindow *docWindow = [document windowForSheet];
+        
+        // check for attached sheet, since reloading the document while an alert is up looks a bit strange
+        if ([docWindow attachedSheet]) {
+            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleWindowDidEndSheetNotification:) 
+                                                         name:NSWindowDidEndSheetNotification object:docWindow];
+        } else if (canUpdateFromURL(fileURL)) {
+            BOOL documentHasEdits = [document isDocumentEdited]/* || [[document notes] count] > 0*/;
+            if (fucFlags.autoUpdate && documentHasEdits == NO) {
+                // tried queuing this with a delayed perform/cancel previous, but revert takes long enough that the cancel was never used
+                [self fileUpdateAlertDidEnd:nil returnCode:NSAlertFirstButtonReturn contextInfo:NULL];
+            } else {
+                NSString *message;
+                if (documentHasEdits)
+                    message = NSLocalizedString(@"The PDF file has changed on disk. If you reload, your changes will be lost. Do you want to reload this document now?", @"Informative text in alert dialog");
+                else if (fucFlags.autoUpdate)
+                    message = NSLocalizedString(@"The PDF file has changed on disk. Do you want to reload this document now?", @"Informative text in alert dialog");
+                else
+                    message = NSLocalizedString(@"The PDF file has changed on disk. Do you want to reload this document now? Choosing Auto will reload this file automatically for future changes.", @"Informative text in alert dialog");
+                
+                NSAlert *alert = [[NSAlert alloc] init];
+                [alert setMessageText:NSLocalizedString(@"File Updated", @"Message in alert dialog")];
+                [alert setInformativeText:message];
+                [alert addButtonWithTitle:NSLocalizedString(@"Yes", @"Button title")];
+                [alert addButtonWithTitle:NSLocalizedString(@"No", @"Button title")];
+                if (fucFlags.autoUpdate == NO)
+                    [alert addButtonWithTitle:NSLocalizedString(@"Auto", @"Button title")];
+//                [alert beginSheetModalForWindow:docWindow
+//                                  modalDelegate:self
+//                                 didEndSelector:@selector(fileUpdateAlertDidEnd:returnCode:contextInfo:)
+//                                    contextInfo:NULL];
+                [alert beginSheetModalForWindow:docWindow completionHandler:^(NSModalResponse returnCode) {
+                    [self fileUpdateAlertDidEnd:nil returnCode:NSAlertFirstButtonReturn contextInfo:NULL];
+                }];
+            }
+        } else {
+            fucFlags.isUpdatingFile = NO;
+            fucFlags.fileWasUpdated = NO;
+        }
+    } else {
+        fucFlags.isUpdatingFile = NO;
+        fucFlags.fileWasUpdated = NO;
+    }
+}
+
+- (void)noteFileUpdated {
+    if (fucFlags.fileWasMoved == NO) {
+        if (fucFlags.isUpdatingFile)
+            fucFlags.fileWasUpdated = YES;
+        else
+            [self fileUpdated];
+    }
+}
+
+- (void)noteFileMoved {
+    // If the file is moved, NSDocument will notice and will call setFileURL, where we start watching again
+    // unless the file is deleted before NSDocument notices, in which case we can treat this as just deleting the file
+    // but as long as neither happens we will ignore updates, as we cannot know which file NSDocument will think it has
+    fucFlags.fileChangedOnDisk = YES;
+    fucFlags.fileWasMoved = YES;
+}
+
+- (void)noteFileRemoved {
+    [self stop];
+    fucFlags.fileChangedOnDisk = YES;
+    // poll the (old) path to see whether the deleted file will be replaced
+    [self startTimerWithSelector:@selector(checkForFileReplacement:)];
+}
+
+- (void)setEnabled:(BOOL)flag {
+    if (fucFlags.enabled != flag) {
+        fucFlags.enabled = flag;
+        [self reset];
+    }
+}
+
+- (BOOL)isEnabled {
+    return fucFlags.enabled;
+}
+
+- (BOOL)fileChangedOnDisk {
+    return fucFlags.fileChangedOnDisk;
+}
+
+- (BOOL)isUpdatingFile {
+    return fucFlags.isUpdatingFile;
+}
+
+- (void)didUpdateFromURL:(NSURL *)fileURL {
+    fucFlags.fileChangedOnDisk = NO;
+    lastModifiedDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:[[fileURL URLByResolvingSymlinksInPath] path] error:NULL] fileModificationDate];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
+    if (context == &SKFileUpdateCheckerObservationContext)
+        [self reset];
+    else
+        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+}
+
+@end
+
+
+static BOOL isURLOnHFSVolume(NSURL *fileURL) {
+    BOOL isHFSVolume = NO;
+    FSRef fileRef;
+    
+    if (CFURLGetFSRef((CFURLRef)fileURL, &fileRef)) {
+        OSStatus err;
+        FSCatalogInfo fileInfo;
+        err = FSGetCatalogInfo(&fileRef, kFSCatInfoVolume, &fileInfo, NULL, NULL, NULL);
+    
+        FSVolumeInfo volInfo;
+        if (noErr == err) {
+            err = FSGetVolumeInfo(fileInfo.volume, 0, NULL, kFSVolInfoFSInfo, &volInfo, NULL, NULL);
+            
+            if (noErr == err)
+                // HFS and HFS+ are documented to have zero for filesystemID; AFP at least is non-zero
+                isHFSVolume = (0 == volInfo.filesystemID);
+        }
+    }
+    return isHFSVolume;
+}
+
+static BOOL canUpdateFromURL(NSURL *fileURL) {
+    NSString *extension = [fileURL pathExtension];
+    BOOL isDVI = NO;
+    if (extension) {
+        NSWorkspace *ws = [NSWorkspace sharedWorkspace];
+        NSString *theUTI = [ws typeOfFile:[[fileURL URLByStandardizingPath] path] error:NULL];
+        if ([extension isCaseInsensitiveEqual:@"pdfd"] || [ws type:theUTI conformsToType:@"net.sourceforge.skim-app.pdfd"]) {
+//            fileURL = [[NSFileManager defaultManager] bundledFileURLWithExtension:@"pdf" inPDFBundleAtURL:fileURL error:NULL];
+            if ([fileURL.pathExtension hasSuffix:@"pdf"]) {
+                return [[NSFileManager defaultManager] fileExistsAtPath:fileURL.path];
+            }else{
+                NSString *pathS = [fileURL.path stringByAppendingPathExtension:@"pdf"];
+                return [[NSFileManager defaultManager] fileExistsAtPath:pathS];
+            }
+        } else if ([extension isCaseInsensitiveEqual:@"dvi"] || [extension isCaseInsensitiveEqual:@"xdv"]) {
+            isDVI = YES;
+        }
+    }
+    
+    NSFileHandle *fh = [NSFileHandle fileHandleForReadingFromURL:fileURL error:NULL];
+    
+    // read the last 1024 bytes of the file (or entire file); Adobe's spec says they allow %%EOF anywhere in that range
+    unsigned long long fileEnd = [fh seekToEndOfFile];
+    unsigned long long startPos = fileEnd < 1024 ? 0 : fileEnd - 1024;
+    [fh seekToFileOffset:startPos];
+    NSData *trailerData = [fh readDataToEndOfFile];
+    NSRange range = NSMakeRange(0, [trailerData length]);
+    NSData *pattern = [NSData dataWithBytes:"%%EOF" length:5];
+    NSDataSearchOptions options = NSDataSearchBackwards;
+    
+    if (isDVI) {
+        const char bytes[4] = {0xDF, 0xDF, 0xDF, 0xDF};
+        pattern = [NSData dataWithBytes:bytes length:4];
+        options |= NSDataSearchAnchored;
+    }
+    return NSNotFound != [trailerData rangeOfData:pattern options:options range:range].location;
+}

+ 17 - 0
PDF Office/PDF Master/Class/Document/KMMainDocument.swift

@@ -6,6 +6,7 @@
 //
 
 import Cocoa
+import CoreFoundation
 
 @objc enum KMArchiveMask: Int {
     case diskImage       = 1
@@ -14,6 +15,14 @@ import Cocoa
 
 typealias KMMainDocumentCloudUploadHanddler = (@escaping(Bool, String)->()) -> ()
 @objcMembers class KMMainDocument: CTTabContents {
+    struct MDFlags {
+        var exportOption: UInt32 // assuming this is a 2-bit field, change to appropriate data type
+        var exportUsingPanel: UInt32 // assuming this is a 1-bit field, change to appropriate data type
+        var gettingFileType: UInt32 // assuming this is a 1-bit field, change to appropriate data type
+        var convertingNotes: UInt32 // assuming this is a 1-bit field, change to appropriate data type
+        var needsPasswordToConvert: UInt32 // assuming this is a 1-bit field, change to appropriate data type
+    }
+    
     var mainViewController: KMMainViewController?
     var homeWindowController: KMHomeWindowController?
     var homeViewController: KMHomeViewController?
@@ -25,6 +34,8 @@ typealias KMMainDocumentCloudUploadHanddler = (@escaping(Bool, String)->()) -> (
     var cloudUploadHanddler: KMMainDocumentCloudUploadHanddler?
     var isUnlockFromKeychain: Bool = false
     private var _saveAsing = false
+    var fileUpdateChecker: SKFileUpdateChecker?
+    var mdFlags: MDFlags?
     
     private var _saveToURL: URL?
     var saveToURL: URL? {
@@ -197,6 +208,12 @@ typealias KMMainDocumentCloudUploadHanddler = (@escaping(Bool, String)->()) -> (
         super.windowControllerDidLoadNib(aController)
         
         self.setDataFromTmpData()
+        
+        fileUpdateChecker = SKFileUpdateChecker.init(for: self)
+        
+        fileUpdateChecker?.isEnabled = true
+        
+        
     }
     
     override func save(to url: URL, ofType typeName: String, for saveOperation: NSDocument.SaveOperationType) async throws {

+ 3 - 3
PDF Office/PDF Master/Class/PDFTools/Convert/NewController/KMToolCompareWindowController.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -18,7 +18,7 @@
             <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" fullSizeContentView="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="374" y="227" width="596" height="404"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
             <view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
                 <rect key="frame" x="0.0" y="0.0" width="596" height="404"/>
                 <autoresizingMask key="autoresizingMask"/>

+ 1 - 1
PDF Office/PDF Master/Class/PDFWindowController/Side/RightSide/AnnotationProperty/ViewController/PageDisplay/KMPageDisplayThemeCollectionViewItem.xib

@@ -18,7 +18,7 @@
         </customObject>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <customView identifier="KMPageDisplayThemeCollectionViewItem" misplaced="YES" id="3SZ-T6-0pc">
+        <customView identifier="KMPageDisplayThemeCollectionViewItem" id="3SZ-T6-0pc">
             <rect key="frame" x="0.0" y="0.0" width="58" height="58"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
             <subviews>

+ 7 - 7
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -44,10 +44,6 @@
             <subviews>
                 <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Qt3-H1-Txz">
                     <rect key="frame" x="667" y="347" width="1" height="1"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="0.10000000000000001" id="3Ah-UW-M3a"/>
-                        <constraint firstAttribute="width" constant="0.10000000000000001" id="Iz6-2Y-Kn5"/>
-                    </constraints>
                     <buttonCell key="cell" type="bevel" bezelStyle="rounded" alignment="center" imageScaling="proportionallyDown" inset="2" id="RgE-Pm-Sre">
                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                         <font key="font" metaFont="system"/>
@@ -55,6 +51,10 @@
 Gw
 </string>
                     </buttonCell>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="0.10000000000000001" id="3Ah-UW-M3a"/>
+                        <constraint firstAttribute="width" constant="0.10000000000000001" id="Iz6-2Y-Kn5"/>
+                    </constraints>
                     <connections>
                         <action selector="exitFullScreen:" target="-2" id="eVN-b0-2s4"/>
                     </connections>
@@ -240,7 +240,7 @@ Gw
                     </constraints>
                     <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="OeM-gK-2cL"/>
                 </imageView>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wp0-L3-5I3">
+                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wp0-L3-5I3">
                     <rect key="frame" x="21" y="8" width="734" height="17"/>
                     <textFieldCell key="cell" lineBreakMode="clipping" title="Please use the scroll bar, thumbnail tool to locate the target page, click or box the area to select the target range." id="P3j-kh-acn">
                         <font key="font" metaFont="system" size="14"/>

+ 11 - 11
PDF Office/PDF Master/Class/Preference/Controller/Base.lproj/SyncPreferences.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -26,7 +26,7 @@
             <rect key="frame" x="0.0" y="0.0" width="428" height="213"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
             <subviews>
-                <button toolTip="Select this to check for external file changes. Use at your own risk." fixedFrame="YES" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2">
+                <button toolTip="Select this to check for external file changes. Use at your own risk." imageHugsTitle="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2">
                     <rect key="frame" x="18" y="177" width="392" height="18"/>
                     <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                     <buttonCell key="cell" type="check" title="Check for file changes" bezelStyle="regularSquare" imagePosition="leading" alignment="left" inset="2" id="23">
@@ -41,7 +41,7 @@
                     <rect key="frame" x="12" y="132" width="404" height="5"/>
                     <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                 </box>
-                <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
+                <textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
                     <rect key="frame" x="34" y="51" width="73" height="17"/>
                     <autoresizingMask key="autoresizingMask"/>
                     <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Command:" id="22">
@@ -50,7 +50,7 @@
                         <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
                     </textFieldCell>
                 </textField>
-                <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
+                <textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
                     <rect key="frame" x="17" y="107" width="394" height="17"/>
                     <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                     <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="PDF-TeX Sync support:" id="21">
@@ -59,7 +59,7 @@
                         <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
                     </textFieldCell>
                 </textField>
-                <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
+                <textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
                     <rect key="frame" x="29" y="22" width="78" height="17"/>
                     <autoresizingMask key="autoresizingMask"/>
                     <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Arguments:" id="20">
@@ -68,7 +68,7 @@
                         <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
                     </textFieldCell>
                 </textField>
-                <textField toolTip="Enter the arguments for the command. Use %file to indicate the file to open and %line for the line number" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7">
+                <textField toolTip="Enter the arguments for the command. Use %file to indicate the file to open and %line for the line number" focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7">
                     <rect key="frame" x="112" y="20" width="296" height="22"/>
                     <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                     <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="19">
@@ -81,7 +81,7 @@
                         <binding destination="27" name="value" keyPath="values.SKTeXEditorArguments" id="30"/>
                     </connections>
                 </textField>
-                <popUpButton toolTip="Choose settings for a preset TeX editor, or use custom settings" verticalHuggingPriority="750" fixedFrame="YES" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8">
+                <popUpButton toolTip="Choose settings for a preset TeX editor, or use custom settings" imageHugsTitle="YES" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8">
                     <rect key="frame" x="109" y="75" width="302" height="26"/>
                     <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                     <popUpButtonCell key="cell" type="push" title="Custom" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="17" id="15">
@@ -102,7 +102,7 @@
                         <action selector="changeTeXEditorPreset:" target="-2" id="58"/>
                     </connections>
                 </popUpButton>
-                <textField toolTip="Enter the command to call your favorite TeX editor" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9">
+                <textField toolTip="Enter the command to call your favorite TeX editor" focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9">
                     <rect key="frame" x="112" y="49" width="296" height="22"/>
                     <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
                     <textFieldCell key="cell" lineBreakMode="truncatingMiddle" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="14">
@@ -116,7 +116,7 @@
                         <binding destination="27" name="value" keyPath="values.SKTeXEditorCommand" id="29"/>
                     </connections>
                 </textField>
-                <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="10">
+                <textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="10">
                     <rect key="frame" x="60" y="81" width="47" height="17"/>
                     <autoresizingMask key="autoresizingMask"/>
                     <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Preset:" id="13">
@@ -125,7 +125,7 @@
                         <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
                     </textFieldCell>
                 </textField>
-                <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" preferredMaxLayoutWidth="390" translatesAutoresizingMaskIntoConstraints="NO" id="11">
+                <textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" preferredMaxLayoutWidth="390" translatesAutoresizingMaskIntoConstraints="NO" id="11">
                     <rect key="frame" x="17" y="143" width="394" height="28"/>
                     <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
                     <textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" title="Do not select this when using a script or program that will force a revert." id="12">

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

@@ -106,3 +106,4 @@
 #import "SKBookmark.h"
 
 #import "AutoSavePopController.h"
+#import "SKFileUpdateChecker.h"

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

@@ -102,3 +102,4 @@
 #import "SKBookmark.h"
 
 #import "AutoSavePopController.h"
+#import "SKFileUpdateChecker.h"

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

@@ -102,3 +102,4 @@
 #import "SKBookmark.h"
 
 #import "AutoSavePopController.h"
+#import "SKFileUpdateChecker.h"

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

@@ -4143,6 +4143,9 @@
 		BBA762D229D2D98D00844513 /* KMCommonDefine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA762D129D2D98D00844513 /* KMCommonDefine.swift */; };
 		BBA762D329D2D98D00844513 /* KMCommonDefine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA762D129D2D98D00844513 /* KMCommonDefine.swift */; };
 		BBA762D429D2D98D00844513 /* KMCommonDefine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA762D129D2D98D00844513 /* KMCommonDefine.swift */; };
+		BBA8B66F2B9027D700CB07B0 /* SKFileUpdateChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = BBA8B66D2B9027D500CB07B0 /* SKFileUpdateChecker.m */; };
+		BBA8B6702B9027D700CB07B0 /* SKFileUpdateChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = BBA8B66D2B9027D500CB07B0 /* SKFileUpdateChecker.m */; };
+		BBA8B6712B9027D700CB07B0 /* SKFileUpdateChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = BBA8B66D2B9027D500CB07B0 /* SKFileUpdateChecker.m */; };
 		BBA8B7A32935CD740097D183 /* KMRemovePasswordAlertWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA8B7A12935CD740097D183 /* KMRemovePasswordAlertWindowController.swift */; };
 		BBA8B7A42935CD740097D183 /* KMRemovePasswordAlertWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA8B7A12935CD740097D183 /* KMRemovePasswordAlertWindowController.swift */; };
 		BBA8B7A52935CD740097D183 /* KMRemovePasswordAlertWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA8B7A12935CD740097D183 /* KMRemovePasswordAlertWindowController.swift */; };
@@ -6755,6 +6758,8 @@
 		BBA5429B29F13A140041BAD0 /* KMMemorandumPattern.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMMemorandumPattern.swift; sourceTree = "<group>"; };
 		BBA5B6492A823E0200748A83 /* KMPDFEditViewController_dmg.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPDFEditViewController_dmg.swift; sourceTree = "<group>"; };
 		BBA762D129D2D98D00844513 /* KMCommonDefine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMCommonDefine.swift; sourceTree = "<group>"; };
+		BBA8B66D2B9027D500CB07B0 /* SKFileUpdateChecker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKFileUpdateChecker.m; sourceTree = "<group>"; };
+		BBA8B66E2B9027D600CB07B0 /* SKFileUpdateChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKFileUpdateChecker.h; sourceTree = "<group>"; };
 		BBA8B7A12935CD740097D183 /* KMRemovePasswordAlertWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMRemovePasswordAlertWindowController.swift; sourceTree = "<group>"; };
 		BBA8B7A22935CD740097D183 /* KMRemovePasswordAlertWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMRemovePasswordAlertWindowController.xib; sourceTree = "<group>"; };
 		BBA8B7A92935DC120097D183 /* KMRemovePasswordResultTipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMRemovePasswordResultTipView.swift; sourceTree = "<group>"; };
@@ -11519,6 +11524,7 @@
 		BB5F8A0329BB04EF00365ADB /* OC */ = {
 			isa = PBXGroup;
 			children = (
+				BBA8B66C2B9027A900CB07B0 /* CheckFileUpdate */,
 				BBD8EE892B8EC86900EB05FE /* AutoSave */,
 				BBBBB49C2B6F743700C7205E /* AttachmentEmailer */,
 				BBBBB4962B6F70B100C7205E /* Common */,
@@ -12214,6 +12220,15 @@
 			path = Control;
 			sourceTree = "<group>";
 		};
+		BBA8B66C2B9027A900CB07B0 /* CheckFileUpdate */ = {
+			isa = PBXGroup;
+			children = (
+				BBA8B66E2B9027D600CB07B0 /* SKFileUpdateChecker.h */,
+				BBA8B66D2B9027D500CB07B0 /* SKFileUpdateChecker.m */,
+			);
+			path = CheckFileUpdate;
+			sourceTree = "<group>";
+		};
 		BBA8B7AD293600590097D183 /* Window */ = {
 			isa = PBXGroup;
 			children = (
@@ -15040,6 +15055,7 @@
 				BB6347B42AF224D600F5438E /* KMConvertCollectionViewHeader.swift in Sources */,
 				AD055E7E2B88294F0035F824 /* SKBookmarkSheetController.m in Sources */,
 				BB897246294C19980045787C /* KMWatermarkAdjectiveListController.swift in Sources */,
+				BBA8B66F2B9027D700CB07B0 /* SKFileUpdateChecker.m in Sources */,
 				BBC347FD295448DE008D2CD1 /* KMWatermarkTemplateModel.swift in Sources */,
 				ADDEEA5E2AD39DC500EF675D /* KMSignatureManager.swift in Sources */,
 				ADF6B87E2A485A8F0090CB78 /* KMComparativeViewCollectionItemItem.swift in Sources */,
@@ -17013,6 +17029,7 @@
 				89D2D2C6294972B900BFF5FE /* KMFormCellView.swift in Sources */,
 				ADAFDA432AE8F3C400F084BC /* KMAdvertisementTimeStampConversion.swift in Sources */,
 				BB146FFD299DC0D100784A6A /* OIDAuthState+Mac.m in Sources */,
+				BBA8B6702B9027D700CB07B0 /* SKFileUpdateChecker.m in Sources */,
 				BB897225294B07960045787C /* KMWatermarkAdjectiveTopBarItemView.swift in Sources */,
 				ADDEEA6F2AD3E16100EF675D /* KMSigntureViewItem.swift in Sources */,
 				BB14703F299DC0D200784A6A /* OIDEndSessionResponse.m in Sources */,
@@ -18303,6 +18320,7 @@
 				BBFEF7252B3A78BC00C28AC0 /* KMSystemGotoMenu.swift in Sources */,
 				9F1FE4F229406E4700E952CA /* BackgroundGradientView.m in Sources */,
 				ADAFDA272AE8DE1B00F084BC /* KMAdvertisementModel.swift in Sources */,
+				BBA8B6712B9027D700CB07B0 /* SKFileUpdateChecker.m in Sources */,
 				89316824296D73CC0073EA59 /* KMSignatureAnnotationViewController.m in Sources */,
 				9F1FE4A429406E4700E952CA /* CTToolbarController.m in Sources */,
 				BB1B0AFD2B4FC6E900889528 /* KMCustomColorGuideView.swift in Sources */,