Jelajahi Sumber

Merge branch 'develop_PDFReaderProNew' of git.kdan.cc:Mac_PDF/PDF_Office into develop_PDFReaderProNew

jiajie 1 tahun lalu
induk
melakukan
4e338e1a29

+ 34 - 0
PDF Office/PDF Master.xcodeproj/project.pbxproj

@@ -2688,6 +2688,18 @@
 		BB8F4586295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB8F4585295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift */; };
 		BB8F4587295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB8F4585295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift */; };
 		BB8F4588295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB8F4585295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift */; };
+		BB90E4E62AF3473300B04B9F /* SKPreferenceController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4E42AF3473300B04B9F /* SKPreferenceController.m */; };
+		BB90E4E72AF3473300B04B9F /* SKPreferenceController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4E42AF3473300B04B9F /* SKPreferenceController.m */; };
+		BB90E4E82AF3473300B04B9F /* SKPreferenceController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4E42AF3473300B04B9F /* SKPreferenceController.m */; };
+		BB90E4EA2AF347A700B04B9F /* PreferenceWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB90E4E92AF347A700B04B9F /* PreferenceWindow.xib */; };
+		BB90E4EB2AF347A700B04B9F /* PreferenceWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB90E4E92AF347A700B04B9F /* PreferenceWindow.xib */; };
+		BB90E4EC2AF347A700B04B9F /* PreferenceWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB90E4E92AF347A700B04B9F /* PreferenceWindow.xib */; };
+		BB90E4EE2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4ED2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift */; };
+		BB90E4EF2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4ED2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift */; };
+		BB90E4F02AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4ED2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift */; };
+		BB90E4F22AF37F9F00B04B9F /* KMCustomViewButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4F12AF37F9F00B04B9F /* KMCustomViewButton.swift */; };
+		BB90E4F32AF37F9F00B04B9F /* KMCustomViewButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4F12AF37F9F00B04B9F /* KMCustomViewButton.swift */; };
+		BB90E4F42AF37F9F00B04B9F /* KMCustomViewButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90E4F12AF37F9F00B04B9F /* KMCustomViewButton.swift */; };
 		BB93CDE52AE757A000B29C57 /* KMToolbarItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB93CDE42AE757A000B29C57 /* KMToolbarItemView.swift */; };
 		BB93CDE62AE757A000B29C57 /* KMToolbarItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB93CDE42AE757A000B29C57 /* KMToolbarItemView.swift */; };
 		BB93CDE72AE757A000B29C57 /* KMToolbarItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB93CDE42AE757A000B29C57 /* KMToolbarItemView.swift */; };
@@ -4488,6 +4500,11 @@
 		BB8F457D295B00130037EA22 /* KMWatermarkAdjectiveTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMWatermarkAdjectiveTools.swift; sourceTree = "<group>"; };
 		BB8F4581295B0F900037EA22 /* KMHeaderFooterMarginInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMHeaderFooterMarginInfoView.swift; sourceTree = "<group>"; };
 		BB8F4585295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMHeaderFooterDateInfoView.swift; sourceTree = "<group>"; };
+		BB90E4E42AF3473300B04B9F /* SKPreferenceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKPreferenceController.m; sourceTree = "<group>"; };
+		BB90E4E52AF3473300B04B9F /* SKPreferenceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKPreferenceController.h; sourceTree = "<group>"; };
+		BB90E4E92AF347A700B04B9F /* PreferenceWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PreferenceWindow.xib; sourceTree = "<group>"; };
+		BB90E4ED2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSUserDefaultsController+KMExtension.swift"; sourceTree = "<group>"; };
+		BB90E4F12AF37F9F00B04B9F /* KMCustomViewButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMCustomViewButton.swift; sourceTree = "<group>"; };
 		BB93CDE42AE757A000B29C57 /* KMToolbarItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMToolbarItemView.swift; sourceTree = "<group>"; };
 		BB93CDE82AE7B6E100B29C57 /* KMToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMToolbarView.swift; sourceTree = "<group>"; };
 		BB9695B029BDA46500FD68D3 /* SKLocalization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKLocalization.h; sourceTree = "<group>"; };
@@ -7107,6 +7124,7 @@
 				BB60138F2AD3AFF000A76FB2 /* NSPopover+KMExtension.swift */,
 				BB7BC4DB2AD3FFC200D6BEE6 /* NSImage+ KMExtension.swift */,
 				BBA388122AEF9A42004FE93F /* NSWindow+KMExtension.swift */,
+				BB90E4ED2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift */,
 			);
 			path = Category;
 			sourceTree = "<group>";
