Browse Source

【综合】系统菜单栏 saveArchive相关菜单补充

tangchao 1 year ago
parent
commit
af96e2bd08

+ 6 - 6
PDF Office/PDF Master/Base.lproj/Main.storyboard

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
     <dependencies>
     <dependencies>
         <deployment identifier="macosx"/>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     </dependencies>
     <scenes>
     <scenes>
@@ -336,14 +336,14 @@
                                                 <action selector="saveArchive:" target="Ady-hI-5gd" id="GTR-aC-Btw"/>
                                                 <action selector="saveArchive:" target="Ady-hI-5gd" id="GTR-aC-Btw"/>
                                             </connections>
                                             </connections>
                                         </menuItem>
                                         </menuItem>
-                                        <menuItem title="Mail Archive…" tag="2" id="Itb-6n-NnQ">
+                                        <menuItem title="Save Disk Image…" tag="1" id="Ur6-zP-ieP">
                                             <connections>
                                             <connections>
-                                                <action selector="saveArchive:" target="Ady-hI-5gd" id="dDE-GG-Xth"/>
+                                                <action selector="saveArchive:" target="Ady-hI-5gd" id="CCF-6B-Pf9"/>
                                             </connections>
                                             </connections>
                                         </menuItem>
                                         </menuItem>
-                                        <menuItem title="Save Disk Image…" tag="1" id="Ur6-zP-ieP">
+                                        <menuItem title="Mail Archive…" tag="2" id="Itb-6n-NnQ">
                                             <connections>
                                             <connections>
-                                                <action selector="saveArchive:" target="Ady-hI-5gd" id="CCF-6B-Pf9"/>
+                                                <action selector="saveArchive:" target="Ady-hI-5gd" id="dDE-GG-Xth"/>
                                             </connections>
                                             </connections>
                                         </menuItem>
                                         </menuItem>
                                         <menuItem title="Mail Disk Image…" tag="3" id="oFD-Tc-WY3">
                                         <menuItem title="Mail Disk Image…" tag="3" id="oFD-Tc-WY3">

+ 56 - 0
PDF Office/PDF Master/Class/Common/Category/NSObject+KMExtension.swift

@@ -6,6 +6,8 @@
 //
 //
 
 
 import Foundation
 import Foundation
+import Cocoa
+import Carbon
 
 
 func GetDeviceInfo(key: String) -> Any? {
 func GetDeviceInfo(key: String) -> Any? {
     var ret: Any?
     var ret: Any?
@@ -794,6 +796,60 @@ extension NSTableView {
     }
     }
 }
 }
 
 
+// MARK: - NSFileManager
+
+var _chewableItemsDirectoryURL: URL?
+
+extension FileManager {
+    func uniqueChewableItemsDirectoryURL() -> URL {
+        if _chewableItemsDirectoryURL == nil {
+//            FSRef chewableRef;
+            var chewableRef: URL?
+            let urlString = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).first ?? ""
+//            if (noErr == FSFindFolder(kUserDomain, kChewableItemsFolderType, TRUE, &chewableRef)) {
+//                NSURL *chewableURL = (NSURL *)CFURLCreateFromFSRef(kCFAllocatorDefault, &chewableRef);
+            let url = URL(fileURLWithPath: urlString)
+//                NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey];
+            let appName = Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String)
+//                chewableItemsDirectoryURL = [[chewableURL URLByAppendingPathComponent:appName] copy];
+            _chewableItemsDirectoryURL = url.appendingPathComponent(appName as? String ?? "")
+            if let check = try?_chewableItemsDirectoryURL?.checkResourceIsReachable(), check == false {
+//                if ([chewableItemsDirectoryURL checkResourceIsReachableAndReturnError:NULL] == NO)
+                try?self.createDirectory(atPath: _chewableItemsDirectoryURL?.path ?? "", withIntermediateDirectories: false)
+           }
+        }
+
+        var uniqueURL: URL?
+
+        repeat {
+//            CFUUIDRef uuid = CFUUIDCreate(NULL);
+//            uniqueURL = [chewableItemsDirectoryURL URLByAppendingPathComponent:[(NSString *)CFUUIDCreateString(NULL, uuid) autorelease]];
+            let uuid: CFUUID = CFUUIDCreate(nil)
+            let uuidString = CFUUIDCreateString(nil, uuid)
+            uniqueURL = _chewableItemsDirectoryURL?.appendingPathComponent((uuidString as? String) ?? "")
+            let check = (try?uniqueURL?.checkResourceIsReachable()) ?? false
+            if check {
+                break
+            }
+        } while ((try?uniqueURL?.checkResourceIsReachable()) != nil)
+        
+        try?self.createDirectory(atPath: uniqueURL?.path ?? "", withIntermediateDirectories: false)
+        return uniqueURL!
+    }
+}
+
+// MARK: - URL
+
+extension URL {
+    func lastPathComponentReplacingPathExtension(_ ext: String) -> String {
+        return self.URLReplacingPathExtension(ext).lastPathComponent
+    }
+    
+    func URLReplacingPathExtension(_ ext: String) -> URL {
+        return self.deletingPathExtension().appendingPathExtension(ext)
+    }
+}
+
 // MARK: - Other
 // MARK: - Other
 
 
 func KMSquaredDistanceFromPointToRect(_ point: NSPoint, _ rect: NSRect) -> CGFloat {
 func KMSquaredDistanceFromPointToRect(_ point: NSPoint, _ rect: NSRect) -> CGFloat {

+ 57 - 0
PDF Office/PDF Master/Class/Common/OC/AttachmentEmailer/SKAttachmentEmailer.h

@@ -0,0 +1,57 @@
+//
+//  SKAttachmentEmailer.h
+//  Skim
+//
+//  Created by Christiaan Hofman on 11/4/12.
+/*
+ This software is Copyright (c) 2012-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 SKAttachmentEmailer : NSObject {
+    NSURL *fileURL;
+    NSString *subject;
+}
+
++ (id)attachmentEmailerWithFileURL:(NSURL *)aURL subject:(NSString *)aSubject waitingForTask:(NSTask *)task;
+
+@property (nonatomic, retain) NSURL *fileURL;
+@property (nonatomic, retain) NSString *subject;
+
+- (void)emailAttachmentFile;
+
+- (void)waitForTaskTermination:(NSTask *)task;
+- (void)taskFailed;
+
+@end

+ 147 - 0
PDF Office/PDF Master/Class/Common/OC/AttachmentEmailer/SKAttachmentEmailer.m

@@ -0,0 +1,147 @@
+//
+//  SKAttachmentEmailer.m
+//  Skim
+//
+//  Created by Christiaan Hofman on 11/4/12.
+/*
+ This software is Copyright (c) 2012-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 "SKAttachmentEmailer.h"
+//#import "NSString_SKExtensions.h"
+#import "NSObject+OCExtensions.h"
+//#import "NSFileManager_SKExtensions.h"
+
+
+@implementation SKAttachmentEmailer
+
+@synthesize fileURL, subject;
+
++ (id)attachmentEmailerWithFileURL:(NSURL *)aURL subject:(NSString *)aSubject waitingForTask:(NSTask *)task {
+    id attachmentEmailer = [[self alloc] init];
+    [attachmentEmailer setFileURL:aURL];
+    [attachmentEmailer setSubject:aSubject];
+    [attachmentEmailer waitForTaskTermination:task];
+    return attachmentEmailer;
+}
+
+- (void)dealloc {
+//    SKDESTROY(fileURL);
+//    SKDESTROY(subject);
+//    [super dealloc];
+}
+
+- (void)emailAttachmentFile {
+    NSString *scriptFormat = nil;
+    NSString *mailAppID = (NSString *)CFBridgingRelease(LSCopyDefaultHandlerForURLScheme(CFSTR("mailto")));
+    
+    if ([@"com.microsoft.entourage" isCaseInsensitiveEqual:mailAppID]) {
+        scriptFormat = @"tell application \"Microsoft Entourage\"\n"
+                       @"activate\n"
+                       @"set m to make new draft window with properties {subject:\"%@\", visible:true}\n"
+                       @"tell m\n"
+                       @"make new attachment with properties {file:POSIX file \"%@\"}\n"
+                       @"end tell\n"
+                       @"end tell\n";
+    } else if ([@"com.microsoft.outlook" isCaseInsensitiveEqual:mailAppID]) {
+        scriptFormat = @"tell application \"Microsoft Outlook\"\n"
+                       @"activate\n"
+                       @"set m to make new draft window with properties {subject:\"%@\", visible:true}\n"
+                       @"tell m\n"
+                       @"make new attachment with properties {file:POSIX file \"%@\"}\n"
+                       @"end tell\n"
+                       @"end tell\n";
+    } else if ([@"com.barebones.mailsmith" isCaseInsensitiveEqual:mailAppID]) {
+        scriptFormat = @"tell application \"Mailsmith\"\n"
+                       @"activate\n"
+                       @"set m to make new message window with properties {subject:\"%@\", visible:true}\n"
+                       @"tell m\n"
+                       @"make new enclosure with properties {file:POSIX file \"%@\"}\n"
+                       @"end tell\n"
+                       @"end tell\n";
+    } else if ([@"com.mailplaneapp.Mailplane" isCaseInsensitiveEqual:mailAppID]) {
+        scriptFormat = @"tell application \"Mailplane\"\n"
+                       @"activate\n"
+                       @"set m to make new outgoing message with properties {subject:\"%@\", visible:true}\n"
+                       @"tell m\n"
+                       @"make new mail attachment with properties {path:\"%@\"}\n"
+                       @"end tell\n"
+                       @"end tell\n";
+    } else if ([@"com.postbox-inc.postboxexpress" isCaseInsensitiveEqual:mailAppID]) {
+        scriptFormat = @"tell application \"PostboxExpress\"\n"
+                       @"activate\n"
+                       @"send message subject \"%@\" attachment \"%@\"\n"
+                       @"end tell\n";
+    } else if ([@"com.postbox-inc.postbox" isCaseInsensitiveEqual:mailAppID]) {
+        scriptFormat = @"tell application \"Postbox\"\n"
+                       @"activate\n"
+                       @"send message subject \"%@\" attachment \"%@\"\n"
+                       @"end tell\n";
+    } else {
+        scriptFormat = @"tell application \"Mail\"\n"
+                       @"activate\n"
+                       @"set m to make new outgoing message with properties {subject:\"%@\", visible:true}\n"
+                       @"tell content of m\n"
+                       @"make new attachment at after last character with properties {file name:\"%@\"}\n"
+                       @"end tell\n"
+                       @"end tell\n";
+    }
+    
+    
+    NSString *scriptString = [NSString stringWithFormat:scriptFormat, subject, [fileURL path]];
+    NSAppleScript *script = [[NSAppleScript alloc] initWithSource:scriptString];
+    NSDictionary *errorDict = nil;
+    if ([script compileAndReturnError:&errorDict] == NO)
+        NSLog(@"Error compiling mail to script: %@", errorDict);
+    else if ([script executeAndReturnError:&errorDict] == NO)
+        NSLog(@"Error running mail to script: %@", errorDict);
+}
+
+- (void)taskFinished:(NSNotification *)notification {
+    if ([fileURL checkResourceIsReachableAndReturnError:NULL] && [[notification object] terminationStatus] == 0)
+        [self emailAttachmentFile];
+    else
+        NSBeep();
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)waitForTaskTermination:(NSTask *)task {
+//    [self retain];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskFinished:) name:NSTaskDidTerminateNotification object:task];
+}
+
+- (void)taskFailed {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+//    [self autorelease];
+}
+
+@end

+ 29 - 0
PDF Office/PDF Master/Class/Common/OC/Common/NSObject+OCExtensions.h

@@ -0,0 +1,29 @@
+//
+//  NSObject+OCExtensions.h
+//  PDF Reader Pro
+//
+//  Created by tangchao on 2024/2/4.
+//
+
+#import <Foundation/Foundation.h>
+#import <AppKit/AppKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NSObject (OCExtensions)
+
+@end
+
+@interface NSDocument (OCExtensions)
+
+- (void)newSaveArchiveToURL:(NSURL *)fileURL email:(BOOL)email;
+
+@end
+
+@interface NSString (OCExtensions)
+
+- (BOOL)isCaseInsensitiveEqual:(NSString *)aString;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
PDF Office/PDF Master/Class/Common/OC/Common/NSObject+OCExtensions.m

@@ -0,0 +1,50 @@
+//
+//  NSObject+OCExtensions.m
+//  PDF Reader Pro
+//
+//  Created by tangchao on 2024/2/4.
+//
+
+#import "NSObject+OCExtensions.h"
+
+@implementation NSObject (OCExtensions)
+
+@end
+
+@implementation NSDocument (OCExtensions)
+
+- (void)newSaveArchiveToURL:(NSURL *)fileURL email:(BOOL)email {
+    NSTask *task = [[NSTask alloc] init];
+    if ([[fileURL pathExtension] isEqualToString:@"dmg"]) {
+        [task setLaunchPath:@"/usr/bin/hdiutil"];
+        [task setArguments:[NSArray arrayWithObjects:@"create", @"-srcfolder", [[self fileURL] path], @"-format", @"UDZO", @"-volname", [[fileURL lastPathComponent] stringByDeletingPathExtension], [fileURL path], nil]];
+    } else {
+        [task setLaunchPath:@"/usr/bin/tar"];
+        [task setArguments:[NSArray arrayWithObjects:@"-czf", [fileURL path], [[self fileURL] lastPathComponent], nil]];
+    }
+    [task setCurrentDirectoryPath:[[[self fileURL] URLByDeletingLastPathComponent] path]];
+    [task setStandardOutput:[NSFileHandle fileHandleWithNullDevice]];
+    [task setStandardError:[NSFileHandle fileHandleWithNullDevice]];
+    
+//    SKAttachmentEmailer *emailer = nil;
+//    if (email)
+//        emailer = [SKAttachmentEmailer attachmentEmailerWithFileURL:fileURL subject:[self displayName] waitingForTask:task];
+    
+    @try {
+        [task launch];
+    }
+    @catch (id exception) {
+//        [emailer taskFailed];
+    }
+}
+
+@end
+
+@implementation NSString (OCExtensions)
+
+- (BOOL)isCaseInsensitiveEqual:(NSString *)aString {
+    return [self caseInsensitiveCompare:aString] == NSOrderedSame;
+}
+
+@end
+

+ 72 - 1
PDF Office/PDF Master/Class/Document/KMMainDocument.swift

@@ -7,6 +7,11 @@
 
 
 import Cocoa
 import Cocoa
 
 
+@objc enum KMArchiveMask: Int {
+    case diskImage       = 1
+    case email           = 2
+}
+
 typealias KMMainDocumentCloudUploadHanddler = (@escaping(Bool, String)->()) -> ()
 typealias KMMainDocumentCloudUploadHanddler = (@escaping(Bool, String)->()) -> ()
 @objcMembers class KMMainDocument: CTTabContents {
 @objcMembers class KMMainDocument: CTTabContents {
     var mainViewController: KMMainViewController?
     var mainViewController: KMMainViewController?
@@ -553,8 +558,72 @@ typealias KMMainDocumentCloudUploadHanddler = (@escaping(Bool, String)->()) -> (
     }
     }
     
     
     @IBAction func saveArchive(_ sender: Any?) {
     @IBAction func saveArchive(_ sender: Any?) {
-        KMPrint("saveArchive")
+        guard let item = sender as? NSMenuItem else {
+            NSSound.beep()
+            return
+        }
+        guard let fileURL = self.fileURL else {
+            NSSound.beep()
+            return
+        }
+        let check = try?fileURL.checkResourceIsReachable()
+        if check == false || self.isDocumentEdited {
+            let msg = KMLocalizedString("You must save this file first", "Alert text when trying to create archive for unsaved document")
+            let inf = KMLocalizedString("The document has unsaved changes, or has not previously been saved to disk.", "Informative text in alert dialog")
+            Task {
+                _ = await KMAlertTool.runModel(message: msg, informative: inf)
+            }
+            return
+        }
+//        NSString *ext = ([sender tag] | SKArchiveDiskImageMask) ? @"dmg" : @"tgz";
+        let idx = item.tag
+        let ext = "dmg"
+        let isEmail = true
+        if isEmail  {
+//            if (([sender tag] | SKArchiveEmailMask)) {
+            let tmpDirURL = FileManager.default.uniqueChewableItemsDirectoryURL()
+            let tmpFileURL = tmpDirURL.appendingPathComponent(fileURL.lastPathComponentReplacingPathExtension(ext))
+            self.newSaveArchive(to: tmpFileURL, email: true)
+        } else {
+            let sp = NSSavePanel()
+            sp.allowedFileTypes = [ext]
+            sp.canCreateDirectories = true
+//                [sp setNameFieldStringValue:[fileURL lastPathComponentReplacingPathExtension:ext]];
+            sp.beginSheetModal(for: self.windowForSheet!) { result in
+                if result == .OK {
+                    self.newSaveArchive(to: sp.url!, email: false)
+                }
+            }
+        }
     }
     }
+    
+//    func saveArchiveToURL(to fileURL: URL, email: Bool) {
+//        NSTask *task = [[[NSTask alloc] init] autorelease];
+//        let task = Task()
+//        if fileURL.pathExtension == "dmg" {
+//            [task setLaunchPath:@""];
+//            task.launchPath = "/usr/bin/hdiutil"
+//            [task setArguments:[NSArray arrayWithObjects:@"create", @"-srcfolder", [[self fileURL] path], @"-format", @"UDZO", @"-volname", [[fileURL lastPathComponent] stringByDeletingPathExtension], [fileURL path], nil]];
+//        } else {
+//            [task setLaunchPath:@"/usr/bin/tar"];
+//            [task setArguments:[NSArray arrayWithObjects:@"-czf", [fileURL path], [[self fileURL] lastPathComponent], nil]];
+//        }
+//        [task setCurrentDirectoryPath:[[[self fileURL] URLByDeletingLastPathComponent] path]];
+//        [task setStandardOutput:[NSFileHandle fileHandleWithNullDevice]];
+//        [task setStandardError:[NSFileHandle fileHandleWithNullDevice]];
+//
+//        SKAttachmentEmailer *emailer = nil;
+//        if (email)
+//            emailer = [SKAttachmentEmailer attachmentEmailerWithFileURL:fileURL subject:[self displayName] waitingForTask:task];
+//
+//        @try {
+//            [task launch];
+//        }
+//        @catch (id exception) {
+//            [emailer taskFailed];
+//        }
+//    }
+    
     @IBAction func readNotes(_ sender: Any?) {
     @IBAction func readNotes(_ sender: Any?) {
         KMPrint("readNotes")
         KMPrint("readNotes")
     }
     }
@@ -740,6 +809,8 @@ extension KMMainDocument {
                 return false
                 return false
             }
             }
             return true
             return true
+        } else if menuItem.action == #selector(saveArchive) {
+            return !self.isHome
         }
         }
         return super.validateMenuItem(menuItem)
         return super.validateMenuItem(menuItem)
     }
     }

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

@@ -91,3 +91,4 @@
 #import "NSString+Utils.h"
 #import "NSString+Utils.h"
 #import "NSEvent+PDFListView.h"
 #import "NSEvent+PDFListView.h"
 #import "NSURL+Utils.h"
 #import "NSURL+Utils.h"
+#import "NSObject+OCExtensions.h"

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

@@ -87,3 +87,4 @@
 #import "NSString+Utils.h"
 #import "NSString+Utils.h"
 #import "NSEvent+PDFListView.h"
 #import "NSEvent+PDFListView.h"
 #import "NSURL+Utils.h"
 #import "NSURL+Utils.h"
+#import "NSObject+OCExtensions.h"

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

@@ -87,3 +87,4 @@
 #import "NSString+Utils.h"
 #import "NSString+Utils.h"
 #import "NSEvent+PDFListView.h"
 #import "NSEvent+PDFListView.h"
 #import "NSURL+Utils.h"
 #import "NSURL+Utils.h"
+#import "NSObject+OCExtensions.h"

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

@@ -4215,6 +4215,12 @@
 		BBBB6CDE2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */; };
 		BBBB6CDE2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */; };
 		BBBB6CDF2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */; };
 		BBBB6CDF2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */; };
 		BBBB6CE02AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */; };
 		BBBB6CE02AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */; };