@@ -7794,6 +7812,9 @@
 		BB6CA4C9298BB0B100A13864 /* Window */ = {
 			isa = PBXGroup;
 			children = (
+				BB90E4E52AF3473300B04B9F /* SKPreferenceController.h */,
+				BB90E4E42AF3473300B04B9F /* SKPreferenceController.m */,
+				BB90E4E92AF347A700B04B9F /* PreferenceWindow.xib */,
 				BB6CA4CA298BB0D000A13864 /* KMPreferenceWindowController.swift */,
 				BB6CA4CB298BB0D000A13864 /* KMPreferenceWindowController.xib */,
 			);
@@ -8498,6 +8519,7 @@
 				BB6347B72AF224E100F5438E /* KMConvertCollectionViewHeader.xib */,
 				BB6347C32AF24F6300F5438E /* KMBatchoperateConvertCollectionViewItem.swift */,
 				BB6347C72AF24F6C00F5438E /* KMBatchoperateConvertCollectionViewItem.xib */,
+				BB90E4F12AF37F9F00B04B9F /* KMCustomViewButton.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -9079,6 +9101,7 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				BB90E4EA2AF347A700B04B9F /* PreferenceWindow.xib in Resources */,
 				ADE3C1AE29A4779E00793B13 /* KMPrintAccessoryController.xib in Resources */,
 				BBEC00BA295C2C1600A26C98 /* KMBatesPropertyHomeController.xib in Resources */,
 				AD1CA3FA2A05FCB60070541F /* KMAnnotationScreenViewController.xib in Resources */,
@@ -9552,6 +9575,7 @@
 				BBA8B7B4293635D80097D183 /* KMPasswordInputWindow.xib in Resources */,
 				9F78EFBF28F7C1CC001E66F4 /* KMHomeViewController.xib in Resources */,
 				9F8539FA2947137500DF644E /* newtab_p.pdf in Resources */,
+				BB90E4EB2AF347A700B04B9F /* PreferenceWindow.xib in Resources */,
 				9FBA0EF228FFC716001117AF /* KMHomeFastToolViewController.xib in Resources */,
 				ADF6B8712A480CCE0090CB78 /* KMComparativeView.xib in Resources */,
 				ADCFFC0729C04617007D3657 /* BOTA.xcassets in Resources */,
@@ -9720,6 +9744,7 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				BB90E4EC2AF347A700B04B9F /* PreferenceWindow.xib in Resources */,
 				9F705F7B291A3A84005199AD /* KMHistoryFileDeleteWindowController.xib in Resources */,
 				89E4E7432964160F002DBA6F /* KMAnnotationLinkViewController.xib in Resources */,
 				ADBC373929CA975B00D93208 /* KMCompatative.xcassets in Resources */,
@@ -10225,6 +10250,7 @@
 				BB74DA7B2AC41DE9006EDFE7 /* NSString+KMExtension.swift in Sources */,
 				AD1CA4112A061CCD0070541F /* KMAnnotationScreenColorViewItem.swift in Sources */,
 				BBF8A4012AE8B4E200788BAC /* KMBatchBaseParameter.swift in Sources */,
+				BB90E4E62AF3473300B04B9F /* SKPreferenceController.m in Sources */,
 				AD867FC129DFC39400F00440 /* KMBOTAAnnotationItem.swift in Sources */,
 				BBDA8A6D2A31F9A6006A2C4E /* KMDesignStepperView.swift in Sources */,
 				BBFDFA9E2AF3814000E08AA2 /* KMTextHintWindowController.swift in Sources */,
@@ -10694,6 +10720,7 @@
 				BBEB93EF2AD6C72C00739573 /* KMPDFMergePageRangeTabelViewCell.swift in Sources */,
 				BB897256294C559F0045787C /* KMWatermarkPropertyCreateController.swift in Sources */,
 				F35B484B29A4903300756255 /* NSPointerArray+PDFListView.m in Sources */,
+				BB90E4EE2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift in Sources */,
 				BBB14A532978DD5400936EDB /* KMRedactTools.swift in Sources */,
 				BB5F8A1129BB04F000365ADB /* GBDeviceInfo_Common.m in Sources */,
 				BBAFC83C2985194800D0648E /* KMPDFEditAppendWindow.m in Sources */,
@@ -10705,6 +10732,7 @@
 				9F0CB4ED298655A800007028 /* KMDesignToken+PaddingLeft.swift in Sources */,
 				BB00302E298D315E002DD1A0 /* KMPreferenceMarkupController.swift in Sources */,
 				9F1FE49C29406E4700E952CA /* HoverCloseButton.m in Sources */,
+				BB90E4F22AF37F9F00B04B9F /* KMCustomViewButton.swift in Sources */,
 				AD9527D72952ED970039D2BC /* KMPrintPresenter_C.swift in Sources */,
 				ADDEEA6E2AD3E16100EF675D /* KMSigntureViewItem.swift in Sources */,
 				BB6CA4CC298BB0D000A13864 /* KMPreferenceWindowController.swift in Sources */,
@@ -10885,6 +10913,7 @@
 				BB14700C299DC0D100784A6A /* OIDAuthorizationRequest.m in Sources */,
 				ADE3C1DF29A5AA0B00793B13 /* KMRequestServer.swift in Sources */,
 				BBC3484B2958222C008D2CD1 /* KMBackgroundOutsideView.swift in Sources */,
+				BB90E4F32AF37F9F00B04B9F /* KMCustomViewButton.swift in Sources */,
 				AD0257402A8601CD00EAD5D5 /* KMAppleLoginManager.swift in Sources */,
 				ADBC2CFB299CA6B9006280C8 /* KMPrintDuplexPrintingSetView.swift in Sources */,
 				BBA19F4429ADE6A3001A285A /* KMBookMarkRowView.swift in Sources */,
@@ -11424,6 +11453,7 @@
 				BB162E98295062CD0088E9D1 /* KMPageRangeTools.swift in Sources */,
 				AD8810B329A846B100178CA1 /* KMVerficationCodeWindowController.swift in Sources */,
 				BB981E532AD4F638001988CA /* KMCoverButton.swift in Sources */,
+				BB90E4E72AF3473300B04B9F /* SKPreferenceController.m in Sources */,
 				BB5F8A0F29BB04F000365ADB /* GBDeviceInfo_OSX.m in Sources */,
 				BBB7B48A2A033F6200B58A5A /* KMThumbnailView.swift in Sources */,
 				BB1BFF6A2AEA02F8003EB179 /* KMBatchOperateSplitViewController.swift in Sources */,
@@ -11546,6 +11576,7 @@
 				9F8DDF2729237910006CDC73 /* Array+KMExtensions.swift in Sources */,
 				8942F7EA2925E1C400389627 /* KMLiftSideCellView.swift in Sources */,
 				ADE8BC3029F8CD7200570F89 /* KMPDFThumbnailModel.swift in Sources */,
+				BB90E4EF2AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift in Sources */,
 				ADDEEA7F2AD3FB1D00EF675D /* KMImageAccessoryController.swift in Sources */,
 				BB4EEF4129764FCC003A3537 /* KMWatermarkColorView.swift in Sources */,
 				BB146FCA299DC0D100784A6A /* GTMSessionFetcher.m in Sources */,
@@ -11871,6 +11902,7 @@
 				BB1BFF732AEA0AFE003EB179 /* KMBatchOperateLeftViewController.swift in Sources */,
 				9F1FE4E629406E4700E952CA /* GTMNSColor+Luminance.m in Sources */,
 				9F0CB523298656AA00007028 /* KMDesignToken+BorderRadiusBottomLeft.swift in Sources */,
+				BB90E4E82AF3473300B04B9F /* SKPreferenceController.m in Sources */,
 				BB3A81AE2AC2A4E4006FC66C /* NSTextView+KMExtension.swift in Sources */,
 				9F0CB4DF2986554D00007028 /* KMDesignToken+HorizontalPadding.swift in Sources */,
 				ADDEEA682AD3C4BF00EF675D /* KMPDFSignatureImageView.swift in Sources */,
@@ -12026,6 +12058,7 @@
 				ADDEEA6C2AD3CF3A00EF675D /* KMDrawView.swift in Sources */,
 				9F1F82EC2935D02E0092C4B4 /* KMComboBox.swift in Sources */,
 				8997012128F41AB8009AF911 /* KMLeftSideViewController.swift in Sources */,
+				BB90E4F42AF37F9F00B04B9F /* KMCustomViewButton.swift in Sources */,
 				F35B484D29A4903300756255 /* NSPointerArray+PDFListView.m in Sources */,
 				BBC70EB62AEA847500AC1585 /* KMToolbarCustomViewController.swift in Sources */,
 				89752E062939DB42003FF08E /* KMToolbarViewController.swift in Sources */,
@@ -12118,6 +12151,7 @@
 				9F78EFBD28F7C1CC001E66F4 /* KMHomeViewController.swift in Sources */,
 				9FCFEC9A2AD14EEF00EAD2CB /* KMMailHelper.swift in Sources */,
 				BBC745EC295F067B0072C2ED /* KMCropSettingWindowController.swift in Sources */,
+				BB90E4F02AF3546500B04B9F /* NSUserDefaultsController+KMExtension.swift in Sources */,
 				ADE8BC2729F7CCA600570F89 /* KMPageNumberDisplayView.swift in Sources */,
 				ADB5E50E2A3703E6007110A8 /* KMInAppPurchaseManager.swift in Sources */,
 				ADD1B6C92942E83000C3FFF7 /* KMPrintBottomView.swift in Sources */,

+ 2 - 1
PDF Office/PDF Master/AppDelegate.swift

@@ -378,7 +378,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
     
     // MARK: PDF Master Menu
     @IBAction func openPreferenceWindow(_ sender: Any) {
-        KMPreferenceWindowController.shared.showWindow(nil)
+//        KMPreferenceWindowController.shared.showWindow(nil)
+        (SKPreferenceController.sharedPrefenceController() as? NSWindowController)?.showWindow(self)
     }
     
     @objc @IBAction func manageAcctounMenuAction(_ sender: Any) {

+ 45 - 45
PDF Office/PDF Master/Class/Batch/View/KMBatchTableCellView.swift

@@ -251,62 +251,62 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
     func updateInterface(_ file: KMBatchOperateFile) {
         self.file = file
         if self.type == .Size {
-            self.textField!.stringValue = file.sizeString
+            self.textField?.stringValue = file.sizeString
         } else if self.type == .FileName {
             if (file.error != nil) {
-                self.errorTextField!.stringValue = file.error!.localizedDescription
-                self.errorTextField!.isHidden = false
+                self.errorTextField?.stringValue = file.error!.localizedDescription
+                self.errorTextField?.isHidden = false
             } else {
-                self.errorTextField!.isHidden = true
+                self.errorTextField?.isHidden = true
             }
-            self.textField!.stringValue = file.filePath.lastPathComponent
+            self.textField?.stringValue = file.filePath.lastPathComponent
         } else if self.type == .PageRange {
-            self.pageRangeCombobox!.isEnabled = self.file!.status != .processing
-            self.pageRangeCombobox!.delegate = nil
-            self.pageRangeCombobox!.selectItem(at: file.currentOperateInfo!.pageChoice?.rawValue ?? 0)
-            self.pageRangeCombobox!.isEditable = false
+            self.pageRangeCombobox?.isEnabled = self.file!.status != .processing
+            self.pageRangeCombobox?.delegate = nil
+            self.pageRangeCombobox?.selectItem(at: file.currentOperateInfo?.pageChoice?.rawValue ?? 0)
+            self.pageRangeCombobox?.isEditable = false
             if file.currentOperateInfo!.pageChoice == .Input {
-                self.pageRangeCombobox!.isEditable = true
-                self.pageRangeCombobox!.stringValue = file.currentOperateInfo!.pageRangeString ?? ""
+                self.pageRangeCombobox?.isEditable = true
+                self.pageRangeCombobox?.stringValue = file.currentOperateInfo?.pageRangeString ?? ""
             }
             self.pageRangeCombobox!.delegate = self
         } else if self.type == .Status {
             if file.status == .Waiting {
-                self.indicateImageView!.isHidden = false
-                self.progressIndicator!.isHidden = true
+                self.indicateImageView?.isHidden = false
+                self.progressIndicator?.isHidden = true
                 
-                self.indicateImageView!.image = NSImage(named: KMImageNameUXIconProgressWaiting)
+                self.indicateImageView?.image = NSImage(named: KMImageNameUXIconProgressWaiting)
             } else if file.status == .Success {
-                self.indicateImageView!.isHidden = false
-                self.progressIndicator!.isHidden = true
-                self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressComplete")
+                self.indicateImageView?.isHidden = false
+                self.progressIndicator?.isHidden = true
+                self.indicateImageView?.image = NSImage(named: "KMImageNameUXIconProgressComplete")
             } else if file.status == .Failed {
-                self.indicateImageView!.isHidden = false
-                self.progressIndicator!.isHidden = true
-                self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressFailure")
+                self.indicateImageView?.isHidden = false
+                self.progressIndicator?.isHidden = true
+                self.indicateImageView?.image = NSImage(named: "KMImageNameUXIconProgressFailure")
             } else if file.status == .processing {
-                self.indicateImageView!.isHidden = true
-                self.progressIndicator!.isHidden = false
-                self.progressIndicator!.startAnimation(nil)
+                self.indicateImageView?.isHidden = true
+                self.progressIndicator?.isHidden = false
+                self.progressIndicator?.startAnimation(nil)
             }
         } else if self.type == .DPI {
             switch self.file?.dpi {
             case 50:
-                self.DPIComboBox!.selectItem(at: 0)
+                self.DPIComboBox?.selectItem(at: 0)
             case 72:
-                self.DPIComboBox!.selectItem(at: 1)
+                self.DPIComboBox?.selectItem(at: 1)
             case 96:
-                self.DPIComboBox!.selectItem(at: 2)
+                self.DPIComboBox?.selectItem(at: 2)
             case 150:
-                self.DPIComboBox!.selectItem(at: 3)
+                self.DPIComboBox?.selectItem(at: 3)
             case 300:
-                self.DPIComboBox!.selectItem(at: 4)
+                self.DPIComboBox?.selectItem(at: 4)
             case 600:
-                self.DPIComboBox!.selectItem(at: 5)
+                self.DPIComboBox?.selectItem(at: 5)
             default:
                 break
             }
-            self.DPIComboBox!.isEnabled = self.file?.status != .processing
+            self.DPIComboBox?.isEnabled = self.file?.status != .processing
         } else if self.type == .Dimensions {
             
         }
@@ -314,37 +314,37 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
     func updateInterface( file: KMBatchOperateFile, progress: Float) {
         updateInterface(file)
         if progress > 0 && file.status == .processing {
-            self.progressIndicator!.doubleValue = Double(progress)
-            self.progressIndicator!.startAnimation(nil)
-            self.progressIndicator!.isIndeterminate = false
+            self.progressIndicator?.doubleValue = Double(progress)
+            self.progressIndicator?.startAnimation(nil)
+            self.progressIndicator?.isIndeterminate = false
         }
     }
     func updateInterface(isProgress progress: Int) {
         if progress == -1 {
-            self.indicateImageView!.isHidden = false
-            self.progressIndicator!.isHidden = true
-            self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressFailure")
+            self.indicateImageView?.isHidden = false
+            self.progressIndicator?.isHidden = true
+            self.indicateImageView?.image = NSImage(named: "KMImageNameUXIconProgressFailure")
         } else if progress == 0 {
-            self.indicateImageView!.isHidden = false
-            self.progressIndicator!.isHidden = true
-            self.indicateImageView!.image = NSImage(named: KMImageNameUXIconProgressWaiting)
+            self.indicateImageView?.isHidden = false
+            self.progressIndicator?.isHidden = true
+            self.indicateImageView?.image = NSImage(named: KMImageNameUXIconProgressWaiting)
         } else {
-            self.indicateImageView!.isHidden = false
-            self.progressIndicator!.isHidden = true
-            self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressComplete")
+            self.indicateImageView?.isHidden = false
+            self.progressIndicator?.isHidden = true
+            self.indicateImageView?.image = NSImage(named: "KMImageNameUXIconProgressComplete")
         }
     }
     func controlTextDidEndEditing(_ obj: Notification) {
         if let object = self.pageRangeCombobox?.isEqual(obj.object) {
-            self.file!.currentOperateInfo!.pageRangeString = self.pageRangeCombobox!.stringValue
-            if self.file!.currentOperateInfo?.pagesArray == nil {
+            self.file?.currentOperateInfo?.pageRangeString = self.pageRangeCombobox!.stringValue
+            if self.file?.currentOperateInfo?.pagesArray == nil {
                 let alert = NSAlert()
                 alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
                 alert.alertStyle = .critical
                 alert.messageText = self.file!.filePath.lastPathComponent.lastPathComponent + NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
                 alert.beginSheetModal(for: self.window!, completionHandler: nil)
                 self.pageRangeCombobox?.selectItem(at: 0)
-                self.file?.currentOperateInfo!.pageChoice = .All
+                self.file?.currentOperateInfo?.pageChoice = .All
             }
         }
     }

+ 512 - 0
PDF Office/PDF Master/Class/Batch/View/KMCustomViewButton.swift

@@ -0,0 +1,512 @@
+//
+//  KMCustomViewButton.swift
+//  PDF Master
+//
+//  Created by tangchao on 2023/11/2.
+//
+
+import Cocoa
+@objc enum KMCustomViewButtonType: Int {
+    case batchToolbar = 0
+    case menuItem
+    case normal
+}
+
+@objc enum KMCustomViewButtonState: Int {
+    case normal = 0
+    case mouseIn
+    case hightLighted
+}
+
+@objc protocol KMCustomButtonViewPopDataSource: NSObjectProtocol {
+    /// pop框有多少行
+    func numberOfLine(in button: KMCustomViewButton) -> Int
+    /// pop框某行显示的文字
+    func string(for button: KMCustomViewButton, index: Int) -> String?
+    /// 某行是否需要下划线
+    func needInsertSeperateLine(_ button: KMCustomViewButton, index: Int) -> Bool
+    /// 某行是否需要选取
+    func needHightLightLine(_ button: KMCustomViewButton, index: Int) -> Bool
+}
+
+@objc protocol KMCustomButtonViewPopDelegate: NSObjectProtocol {
+    func customViewButton(_ button: KMCustomViewButton, didSelectIndex index: Int)
+}
+
+@objcMembers class KMCustomViewButton: NSView {
+    /// constraint
+    var frontImageLeftConstraint: MASConstraint? //左边图片距离左边约束
+    var frontImageTopConstraint: MASConstraint? //左边图片顶部约束
+    var titleLeftConstraint: MASConstraint? //标题距离左边约束
+    var titleTopConstraint: MASConstraint? //标题顶部约束
+    var backImageLeftConstraint: MASConstraint? //右边图片距离左边约束
+    
+    /// view
+    lazy var imageView: NSImageView = {
+        let view = NSImageView()
+        return view
+    }()
+    lazy var titleTextField: NSTextField = {
+        let view = NSTextField()
+        view.isBordered = false
+        view.drawsBackground = true
+        view.backgroundColor = .clear
+        view.isEditable = false
+        return view
+    }()
+    lazy var indicateImageView: NSImageView = {
+        let view = NSImageView()
+        return view
+    }()
+    weak var layoutReferenceView: NSView?
+    
+    /// layer
+    var backLayer: CALayer?
+    
+    /// state
+    var isSelected = false {
+        didSet {
+            if (self.isSelected) {
+                self._toolbarButtonSelected(true)
+                if let color = self.selectColor {
+                    self.backLayer?.backgroundColor = color.cgColor
+                }
+            } else {
+                self._toolbarButtonSelected(true)
+                self.backLayer?.backgroundColor = .clear
+            }
+        }
+    }
+    
+    var mouseInColor: NSColor?
+    var highLightColor: NSColor?
+    var selectColor: NSColor?
+    
+    /// popover
+    var popOver: NSPopover?
+    
+    var enable = false
+    
+    /// title Attribute
+    var titleAttributeDict: [String : Any]?
+    
+    weak var dataSource: KMCustomButtonViewPopDataSource? {
+        didSet {
+            NotificationCenter.default.removeObserver(self)
+            NotificationCenter.default.addObserver(self, selector: #selector(_closePop), name: NSNotification.Name("KMCloseCustomViewButtonPopNotification"), object: nil)
+        }
+    }
+    weak var delegate: KMCustomButtonViewPopDelegate?
+    
+    private var _showMenuFlag = false
+    
+    private var _type: KMCustomViewButtonType = .batchToolbar
+    private var _state: KMCustomViewButtonState = .normal {
+        didSet {
+            if (self._state == .normal) {
+                if (self.isSelected) {
+                    self.backLayer?.backgroundColor = self.selectColor != nil ? self.selectColor!.cgColor : .clear
+                } else {
+                    self._toolbarButtonSelected(true)
+                    self.backLayer?.backgroundColor = .clear
+                }
+            } else if (self._state == .mouseIn) {
+                self._toolbarButtonSelected(true)
+                if (self.isSelected) {
+                    self.backLayer?.backgroundColor = self.selectColor != nil ? self.selectColor!.cgColor : (self.mouseInColor ?? NSColor.clear).cgColor
+                } else {
+                    self.backLayer?.backgroundColor = (self.mouseInColor ?? NSColor.clear).cgColor
+                }
+            } else if (self._state == .hightLighted) {
+                if (self.isSelected) {
+                    self.backLayer?.backgroundColor = self.selectColor != nil ? self.selectColor!.cgColor : (self.highLightColor ?? NSColor.clear).cgColor
+                } else {
+                    self.backLayer?.backgroundColor = (self.highLightColor ?? NSColor.clear).cgColor
+                }
+            }
+            
+            if (self.titleAttributeDict != nil) {
+                self.titleTextField.textColor = self.titleAttributeDict?["\(self._state.rawValue)"] as? NSColor
+            }
+        }
+    }
+    
+    private weak var _target: AnyObject?
+    private var _action: Selector?
+    
+    deinit {
+        KMPrint("KMCustomViewButton deinit.")
+        NotificationCenter.default.removeObserver(self)
+    }
+    
+    /**
+     * 初始化方法
+     * @param frontImage 头部图片
+     * @param backImage 尾部图片
+     * @param title 标题
+     * @param title 样式
+     *
+     */
+    convenience init(frontImage: NSImage?, backImage: NSImage?, title: String?, type: KMCustomViewButtonType) {
+        if frontImage == nil && backImage == nil && title == nil {
+//            return
+        }
+        self.init()
+        self.wantsLayer = true
+        self.enable = false
+        
+        self._addTrackingArea()
+        self.layoutReferenceView = self
+        var leftMargin = 0.0
+         if (frontImage != nil) {
+             self.addSubview(self.imageView)
+             self.imageView.image = frontImage
+             leftMargin = 8
+             self.imageView.mas_makeConstraints { make in
+                 self.frontImageLeftConstraint = make?.left.equalTo()(self.layoutReferenceView)?.offset()(leftMargin)
+                 make?.centerY.top().equalTo()(self.layoutReferenceView)
+                 self.frontImageTopConstraint = make?.top.equalTo()(self.layoutReferenceView)?.offset()(3)
+             }
+             self.layoutReferenceView = self.imageView
+         }
+        
+        if (title != nil) {
+            self.addSubview(self.titleTextField)
+            self.titleTextField.stringValue = title!
+            self.titleTextField.font = .systemFont(ofSize: 12)
+            self.titleTextField.textColor = KMAppearance.Layout.h0Color()
+            self.titleTextField.mas_makeConstraints { make in
+                if self.isEqual(to: self.layoutReferenceView) {
+                    leftMargin = 30
+                    self.titleLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
+                    self.titleTopConstraint = make?.top.equalTo()(self)?.offset()(3)
+                    make?.centerY.equalTo()(self)
+                } else {
+                    leftMargin = 8
+                    self.titleLeftConstraint = make?.left.equalTo()(self.imageView.mas_right)?.offset()(leftMargin)
+                    make?.centerY.equalTo()(self)
+                }
+            }
+            self.layoutReferenceView = self.titleTextField
+        }
+        
+        if (backImage != nil) {
+            self.addSubview(self.indicateImageView)
+            self.indicateImageView.image = backImage
+            self.indicateImageView.mas_makeConstraints { make in
+                self.backImageLeftConstraint = make?.left.equalTo()(self.layoutReferenceView?.mas_right)?.offset()(2)
+                make?.centerY.equalTo()(self)
+            }
+            self.layoutReferenceView = self.indicateImageView
+        }
+        
+        self.layoutReferenceView?.mas_makeConstraints({ make in
+            make?.right.equalTo()(self)?.offset()(-leftMargin)
+        })
+        self.configuAppearance(type: type)
+        self._type = type
+        self._state = .normal
+        self.isSelected = false
+    }
+    
+    override func mouseEntered(with event: NSEvent) {
+        if (self.enable) {
+            super.mouseEntered(with: event)
+//            [self setState:KMCustomViewButtonState_MouseIn];
+            self._showPop()
+            if (self.dataSource == nil) {
+                NotificationCenter.default.post(name: NSNotification.Name("KMCloseCustomViewButtonPopNotification"), object: nil)
+            }
+        }
+    }
+    
+    // MARK: - Public Methods
+    
+    /// 设置设置target-action
+    func addTarget(_ target: AnyObject?, action: Selector?) {
+        self._target = target
+        self._action = action
+    }
+    
+    /// 关闭pop
+    func closePop() {
+        self._closePop()
+    }
+    
+    override func mouseExited(with event: NSEvent) {
+        if (self.enable) {
+            super.mouseExited(with: event)
+            if (self._showMenuFlag) {
+            } else {
+                self._state = .normal
+            }
+        }
+    }
+    
+    override func mouseDown(with event: NSEvent) {
+        if (self.enable) {
+            super.mouseDown(with: event)
+            self._state = .hightLighted
+        }
+    }
+    
+    override func mouseUp(with event: NSEvent) {
+        if (self.enable) {
+            super.mouseUp(with: event)
+            if (self._showMenuFlag) {
+            } else {
+                self._state = .normal
+            }
+            /// 响应事件
+            if let data = (self._target as? NSObject)?.responds(to: self._action), data {
+                (self._target as? NSObject)?.perform(self._action, with: self)
+            }
+        }
+    }
+}
+
+// MARK: - Private Methods
+
+extension KMCustomViewButton {
+    private func _toolbarButtonSelected(_ isSelected: Bool) {
+        //    if (isSelected) {
+        //        if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Convert", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvert"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Merge", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchMerge"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Compress", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchOptimize"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"OCR", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvertOCR"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Security", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchSafe"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Watermark", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchWatermark"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Background", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBackground"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Header & Footer", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchHeaderandfooter"];
+        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Bates Numbers", nil)]) {
+        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBates"];
+        //        }
+        //    } else {
+        if self.titleTextField.stringValue == KMLocalizedString("Convert", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchConvertNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("Merge", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchMergeNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("Compress", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchOptimizeNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("OCR", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchConvertOCRNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("Security", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchSafeNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("Watermark", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchWatermarkNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("Background", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchBackgroundNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("Header & Footer", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchHeaderandfooterNor")
+        } else if self.titleTextField.stringValue == KMLocalizedString("Bates Numbers", nil) {
+            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchBatesNor")
+        }
+
+        //    }
+    }
+    
+    @objc private func _closePop() {
+        self.popOver?.close()
+        self._state = .normal
+    }
+    
+    private func _showPop() {
+        if (self.delegate == nil || self.dataSource == nil) {
+            return
+        }
+        
+        let menuViewController = KMCustomButtonPopMenuViewController()
+        menuViewController.delegate = self
+        menuViewController.dataSources = self
+        if (self.popOver == nil) {
+            self.popOver = NSPopover()
+        }
+        
+        self.popOver?.delegate = self
+        self.popOver?.contentViewController = menuViewController
+        self.popOver?.animates = false
+        self.popOver?.behavior = .semitransient
+        self.popOver?.contentSize = menuViewController.view.frame.size
+        
+        var sourcesRect = self.bounds
+        sourcesRect = self.convert(sourcesRect, to: nil)
+        sourcesRect.origin.y -= 20
+        sourcesRect.size.height+=20
+        self.window?.popover = self.popOver
+        self.window?.sourcesRect = sourcesRect
+        self.popOver?.show(relativeTo: CGRectInset(self.bounds, 0, 5), of: self, preferredEdge: .minY)
+    }
+    
+    private func _addTrackingArea() {
+        let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .inVisibleRect, .activeAlways,.mouseMoved], owner: self)
+        self.addTrackingArea(trackingArea)
+    }
+}
+
+// MARK: - NSPopoverDelegate
+
+extension KMCustomViewButton: NSPopoverDelegate {
+    func popoverDidShow(_ notification: Notification) {
+        self._showMenuFlag = true
+    }
+    
+    func popoverDidClose(_ notification: Notification) {
+        self._showMenuFlag = false
+        self._state = .normal
+    }
+}
+
+// MARK: - KMCustomButtonPopMenuViewControllerDelegate, KMCustomButtonPopMenuViewControllerDataSources
+
+extension KMCustomViewButton: KMCustomButtonPopMenuViewControllerDelegate, KMCustomButtonPopMenuViewControllerDataSources {
+    func customViewButtonPopDidSelectIndex(_ index: Int) {
+        if let _ = self.delegate?.customViewButton(self, didSelectIndex: index) {
+            self._closePop()
+        }
+    }
+    
+    func numberOfLine() -> Int {
+        if let data = self.dataSource?.numberOfLine(in: self) {
+            return data
+        }
+        return 0
+    }
+    
+    /// pop框某行显示的文字
+    func stringForLine(at index: Int) -> String? {
+        if let data = self.dataSource?.string(for: self, index: index) {
+            return data
+        }
+        return nil;
+    }
+    
+    /// 某行是否需要下划线
+    func needInsertSeperateLine(at index: Int) -> Bool {
+        if let data = self.dataSource?.needInsertSeperateLine(self, index: index) {
+            return data
+        }
+        return false
+    }
+    
+    /// 某行是否需要选取
+    func needHightLightLine(at index: Int) -> Bool {
+        if let data = self.dataSource?.needHightLightLine(self, index: index) {
+            return data
+        }
+        return false
+    }
+    
+    func imageForLine(at index: Int) -> NSImage? {
+        return nil
+    }
+    
+    func itemEnable(at index: Int) -> Bool {
+        return true
+    }
+}
+
+// MARK: - Appearance
+
+extension KMCustomViewButton {
+    func configuAppearance(type: KMCustomViewButtonType) {
+        if (type == .batchToolbar) {
+            self.backLayer = CALayer()
+            self.backLayer?.frame = self.layer?.frame ?? NSRect.zero
+            self.backLayer?.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
+            self.layer?.addSublayer(self.backLayer!)
+            self.backLayer?.cornerRadius = 6.0;
+            self.selectColor = KMAppearance.Status.selColor()
+            self.highLightColor = KMAppearance.Status.selColor()
+            self.mouseInColor = KMAppearance.Status.selColor()
+        } else if (type == .menuItem) {
+            self.alignCenter(margin: 10)
+            self.changeTopMargin(5)
+        }
+    }
+    
+    /// 调整按钮左右间距并居中
+    func alignCenter(margin: CGFloat) {
+        self.changeLeftMargin(margin)
+        self.changeRightMargin(margin)
+    }
+    
+    /// 调整顶部间距离
+    func changeTopMargin(_ topMargin: CGFloat) {
+        let v = self._leftestView()
+        if self.imageView.isEqual(to: v) {
+            self.imageView.mas_updateConstraints { make in
+                make?.top.equalTo()(self)?.offset()(topMargin)
+            }
+        } else if self.titleTextField.isEqual(to: v) {
+            self.titleTextField.mas_updateConstraints { make in
+                make?.top.equalTo()(self)?.offset()(topMargin)
+            }
+        } else if self.indicateImageView.isEqual(to: v) {
+            
+        }
+    }
+    /// 调整按钮左边间距
+    func changeLeftMargin(_ leftMargin: CGFloat) {
+        let v = self._leftestView()
+        if self.imageView.isEqual(to: v) {
+            self.imageView.mas_updateConstraints { make in
+                self.frontImageLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
+            }
+        } else if self.titleTextField.isEqual(to: v) {
+            self.titleTextField.mas_updateConstraints { make in
+                self.titleLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
+            }
+        } else if self.indicateImageView.isEqual(to: v) {
+            self.indicateImageView.mas_updateConstraints { make in
+                self.backImageLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
+            }
+        }
+    }
+    /// 调整按钮右边间距
+    func changeRightMargin(_ rightMargin: CGFloat) {
+        let v = self._rightestView()
+        if self.imageView.isEqual(to: v) {
+            self.imageView.mas_updateConstraints { make in
+                make?.right.equalTo()(self)?.offset()(-rightMargin)
+            }
+        } else if self.titleTextField.isEqual(to: v) {
+            self.titleTextField.mas_updateConstraints { make in
+                make?.right.equalTo()(self)?.offset()(-rightMargin)
+            }
+        } else if self.indicateImageView.isEqual(to: v) {
+            self.indicateImageView.mas_updateConstraints { make in
+                make?.right.equalTo()(self)?.offset()(-rightMargin)
+            }
+        }
+    }
+    
+    private func _leftestView() -> NSView? {
+        if self.subviews.contains(self.imageView) {
+            return self.imageView
+        } else if self.subviews.contains(self.titleTextField) {
+            return self.titleTextField
+        } else if (self.subviews.contains(self.indicateImageView)) {
+            return self.indicateImageView
+        }
+        return nil
+    }
+    
+    private func _rightestView() -> NSView? {
+        if self.subviews.contains(self.indicateImageView) {
+            return self.indicateImageView
+        } else if self.subviews.contains(self.titleTextField) {
+            return self.titleTextField
+        } else if self.subviews.contains(self.imageView) {
+            return self.imageView
+        }
+        return nil
+    }
+}

+ 2 - 2
PDF Office/PDF Master/Class/Batch/View/KMLongerButton.swift

@@ -50,8 +50,8 @@ class KMLongerButton: NSButton{
         sourcesRect = sender.convert(sourcesRect, to: nil)
         sourcesRect.origin.y -= 20
         sourcesRect.size.height += 20
-        self.window!.popover = self.popOver
-        self.window!.sourcesRect = sourcesRect
+        self.window?.popover = self.popOver
+        self.window?.sourcesRect = sourcesRect
         
         self.popOver?.show(relativeTo: self.bounds.insetBy(dx: 0, dy: 5), of: self, preferredEdge: .maxY)
     }

+ 4 - 2
PDF Office/PDF Master/Class/Batch/View/KMSlider.swift

@@ -62,8 +62,10 @@ class KMSlider: NSSlider, NSPopoverDelegate{
             self.adjustTipAlignment()
         }
     }
-    func adjustTipAlignment() { guard let tipContentView = self.tipPopover?.contentViewController?.view
-        else { return }
+    func adjustTipAlignment() {
+        guard let tipContentView = self.tipPopover?.contentViewController?.view else {
+            return
+        }
         guard let tipView = tipContentView.subviews.first as? NSTextField else {
             return
         }

+ 0 - 106
PDF Office/PDF Master/Class/Batch/WindowController/OC/KMCustomViewButton.h

@@ -1,106 +0,0 @@
-//
-//  KMBatchToolbarItemView_New.h
-//  PDF Reader Pro Edition
-//
-//  Created by Kdan on 2020/10/22.
-//
-
-#import <Cocoa/Cocoa.h>
-#import "KMBatchOperateManager.h"
-
-#import <Masonry/Masonry.h>
-
-typedef NS_ENUM(NSUInteger, KMCustomViewButtonType) {
-    KMCustomViewButtonType_BatchToolbar = 0,
-    KMCustomViewButtonType_MenuItem,
-    KMCustomViewButtonType_Normal,
-};
-
-typedef NS_ENUM(NSUInteger, KMCustomViewButtonState) {
-    KMCustomViewButtonState_Normal = 0,
-    KMCustomViewButtonState_MouseIn,
-    KMCustomViewButtonState_HightLighted,
-};
-
-@class KMCustomViewButton;
-
-
-
-@protocol KMCustomButtonViewPopDataSource <NSObject>
-@required
-//pop框有多少行
-- (NSInteger)numberOfLineInCustomViewButtonPop:(KMCustomViewButton *)button;
-//pop框某行显示的文字
-- (NSString *)stringForCustomViewButtonPop:(KMCustomViewButton *)button index:(NSInteger)index;
-//某行是否需要下划线
-- (BOOL)needInsertSeperateLine:(KMCustomViewButton *)button index:(NSInteger)index;
-//某行是否需要选取
-- (BOOL)needHightLightLine:(KMCustomViewButton *)button index:(NSInteger)index;
-
-@end
-
-@protocol KMCustomButtonViewPopDelegate <NSObject>
-@required
-- (void)customViewButton:(KMCustomViewButton *)button didSelectIndex:(NSInteger)index;
-
-@end
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface KMCustomViewButton : NSView
-
-//constraint
-@property (nonatomic, retain) MASConstraint *frontImageLeftConstraint;//左边图片距离左边约束
-@property (nonatomic, retain) MASConstraint *frontImageTopConstraint;//左边图片顶部约束
-@property (nonatomic, retain) MASConstraint *titleLeftConstraint;//标题距离左边约束
-@property (nonatomic, retain) MASConstraint *titleTopConstraint;//标题顶部约束
-@property (nonatomic, retain) MASConstraint *backImageLeftConstraint;//右边图片距离左边约束
-
-//view
-@property (nonatomic, retain) NSImageView *imageView;
-@property (nonatomic, retain) NSTextField *titleTextField;
-@property (nonatomic, retain) NSImageView *indicateImageView;
-@property (nonatomic, assign) NSView *layoutReferenceView;
-
-//layer
-@property (nonatomic, retain) CALayer *backLayer;
-
-//popover
-@property (nonatomic, retain) NSPopover *popOver;
-
-//type
-@property (nonatomic, assign, readonly) KMCustomViewButtonType type;
-//title Attribute
-@property (nonatomic, retain) NSMutableDictionary *titleAttributeDict;
-//delegate&datasources
-@property (nonatomic, assign) id <KMCustomButtonViewPopDataSource>dataSource;
-@property (nonatomic, assign) id <KMCustomButtonViewPopDelegate>delegate;
-//state
-@property (nonatomic, assign) BOOL isSelected;
-
-@property (nonatomic, retain) NSColor *mouseInColor;
-@property (nonatomic, retain) NSColor *highLightColor;
-@property (nonatomic, retain) NSColor *selectColor;
-
-@property (nonatomic, assign) BOOL enable;
-
-/// 初始化方法
-/// @param frontImage 头部图片
-/// @param backImage 尾部图片
-/// @param title 标题
-/// @param type 样式
-- (instancetype)initWithFrontImage:(nullable NSImage *)frontImage
-                         backImage:(nullable NSImage *)backImage
-                             title:(NSString *)title
-                             type:(KMCustomViewButtonType)type;
-
-//设置设置target-action
-- (void)addTarget:(id)target action:(SEL)action;
-
-//关闭pop
-- (void)closePop;
-
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 393
PDF Office/PDF Master/Class/Batch/WindowController/OC/KMCustomViewButton.m

@@ -1,393 +0,0 @@
-//
-//  KMBatchToolbarItemView_New.m
-//  PDF Reader Pro Edition
-//
-//  Created by Kdan on 2020/10/22.
-//
-
-#import "KMCustomViewButton.h"
-
-#import "KMAppearance.h"
-
-#import "KMToolbarItemPopViewController.h"
-
-#import "KMCustomButtonPopMenuViewController.h"
-
-#import "NSPopover+MISSINGBackgroundView.h"
-
-#import "KMCustomViewButton+Appearance.h"
-#import "NSWindow+PopOver.h"
-
-@interface KMCustomViewButton ()<KMCustomButtonPopMenuViewControllerDataSources,KMCustomButtonPopMenuViewControllerDelegate,NSPopoverDelegate>
-
-@property (nonatomic, assign) NSView *lastPart;//弃用
-@property (nonatomic, assign) BOOL showBackLayerFlag;
-@property (nonatomic, assign) BOOL showMenuFlag;
-@property (nonatomic, assign) id target;
-@property (nonatomic, assign) SEL action;
-@property (nonatomic, assign) KMCustomViewButtonType type;
-@property (nonatomic, assign) KMCustomViewButtonState state;
-@property (nonatomic, assign) BOOL popShowFlag;
-
-@end
-
-@implementation KMCustomViewButton
-
-#pragma mark - Life Cycle
-
-- (void)dealloc {
-    //constraint
-    [_frontImageLeftConstraint release];
-    [_frontImageTopConstraint release];
-    [_titleLeftConstraint release];
-    [_titleTopConstraint release];
-    [_backImageLeftConstraint release];
-    [_imageView release];
-    [_titleTextField release];
-    [_indicateImageView release];
-    [_backLayer release];
-    _popOver.delegate = nil;
-    [_popOver release];
-    [_titleAttributeDict release];
-    [_mouseInColor release];
-    [_highLightColor release];
-    [_selectColor release];
-
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    
-     
-    [super dealloc];
-}
-
-- (instancetype)initWithFrontImage:(nullable NSImage *)frontImage
-                         backImage:(nullable NSImage *)backImage
-                             title:(NSString *)title
-                              type:(KMCustomViewButtonType)type {
-    if (!frontImage && !backImage && !title) {
-        return nil;
-    }
-    if (self = [super init]) {
-        self.wantsLayer = YES;
-        self.enable = NO;
-        
-        [self addTrackingArea];
-        self.layoutReferenceView = self;
-       __block CGFloat leftMargin = 0;
-        if (frontImage) {
-            [self addSubview:self.imageView];
-            self.imageView.image = frontImage;
-            leftMargin = 8;
-            [self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
-                self.frontImageLeftConstraint =   make.left.equalTo(self.layoutReferenceView).offset(leftMargin);
-                make.centerY.top.equalTo(self.layoutReferenceView);
-               self.frontImageTopConstraint = make.top.equalTo(self.layoutReferenceView).offset(3);
-            }];
-            self.layoutReferenceView = self.imageView;
-        }
-        
-        
-        if (title) {
-            [self addSubview:self.titleTextField];
-            self.titleTextField.stringValue = title;
-            self.titleTextField.font = [NSFont systemFontOfSize:12];
-            self.titleTextField.textColor = [KMAppearance KMColor_Layout_H0];
-            [self.titleTextField mas_makeConstraints:^(MASConstraintMaker *make) {
-                if ([self.layoutReferenceView isEqual:self]) {
-                    leftMargin = 30;
-                    self.titleLeftConstraint = make.left.equalTo(self).offset(leftMargin);
-                    self.titleTopConstraint = make.top.equalTo(self).offset(3);
-                    make.centerY.equalTo(self);
-                    
-                } else {
-                    leftMargin = 8;
-                    self.titleLeftConstraint = make.left.equalTo(self.imageView.mas_right).offset(leftMargin);
-                    make.centerY.equalTo(self);
-                }
-            }];
-            self.layoutReferenceView = self.titleTextField;
-        }
-        
-        if (backImage) {
-            [self addSubview:self.indicateImageView];
-            self.indicateImageView.image = backImage;
-            [self.indicateImageView mas_makeConstraints:^(MASConstraintMaker *make) {
-                self.backImageLeftConstraint = make.left.equalTo(self.layoutReferenceView.mas_right).offset(2);
-                make.centerY.equalTo(self);
-            }];
-            self.layoutReferenceView = self.indicateImageView;
-        }
-        
-        [self.layoutReferenceView mas_updateConstraints:^(MASConstraintMaker *make) {
-            make.right.equalTo(self).offset(-leftMargin);
-        }];
-        [self configuAppearance:type];
-        self.type =type;
-        self.state = KMCustomViewButtonState_Normal;
-        self.isSelected = NO;
-    }
-    return self;
-}
-
-
-#pragma mark - Getter & Setter
-
-- (NSImageView *)imageView {
-    if (!_imageView) {
-        _imageView = [[NSImageView alloc] init];
-    }
-    return _imageView;
-}
-
-- (NSTextField *)titleTextField {
-    if (!_titleTextField) {
-        _titleTextField = [[NSTextField alloc] initWithFrame:CGRectZero];
-        _titleTextField.bordered = NO;
-        _titleTextField.drawsBackground = YES;//如果设置成NO,颜色会透下去
-        _titleTextField.backgroundColor = [NSColor clearColor];
-        _titleTextField.editable = NO;
-    }
-    return _titleTextField;
-}
-
-- (NSImageView *)indicateImageView {
-    if (!_indicateImageView) {
-        _indicateImageView = [[[NSImageView alloc] init] autorelease];
-    }
-    return _indicateImageView;
-}
-
-- (void)setState:(KMCustomViewButtonState)state {
-    _state = state;
-    
-    if (state == KMCustomViewButtonState_Normal) {
-        if (self.isSelected) {
-            self.backLayer.backgroundColor = self.selectColor?self.selectColor.CGColor:[NSColor clearColor].CGColor;
-        } else {
-            [self toolbarButtonSelected:YES];
-            self.backLayer.backgroundColor = [NSColor clearColor].CGColor;
-        }
-    } else if (state == KMCustomViewButtonState_MouseIn) {
-        [self toolbarButtonSelected:YES];
-        if (self.isSelected) {
-            self.backLayer.backgroundColor = self.selectColor?self.selectColor.CGColor:self.mouseInColor.CGColor;
-        } else {
-            self.backLayer.backgroundColor = self.mouseInColor.CGColor;
-        }
-    } else if (state == KMCustomViewButtonState_HightLighted) {
-        if (self.isSelected) {
-            self.backLayer.backgroundColor = self.selectColor?self.selectColor.CGColor:self.highLightColor.CGColor;
-        } else {
-            self.backLayer.backgroundColor = self.highLightColor.CGColor;
-        }
-    }
-    
-    if (self.titleAttributeDict) {
-        self.titleTextField.textColor = [self.titleAttributeDict objectForKey:[NSString stringWithFormat:@"%ld",state]];
-    }
-}
-
-#pragma mark - Private Methods
-
-- (void)addTrackingArea {
-    NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveAlways |NSTrackingMouseMoved owner:self userInfo:nil];
-    [self addTrackingArea:trackingArea];
-    [trackingArea release];
-}
-
-#pragma mark - Event Methods
-
-- (void)mouseEntered:(NSEvent *)event {
-    
-    if (self.enable) {
-        [super mouseEntered:event];
-        [self setState:KMCustomViewButtonState_MouseIn];
-        [self showPop];
-        if (!self.dataSource) {
-            [[NSNotificationCenter defaultCenter] postNotificationName:@"KMCloseCustomViewButtonPopNotification" object:nil userInfo:nil];
-        }
-    }
-
-}
-
-- (void)mouseExited:(NSEvent *)event {
-    if (self.enable) {
-        [super mouseExited:event];
-        if (self.showMenuFlag) {
-            
-        } else {
-            [self setState:KMCustomViewButtonState_Normal];
-        }
-    }
-}
-
-- (void)mouseDown:(NSEvent *)event {
-    if (self.enable) {
-        [super mouseDown:event];
-        [self setState:KMCustomViewButtonState_HightLighted];
-    }
-    
-}
-
-- (void)mouseUp:(NSEvent *)event {
-    if (self.enable) {
-        [super mouseUp:event];
-        if (self.showMenuFlag) {
-        } else {
-            [self setState:KMCustomViewButtonState_Normal];
-        }
-        //响应事件
-        if ([self.target respondsToSelector:self.action]) {
-            [self.target performSelector:self.action withObject:self];
-        }
-    }
-}
-
-#pragma mark - Public Methods
-
-- (void)addTarget:(id)target action:(SEL)action {
-    self.target = target;
-    self.action = action;
-}
-
-- (void)setIsSelected:(BOOL)isSelected{
-    _isSelected = isSelected;
-    if (isSelected) {
-        [self toolbarButtonSelected:YES];
-        self.backLayer.backgroundColor = self.selectColor.CGColor;
-    } else {
-        [self toolbarButtonSelected:YES];
-        self.backLayer.backgroundColor = [NSColor clearColor].CGColor;
-    }
-}
-    
-- (void)closePop {
-    [self.popOver close];
-    [self setState:KMCustomViewButtonState_Normal];
-    
-}
-
-- (void)showPop {
-    if (!self.delegate || !self.dataSource) {
-        return;
-    }
-    KMCustomButtonPopMenuViewController *menuViewController = [[[KMCustomButtonPopMenuViewController alloc] init] autorelease];
-    menuViewController.delegate = self;
-    menuViewController.dataSources = self;
-    if (!self.popOver) {
-        self.popOver = [[[NSPopover alloc] init] autorelease];
-    }
-    
-    self.popOver.delegate = self;
-    self.popOver.contentViewController = menuViewController;
-    self.popOver.animates = NO;
-    self.popOver.behavior = NSPopoverBehaviorSemitransient;
-    self.popOver.contentSize = menuViewController.view.frame.size;
-    
-    CGRect sourcesRect = self.bounds;
-    sourcesRect = [self convertRect:sourcesRect toView:nil];
-    sourcesRect.origin.y-= 20;
-    sourcesRect.size.height+=20;
-    self.window.popover = self.popOver;
-    self.window.sourcesRect = sourcesRect;
-    [self.popOver showRelativeToRect:CGRectInset(self.bounds, 0, 5) ofView:self preferredEdge:CGRectMinYEdge];
-}
-
-- (void)toolbarButtonSelected:(BOOL)isSelected {
-//    if (isSelected) {
-//        if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Convert", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvert"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Merge", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchMerge"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Compress", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchOptimize"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"OCR", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvertOCR"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Security", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchSafe"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Watermark", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchWatermark"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Background", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBackground"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Header & Footer", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchHeaderandfooter"];
-//        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Bates Numbers", nil)]) {
-//            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBates"];
-//        }
-//    } else {
-        if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Convert", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvertNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Merge", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchMergeNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Compress", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchOptimizeNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"OCR", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvertOCRNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Security", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchSafeNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Watermark", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchWatermarkNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Background", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBackgroundNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Header & Footer", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchHeaderandfooterNor"];
-        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Bates Numbers", nil)]) {
-            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBatesNor"];
-        }
-//    }
-}
-
-#pragma mark -KMCustomButtonPopMenuViewControllerDataSources
-
-- (NSInteger)numberOfLine {
-    if ([self.dataSource respondsToSelector:@selector(numberOfLineInCustomViewButtonPop:)]) {
-        return [self.dataSource numberOfLineInCustomViewButtonPop:self];
-    }
-    return 0;
-}
-
-//pop框某行显示的文字
-- (nullable NSString *)stringForLineAtIndex:(NSInteger)index {
-    if ([self.dataSource respondsToSelector:@selector(stringForCustomViewButtonPop:index:)]) {
-        return [self.dataSource stringForCustomViewButtonPop:self index:index];
-    }
-    return nil;
-}
-//某行是否需要下划线
-- (BOOL)needInsertSeperateLineAtIndex:(NSInteger)index {
-    if ([self.dataSource respondsToSelector:@selector(needInsertSeperateLine:index:)]) {
-        return [self.dataSource needInsertSeperateLine:self index:index];
-    }
-    return NO;
-}
-//某行是否需要选取
-- (BOOL)needHightLightLineAtIndex:(NSInteger)index {
-    if ([self.dataSource respondsToSelector:@selector(needHightLightLine:index:)]) {
-        return [self.dataSource needHightLightLine:self index:index];
-    }
-    return NO;
-}
-
-#pragma mark - KMCustomButtonPopMenuViewControllerDelegate
-- (void)customViewButtonPopDidSelectIndex:(NSInteger)index {
-    if ([self.delegate respondsToSelector:@selector(customViewButton:didSelectIndex:)]) {
-        [self closePop];
-        [self.delegate customViewButton:self didSelectIndex:index];
-    }
-}
-
-- (void)popoverDidClose:(NSNotification *)notification {
-    self.showMenuFlag = NO;
-    [self setState:KMCustomViewButtonState_Normal];
-}
-
-- (void)popoverDidShow:(NSNotification *)notification {
-    self.showMenuFlag = YES;
-}
-
-- (void)setDataSource:(id<KMCustomButtonViewPopDataSource>)dataSource {
-    _dataSource = dataSource;
-    [[NSNotificationCenter defaultCenter] removeObserver:self];
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closePop) name:@"KMCloseCustomViewButtonPopNotification" object:nil];
-}
-
-@end

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

@@ -200,6 +200,41 @@ private var _currentPointingDeviceType: NSEvent.PointingDeviceType = .unknown
     }
 }
 
+// MARK: - NSGraphics_SKExtensions
+
+let  MIN_BUTTON_WIDTH = 82.0
+let MAX_BUTTON_WIDTH = 100.0
+let EXTRA_BUTTON_WIDTH = 12.0
+@objc extension NSGraphicsContext {
+    @objc static func SKAutoSizeButtons(_ buttons: NSArray, rightAlign: Bool) {
+        if (buttons.count == 0) {
+            return
+        }
+        let button = buttons.firstObject as! NSButton
+        var x = rightAlign ? NSMaxX(button.frame) : NSMinX(button.frame)
+        var width = 0.0
+        for btn in buttons {
+            let _btn = btn as! NSButton
+            _btn.sizeToFit()
+            width = fmax(width, NSWidth(_btn.frame) + EXTRA_BUTTON_WIDTH)
+        }
+        width = fmin(MAX_BUTTON_WIDTH, fmax(MIN_BUTTON_WIDTH, width))
+        for btn in buttons {
+            let _btn = btn as! NSButton
+            var frame = _btn.frame
+            frame.size.width = fmax(width, NSWidth(frame) + EXTRA_BUTTON_WIDTH)
+            if (rightAlign) {
+                x -= NSWidth(frame)
+                frame.origin.x = x
+            } else {
+                frame.origin.x = x
+                x += NSWidth(frame)
+            }
+            _btn.frame = frame
+        }
+    }
+}
+
 // MARK: - CGContext 相关
 
 func KMContextSaveGState(_ ctx: CGContext?) {

+ 45 - 0
PDF Office/PDF Master/Class/Common/Category/NSUserDefaultsController+KMExtension.swift

@@ -0,0 +1,45 @@
+//
+//  NSUserDefaultsController+KMExtension.swift
+//  PDF Master
+//
+//  Created by tangchao on 2023/11/2.
+//
+
+import Foundation
+
+extension NSUserDefaultsController {
+//    @objc addObserver(_ anObserver: AnyObject, forKey key: String, context: Any?) {
+//        self.addObserver(anObserver, forKeyPath: key, options: .init(rawValue: 0), context: context)
+//    }
+    
+    @objc func revertToInitialValues(forKeys keys: [String]) {
+        for key in keys {
+            (self.values as? NSMutableDictionary)?.setValue(self.initialValues?[key], forKey: key)
+        }
+    }
+}
+
+/*
+ - (void)addObserver:(NSObject *)anObserver forKey:(NSString *)key context:(void *)context {
+     [self addObserver:anObserver forKeyPath:VALUES_KEY_PATH(key) options:0 context:context];
+ }
+
+ - (void)removeObserver:(NSObject *)anObserver forKey:(NSString *)key {
+     [self removeObserver:anObserver forKeyPath:VALUES_KEY_PATH(key)];
+ }
+
+ - (void)addObserver:(NSObject *)anObserver forKeys:(NSArray *)keys context:(void *)context {
+     for (NSString *key in keys)
+         [self addObserver:anObserver forKey:key context:context];
+ }
+
+ - (void)removeObserver:(NSObject *)anObserver forKeys:(NSArray *)keys {
+     for (NSString *key in keys)
+         [self removeObserver:anObserver forKey:key];
+ }
+
+ - (void)revertToInitialValueForKey:(NSString *)key {
+     [[self values] setValue:[[self initialValues] objectForKey:key] forKey:key];
+ }
+
+ */

+ 8 - 0
PDF Office/PDF Master/Class/Common/Category/NSView+KMExtension.swift

@@ -134,8 +134,16 @@ extension NSView {
         }
         return false
     }
+    
+    @objc func deactivateWellSubcontrols() {
+        for sv in self.subviews {
+            sv.deactivateWellSubcontrols()
+        }
+    }
 }
 
+
+
 // MARK: - layout code
 
 extension NSView {

+ 9 - 0
PDF Office/PDF Master/Class/Common/KMCommonDefine.swift

@@ -42,3 +42,12 @@ typealias KMResultBlock = (_ result: KMResult?, _ params: Any...)->Void
 let kKMLocalForDraggedTypes = NSPasteboard.PasteboardType(rawValue: "KMLocalForDraggedTypes")
 
 let kKMMainMenuAccountRefreshItemTag = 16
+
+// MARK: - SKStringConstants
+
+let SKDisableAnimationsKey = "SKDisableAnimations"
+
+@objcMembers class SKStringConstants: NSObject {
+    public static let disableAnimationsKey = SKDisableAnimationsKey
+}
+

+ 6 - 0
PDF Office/PDF Master/Class/PDFWindowController/Toolbar/KMToolbarView.swift

@@ -313,6 +313,9 @@ private let KMToolbarItemSpace = 8.0
         for item in self.leftView.subviews {
             item.removeFromSuperview()
         }
+        if (self.leftView.superview != nil) {
+            self.leftView.removeFromSuperview()
+        }
         
         if let itemIdentifiers = self.delegate?.toolbarLeftDefaultItemIdentifiers?(self), itemIdentifiers.count > 0 {
             if (self.leftView.superview == nil) {
@@ -386,6 +389,9 @@ private let KMToolbarItemSpace = 8.0
         for item in self.rightView.subviews {
             item.removeFromSuperview()
         }
+        if (self.rightView.superview != nil) {
+            self.rightView.removeFromSuperview()
+        }
         
         if let itemIdentifiers = self.delegate?.toolbarRightDefaultItemIdentifiers?(self) {
             if (self.rightView.superview == nil) {

+ 64 - 0
PDF Office/PDF Master/Class/Preference/Window/PreferenceWindow.xib

@@ -0,0 +1,64 @@
+<?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">
+    <dependencies>
+        <deployment version="101100" identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="SKPreferenceController" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="resetButtons" destination="1657" id="1658"/>
+                <outlet property="window" destination="5" id="7"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application"/>
+        <window allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="5" userLabel="Window" customClass="SKPreferenceWindow" customModule="PDF_Master" customModuleProvider="target">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES"/>
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+            <rect key="contentRect" x="327" y="514" width="438" height="256"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="875"/>
+            <value key="minSize" type="size" width="213" height="107"/>
+            <view key="contentView" id="6">
+                <rect key="frame" x="0.0" y="0.0" width="438" height="256"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <button toolTip="Revert all preferences to their original values" verticalHuggingPriority="750" fixedFrame="YES" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="491">
+                        <rect key="frame" x="76" y="3" width="73" height="28"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                        <buttonCell key="cell" type="push" title="Reset All" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" inset="2" id="1648">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="smallSystem"/>
+                        </buttonCell>
+                        <connections>
+                            <action selector="resetAll:" target="-2" id="494"/>
+                        </connections>
+                    </button>
+                    <button toolTip="Revert all currently shown preferences to their original values" verticalHuggingPriority="750" fixedFrame="YES" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="492">
+                        <rect key="frame" x="5" y="3" width="73" height="28"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                        <buttonCell key="cell" type="push" title="Reset" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" inset="2" id="1649">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="smallSystem"/>
+                        </buttonCell>
+                        <connections>
+                            <accessibilityConnection property="link" destination="491" id="1656"/>
+                            <action selector="resetCurrent:" target="-2" id="495"/>
+                        </connections>
+                    </button>
+                </subviews>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="8"/>
+            </connections>
+            <point key="canvasLocation" x="-273" y="-27"/>
+        </window>
+        <customObject id="1657" userLabel="Reset Buttons" customClass="SKIBArray" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="object1" destination="492" id="1659"/>
+                <outlet property="object2" destination="491" id="1660"/>
+            </connections>
+        </customObject>
+    </objects>
+</document>

+ 89 - 0
PDF Office/PDF Master/Class/Preference/Window/SKPreferenceController.h

@@ -0,0 +1,89 @@
+//
+//  SKPreferenceController.h
+//  Skim
+//
+//  Created by Christiaan Hofman on 2/10/07.
+/*
+ This software is Copyright (c) 2007-2018
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+//#import "SKWindowController.h"
+
+@class SKIBArray;
+@protocol SKPreferencePane;
+
+@interface SKPreferenceController : NSWindowController <NSWindowDelegate, NSTabViewDelegate, NSToolbarDelegate> {
+    NSArray *resetButtons;
+    NSArray *preferencePanes;
+    NSViewController<SKPreferencePane> *currentPane;
+    NSMutableArray *history;
+    NSUInteger historyIndex;
+}
+
+@property (nonatomic, retain) IBOutlet NSArray *resetButtons;
+
++ (id)sharedPrefenceController;
+
+- (IBAction)resetAll:(id)sender;
+- (IBAction)resetCurrent:(id)sender;
+
+- (IBAction)doGoToNextPage:(id)sender;
+- (IBAction)doGoToPreviousPage:(id)sender;
+- (IBAction)doGoToFirstPage:(id)sender;
+- (IBAction)doGoToLastPage:(id)sender;
+- (IBAction)doGoBack:(id)sender;
+- (IBAction)doGoForward:(id)sender;
+
+- (IBAction)changeFont:(id)sender;
+- (IBAction)changeAttributes:(id)sender;
+
+- (void)selectPaneWithIdentifier:(NSString *)itemIdentifier;
+
+@end
+
+
+@protocol SKPreferencePane
+@optional
+- (void)defaultsDidRevert;
+@end
+
+@interface SKPreferenceWindow : NSWindow
+@end
+
+@interface SKIBArray : NSArray {
+    id object[9];
+    unsigned long mutations;
+}
+@property (nonatomic, retain) IBOutlet id object1, object2, object3, object4, object5, object6, object7, object8, object9;
+@end
+

+ 494 - 0
PDF Office/PDF Master/Class/Preference/Window/SKPreferenceController.m

@@ -0,0 +1,494 @@
+//
+//  SKPreferenceController.m
+//  Skim
+//
+//  Created by Christiaan Hofman on 2/10/07.
+/*
+ This software is Copyright (c) 2007-2018
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKPreferenceController.h"
+//#import "SKGeneralPreferences.h"
+//#import "SKDisplayPreferences.h"
+//#import "SKNotesPreferences.h"
+//#import "SKSyncPreferences.h"
+//#import "NSUserDefaultsController_SKExtensions.h"
+//#import "SKFontWell.h"
+//#import "SKStringConstants.h"
+//#import "NSView_SKExtensions.h"
+//#import "NSGraphics_SKExtensions.h"
+//#import "NSGeometry_SKExtensions.h"
+//#import "NSAnimationContext_SKExtensions.h"
+//#import "DropboxPreferences.h"
+/*#import "KMOCRPreferences.h" //恢复OCR架上版本样式*/
+
+#define SKPreferencesToolbarIdentifier @"SKPreferencesToolbarIdentifier"
+
+#define SKPreferenceWindowFrameAutosaveName @"SKPreferenceWindow"
+
+#define SKLastSelectedPreferencePaneKey @"SKLastSelectedPreferencePane"
+
+#define NIBNAME_KEY @"nibName"
+
+#define BOTTOM_MARGIN 27.0
+
+#define INITIALUSERDEFAULTS_KEY @"InitialUserDefaults"
+#define RESETTABLEKEYS_KEY @"ResettableKeys"
+#import <PDF_Master-Swift.h>
+
+static inline NSRect SKShrinkRect(NSRect rect, CGFloat amount, NSRectEdge edge) {
+    NSRect ignored;
+    NSDivideRect(rect, &ignored, &rect, amount, edge);
+    return rect;
+}
+
+@implementation SKPreferenceController
+
+//@synthesize resetButtons;
+
+static SKPreferenceController *sharedPrefenceController = nil;
+
++ (id)sharedPrefenceController {
+    if (sharedPrefenceController == nil)
+        [[self alloc] init];
+    return sharedPrefenceController;
+}
+
++ (id)allocWithZone:(NSZone *)zone {
+    return sharedPrefenceController ?: [super allocWithZone:zone];
+}
+
+- (id)init {
+    if (sharedPrefenceController == nil) {
+        self = [super initWithWindowNibName:@"PreferenceWindow"];
+        if (self) {
+//            preferencePanes = [[NSArray alloc] initWithObjects:
+//                [[[SKGeneralPreferences alloc] init] autorelease],
+//                [[[SKDisplayPreferences alloc] init] autorelease],
+//                [[[SKNotesPreferences alloc] init] autorelease],
+//                [[[SKSyncPreferences alloc] init] autorelease],
+//                [[[DropboxPreferences alloc] init] autorelease],
+//                [[[KMOCRPreferences alloc] init] autorelease], nil];  //恢复OCR架上版本样式
+//                [[[DropboxPreferences alloc] init] autorelease],
+//                               nil];
+            history = [[NSMutableArray alloc] init];
+            historyIndex = 0;
+        }
+        sharedPrefenceController = self;
+    } else if (self != sharedPrefenceController) {
+        NSLog(@"Attempt to allocate second instance of %@", [self class]);
+        self = sharedPrefenceController;
+    }
+    return self;
+}
+
+- (void)dealloc {
+    currentPane = nil;
+//    SKDESTROY(preferencePanes);
+//    SKDESTROY(resetButtons);
+//    SKDESTROY(history);
+//    [super dealloc];
+}
+
+- (NSViewController<SKPreferencePane> *)preferencePaneForItemIdentifier:(NSString *)itemIdent {
+    [self panelControlSelectColor:itemIdent];
+
+    for (NSViewController<SKPreferencePane> *pane in preferencePanes)
+        if ([[pane nibName] isEqualToString:itemIdent])
+            return pane;
+    return nil;
+}
+
+- (void)selectPane:(NSViewController<SKPreferencePane> *)pane {
+    if ([pane isEqual:currentPane] == NO) {
+        if (pane) {
+            historyIndex++;
+            if ([history count] > historyIndex)
+                [history removeObjectsInRange:NSMakeRange(historyIndex, [history count] - historyIndex)];
+            [history addObject:pane];
+        } else {
+            pane = [history objectAtIndex:historyIndex];
+        }
+        
+        NSWindow *window = [self window];
+        NSView *contentView = [window contentView];
+        NSView *oldView = [currentPane view];
+        NSView *view = [pane view];
+        NSRect frame = SKShrinkRect([window frame],  NSHeight([contentView frame]) - NSMaxY([view frame]), NSMinYEdge);
+        
+        // make sure edits are committed
+        [currentPane commitEditing];
+        [[NSUserDefaultsController sharedUserDefaultsController] commitEditing];
+        
+        currentPane = pane;
+        
+        [window setTitle:[currentPane title]];
+        [[NSUserDefaults standardUserDefaults] setObject:[currentPane nibName] forKey:SKLastSelectedPreferencePaneKey];
+        [[window toolbar] setSelectedItemIdentifier:[currentPane nibName]];
+
+        if ([[NSUserDefaults standardUserDefaults] boolForKey:SKStringConstants.disableAnimationsKey]) {
+            [contentView replaceSubview:oldView with:view];
+            [window setFrame:frame display:YES];
+        } else {
+            NSTimeInterval duration = [window animationResizeTime:frame];
+            [contentView displayIfNeeded];
+            [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
+                    [context setDuration:duration];
+                    [[contentView animator] replaceSubview:oldView with:view];
+                    [[window animator] setFrame:frame display:YES];
+                }
+                completionHandler:^{}];
+        }
+    }
+}
+
+- (void)windowDidLoad {
+    if (@available(macOS 11.0,*)) {
+        self.window.toolbarStyle = NSWindowToolbarStyleExpanded;
+    }
+    
+    NSWindow *window = [self window];
+    NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:SKPreferencesToolbarIdentifier];
+    
+    [toolbar setAllowsUserCustomization:NO];
+    [toolbar setAutosavesConfiguration:NO];
+    [toolbar setVisible:YES];
+    [toolbar setDelegate:self];
+    [window setToolbar:toolbar];
+    [window setShowsToolbarButton:NO];
+    
+    [[window contentView] setWantsLayer:YES];
+    
+    // we want to restore the top of the window, while without the force it restores the bottom position without the size
+    [window setFrameUsingName:SKPreferenceWindowFrameAutosaveName force:YES];
+    [self setWindowFrameAutosaveName:SKPreferenceWindowFrameAutosaveName];
+    
+//    [NSGraphicsContext SKAutoSizeButtons:resetButtons rightAlign:false];
+    
+    CGFloat width = 200.0;
+    NSRect frame;
+    NSViewController<SKPreferencePane> *pane;
+    NSView *view;
+    for (pane in preferencePanes)
+        width = fmax(width, NSWidth([[pane view] frame]));
+    for (pane in preferencePanes) {
+        view = [pane view];
+        frame = [view frame];
+        if (([view autoresizingMask] & NSViewWidthSizable))
+            frame.size.width = width;
+        else
+            frame.origin.x = floor(0.5 * (width - NSWidth(frame)));
+        frame.origin.y = BOTTOM_MARGIN;
+        [view setFrame:frame];
+    }
+    
+    currentPane = [self preferencePaneForItemIdentifier:[[NSUserDefaults standardUserDefaults] stringForKey:SKLastSelectedPreferencePaneKey]] ?: [preferencePanes objectAtIndex:0];
+    [toolbar setSelectedItemIdentifier:[currentPane nibName]];
+//    [window setTitle:[currentPane title]];
+//    [history addObject:currentPane];
+    
+    view = [currentPane view];
+    frame = [window frame];
+    frame.size.width = width;
+    frame = SKShrinkRect(frame, NSHeight([[window contentView] frame]) - NSMaxY([view frame]), NSMinYEdge);
+    [window setFrame:frame display:NO];
+    
+    [[window contentView] addSubview:view];
+}
+
+- (void)windowDidResignMain:(NSNotification *)notification {
+    [[[self window] contentView] deactivateWellSubcontrols];
+}
+
+- (void)windowWillClose:(NSNotification *)notification {
+    // make sure edits are committed
+    [currentPane commitEditing];
+    [[NSUserDefaultsController sharedUserDefaultsController] commitEditing];
+}
+
+- (void)selectPaneWithIdentifier:(NSString *)itemIdentifier {
+    [self selectPane:[self preferencePaneForItemIdentifier:itemIdentifier]];
+}
+
+- (void)panelControlSelectColor:(NSString *)identifier {
+    for (NSToolbarItem *item in self.window.toolbar.items) {
+        if ([item.itemIdentifier isEqualToString:identifier]) {
+            if ([item.itemIdentifier isEqualToString:@"GeneralPreferences"]) {
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsGeneralSel"];
+            } else if ([item.itemIdentifier isEqualToString:@"DisplayPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsViewSel"];
+            } else if ([item.itemIdentifier isEqualToString:@"NotesPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsAnnotationSel"];
+            } else if ([item.itemIdentifier isEqualToString:@"SyncPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsSynchronizeSel"];
+            } else if ([item.itemIdentifier isEqualToString:@"DropboxPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsDropboxSel"];
+            }
+        } else {
+            if ([item.itemIdentifier isEqualToString:@"GeneralPreferences"]) {
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsGeneralNor"];
+            } else if ([item.itemIdentifier isEqualToString:@"DisplayPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsViewNor"];
+            } else if ([item.itemIdentifier isEqualToString:@"NotesPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsAnnotationNor"];
+            } else if ([item.itemIdentifier isEqualToString:@"SyncPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsSynchronizeNor"];
+            } else if ([item.itemIdentifier isEqualToString:@"DropboxPreferences"]){
+                item.image = [NSImage imageNamed:@"KMImageNameElseSettingsDropboxNor"];
+            }
+        }
+    }
+}
+
+#pragma mark Actions
+
+- (void)selectPaneAction:(id)sender {
+    [self panelControlSelectColor:[sender itemIdentifier]];
+    
+    [self selectPane:[self preferencePaneForItemIdentifier:[sender  itemIdentifier]]];
+}
+
+- (void)resetAllSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
+    if (returnCode == NSAlertFirstButtonReturn) {
+        [[NSUserDefaultsController sharedUserDefaultsController] revertToInitialValues:nil];
+        for (NSViewController<SKPreferencePane> *pane in preferencePanes) {
+            if ([pane respondsToSelector:@selector(defaultsDidRevert)])
+                [pane defaultsDidRevert];
+        }
+        
+        //重置OCR后,记录切换值
+        [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"KMStatusPlanPopUpBtnKey"];
+        [[NSUserDefaults standardUserDefaults] synchronize];
+    }
+}
+
+- (IBAction)resetAll:(id)sender {
+    NSAlert *alert = [[NSAlert alloc] init];
+    [alert setMessageText:NSLocalizedString(@"Reset all preferences to their original values?", @"Message in alert dialog when pressing Reset All button")];
+    [alert setInformativeText:NSLocalizedString(@"Choosing Reset will restore all settings to the state they were in when PDF Reader Pro Edition was first installed.", @"Informative text in alert dialog when pressing Reset All button")];
+    [alert addButtonWithTitle:NSLocalizedString(@"Reset", @"Button title")];
+    [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Button title")];
+    [alert beginSheetModalForWindow:[self window]
+                      modalDelegate:self
+                     didEndSelector:@selector(resetAllSheetDidEnd:returnCode:contextInfo:)
+                        contextInfo:NULL];
+}
+
+- (void)resetCurrentSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
+    if (returnCode == NSAlertFirstButtonReturn) {
+        NSURL *initialUserDefaultsURL = [[NSBundle mainBundle] URLForResource:INITIALUSERDEFAULTS_KEY withExtension:@"plist"];
+        NSArray *resettableKeys = [[[NSDictionary dictionaryWithContentsOfURL:initialUserDefaultsURL] objectForKey:RESETTABLEKEYS_KEY] objectForKey:[currentPane nibName]];
+        [[NSUserDefaultsController sharedUserDefaultsController] revertToInitialValuesForKeys:resettableKeys];
+        if ([currentPane respondsToSelector:@selector(defaultsDidRevert)])
+            [currentPane defaultsDidRevert];
+        if ([[currentPane title] isEqualToString:@"OCR"]) { //重置OCR后,记录切换值
+            [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"KMStatusPlanPopUpBtnKey"];
+            [[NSUserDefaults standardUserDefaults] synchronize];
+        }
+    }
+}
+
+- (IBAction)resetCurrent:(id)sender {
+    if (currentPane == nil) {
+        NSBeep();
+        return;
+    }
+    NSString *label = [currentPane title];
+    NSAlert *alert = [[NSAlert alloc] init];
+    [alert setMessageText:[NSString stringWithFormat:NSLocalizedString(@"Reset %@ preferences to their original values?", @"Message in alert dialog when pressing Reset All button"), label]];
+    [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Choosing Reset will restore all settings in this pane to the state they were in when PDF Reader Pro Edition was first installed.", @"Informative text in alert dialog when pressing Reset All button"), label]];
+    [alert addButtonWithTitle:NSLocalizedString(@"Reset", @"Button title")];
+    [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Button title")];
+    [alert beginSheetModalForWindow:[self window]
+                      modalDelegate:self
+                     didEndSelector:@selector(resetCurrentSheetDidEnd:returnCode:contextInfo:)
+                        contextInfo:NULL];
+}
+
+- (IBAction)doGoToNextPage:(id)sender {
+    NSUInteger itemIndex = [preferencePanes indexOfObject:currentPane];
+    if (itemIndex != NSNotFound && ++itemIndex < [preferencePanes count])
+        [self selectPane:[preferencePanes objectAtIndex:itemIndex]];
+}
+
+- (IBAction)doGoToPreviousPage:(id)sender {
+    NSUInteger itemIndex = [preferencePanes indexOfObject:currentPane];
+    if (itemIndex != NSNotFound && itemIndex-- > 0)
+        [self selectPane:[preferencePanes objectAtIndex:itemIndex]];
+}
+
+- (IBAction)doGoToFirstPage:(id)sender {
+    [self selectPane:[preferencePanes objectAtIndex:0]];
+}
+
+- (IBAction)doGoToLastPage:(id)sender {
+    [self selectPane:[preferencePanes lastObject]];
+}
+
+- (IBAction)doGoBack:(id)sender {
+    if (historyIndex > 0) {
+        historyIndex--;
+        [self selectPane:nil];
+    }
+}
+
+- (IBAction)doGoForward:(id)sender {
+    if (historyIndex + 1 < [history count]) {
+        historyIndex++;
+        [self selectPane:nil];
+    }
+}
+
+- (IBAction)changeFont:(id)sender {
+//    [[[[self window] contentView] activeFontWell] changeFontFromFontManager:sender];
+}
+
+- (IBAction)changeAttributes:(id)sender {
+//    [[[[self window] contentView] activeFontWell] changeAttributesFromFontManager:sender];
+}
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
+    if ([menuItem action] == @selector(doGoToNextPage:) || [menuItem action] == @selector(doGoToLastPage:))
+        return [currentPane isEqual:[preferencePanes lastObject]] == NO;
+    else if ([menuItem action] == @selector(doGoToPreviousPage:) || [menuItem action] == @selector(doGoToFirstPage:))
+        return [currentPane isEqual:[preferencePanes objectAtIndex:0]] == NO;
+    else if ([menuItem action] == @selector(doGoBack:))
+        return historyIndex > 0;
+    else if ([menuItem action] == @selector(doGoForward:))
+        return historyIndex + 1 < [history count];
+    return YES;
+}
+
+#pragma mark Toolbar
+
+- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdent willBeInsertedIntoToolbar:(BOOL)willBeInserted {
+    NSViewController<SKPreferencePane> *pane = [self preferencePaneForItemIdentifier:itemIdent];
+    NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdent];
+    [item setLabel:[pane title]];
+    NSImage  * ima = nil;
+    if ([itemIdent isEqualToString:@"GeneralPreferences"]) {
+        ima = [NSImage imageNamed:@"KMImageNameElseSettingsGeneralNor"];//generalPreferences
+    } else if ([itemIdent isEqualToString:@"DisplayPreferences"]){
+        ima = [NSImage imageNamed:@"KMImageNameElseSettingsViewNor"];//displayPreferences
+    } else if ([itemIdent isEqualToString:@"NotesPreferences"]){
+        ima = [NSImage imageNamed:@"KMImageNameElseSettingsAnnotationNor"];//notesPreferences
+    } else if ([itemIdent isEqualToString:@"SyncPreferences"]){
+        ima = [NSImage imageNamed:@"KMImageNameElseSettingsSynchronizeNor"];//syncPreferences
+    } else if ([itemIdent isEqualToString:@"DropboxPreferences"]){
+        ima = [NSImage imageNamed:@"KMImageNameElseSettingsDropboxNor"];//dropboxPreferences
+    }
+    //恢复OCR架上版本样式
+//    else if ([itemIdent isEqualToString:@"KMOCRPreferences"]) {
+//        ima = [NSImage imageNamed:@"ocrPreferences"];
+//    }
+    [item setImage:ima];
+    [item setTarget:self];
+    [item setAction:@selector(selectPaneAction:)];
+    return item;
+}
+
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
+    return [preferencePanes valueForKey:NIBNAME_KEY];
+}
+
+- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
+    return [self toolbarDefaultItemIdentifiers:toolbar];
+}
+
+- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar {
+    return [self toolbarDefaultItemIdentifiers:toolbar];
+}
+
+@end
+
+@implementation SKPreferenceWindow
+
+- (BOOL)respondsToSelector:(SEL)aSelector {
+    return aSelector != @selector(toggleToolbarShow:) && aSelector != @selector(runToolbarCustomizationPalette:) && [super respondsToSelector:aSelector];
+}
+
+@end
+
+@implementation SKIBArray
+
+static void setObjectAtIndex(id *object, id obj, NSUInteger i, unsigned long *mutationsPtr) {
+    if (object[i] != obj) {
+//        [object[i] release];
+        object[i] = obj;
+        (*mutationsPtr)++;
+    }
+}
+
+#define SYNTHESIZE_OBJECT_ACCESSORS(i) \
+@dynamic object##i; \
+- (id)object##i { return object[i-1]; } \
+- (void)setObject##i:(id)obj { setObjectAtIndex(object, obj, i-1, &mutations); }
+
+//SYNTHESIZE_OBJECT_ACCESSORS(1)
+//SYNTHESIZE_OBJECT_ACCESSORS(2)
+//SYNTHESIZE_OBJECT_ACCESSORS(3)
+//SYNTHESIZE_OBJECT_ACCESSORS(4)
+//SYNTHESIZE_OBJECT_ACCESSORS(5)
+//SYNTHESIZE_OBJECT_ACCESSORS(6)
+//SYNTHESIZE_OBJECT_ACCESSORS(7)
+//SYNTHESIZE_OBJECT_ACCESSORS(8)
+//SYNTHESIZE_OBJECT_ACCESSORS(9)
+
+- (void)dealloc {
+    NSUInteger i;
+//    for (i = 0; i < 9; i++)
+//        setObjectAtIndex(object, nil, i, &mutations);
+//    [super dealloc];
+}
+
+- (NSUInteger)count {
+    NSUInteger i;
+    for (i = 0; i < 9; i++)
+        if (object[i] == nil) break;
+    return i;
+}
+
+- (id)objectAtIndex:(NSUInteger)anIndex {
+    return object[anIndex];
+}
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len {
+    if (state->state == 0) {
+        state->state = 1;
+//        state->itemsPtr = object;
+//        state->mutationsPtr = &mutations;
+        return [self count];
+    }
+    return 0;
+}
+
+@end

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

@@ -55,3 +55,4 @@
 #import "KMColorPickerViewController.h"
 
 #import "KMConvertURLToPDF.h"
+#import "SKPreferenceController.h"