+		BBBBB4992B6F714000C7205E /* NSObject+OCExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBBB4982B6F713F00C7205E /* NSObject+OCExtensions.m */; };
+		BBBBB49A2B6F714000C7205E /* NSObject+OCExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBBB4982B6F713F00C7205E /* NSObject+OCExtensions.m */; };
+		BBBBB49B2B6F714000C7205E /* NSObject+OCExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBBB4982B6F713F00C7205E /* NSObject+OCExtensions.m */; };
+		BBBBB49F2B6F743700C7205E /* SKAttachmentEmailer.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBBB49E2B6F743700C7205E /* SKAttachmentEmailer.m */; };
+		BBBBB4A02B6F743700C7205E /* SKAttachmentEmailer.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBBB49E2B6F743700C7205E /* SKAttachmentEmailer.m */; };
+		BBBBB4A12B6F743700C7205E /* SKAttachmentEmailer.m in Sources */ = {isa = PBXBuildFile; fileRef = BBBBB49E2B6F743700C7205E /* SKAttachmentEmailer.m */; };
 		BBBC087E2B2A93DB009B237F /* KMToolbarMainItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */; };
 		BBBC087E2B2A93DB009B237F /* KMToolbarMainItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */; };
 		BBBC087F2B2A93DB009B237F /* KMToolbarMainItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */; };
 		BBBC087F2B2A93DB009B237F /* KMToolbarMainItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */; };
 		BBBC08802B2A93DB009B237F /* KMToolbarMainItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */; };
 		BBBC08802B2A93DB009B237F /* KMToolbarMainItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */; };
@@ -6589,6 +6595,10 @@
 		BBBB6CD52AD150D20035AA66 /* CPDFCircleAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFCircleAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BBBB6CD52AD150D20035AA66 /* CPDFCircleAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFCircleAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BBBB6CD92AD15B900035AA66 /* CPDFFreeTextAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFFreeTextAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BBBB6CD92AD15B900035AA66 /* CPDFFreeTextAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFFreeTextAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFInkAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
 		BBBB6CDD2AD174080035AA66 /* CPDFInkAnnotation+PDFListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFInkAnnotation+PDFListView.swift"; sourceTree = "<group>"; };
+		BBBBB4972B6F713F00C7205E /* NSObject+OCExtensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+OCExtensions.h"; sourceTree = "<group>"; };
+		BBBBB4982B6F713F00C7205E /* NSObject+OCExtensions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+OCExtensions.m"; sourceTree = "<group>"; };
+		BBBBB49D2B6F743700C7205E /* SKAttachmentEmailer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKAttachmentEmailer.h; sourceTree = "<group>"; };
+		BBBBB49E2B6F743700C7205E /* SKAttachmentEmailer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKAttachmentEmailer.m; sourceTree = "<group>"; };
 		BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMToolbarMainItemView.swift; sourceTree = "<group>"; };
 		BBBC087D2B2A93DB009B237F /* KMToolbarMainItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMToolbarMainItemView.swift; sourceTree = "<group>"; };
 		BBBC08822B2AC863009B237F /* KMSnapshotModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMSnapshotModel.swift; sourceTree = "<group>"; };
 		BBBC08822B2AC863009B237F /* KMSnapshotModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMSnapshotModel.swift; sourceTree = "<group>"; };
 		BBBE208A2B21649100509C4E /* KMPDFEditWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPDFEditWindowController.swift; sourceTree = "<group>"; };
 		BBBE208A2B21649100509C4E /* KMPDFEditWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPDFEditWindowController.swift; sourceTree = "<group>"; };
@@ -10972,6 +10982,8 @@
 		BB5F8A0329BB04EF00365ADB /* OC */ = {
 		BB5F8A0329BB04EF00365ADB /* OC */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				BBBBB49C2B6F743700C7205E /* AttachmentEmailer */,
+				BBBBB4962B6F70B100C7205E /* Common */,
 				BBBAED082B57D52D00266BD3 /* KMTransitionController */,
 				BBBAED082B57D52D00266BD3 /* KMTransitionController */,
 				BB8810D32B4F984000AFA63E /* JSONKit */,
 				BB8810D32B4F984000AFA63E /* JSONKit */,
 				BB8810CD2B4F980E00AFA63E /* NSNULL+Filtration */,
 				BB8810CD2B4F980E00AFA63E /* NSNULL+Filtration */,
@@ -11818,6 +11830,24 @@
 			path = KMTransitionController;
 			path = KMTransitionController;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		BBBBB4962B6F70B100C7205E /* Common */ = {
+			isa = PBXGroup;
+			children = (
+				BBBBB4972B6F713F00C7205E /* NSObject+OCExtensions.h */,
+				BBBBB4982B6F713F00C7205E /* NSObject+OCExtensions.m */,
+			);
+			path = Common;
+			sourceTree = "<group>";
+		};
+		BBBBB49C2B6F743700C7205E /* AttachmentEmailer */ = {
+			isa = PBXGroup;
+			children = (
+				BBBBB49D2B6F743700C7205E /* SKAttachmentEmailer.h */,
+				BBBBB49E2B6F743700C7205E /* SKAttachmentEmailer.m */,
+			);
+			path = AttachmentEmailer;
+			sourceTree = "<group>";
+		};
 		BBBC08812B2AC845009B237F /* Model */ = {
 		BBBC08812B2AC845009B237F /* Model */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -14696,6 +14726,7 @@
 				BB6D2DA72B674A6300624C24 /* CPDFOutline+KMExtension.swift in Sources */,
 				BB6D2DA72B674A6300624C24 /* CPDFOutline+KMExtension.swift in Sources */,
 				BBBF68802A3BF17F0058E14E /* KMFilePromiseProvider.swift in Sources */,
 				BBBF68802A3BF17F0058E14E /* KMFilePromiseProvider.swift in Sources */,
 				ADDF832C2B391A5C00A81A4E /* NSEvent+PDFListView.m in Sources */,
 				ADDF832C2B391A5C00A81A4E /* NSEvent+PDFListView.m in Sources */,
+				BBBBB4992B6F714000C7205E /* NSObject+OCExtensions.m in Sources */,
 				9F0CB46F2967E63100007028 /* KMPropertiesPanelNameSubVC.swift in Sources */,
 				9F0CB46F2967E63100007028 /* KMPropertiesPanelNameSubVC.swift in Sources */,
 				9FD0FA3129CD947000F2AB0D /* KMOpacityPanel.swift in Sources */,
 				9FD0FA3129CD947000F2AB0D /* KMOpacityPanel.swift in Sources */,
 				9F0201792A1B5C0300C9B673 /* KMAIServerConfig.swift in Sources */,
 				9F0201792A1B5C0300C9B673 /* KMAIServerConfig.swift in Sources */,
@@ -15282,6 +15313,7 @@
 				ADE8BC2F29F8CD7200570F89 /* KMPDFThumbnailModel.swift in Sources */,
 				ADE8BC2F29F8CD7200570F89 /* KMPDFThumbnailModel.swift in Sources */,
 				BBBAECFC2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */,
 				BBBAECFC2B57713F00266BD3 /* KMTransitionInfo.swift in Sources */,
 				BB4EEF4029764FCC003A3537 /* KMWatermarkColorView.swift in Sources */,
 				BB4EEF4029764FCC003A3537 /* KMWatermarkColorView.swift in Sources */,
+				BBBBB49F2B6F743700C7205E /* SKAttachmentEmailer.m in Sources */,
 				BB146FC9299DC0D100784A6A /* GTMSessionFetcher.m in Sources */,
 				BB146FC9299DC0D100784A6A /* GTMSessionFetcher.m in Sources */,
 				9F8DDF342924DA6B006CDC73 /* KMPDFToolsCollectionView.swift in Sources */,
 				9F8DDF342924DA6B006CDC73 /* KMPDFToolsCollectionView.swift in Sources */,
 				BB99ACC2292DE22E0048AFD9 /* KMMergeViewController.swift in Sources */,
 				BB99ACC2292DE22E0048AFD9 /* KMMergeViewController.swift in Sources */,
@@ -16111,6 +16143,7 @@
 				BBB14A60297929BD00936EDB /* KMRedactPageRangeWindowController.swift in Sources */,
 				BBB14A60297929BD00936EDB /* KMRedactPageRangeWindowController.swift in Sources */,
 				ADA08A8B29F21A53009B2A7B /* KMPDFViewAnnotationOnceModeStore.swift in Sources */,
 				ADA08A8B29F21A53009B2A7B /* KMPDFViewAnnotationOnceModeStore.swift in Sources */,
 				9FF0D05D2B6A4C210018A732 /* KMPDFAnnotationChoiceWidgetSub.swift in Sources */,
 				9FF0D05D2B6A4C210018A732 /* KMPDFAnnotationChoiceWidgetSub.swift in Sources */,
+				BBBBB49A2B6F714000C7205E /* NSObject+OCExtensions.m in Sources */,
 				BB853C872AF8BC12009C20C1 /* KMAddPasswordOperationQueue.swift in Sources */,
 				BB853C872AF8BC12009C20C1 /* KMAddPasswordOperationQueue.swift in Sources */,
 				89E4E7832967BF5A002DBA6F /* KMCustomizeStampViewController.m in Sources */,
 				89E4E7832967BF5A002DBA6F /* KMCustomizeStampViewController.m in Sources */,
 				BB897252294C3F660045787C /* KMMenuTableView.swift in Sources */,
 				BB897252294C3F660045787C /* KMMenuTableView.swift in Sources */,
@@ -16359,6 +16392,7 @@
 				ADFA8F122B60E01C002595A4 /* KMSecureAlertView.swift in Sources */,
 				ADFA8F122B60E01C002595A4 /* KMSecureAlertView.swift in Sources */,
 				BB147012299DC0D100784A6A /* OIDError.m in Sources */,
 				BB147012299DC0D100784A6A /* OIDError.m in Sources */,
 				9F1FE50E29407B2B00E952CA /* KMUploadFilePanel.swift in Sources */,
 				9F1FE50E29407B2B00E952CA /* KMUploadFilePanel.swift in Sources */,
+				BBBBB4A02B6F743700C7205E /* SKAttachmentEmailer.m in Sources */,
 				BBA93D2E29BEBAA60044E0DD /* KMPreferenceEnum.swift in Sources */,
 				BBA93D2E29BEBAA60044E0DD /* KMPreferenceEnum.swift in Sources */,
 				ADE8BC3F29F9458700570F89 /* KMRecommondInfo.m in Sources */,
 				ADE8BC3F29F9458700570F89 /* KMRecommondInfo.m in Sources */,
 				BB1B0ADE2B4FC6E900889528 /* KMOpenFileGuidePanel.swift in Sources */,
 				BB1B0ADE2B4FC6E900889528 /* KMOpenFileGuidePanel.swift in Sources */,
@@ -16802,6 +16836,7 @@
 				BB853C9B2AF8E39D009C20C1 /* KMRemovePasswordOperationQueue.swift in Sources */,
 				BB853C9B2AF8E39D009C20C1 /* KMRemovePasswordOperationQueue.swift in Sources */,
 				BB8810AB2B4F7D7500AFA63E /* KMVerificationViewController.m in Sources */,
 				BB8810AB2B4F7D7500AFA63E /* KMVerificationViewController.m in Sources */,
 				BBE78F1D2B36F69F0071AC1A /* KMLeftSideViewController+Note.swift in Sources */,
 				BBE78F1D2B36F69F0071AC1A /* KMLeftSideViewController+Note.swift in Sources */,
+				BBBBB49B2B6F714000C7205E /* NSObject+OCExtensions.m in Sources */,
 				BBCE571A2A72723600508EFC /* NSResponder+KMExtension.swift in Sources */,
 				BBCE571A2A72723600508EFC /* NSResponder+KMExtension.swift in Sources */,
 				BB6D2DAD2B674D7900624C24 /* CPDFPage+KMExtension.swift in Sources */,
 				BB6D2DAD2B674D7900624C24 /* CPDFPage+KMExtension.swift in Sources */,
 				BB67EE252B54FFEF00573BF0 /* ASIInputStream.m in Sources */,
 				BB67EE252B54FFEF00573BF0 /* ASIInputStream.m in Sources */,
@@ -17419,6 +17454,7 @@
 				BB89726F294DB67D0045787C /* KMWatermarkAdjectiveBaseView.swift in Sources */,
 				BB89726F294DB67D0045787C /* KMWatermarkAdjectiveBaseView.swift in Sources */,
 				BB67EE222B54FFEF00573BF0 /* ASIDataDecompressor.m in Sources */,
 				BB67EE222B54FFEF00573BF0 /* ASIDataDecompressor.m in Sources */,
 				BB31981C2AC567B600107371 /* CPDFSelection+PDFListView.swift in Sources */,
 				BB31981C2AC567B600107371 /* CPDFSelection+PDFListView.swift in Sources */,
+				BBBBB4A12B6F743700C7205E /* SKAttachmentEmailer.m in Sources */,
 				AD58F4212B1DC29100299EE0 /* KMPrintViewModel.swift in Sources */,
 				AD58F4212B1DC29100299EE0 /* KMPrintViewModel.swift in Sources */,
 				AD1CA4132A061CCD0070541F /* KMAnnotationScreenColorViewItem.swift in Sources */,
 				AD1CA4132A061CCD0070541F /* KMAnnotationScreenColorViewItem.swift in Sources */,
 				BB3198202AC57ACA00107371 /* CPDFPage+PDFListView.swift in Sources */,
 				BB3198202AC57ACA00107371 /* CPDFPage+PDFListView.swift in Sources */,

+ 31 - 79
PDF Office/PDF Reader Pro.xcodeproj/xcuserdata/kdanmobile.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -324,12 +324,12 @@
             landmarkType = "7">
             landmarkType = "7">
             <Locations>
             <Locations>
                <Location
                <Location
-                  uuid = "A20B3568-4CD6-49FA-966A-0964A1226408 - d7da3d21f2c61f59"
+                  uuid = "A20B3568-4CD6-49FA-966A-0964A1226408 - ac90159306196e5d"
                   shouldBeEnabled = "Yes"
                   shouldBeEnabled = "Yes"
                   ignoreCount = "0"
                   ignoreCount = "0"
                   continueAfterRunningActions = "No"
                   continueAfterRunningActions = "No"
-                  symbolName = "PDF_Reaer_Pro.KMLeftSideViewController.noteFilterAction(Swift.Optional&lt;Swift.AnyObject&gt;) -&gt; ()"
-                  moduleName = "PDF Reaer Pro"
+                  symbolName = "PDF_Reader_Pro.KMLeftSideViewController.noteFilterAction(Swift.Optional&lt;Swift.AnyObject&gt;) -&gt; ()"
+                  moduleName = "PDF Reader Pro"
                   usesParentBreakpointCondition = "Yes"
                   usesParentBreakpointCondition = "Yes"
                   urlString = "file:///Users/kdanmobile/work/tangchao/git/PDFOffice/PDF%20Office/PDF%20Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController+Note.swift"
                   urlString = "file:///Users/kdanmobile/work/tangchao/git/PDFOffice/PDF%20Office/PDF%20Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController+Note.swift"
                   startingColumnNumber = "9223372036854775807"
                   startingColumnNumber = "9223372036854775807"
@@ -339,12 +339,12 @@
                   offsetFromSymbolStart = "145">
                   offsetFromSymbolStart = "145">
                </Location>
                </Location>
                <Location
                <Location
-                  uuid = "A20B3568-4CD6-49FA-966A-0964A1226408 - d7da3d21f2c61f59"
+                  uuid = "A20B3568-4CD6-49FA-966A-0964A1226408 - ac90159306196e5d"
                   shouldBeEnabled = "Yes"
                   shouldBeEnabled = "Yes"
                   ignoreCount = "0"
                   ignoreCount = "0"
                   continueAfterRunningActions = "No"
                   continueAfterRunningActions = "No"
-                  symbolName = "PDF_Reaer_Pro.KMLeftSideViewController.noteFilterAction(Swift.Optional&lt;Swift.AnyObject&gt;) -&gt; ()"
-                  moduleName = "PDF Reaer Pro"
+                  symbolName = "PDF_Reader_Pro.KMLeftSideViewController.noteFilterAction(Swift.Optional&lt;Swift.AnyObject&gt;) -&gt; ()"
+                  moduleName = "PDF Reader Pro"
                   usesParentBreakpointCondition = "Yes"
                   usesParentBreakpointCondition = "Yes"
                   urlString = "file:///Users/kdanmobile/work/tangchao/git/PDFOffice/PDF%20Office/PDF%20Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController+Note.swift"
                   urlString = "file:///Users/kdanmobile/work/tangchao/git/PDFOffice/PDF%20Office/PDF%20Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController+Note.swift"
                   startingColumnNumber = "9223372036854775807"
                   startingColumnNumber = "9223372036854775807"
@@ -468,22 +468,6 @@
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "0E83125F-00B9-4F94-9611-32508D9FDE88"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/ChromiumTabs/src/Tab/CTTabController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "238"
-            endingLineNumber = "238"
-            landmarkName = "-closeTab:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
       <BreakpointProxy
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
          <BreakpointContent
@@ -503,112 +487,80 @@
       <BreakpointProxy
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
          <BreakpointContent
-            uuid = "9E718376-DE80-4634-8B64-3F1429EA80A7"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/ChromiumTabs/src/Tab Strip/CTTabStripController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "655"
-            endingLineNumber = "655"
-            landmarkName = "-closeTab:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "5D015F4F-C9E5-40B2-A985-34CAC043AB2E"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/ChromiumTabs/src/Tab Strip/CTTabStripModel.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "374"
-            endingLineNumber = "374"
-            landmarkName = "-closeTabContentsAtIndex:closeTypes:"
-            landmarkType = "7">
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "A0735532-C836-484C-BE11-2A5824747B8E"
+            uuid = "62860C5A-ECF0-4262-BBDB-099360B5B9BA"
             shouldBeEnabled = "Yes"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/ChromiumTabs/src/Tab Strip/CTTabStripModel.m"
+            filePath = "PDF Master/Class/ChromiumTabs/KMBrowser.swift"
             startingColumnNumber = "9223372036854775807"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "718"
-            endingLineNumber = "718"
-            landmarkName = "-internalCloseTabs:closeTypes:"
+            startingLineNumber = "226"
+            endingLineNumber = "226"
+            landmarkName = "document(_:shouldClose:contextInfo:)"
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
       <BreakpointProxy
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
          <BreakpointContent
-            uuid = "08763613-0A18-4FF6-8B56-FF393545ADAB"
+            uuid = "91F33339-1DFF-47F6-B2E9-9B4A12D84A5E"
             shouldBeEnabled = "Yes"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/ChromiumTabs/KMBrowser.swift"
+            filePath = "PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift"
             startingColumnNumber = "9223372036854775807"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "132"
-            endingLineNumber = "132"
-            landmarkName = "canCloseContents(at:)"
+            startingLineNumber = "473"
+            endingLineNumber = "473"
+            landmarkName = "addAnnotationForStyleMenu(_:)"
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
       <BreakpointProxy
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
          <BreakpointContent
-            uuid = "62860C5A-ECF0-4262-BBDB-099360B5B9BA"
+            uuid = "84C1CA5D-0448-47E5-92DB-8A76F64B1A7B"
             shouldBeEnabled = "Yes"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/ChromiumTabs/KMBrowser.swift"
+            filePath = "PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift"
             startingColumnNumber = "9223372036854775807"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "226"
-            endingLineNumber = "226"
-            landmarkName = "document(_:shouldClose:contextInfo:)"
+            startingLineNumber = "1029"
+            endingLineNumber = "1029"
+            landmarkName = "changeAnnotationMode_itemAction(sender:)"
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
       <BreakpointProxy
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
          <BreakpointContent
-            uuid = "91F33339-1DFF-47F6-B2E9-9B4A12D84A5E"
+            uuid = "CB90171A-4C0B-4AC2-96C8-5E824332ED5B"
             shouldBeEnabled = "Yes"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift"
+            filePath = "PDF Master/Class/Document/KMMainDocument.swift"
             startingColumnNumber = "9223372036854775807"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "473"
-            endingLineNumber = "473"
-            landmarkName = "addAnnotationForStyleMenu(_:)"
+            startingLineNumber = "561"
+            endingLineNumber = "561"
+            landmarkName = "saveArchive(_:)"
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>
       <BreakpointProxy
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
          <BreakpointContent
-            uuid = "84C1CA5D-0448-47E5-92DB-8A76F64B1A7B"
+            uuid = "2B2F3874-0006-4323-8A7D-D4A4D3E0BE5A"
             shouldBeEnabled = "Yes"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift"
+            filePath = "PDF Master/Class/Common/OC/Common/NSObject+OCExtensions.m"
             startingColumnNumber = "9223372036854775807"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1029"
-            endingLineNumber = "1029"
-            landmarkName = "changeAnnotationMode_itemAction(sender:)"
+            startingLineNumber = "17"
+            endingLineNumber = "17"
+            landmarkName = "-newSaveArchiveToURL:email:"
             landmarkType = "7">
             landmarkType = "7">
          </BreakpointContent>
          </BreakpointContent>
       </BreakpointProxy>
       </BreakpointProxy>