Browse Source

【批量处理】- 主界面 - 右侧、split、转档

jiajie 1 year ago
parent
commit
6054fbb6a6

+ 58 - 18
PDF Office/PDF Master.xcodeproj/project.pbxproj

@@ -2501,12 +2501,6 @@
 		BB74DA7F2AC42959006EDFE7 /* NSButton+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB74DA7E2AC42959006EDFE7 /* NSButton+KMExtension.swift */; };
 		BB74DA802AC42959006EDFE7 /* NSButton+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB74DA7E2AC42959006EDFE7 /* NSButton+KMExtension.swift */; };
 		BB74DA812AC42959006EDFE7 /* NSButton+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB74DA7E2AC42959006EDFE7 /* NSButton+KMExtension.swift */; };
-		BB7507E929861C37002DBDB1 /* PasswordWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB7507E629861C37002DBDB1 /* PasswordWindowController.m */; };
-		BB7507EA29861C37002DBDB1 /* PasswordWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB7507E629861C37002DBDB1 /* PasswordWindowController.m */; };
-		BB7507EB29861C37002DBDB1 /* PasswordWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB7507E629861C37002DBDB1 /* PasswordWindowController.m */; };
-		BB7507EC29861C37002DBDB1 /* PasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB7507E729861C37002DBDB1 /* PasswordWindowController.xib */; };
-		BB7507ED29861C37002DBDB1 /* PasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB7507E729861C37002DBDB1 /* PasswordWindowController.xib */; };
-		BB7507EE29861C37002DBDB1 /* PasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BB7507E729861C37002DBDB1 /* PasswordWindowController.xib */; };
 		BB7648E829ECECBF00931039 /* Color.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BB7648E729ECECBF00931039 /* Color.xcassets */; };
 		BB7648E929ECECBF00931039 /* Color.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BB7648E729ECECBF00931039 /* Color.xcassets */; };
 		BB7648EA29ECECBF00931039 /* Color.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BB7648E729ECECBF00931039 /* Color.xcassets */; };
@@ -3202,6 +3196,24 @@
 		BBFD2B162AEFAC9C0016C456 /* KMBatchOperateBaseViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFD2B152AEFAC9B0016C456 /* KMBatchOperateBaseViewController.xib */; };
 		BBFD2B172AEFAC9C0016C456 /* KMBatchOperateBaseViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFD2B152AEFAC9B0016C456 /* KMBatchOperateBaseViewController.xib */; };
 		BBFD2B182AEFAC9C0016C456 /* KMBatchOperateBaseViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFD2B152AEFAC9B0016C456 /* KMBatchOperateBaseViewController.xib */; };
+		BBFDFA932AF328B200E08AA2 /* KMBatchOperateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA922AF328B200E08AA2 /* KMBatchOperateManager.swift */; };
+		BBFDFA952AF328B900E08AA2 /* KMBatchOperateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA922AF328B200E08AA2 /* KMBatchOperateManager.swift */; };
+		BBFDFA962AF328BA00E08AA2 /* KMBatchOperateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA922AF328B200E08AA2 /* KMBatchOperateManager.swift */; };
+		BBFDFA9A2AF33DBF00E08AA2 /* KMCustomViewButton.m in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA992AF33DBF00E08AA2 /* KMCustomViewButton.m */; };
+		BBFDFA9B2AF33DBF00E08AA2 /* KMCustomViewButton.m in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA992AF33DBF00E08AA2 /* KMCustomViewButton.m */; };
+		BBFDFA9C2AF33DBF00E08AA2 /* KMCustomViewButton.m in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA992AF33DBF00E08AA2 /* KMCustomViewButton.m */; };
+		BBFDFA9E2AF3814000E08AA2 /* KMTextHintWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA9D2AF3814000E08AA2 /* KMTextHintWindowController.swift */; };
+		BBFDFA9F2AF3814000E08AA2 /* KMTextHintWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA9D2AF3814000E08AA2 /* KMTextHintWindowController.swift */; };
+		BBFDFAA02AF3814000E08AA2 /* KMTextHintWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFA9D2AF3814000E08AA2 /* KMTextHintWindowController.swift */; };
+		BBFDFAA22AF3815C00E08AA2 /* KMTextHintWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFDFAA12AF3815B00E08AA2 /* KMTextHintWindowController.xib */; };
+		BBFDFAA32AF3815C00E08AA2 /* KMTextHintWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFDFAA12AF3815B00E08AA2 /* KMTextHintWindowController.xib */; };
+		BBFDFAA42AF3815C00E08AA2 /* KMTextHintWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFDFAA12AF3815B00E08AA2 /* KMTextHintWindowController.xib */; };
+		BBFDFAA62AF3899400E08AA2 /* PasswordWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFAA52AF3899400E08AA2 /* PasswordWindowController.swift */; };
+		BBFDFAA72AF3899400E08AA2 /* PasswordWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFAA52AF3899400E08AA2 /* PasswordWindowController.swift */; };
+		BBFDFAA82AF3899400E08AA2 /* PasswordWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFDFAA52AF3899400E08AA2 /* PasswordWindowController.swift */; };
+		BBFDFAAA2AF389B700E08AA2 /* PasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFDFAA92AF389B700E08AA2 /* PasswordWindowController.xib */; };
+		BBFDFAAB2AF389B700E08AA2 /* PasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFDFAA92AF389B700E08AA2 /* PasswordWindowController.xib */; };
+		BBFDFAAC2AF389B700E08AA2 /* PasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBFDFAA92AF389B700E08AA2 /* PasswordWindowController.xib */; };
 		BBFE6E582930724B00142C01 /* KMMergePageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFE6E572930724B00142C01 /* KMMergePageModel.swift */; };
 		BBFE6E592930724B00142C01 /* KMMergePageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFE6E572930724B00142C01 /* KMMergePageModel.swift */; };
 		BBFE6E5A2930724B00142C01 /* KMMergePageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFE6E572930724B00142C01 /* KMMergePageModel.swift */; };
@@ -4411,9 +4423,6 @@
 		BB74DA762AC41182006EDFE7 /* NSFont+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSFont+KMExtension.swift"; sourceTree = "<group>"; };
 		BB74DA7A2AC41DE9006EDFE7 /* NSString+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSString+KMExtension.swift"; sourceTree = "<group>"; };
 		BB74DA7E2AC42959006EDFE7 /* NSButton+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSButton+KMExtension.swift"; sourceTree = "<group>"; };
-		BB7507E629861C37002DBDB1 /* PasswordWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PasswordWindowController.m; sourceTree = "<group>"; };
-		BB7507E729861C37002DBDB1 /* PasswordWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PasswordWindowController.xib; sourceTree = "<group>"; };
-		BB7507E829861C37002DBDB1 /* PasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PasswordWindowController.h; sourceTree = "<group>"; };
 		BB7648E729ECECBF00931039 /* Color.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Color.xcassets; sourceTree = "<group>"; };
 		BB7648EB29ECEEF400931039 /* KMAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMAppearance.swift; sourceTree = "<group>"; };
 		BB7BC4D72AD3D6B700D6BEE6 /* PDFListView+KMExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PDFListView+KMExtensions.swift"; sourceTree = "<group>"; };
@@ -4687,6 +4696,13 @@
 		BBFD2B112AEFAAF70016C456 /* KMBatchOperateBaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBatchOperateBaseViewController.swift; sourceTree = "<group>"; };
 		BBFD2B132AEFAB8F0016C456 /* KMOperationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMOperationQueue.swift; sourceTree = "<group>"; };
 		BBFD2B152AEFAC9B0016C456 /* KMBatchOperateBaseViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMBatchOperateBaseViewController.xib; sourceTree = "<group>"; };
+		BBFDFA922AF328B200E08AA2 /* KMBatchOperateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBatchOperateManager.swift; sourceTree = "<group>"; };
+		BBFDFA982AF33DBE00E08AA2 /* KMCustomViewButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMCustomViewButton.h; sourceTree = "<group>"; };
+		BBFDFA992AF33DBF00E08AA2 /* KMCustomViewButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KMCustomViewButton.m; sourceTree = "<group>"; };
+		BBFDFA9D2AF3814000E08AA2 /* KMTextHintWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMTextHintWindowController.swift; sourceTree = "<group>"; };
+		BBFDFAA12AF3815B00E08AA2 /* KMTextHintWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMTextHintWindowController.xib; sourceTree = "<group>"; };
+		BBFDFAA52AF3899400E08AA2 /* PasswordWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordWindowController.swift; sourceTree = "<group>"; };
+		BBFDFAA92AF389B700E08AA2 /* PasswordWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PasswordWindowController.xib; sourceTree = "<group>"; };
 		BBFE6E572930724B00142C01 /* KMMergePageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMMergePageModel.swift; sourceTree = "<group>"; };
 		BBFE6E5B2930809A00142C01 /* KMMergeCollectionPageViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMMergeCollectionPageViewItem.swift; sourceTree = "<group>"; };
 		BBFE6E5C2930809A00142C01 /* KMMergeCollectionPageViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMMergeCollectionPageViewItem.xib; sourceTree = "<group>"; };
@@ -8157,9 +8173,6 @@
 		BBAFC8382985191200D0648E /* OCPart */ = {
 			isa = PBXGroup;
 			children = (
-				BB7507E829861C37002DBDB1 /* PasswordWindowController.h */,
-				BB7507E629861C37002DBDB1 /* PasswordWindowController.m */,
-				BB7507E729861C37002DBDB1 /* PasswordWindowController.xib */,
 				9FCFECA32AD237B500EAD2CB /* KMBatchTableRowView.swift */,
 				9FCFECA72AD243C800EAD2CB /* KMBlankView.swift */,
 				9FD0D2A22AD4ECA800DA3FF8 /* KMPDFEditAppendCustomView.swift */,
@@ -8450,6 +8463,7 @@
 		BBF2454E2AE7726800037D08 /* WindowController */ = {
 			isa = PBXGroup;
 			children = (
+				BBFDFA972AF33D9D00E08AA2 /* OC */,
 				BBE9D0952AF0CEB6002E83CE /* VC */,
 				BBFD2B102AEFAADB0016C456 /* Base */,
 				BB1BFF5C2AE9F1FF003EB179 /* KMBatchOperateBaseWindowController.swift */,
@@ -8464,6 +8478,10 @@
 				BB1BFF7C2AEA0BE8003EB179 /* KMBatchOperateRightViewController.xib */,
 				BBC4F9E92AEB58290098A1A8 /* KMAlertWindowController.swift */,
 				BBC4F9ED2AEB58470098A1A8 /* KMAlertWindowController.xib */,
+				BBFDFA9D2AF3814000E08AA2 /* KMTextHintWindowController.swift */,
+				BBFDFAA12AF3815B00E08AA2 /* KMTextHintWindowController.xib */,
+				BBFDFAA52AF3899400E08AA2 /* PasswordWindowController.swift */,
+				BBFDFAA92AF389B700E08AA2 /* PasswordWindowController.xib */,
 			);
 			path = WindowController;
 			sourceTree = "<group>";
@@ -8501,6 +8519,7 @@
 				BBF8A3FC2AE8B03B00788BAC /* KMBatchOperateFile.swift */,
 				BBF8A4002AE8B4E200788BAC /* KMBatchBaseParameter.swift */,
 				BBF8A4022AE8E10100788BAC /* KMBatchConvertParameter.swift */,
+				BBFDFA922AF328B200E08AA2 /* KMBatchOperateManager.swift */,
 			);
 			path = Data;
 			sourceTree = "<group>";
@@ -8645,6 +8664,15 @@
 			path = Base;
 			sourceTree = "<group>";
 		};
+		BBFDFA972AF33D9D00E08AA2 /* OC */ = {
+			isa = PBXGroup;
+			children = (
+				BBFDFA982AF33DBE00E08AA2 /* KMCustomViewButton.h */,
+				BBFDFA992AF33DBF00E08AA2 /* KMCustomViewButton.m */,
+			);
+			path = OC;
+			sourceTree = "<group>";
+		};
 		BBFE6E7B2930EB8F00142C01 /* Compress */ = {
 			isa = PBXGroup;
 			children = (
@@ -9134,6 +9162,7 @@
 				89E4E7852967BF5A002DBA6F /* KMCustomizeStampViewController.xib in Resources */,
 				BB1BFF652AE9FBA8003EB179 /* KMBatchOperateWindowController.xib in Resources */,
 				F359917B292B7B8A000D25DE /* InitialUserDefaults.plist in Resources */,
+				BBFDFAA22AF3815C00E08AA2 /* KMTextHintWindowController.xib in Resources */,
 				AD1CA4032A06040B0070541F /* KMAnnotationScreenCollectionView.xib in Resources */,
 				BB8F455A295AA1270037EA22 /* KMHeaderFooterPropertyInfoController.xib in Resources */,
 				BB52372A29C313CA00663BD7 /* KMAnnotationPropertyBaseController.xib in Resources */,
@@ -9172,6 +9201,7 @@
 				9FF94F1429A7476000B1EF69 /* KMDesignPropertySelector.xib in Resources */,
 				BBC348462956A638008D2CD1 /* KMEditBackgroundController.xib in Resources */,
 				BBA2109429ACC10F00E6B346 /* signlist_add.pdf in Resources */,
+				BBFDFAAA2AF389B700E08AA2 /* PasswordWindowController.xib in Resources */,
 				9F0201992A1F352100C9B673 /* KMAITranslationConfirmWindowController.xib in Resources */,
 				BB89721B294AED6C0045787C /* KMWatermarkAdjectivePreViewBaseController.xib in Resources */,
 				89E4E72F2963FBA2002DBA6F /* KMPropertiesViewPopController.xib in Resources */,
@@ -9330,7 +9360,6 @@
 				BB51074229A61B4100978662 /* ProgressSheet.xib in Resources */,
 				BB003031298D315E002DD1A0 /* KMPreferenceMarkupController.xib in Resources */,
 				BB1AEF3529F937A50048D179 /* PDF Master User Guide.pdf in Resources */,
-				BB7507EC29861C37002DBDB1 /* PasswordWindowController.xib in Resources */,
 				9F0CB49A29683E1000007028 /* KMPropertiesPanelTextSubVC.xib in Resources */,
 				BBB29BCE2AEA190D005F1B6B /* KMToolbarCustomViewController.xib in Resources */,
 				BBC70EA92AEA6EF800AC1585 /* KMToolbarCustomWindowController.xib in Resources */,
@@ -9391,7 +9420,6 @@
 				AD88109B29A78AEC00178CA1 /* KMVerificationCodeView.xib in Resources */,
 				AD8810A429A8459000178CA1 /* KMComparativeTableViewController.xib in Resources */,
 				AD0FA4F629A8582C00EDEB50 /* KMComparativeTableView.xib in Resources */,
-				BB7507ED29861C37002DBDB1 /* PasswordWindowController.xib in Resources */,
 				ADAFDA112AE8DD6600F084BC /* KMAdvertisementCollectionHeadView.xib in Resources */,
 				ADD1B6CC2942E85300C3FFF7 /* KMPrintBottomView.xib in Resources */,
 				9F0CB4732967E63100007028 /* KMPropertiesPanelNameSubVC.xib in Resources */,
@@ -9430,6 +9458,7 @@
 				BB7F7C0429AA586900A3E4E7 /* signAddBack.png in Resources */,
 				AD867F9929D955D200F00440 /* KMBOTAOutlineCellView.xib in Resources */,
 				BB1BFF662AE9FBA8003EB179 /* KMBatchOperateWindowController.xib in Resources */,
+				BBFDFAAB2AF389B700E08AA2 /* PasswordWindowController.xib in Resources */,
 				9FF94F1D29A770B500B1EF69 /* KMFillSignShapePanel.xib in Resources */,
 				BBC348472956A638008D2CD1 /* KMEditBackgroundController.xib in Resources */,
 				BB49ECFA293F44DC00C82CA2 /* KMConvertExcelWindowController.xib in Resources */,
@@ -9447,6 +9476,7 @@
 				8942F7F42926087200389627 /* KMSearchViewController.xib in Resources */,
 				9FAAA336290BD0A20046FFCE /* KMHistoryFileCollectionViewItem.xib in Resources */,
 				BBAFC8402985194800D0648E /* KMPDFEditAppendWindow.xib in Resources */,
+				BBFDFAA32AF3815C00E08AA2 /* KMTextHintWindowController.xib in Resources */,
 				F3B7DF9E2948565000333201 /* CPDFListHoverAnnotationViewController.xib in Resources */,
 				BBC3481029558DC1008D2CD1 /* KMBackgroundController.xib in Resources */,
 				BBAFC84E298519F700D0648E /* KMSavePanelAccessoryController.xib in Resources */,
@@ -9773,6 +9803,7 @@
 				ADEC7A86299397F8009A8256 /* SF-Pro-Text-Semibold.otf in Resources */,
 				BB1BFF672AE9FBA8003EB179 /* KMBatchOperateWindowController.xib in Resources */,
 				ADD1B6FE2946C0D400C3FFF7 /* KMPrintChoosePageSizePamphletView.xib in Resources */,
+				BBFDFAA42AF3815C00E08AA2 /* KMTextHintWindowController.xib in Resources */,
 				9FF94F1629A7476000B1EF69 /* KMDesignPropertySelector.xib in Resources */,
 				ADE8BC3529F9261900570F89 /* KMSearchCellView.xib in Resources */,
 				ADE787A72AA5A833002EC85A /* KMAccountExceptionWindowController.xib in Resources */,
@@ -9786,7 +9817,6 @@
 				AD6260702A9D968B006C6413 /* KMEditPDFAssets.xcassets in Resources */,
 				89E4E76629656A88002DBA6F /* KMAnnotationStampViewController.xib in Resources */,
 				899700E428F3A9F2009AF911 /* KMHomeWindowController.xib in Resources */,
-				BB7507EE29861C37002DBDB1 /* PasswordWindowController.xib in Resources */,
 				BBC348402955A60B008D2CD1 /* KMBackgroundPropertyInfoController.xib in Resources */,
 				9F0201832A1BAC1600C9B673 /* KMAIRewritingVC.xib in Resources */,
 				9FDD0F9E2952FF4D000C4DAD /* comp-light.json in Resources */,
@@ -9811,6 +9841,7 @@
 				ADB5E5172A371131007110A8 /* KMSubscribeWaterMarkWindowController.xib in Resources */,
 				ADB2D6EB294740F30029D2B3 /* KMPrintPaperSetWindowController.xib in Resources */,
 				AD0FA50029A8DD8700EDEB50 /* KMRegisterSuccessView.xib in Resources */,
+				BBFDFAAC2AF389B700E08AA2 /* PasswordWindowController.xib in Resources */,
 				894A00F72976314C0070ED83 /* KMPDFViewPanelSetViewController.xib in Resources */,
 				899700FB28F4051B009AF911 /* KMAnnotationViewController.xib in Resources */,
 				BB3EAEB2293E3D6000D92407 /* KMConvertBaseWindowController.xib in Resources */,
@@ -10196,6 +10227,7 @@
 				BBF8A4012AE8B4E200788BAC /* KMBatchBaseParameter.swift in Sources */,
 				AD867FC129DFC39400F00440 /* KMBOTAAnnotationItem.swift in Sources */,
 				BBDA8A6D2A31F9A6006A2C4E /* KMDesignStepperView.swift in Sources */,
+				BBFDFA9E2AF3814000E08AA2 /* KMTextHintWindowController.swift in Sources */,
 				ADD1B6AB2941E97F00C3FFF7 /* KMPrintWindowController.swift in Sources */,
 				BB8F454F295A9FA50037EA22 /* KMCreateHeaderFooterController.swift in Sources */,
 				9FA693A82987C0590055488A /* KMStepperView.swift in Sources */,
@@ -10407,7 +10439,6 @@
 				9F1FE4AE29406E4700E952CA /* CTPresentationModeController.m in Sources */,
 				BB146FC0299DC0D100784A6A /* GTMSessionFetcherLogging.m in Sources */,
 				AD1CA4212A061D190070541F /* KMAnnotationScreenAuthorViewItem.swift in Sources */,
-				BB7507E929861C37002DBDB1 /* PasswordWindowController.m in Sources */,
 				BBC3481C295593F0008D2CD1 /* KMBackgroundListController.swift in Sources */,
 				9F5664872988B16F00020985 /* KMTextfieldVC.swift in Sources */,
 				9F1F82DA292F84D60092C4B4 /* KMHomeInsertActionViewController.swift in Sources */,
@@ -10417,6 +10448,7 @@
 				ADD1B6E82946C02600C3FFF7 /* KMPrintChoosePageSizeMultipageView.swift in Sources */,
 				9F1FE4ED29406E4700E952CA /* ThrobberView.m in Sources */,
 				9F0CB4F9298655E500007028 /* KMDesignToken+Border.swift in Sources */,
+				BBFDFAA62AF3899400E08AA2 /* PasswordWindowController.swift in Sources */,
 				9F0CB45F2966C9E200007028 /* KMFormPropertPanelViewController.swift in Sources */,
 				ADCFFC0229C004AD007D3657 /* KMBookMarkTableRowView.swift in Sources */,
 				ADF6B86C2A480C5F0090CB78 /* KMComparativeView.swift in Sources */,
@@ -10716,6 +10748,7 @@
 				9F1FE4C929406E4700E952CA /* CTTabContents.m in Sources */,
 				9FCFEC882AD0EF9900EAD2CB /* KMPopMenuButton.swift in Sources */,
 				9F39B9442A661ED500930ACA /* KMHomeScrollView.swift in Sources */,
+				BBFDFA9A2AF33DBF00E08AA2 /* KMCustomViewButton.m in Sources */,
 				BB89725E294C5DDA0045787C /* KMWatermarkPropertyInfoController.swift in Sources */,
 				BB146FAB299DC0D000784A6A /* GTLRBatchQuery.m in Sources */,
 				BB897218294AED6C0045787C /* KMWatermarkAdjectivePreViewBaseController.swift in Sources */,
@@ -10789,6 +10822,7 @@
 				BB24D4A72977BE6700041659 /* KMRedactConfirmWindowController.swift in Sources */,
 				9F0CB4F1298655BC00007028 /* KMDesignToken+ItemSpacing.swift in Sources */,
 				8997010E28F40842009AF911 /* KMOutlineViewController.swift in Sources */,
+				BBFDFA932AF328B200E08AA2 /* KMBatchOperateManager.swift in Sources */,
 				BB2F61502966A91D001CB369 /* KMBackgroundPropertyHomeController.swift in Sources */,
 				BBBB6CD22AD14A5F0035AA66 /* CPDFChoiceWidgetAnnotation+PDFListView.swift in Sources */,
 				9F1FE3DE293EE51F00E952CA /* KMMainDocument.swift in Sources */,
@@ -10976,6 +11010,7 @@
 				9FBC48B9299B44C600CA39D7 /* KMSecondaryViewController.m in Sources */,
 				ADAFD9F42AE68A7400F084BC /* KMCreatPDFView.swift in Sources */,
 				BBC348152955920B008D2CD1 /* KMBackgroundPropertyController.swift in Sources */,
+				BBFDFA9F2AF3814000E08AA2 /* KMTextHintWindowController.swift in Sources */,
 				BBEC00D2295C33D600A26C98 /* KMCreateBatesController.swift in Sources */,
 				AD867FB429DFBB2700F00440 /* KMAnnotationOutlineSectionView.swift in Sources */,
 				BBEC00A9295BDECF00A26C98 /* KMHeaderFooterContentInfoView.swift in Sources */,
@@ -11004,6 +11039,7 @@
 				9F0CB4CA2986533F00007028 /* KMDesignToken+Sizing.swift in Sources */,
 				9F8539DF29470A0700DF644E /* KMTabStripView.swift in Sources */,
 				AD9527EF295578BD0039D2BC /* KMBaseTextFieldPresenter.swift in Sources */,
+				BBFDFAA72AF3899400E08AA2 /* PasswordWindowController.swift in Sources */,
 				8942F80029260EC700389627 /* KMLeftMethodMode.swift in Sources */,
 				BB49ED1E293F4FB200C82CA2 /* KMConvertPPTsSettingView.swift in Sources */,
 				9FA607DA28F8227500B46586 /* KMBox.swift in Sources */,
@@ -11118,6 +11154,7 @@
 				BBEC00B0295C2AF300A26C98 /* KMBatesPreviewController.swift in Sources */,
 				BB0A551E2A30793F00B6E84B /* KMDesignTextField.swift in Sources */,
 				BBF170592AE296B90013CE02 /* KMView.swift in Sources */,
+				BBFDFA9B2AF33DBF00E08AA2 /* KMCustomViewButton.m in Sources */,
 				9F0CB50E2986564500007028 /* KMDesignToken+BorderLeft.swift in Sources */,
 				9FBC489C2996500300CA39D7 /* KMDocumentController.swift in Sources */,
 				BBC348342955A118008D2CD1 /* KMCreateBackgroundController.swift in Sources */,
@@ -11179,7 +11216,6 @@
 				BBCE57192A72723600508EFC /* NSResponder+KMExtension.swift in Sources */,
 				BB146FC1299DC0D100784A6A /* GTMSessionFetcherLogging.m in Sources */,
 				AD1CA4222A061D190070541F /* KMAnnotationScreenAuthorViewItem.swift in Sources */,
-				BB7507EA29861C37002DBDB1 /* PasswordWindowController.m in Sources */,
 				BB3A81B62AC2C0F4006FC66C /* NSObject+KMExtension.swift in Sources */,
 				BBC3481D295593F0008D2CD1 /* KMBackgroundListController.swift in Sources */,
 				9F5664882988B16F00020985 /* KMTextfieldVC.swift in Sources */,
@@ -11289,6 +11325,7 @@
 				ADD1B7032946C8AD00C3FFF7 /* KMBaseTextField.swift in Sources */,
 				8942F818292B678100389627 /* KMAnnotationTableCellView.swift in Sources */,
 				BB8F456A295ABDC10037EA22 /* KMWatermarkAdjectiveBaseModel.swift in Sources */,
+				BBFDFA952AF328B900E08AA2 /* KMBatchOperateManager.swift in Sources */,
 				9F0CB53A2986570600007028 /* KMDesignToken+BoxShadow.swift in Sources */,
 				9F02017A2A1B5C0300C9B673 /* KMAIServerConfig.swift in Sources */,
 				9F0CB4B62977BC1000007028 /* KMPropertiesPanelPreviewSubVC.swift in Sources */,
@@ -11853,6 +11890,7 @@
 				BB2C6ACF28F41BA000478A33 /* CPDFListView.m in Sources */,
 				BB6013822AD38E0100A76FB2 /* CPDFTextAnnotation+PDFListView.swift in Sources */,
 				BB1331502AD78DC0008F6791 /* KMPDFMergeSizeTabelViewCell.swift in Sources */,
+				BBFDFA9C2AF33DBF00E08AA2 /* KMCustomViewButton.m in Sources */,
 				BB2EDF6C296ECE17003BCF58 /* KMPageEditInsertTypeItemView.swift in Sources */,
 				BBD7FE052A1323A400F96075 /* KMEditImagePropertyViewController.swift in Sources */,
 				BBBB6CD02AD13E210035AA66 /* CPDFButtonWidgetAnnotation+PDFListView.swift in Sources */,
@@ -12049,7 +12087,6 @@
 				9F1FE4A729406E4700E952CA /* CTToolbarView.m in Sources */,
 				BB162E9D295073B50088E9D1 /* KMWatermarkManager.swift in Sources */,
 				BB1CA5C8298E20820059E31C /* KMPreferenceAligementView.swift in Sources */,
-				BB7507EB29861C37002DBDB1 /* PasswordWindowController.m in Sources */,
 				ADE3C1E029A5AA0B00793B13 /* KMRequestServer.swift in Sources */,
 				BBB9B31E299A5D6D004F3235 /* KMCloudOperation.m in Sources */,
 				BB8F4588295B19AC0037EA22 /* KMHeaderFooterDateInfoView.swift in Sources */,
@@ -12241,6 +12278,7 @@
 				BB14702B299DC0D100784A6A /* OIDAuthorizationService.m in Sources */,
 				AD9527D52952D51A0039D2BC /* KMPrintPresenter.swift in Sources */,
 				ADD1B6D92946BDFD00C3FFF7 /* KMPrintChoosePageSizeView.swift in Sources */,
+				BBFDFAA02AF3814000E08AA2 /* KMTextHintWindowController.swift in Sources */,
 				9F0CB50F2986564500007028 /* KMDesignToken+BorderLeft.swift in Sources */,
 				BB2CC5662AF123A400D7A796 /* KMBatchHeader.swift in Sources */,
 				BB2F61522966A91D001CB369 /* KMBackgroundPropertyHomeController.swift in Sources */,
@@ -12261,6 +12299,7 @@
 				ADAFDA4A2AEA7F1300F084BC /* KMAdvertisementShowView.swift in Sources */,
 				AD85D1B72AF0CCFC000F4D28 /* KMHomeHistoryListViewModel.swift in Sources */,
 				AD8F06192999DB5900D93CBC /* KMPrintDrawPage.swift in Sources */,
+				BBFDFA962AF328BA00E08AA2 /* KMBatchOperateManager.swift in Sources */,
 				9FF94F1B29A770B500B1EF69 /* KMFillSignShapePanel.swift in Sources */,
 				BBA5429E29F13A140041BAD0 /* KMMemorandumPattern.swift in Sources */,
 				BB1BFF882AEA30B1003EB179 /* NSWindow+PopOver.swift in Sources */,
@@ -12355,6 +12394,7 @@
 				8997011028F40842009AF911 /* KMOutlineViewController.swift in Sources */,
 				9F1F82BE292E01860092C4B4 /* KMCloudEmptyCollectionViewItem.swift in Sources */,
 				BB6DD8272934D056001F0544 /* KMSecureEncryptSuccessTipView.swift in Sources */,
+				BBFDFAA82AF3899400E08AA2 /* PasswordWindowController.swift in Sources */,
 				ADAFDA782AEB5FCD00F084BC /* KMHomeHistoryCollectionItem.swift in Sources */,
 				ADAFDA052AE8BD5C00F084BC /* KMConvertURLToPDF.m in Sources */,
 				9FCFECAA2AD243C900EAD2CB /* KMBlankView.swift in Sources */,

+ 39 - 0
PDF Office/PDF Master/Class/Batch/Data/KMBatchOperateManager.swift

@@ -0,0 +1,39 @@
+//
+//  KMBatchOperateManager.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/11/2.
+//
+
+import Foundation
+
+class KMBatchOperateManager: NSObject{
+    var files: [KMBatchOperateFile]?
+    var currentType: KMBatchOperationType?{
+        willSet{
+            
+        }
+        didSet {
+            if currentType != oldValue {
+                if ((self.files?.isEmpty) != nil){
+                    return
+                }
+                for i in 0..<self.files!.count {
+                    let file = self.files![i]
+                    if file.currentOperateType != self.currentType {
+                        file.currentOperateType = self.currentType
+                    }
+                }
+            }
+        }
+    }
+        
+    static let defaultManager: KMBatchOperateManager = {
+        let manager = KMBatchOperateManager()
+        manager.files = (NSMutableArray() as! [KMBatchOperateFile])
+        manager.currentType = .Convert
+        return manager
+    }()
+    
+    
+}

+ 65 - 4
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateBaseWindowController.swift

@@ -9,7 +9,45 @@ import Cocoa
 
 class KMBatchOperateBaseWindowController: NSWindowController{
     var files: [KMBatchOperateFile]?
-    var operateType: KMBatchOperationType?
+    var operateType: KMBatchOperationType?{
+        willSet{
+            
+        }
+        didSet {
+            switch operateType {
+            case .Convert:
+                self.window!.title = NSLocalizedString("Convert", comment: "")
+            case .Merge:
+                self.window!.title = NSLocalizedString("Merge", comment: "")
+            case .Compress:
+                self.window!.title = NSLocalizedString("Compress", comment: "")
+            case .AddPassword:
+                self.window!.title = NSLocalizedString("Set Passwords", comment: "")
+            case .RemovePassword:
+                self.window!.title = NSLocalizedString("Remove Security", comment: "")
+            case .AddWatermark:
+                self.window!.title = NSLocalizedString("Add Watermark", comment: "")
+            case .RemoveWatermark:
+                self.window!.title = NSLocalizedString("Remove Watermark", comment: "")
+            case .AddBackground:
+                self.window!.title = NSLocalizedString("Add Background", comment: "")
+            case .RemoveBackground:
+                self.window!.title = NSLocalizedString("Remove Background", comment: "")
+            case .AddHeaderFooter:
+                self.window!.title = NSLocalizedString("Add Header & Footer", comment: "")
+            case .RemoveHeaderFooter:
+                self.window!.title = NSLocalizedString("Remove Header & Footer", comment: "")
+            case .AddBates:
+                self.window!.title = NSLocalizedString("Add Bates Numbers", comment: "")
+            case .RemoveBates:
+                self.window!.title = NSLocalizedString("Remove Bates Numbers", comment: "")
+            case .CreatePDF:
+                self.window!.title = NSLocalizedString("Image To PDF", comment: "")
+            default :
+                self.window!.title = NSLocalizedString("Convert", comment: "")
+            }
+        }
+    }
     
     override func windowDidLoad() {
         super.windowDidLoad()
@@ -21,10 +59,33 @@ class KMBatchOperateBaseWindowController: NSWindowController{
         contentViewController = splitViewController
     }
     func switchToOperateType(_ operateType: KMBatchOperationType, files: [KMBatchOperateFile]) {
-//        self.files = files 
-//        (self.contentViewController as? KMBatchOperateSplitViewController)?.switchToOperateType(operateType: operateType, files: files as! NSMutableArray)
-//        self.operateType = operateType
+        self.files = files 
+        (self.contentViewController as? KMBatchOperateSplitViewController)?.switchToOperateType(operateType: operateType, files: files as! NSMutableArray)
+        self.operateType = operateType
+    }
+    func checkNeedPasswordSwitchToOperateType(operateType: KMBatchOperationType, files: [KMBatchOperateFile]) {
+        self.files = files
+        (self.contentViewController as! KMBatchOperateSplitViewController).checkNeedPasswordSwitchToOperateType(operateType, files: files) 
+        self.operateType = operateType
+    }
+    func switchToConvertType(convertType: KMConvertWithPDFType) {
+        (self.contentViewController as! KMBatchOperateSplitViewController).switchToConvertType(convertType)
     }
+//    func watermarkInterfaceSelectWatermark(watermark: KMPDFWatermarkData) {
+//        (self.contentViewController as! KMBatchOperateSplitViewController).watermarkInterfaceSelectWatermark(watermark: watermark)
+//    }
+//    func backgroundInterfaceSelectBackGround(background: KMBackgroundObject) {
+//        (self.contentViewController as! KMBatchOperateSplitViewController).backgroundInterfaceSelectBackGround(background: background)
+//    }
+//    func headerFooterInterfaceSelectHeaderFooter(headerFooter: KMHeaderFooterObject) {
+//        (self.contentViewController as! KMBatchOperateSplitViewController).headerFooterInterfaceSelectHeaderFooter(headerFooter: headerFooter)
+//    }
+//    func batesInterfaceSelectBates(headerFooter: KMHeaderFooterObject) {
+//        (self.contentViewController as! KMBatchOperateSplitViewController).headerFooterInterfaceSelectHeaderFooter(headerFooter: headerFooter)
+//    }
+    
+    
+    
 }
 
 

+ 23 - 23
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.swift

@@ -280,29 +280,29 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
     }
     func openPasswordWindow() {
         
-//        if lockFilePathArr!.count > lockFileIndex {
-//            let filePath = lockFilePathArr![lockFileIndex] as! String
-//            let com = PasswordWindowController(windowNibName: "PasswordWindowController")
-//            com.fileURL = URL(fileURLWithPath: filePath)
-//            com.beginSheetModal
-//            (for: self.view.window!) {
-//                password in
-//                if let password = password {
-//                    let file = KMBatchOperateFile(filePath: filePath, type: self.type)
-//                    file.password = password
-//                    self.files.add(file)
-//                    self.tableView.reloadData()
-//                }
-//                self.lockFileIndex += 1
-//                if self.lockFilePathArr.count > self.lockFileIndex {
-//                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
-//                        self.openPasswordWindow()
-//                    }
-//                } else {
-//                    self.tableView.reloadData()
-//                }
-//            }
-//        }
+        if lockFilePathArr!.count > lockFileIndex {
+            let filePath = lockFilePathArr![lockFileIndex] as! String
+            let com = PasswordWindowController(windowNibName: "PasswordWindowController")
+            com.fileURL = URL(fileURLWithPath: filePath)
+            com.beginSheetModal
+            (for: self.view.window!) {
+                password in
+                if let password = password {
+                    let file = KMBatchOperateFile(filePath: filePath, type: self.type)
+                    file.password = password
+                    self.files.add(file)
+                    self.tableView.reloadData()
+                }
+                self.lockFileIndex += 1
+                if self.lockFilePathArr.count > self.lockFileIndex {
+                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+                        self.openPasswordWindow()
+                    }
+                } else {
+                    self.tableView.reloadData()
+                }
+            }
+        }
     }
     func chooseFileFromCamera() {
         self.progressInt = 0

+ 544 - 13
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.swift

@@ -8,27 +8,330 @@
 import Cocoa
 import PDFKit
 
-class KMBatchOperateWindowController: KMBatchOperateBaseWindowController{
+let kBatchOperateToolbarIdentifier = "kBatchOperateToolbarIdentifier"
 
+let kBatchOperateToolbar_ConvertIdentifier = "kBatchOperateToolbar_ConvertIdentifier"
+let kBatchOperateToolbar_MergeIdentifier = "kBatchOperateToolbar_MergeIdentifier"
+let kBatchOperateToolbar_CompressIdentifier = "kBatchOperateToolbar_CompressIdentifier"
+let kBatchOperateToolbar_OCRIdentifier = "kBatchOperateToolbar_OCRIdentifier"
+let kBatchOperateToolbar_SecurityIdentifier = "kBatchOperateToolbar_SecurityIdentifier"
+let kBatchOperateToolbar_WatermarkIdentifier = "kBatchOperateToolbar_WatermarkIdentifier"
+
+let kBatchOperateToolbar_BackgroundIdentifier = "kBatchOperateToolbar_BackgroundIdentifier"
+let kBatchOperateToolbar_HeadFooterIdentifier = "kBatchOperateToolbar_HeadFooterIdentifier"
+let kBatchOperateToolbar_BatesIdentifier = "kBatchOperateToolbar_BatesIdentifier"
+
+
+final class KMBatchOperateWindowController: KMBatchOperateBaseWindowController, NSWindowDelegate, KMCustomButtonViewPopDelegate, KMCustomButtonViewPopDataSource, NSToolbarDelegate{
+    func numberOfLine(inCustomViewButtonPop button: KMCustomViewButton!) -> Int {
+        return 2
+    }
+    
+    func string(forCustomViewButtonPop button: KMCustomViewButton!, index: Int) -> String! {
+        if button.isEqual(self.convertToolbarItemView) {
+            if index == 0 {
+                return NSLocalizedString("Create PDF", comment: "")
+            } else {
+                return NSLocalizedString("Export to other format", comment: "")
+            }
+        } else if button.isEqual(self.securityToolbarItemView) {
+            if index == 0 {
+                return NSLocalizedString("Set Passwords", comment: "")
+            } else {
+                return NSLocalizedString("Remove Security", comment: "")
+            }
+        } else if button.isEqual(self.watermarkToolbarItemView) {
+            if index == 0 {
+                return NSLocalizedString("Add Watermark", comment: "")
+            } else {
+                return NSLocalizedString("Remove Watermark", comment: "")
+            }
+        } else if button.isEqual(self.backgroundToolbarItemView) {
+            if index == 0 {
+                return NSLocalizedString("Add Background", comment: "")
+            } else {
+                return NSLocalizedString("Remove Background", comment: "")
+            }
+        } else if button.isEqual(self.headerfooterToolbarItemView) {
+            if index == 0 {
+                return NSLocalizedString("Add Header & Footer", comment: "")
+            } else {
+                return NSLocalizedString("Remove Header & Footer", comment: "")
+            }
+        } else if button.isEqual(self.batesToolbarItemView) {
+            if index == 0 {
+                return NSLocalizedString("Add Bates Numbers", comment: "")
+            } else {
+                return NSLocalizedString("Remove Bates Numbers", comment: "")
+            }
+        }
+        return ""
+    }
+    
+    func needInsertSeperateLine(_ button: KMCustomViewButton!, index: Int) -> Bool {
+        return false
+    }
+    
+    func needHightLightLine(_ button: KMCustomViewButton!, index: Int) -> Bool {
+        if button.isEqual(self.convertToolbarItemView) {
+            if index == 0 {
+                if self.operateType == .CreatePDF {
+                    return true
+                }
+            } else if index == 1 {
+                if self.operateType == .Convert {
+                    return true
+                }
+            }
+        } else if button.isEqual(self.securityToolbarItemView) {
+            if index == 0 {
+                if self.operateType == .AddPassword {
+                    return true
+                }
+            } else if index == 1 {
+                if self.operateType == .RemovePassword {
+                    return true
+                }
+            }
+        } else if button.isEqual(self.watermarkToolbarItemView) {
+            if index == 0 {
+                if self.operateType == .AddWatermark {
+                    return true
+                }
+            } else if index == 1 {
+                if self.operateType == .RemoveWatermark {
+                    return true
+                }
+            }
+        } else if button.isEqual(self.backgroundToolbarItemView) {
+            if index == 0 {
+                if self.operateType == .AddBackground {
+                    return true
+                }
+            } else if index == 1 {
+                if self.operateType == .RemoveBackground {
+                    return true
+                }
+            }
+        } else if button.isEqual(self.headerfooterToolbarItemView) {
+            if index == 0 {
+                if self.operateType == .AddHeaderFooter {
+                    return true
+                }
+            } else if index == 1 {
+                if self.operateType == .RemoveHeaderFooter {
+                    return true
+                }
+            }
+        } else if button.isEqual(self.batesToolbarItemView) {
+            if index == 0 {
+                if self.operateType == .AddBates {
+                    return true
+                }
+            } else if index == 1 {
+                if self.operateType == .RemoveBates {
+                    return true
+                }
+            }
+        }
+        return false
+    }
+    
+    func customViewButton(_ button: KMCustomViewButton!, didSelect index: Int) {
+        if button.isEqual(self.convertToolbarItemView) {
+            if index == 0 {
+                self.createPDF(sender: "")
+            } else if index == 1 {
+                self.convertPDFToOtherFormat(sender: "")
+            }
+        } else if button.isEqual(self.securityToolbarItemView) {
+            if index == 0 {
+                self.setPDFPassword(sender: "")
+            } else if index == 1 {
+                self.removePDFPassword(sender: "")
+            }
+        } else if button.isEqual(self.watermarkToolbarItemView) {
+            if index == 0 {
+                self.addWatermark(sender: "")
+            } else if index == 1 {
+                self.removeWatermark(sender: "")
+            }
+        } else if button.isEqual(self.backgroundToolbarItemView) {
+            if index == 0 {
+                self.addBackgroud(sender: "")
+            } else if index == 1 {
+                self.removeBackground(sender: "")
+            }
+        } else if button.isEqual(self.headerfooterToolbarItemView) {
+            if index == 0 {
+                self.addHeaderFooter(sender: "")
+            } else if index == 1 {
+                self.removeHeaderFooter(sender: "")
+            }
+        } else if button.isEqual(self.batesToolbarItemView) {
+            if index == 0 {
+                self.addBates(sender: "")
+            } else if index == 1 {
+                self.removeBates(sender: "")
+            }
+        }
+    }
+    
+
+    lazy var convertToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchConvert"), back: nil, title: NSLocalizedString("Convert", comment: ""), type: .batchToolbar)
+        item.addTarget(self, action: #selector(convertPDFToOtherFormat(sender:)))
+        self.window?.contentView?.addSubview(item)
+        return item
+    }()
+    lazy var mergeToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchMerge"), back: nil, title: NSLocalizedString("Merge", comment: ""), type: .batchToolbar)
+        item.addTarget(self, action: #selector(convertPDFToOtherFormat(sender:)))
+        self.window?.contentView?.addSubview(item)
+        return item
+    }()
+    lazy var compressToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchOptimize"), back: nil, title: NSLocalizedString("Compress", comment: ""), type: .batchToolbar)
+        item.addTarget(self, action: #selector(convertPDFToOtherFormat(sender:)))
+        self.window?.contentView?.addSubview(item)
+        return item
+    }()
+    lazy var ocrToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchConvertOCR"), back: nil, title: NSLocalizedString("OCR", comment: ""), type: .batchToolbar)
+        item.addTarget(self, action: #selector(ocr(sender:)))
+        self.window?.contentView?.addSubview(item)
+        return item
+    }()
+    lazy var securityToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchSafe"), back: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Security", comment: ""), type: .batchToolbar)
+//        item.addTarget(self, action: #selector(ocr(sender:)))
+        item.delegate = self
+        item.dataSource = self
+        self.window?.contentView?.addSubview(item)
+        
+        item.mas_makeConstraints { make in
+            make?.center.equalTo()(self.window?.contentView)
+        }
+        return item
+    }()
+    
+    lazy var watermarkToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchWatermark"), back: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Watermark", comment: ""), type: .batchToolbar)
+        item.delegate = self
+        item.dataSource = self
+        self.window?.contentView?.addSubview(item)
+        item.mas_makeConstraints { make in
+            make?.center.equalTo()(self.window?.contentView)
+        }
+        return item
+    }()
+    
+    lazy var backgroundToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchBackground"), back: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Background", comment: ""), type: .batchToolbar)
+        item.delegate = self
+        item.dataSource = self
+        self.window?.contentView?.addSubview(item)
+        item.mas_makeConstraints { make in
+            make?.center.equalTo()(self.window?.contentView)
+        }
+        return item
+    }()
+    
+    lazy var headerfooterToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchHeaderandfooter"), back: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Header & Footer", comment: ""), type: .batchToolbar)
+        item.delegate = self
+        item.dataSource = self
+        self.window?.contentView?.addSubview(item)
+        item.mas_makeConstraints { make in
+            make?.center.equalTo()(self.window?.contentView)
+        }
+        return item
+    }()
+    
+    lazy var batesToolbarItemView: KMCustomViewButton = {
+        let item = KMCustomViewButton.init(frontImage: NSImage(named: "KMImageNameUXIconBatchBates"), back: NSImage(named: "KMImageNameUXIconBtnTriDownNor"), title: NSLocalizedString("Bates Numbers", comment: ""), type: .batchToolbar)
+        item.delegate = self
+        item.dataSource = self
+        self.window?.contentView?.addSubview(item)
+        item.mas_makeConstraints { make in
+            make?.center.equalTo()(self.window?.contentView)
+        }
+        return item
+    }()
+    lazy var toolbarItemViews: NSMutableArray = {
+        let arr = [self.convertToolbarItemView,
+                   self.mergeToolbarItemView,
+                   self.compressToolbarItemView,
+                   self.ocrToolbarItemView,
+                   self.securityToolbarItemView,
+                   self.watermarkToolbarItemView,
+                   self.backgroundToolbarItemView,
+                   self.headerfooterToolbarItemView,
+                   self.batesToolbarItemView
+        ]
+        return NSMutableArray(array: arr)
+    }()
+    
+    override var operateType: KMBatchOperationType?{
+        willSet{
+            
+        }
+        didSet {
+            if operateType == oldValue{
+                return
+            }else{
+                super.operateType = operateType
+            }
+            for i in 0..<self.toolbarItemViews.count {
+                let btn = self.toolbarItemViews[i] as! KMCustomViewButton 
+                btn.isSelected = false
+            }
+            switch operateType {
+            case .CreatePDF:
+                self.convertToolbarItemView.isSelected = true
+            case .Convert:
+                self.convertToolbarItemView.isSelected = true
+            case .Merge:
+                self.mergeToolbarItemView.isSelected = true
+            case .Compress:
+                self.compressToolbarItemView.isSelected = true
+            case .OCR:
+                self.ocrToolbarItemView.isSelected = true
+            case .AddPassword,.RemovePassword:
+                self.securityToolbarItemView.isSelected = true
+            case .AddWatermark,.RemoveWatermark:
+                self.watermarkToolbarItemView.isSelected = true
+            case .AddBackground,.RemoveBackground:
+                self.backgroundToolbarItemView.isSelected = true
+            case .AddHeaderFooter,.RemoveHeaderFooter:
+                self.headerfooterToolbarItemView.isSelected = true
+            case .AddBates,.RemoveBates:
+                self.batesToolbarItemView.isSelected = true
+            default :
+                self.convertToolbarItemView.isSelected = true
+            }
+            (self.contentViewController as! KMBatchOperateSplitViewController).switchToOperateType(operateType!)
+        }
+    }
    
     static let sharedWindowController: KMBatchOperateWindowController = {
         let wc = KMBatchOperateWindowController(windowNibName: "KMBatchOperateWindowController")
         let actualWindow = wc.window as! KMBatchWindow
         actualWindow.isBatch = true
-//        wc.switchToOperateType(operateType: .Convert, files: <#T##KMBatchOperateFile#>)
         
-//        if IAPProductsManager.defaultManager().isAvailableAdvancedPDFToOffice {
-//            wc.switchToConvertType(.WordAdvance)
-//        } else {
-//            wc.switchToConvertType(.WordStandard)
-//        }
+        wc.switchToOperateType(.Convert, files:KMBatchOperateManager.defaultManager.files!)
+        
+//        [IAPProductsManager defaultManager].isAvailableAdvancedPDFToOffice? KMConvertWithPDFType_WordAdvance:KMConvertWithPDFType_WordStandard
+        wc.switchToConvertType(convertType: .WordStandard)
+        
         wc.updateViewColor()
         
         return wc
     }()
     
-    func switchToOperateType(operateType: KMBatchOperationType, files:KMBatchOperateFile) {
-        
+    override func switchToOperateType(_ operateType: KMBatchOperationType, files: [KMBatchOperateFile]) {
+        super.switchToOperateType(operateType, files: files)
+        self.operateType = operateType
     }
     
     func updateViewColor() {
@@ -41,13 +344,241 @@ class KMBatchOperateWindowController: KMBatchOperateBaseWindowController{
         if let themeView = self.window?.contentView?.superview {
             for subView in themeView.subviews {
                 if NSStringFromClass(type(of: subView)) == "NSTitlebarContainerView" {
-                    subView.layer?.backgroundColor = color.cgColor 
+                    subView.layer?.backgroundColor = color.cgColor
                     break
                 }
             }
         }
     }
+    
+    func windowShouldClose(_ sender: NSWindow) -> Bool {
+        if self.operateType == .Compress {
+            let vc: KMBatchOperateRightViewController = (self.contentViewController as! KMBatchOperateSplitViewController).rightPropertiesViewController!
+            let compress = vc.compressViewController
+            var begin = false
+            for info in compress!.files! {
+                if info.status == KMBatchOperateStatus.processing {
+                    begin = true
+                    break
+                }
+            }
+            if begin {
+                let alert = NSAlert()
+                alert.alertStyle = .critical
+                alert.messageText = NSLocalizedString("Do you want to cancel compressing?", comment: "")
+                alert.informativeText = NSLocalizedString("Documents which have been compressed will still be retained.", comment: "")
+                alert.addButton(withTitle: NSLocalizedString("Cancel Compressing", comment: ""))
+                alert.addButton(withTitle: NSLocalizedString("Continue compressing", comment: ""))
+                alert.beginSheetModal(for: self.window!, completionHandler: { (response) in
+                    if response == .alertFirstButtonReturn {
+                        compress!.cancelBatchOperation()
+                        self.close()
+                    } else if response == .alertSecondButtonReturn {
+                        compress!.beginBatchOperation()
+                    }
+                })
+                return false
+            }
+        }
+        return true
+    }
+    
+    override func windowDidLoad() {
+        super.windowDidLoad()
+        if #available(macOS 11.0, *) {
+            self.window?.toolbarStyle = NSWindow.ToolbarStyle.expanded
+        }
+        self.updateViewColor()
+        self.window?.titlebarAppearsTransparent = true
+        //        self.toolbarItemViews
+        DispatchQueue.main.async {
+            self.configuToolbar()
+        }
+        NotificationCenter.default.addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
+    }
+    @objc func themeChanged(notification: NSNotification) {
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
+            self.updateViewColor()
+        }
+    }
+    
+    func configuToolbar() {
+        let toolbar = NSToolbar(identifier: kBatchOperateToolbarIdentifier)
+        toolbar.delegate = self
+        self.window?.toolbar = toolbar
+        toolbar.allowsUserCustomization = false
+        toolbar.displayMode = .iconOnly
+    }
+    
+    @objc func convertPDFToOtherFormat(sender: Any) {
+        self.operateType = .Convert
+    }
+    
+    @objc func createPDF(sender: Any) {
+        self.operateType = .CreatePDF
+    }
+    
+    @objc func merge(sender: Any) {
+        self.operateType = .Merge
+    }
+    
+    @objc func compress(sender: Any) {
+        self.operateType = .Compress
+    }
+    
+    @objc func ocr(sender: Any) {
+        self.operateType = .OCR
+    }
+    @objc func setPDFPassword(sender: Any) {
+        self.operateType = .AddPassword
+    }
+    @objc func removePDFPassword(sender: Any) {
+        self.operateType = .RemovePassword
+    }
+    @objc func addWatermark(sender: Any) {
+        self.operateType = .AddWatermark
+    }
+    @objc func removeWatermark(sender: Any) {
+        self.operateType = .RemoveWatermark
+    }
+    @objc func addBackgroud(sender: Any) {
+        self.operateType = .AddBackground
+    }
+    @objc func removeBackground(sender: Any) {
+        self.operateType = .RemoveBackground
+    }
+    @objc func addHeaderFooter(sender: Any) {
+        self.operateType = .AddHeaderFooter
+    }
+    @objc func removeHeaderFooter(sender: Any) {
+        self.operateType = .RemoveHeaderFooter
+    }
+    @objc func addBates(sender: Any) {
+        self.operateType = .AddBates
+    }
+    @objc func removeBates(sender: Any) {
+        self.operateType = .RemoveBates
+    }
+    
+    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
+        let arr = [NSToolbarItem.Identifier.flexibleSpace,
+                   NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_ConvertIdentifier),
+                   NSToolbarItem.Identifier.flexibleSpace,
+                   NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_CompressIdentifier),
+                   NSToolbarItem.Identifier.flexibleSpace,
+                   NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_SecurityIdentifier),
+                   NSToolbarItem.Identifier.flexibleSpace,
+                   NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_WatermarkIdentifier),
+                   NSToolbarItem.Identifier.flexibleSpace,
+                   NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BackgroundIdentifier),
+                   NSToolbarItem.Identifier.flexibleSpace,
+                   NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_HeadFooterIdentifier),
+                   NSToolbarItem.Identifier.flexibleSpace,
+                   NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BatesIdentifier),
+                   NSToolbarItem.Identifier.flexibleSpace
+        ]
+        return arr
+    }
+    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
+        let arr = [
+            NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_ConvertIdentifier),
+            NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_CompressIdentifier),
+            NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_SecurityIdentifier),
+            NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_WatermarkIdentifier),
+            NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BackgroundIdentifier),
+            NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_HeadFooterIdentifier),
+            NSToolbarItem.Identifier(rawValue: kBatchOperateToolbar_BatesIdentifier)
+        ]
+        return arr
+    }
+    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
+        let item = NSToolbarItem(itemIdentifier: itemIdentifier)
+        if itemIdentifier.rawValue == kBatchOperateToolbar_ConvertIdentifier {
+            item.view = self.convertToolbarItemView
+            item.toolTip = NSLocalizedString("Convert", comment: "")
+            let menuItem = NSMenuItem(title: NSLocalizedString("Convert", comment: ""), action: #selector(convertPDFToOtherFormat(sender:)), keyEquivalent: "")
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_MergeIdentifier {
+            item.view = self.mergeToolbarItemView
+            item.toolTip = NSLocalizedString("Merge", comment: "")
+            let menuItem = NSMenuItem(title: NSLocalizedString("Merge", comment: ""), action: #selector(merge(sender:)), keyEquivalent: "")
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_CompressIdentifier {
+            item.view = self.compressToolbarItemView
+            item.toolTip = NSLocalizedString("Compress", comment: "")
+            let menuItem = NSMenuItem(title: NSLocalizedString("Compress", comment: ""), action: #selector(compress(sender:)), keyEquivalent: "")
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_OCRIdentifier {
+            item.view = self.ocrToolbarItemView
+            item.toolTip = NSLocalizedString("OCR", comment: "")
+            let menuItem = NSMenuItem(title: NSLocalizedString("OCR", comment: ""), action: #selector(ocr(sender:)), keyEquivalent: "")
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_SecurityIdentifier {
+            item.view = self.securityToolbarItemView
+            let menuItem = NSMenuItem(title: NSLocalizedString("Security", comment: ""), action: nil, keyEquivalent: "")
+            let menu = NSMenu()
+            menu.addItem(withTitle: NSLocalizedString("Set Passwords", comment: ""), action: #selector(setPDFPassword(sender:)), keyEquivalent: "")
+            menu.addItem(withTitle: NSLocalizedString("Remove Security", comment: ""), action: #selector(removePDFPassword(sender:)), keyEquivalent: "")
+            menuItem.submenu = menu
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_WatermarkIdentifier {
+            item.view = self.watermarkToolbarItemView
+            let menuItem = NSMenuItem(title: NSLocalizedString("Watermark", comment: ""), action: nil, keyEquivalent: "")
+            let menu = NSMenu()
+            menu.addItem(withTitle: NSLocalizedString("Add Watermark", comment: ""), action: #selector(addWatermark(sender:)), keyEquivalent: "")
+            menu.addItem(withTitle: NSLocalizedString("Remove Watermark", comment: ""), action: #selector(removeWatermark(sender:)), keyEquivalent: "")
+            menuItem.submenu = menu
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_BackgroundIdentifier {
+            item.view = self.backgroundToolbarItemView
+            let menuItem = NSMenuItem(title: NSLocalizedString("Background", comment: ""), action: nil, keyEquivalent: "")
+            let menu = NSMenu()
+            menu.addItem(withTitle: NSLocalizedString("Add Background", comment: ""), action: #selector(addBackgroud(sender:)), keyEquivalent: "")
+            menu.addItem(withTitle: NSLocalizedString("Remove Background", comment: ""), action: #selector(removeBackground(sender:)), keyEquivalent: "")
+            menuItem.submenu = menu
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_HeadFooterIdentifier {
+            item.view = self.headerfooterToolbarItemView
+            let menuItem = NSMenuItem(title: NSLocalizedString("Header & Footer", comment: ""), action: nil, keyEquivalent: "")
+            let menu = NSMenu()
+            menu.addItem(withTitle: NSLocalizedString("Add Header & Footer", comment: ""), action: #selector(addHeaderFooter(sender:)), keyEquivalent: "")
+            menu.addItem(withTitle: NSLocalizedString("Remove Header & Footer", comment: ""), action: #selector(removeHeaderFooter(sender:)), keyEquivalent: "")
+            menuItem.submenu = menu
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        } else if itemIdentifier.rawValue == kBatchOperateToolbar_BatesIdentifier {
+            item.view = self.batesToolbarItemView
+            let menuItem = NSMenuItem(title: NSLocalizedString("Bates Numbers", comment: ""), action: nil, keyEquivalent: "")
+            let menu = NSMenu()
+            menu.addItem(withTitle: NSLocalizedString("Add Bates Numbers", comment: ""), action: #selector(addBates(sender:)), keyEquivalent: "")
+            menu.addItem(withTitle: NSLocalizedString("Remove Bates Numbers", comment: ""), action: #selector(removeBates(sender:)), keyEquivalent: "")
+            menuItem.submenu = menu
+            menuItem.target = self
+            item.menuFormRepresentation = menuItem
+        }
+        return item
+    }
+    func showIsConvertingHint() {
+        let texHintWindowController = KMTextHintWindowController(windowNibName: "KMTextHintWindowController")
+        self.window?.beginSheet(texHintWindowController.window!)
+    }
+    func windowDidBecomeKey(_ notification: Notification) {
+        for i in 0..<self.toolbarItemViews.count {
+            var btn = self.toolbarItemViews[i] as! KMCustomViewButton
+            btn.enable = true
+        }
+    }
+    func windowDidResignKey(_ notification: Notification) {
+        for i in 0..<self.toolbarItemViews.count {
+            let btn = self.toolbarItemViews[i] as! KMCustomViewButton
+            btn.enable = false
+        }
+    }
 }
-
-
-

+ 37 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMTextHintWindowController.swift

@@ -0,0 +1,37 @@
+//
+//  KMTextHintWindowController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/11/2.
+//
+
+import Cocoa
+
+class KMTextHintWindowController: NSWindowController{
+    
+    @IBOutlet var headerTextField: NSTextField!
+    
+    @IBOutlet var detailTextfield: NSTextField!
+    
+    @IBOutlet var actionButton: NSButton!
+    
+    override func windowDidLoad() {
+        super.windowDidLoad()
+        self.actionButton.title = NSLocalizedString("OK", comment: "")
+        self.headerTextField.stringValue = NSLocalizedString("Cannot add conversion tasks.", comment: "")
+        self.detailTextfield.stringValue = NSLocalizedString("The conversion is in progress... Please wait for the conversion to be completed before proceeding.", comment: "")
+    }
+    
+    @IBAction func buttonClicked_Action(_ sender: NSButton) {
+        if #available(macOS 10.13, *) {
+            self.window?.endSheet(sender.window!)
+        } else {
+            NSApp.endSheet(self.window!)
+        }
+        self.window?.orderOut(self)
+    }
+    func updateTitleString(titleString: String, detailString: String) {
+        self.headerTextField.stringValue = titleString
+        self.detailTextfield.stringValue = detailString
+    }
+}

+ 77 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMTextHintWindowController.xib

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMTextHintWindowController" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="actionButton" destination="x5y-RO-Lmv" id="rq1-LN-0Xl"/>
+                <outlet property="detailTextfield" destination="ry0-kd-mg3" id="hOn-CU-p3h"/>
+                <outlet property="headerTextField" destination="l42-pQ-rSZ" id="LEa-NJ-HMr"/>
+                <outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+            <rect key="contentRect" x="196" y="240" width="385" height="258"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <view key="contentView" id="se5-gp-TjO">
+                <rect key="frame" x="0.0" y="0.0" width="385" height="133"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="l42-pQ-rSZ">
+                        <rect key="frame" x="22" y="99" width="184" height="16"/>
+                        <textFieldCell key="cell" selectable="YES" title="Cannot add conversion task" id="NfC-Cv-b95">
+                            <font key="font" metaFont="systemBold"/>
+                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                        </textFieldCell>
+                    </textField>
+                    <textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="ry0-kd-mg3">
+                        <rect key="frame" x="22" y="46" width="341" height="45"/>
+                        <textFieldCell key="cell" selectable="YES" id="wDd-jS-7Pi">
+                            <font key="font" metaFont="cellTitle"/>
+                            <string key="title">The current conversion is in progress...
+Please wait for the conversion to be completed before proceeding.</string>
+                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                        </textFieldCell>
+                    </textField>
+                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="x5y-RO-Lmv">
+                        <rect key="frame" x="303" y="11" width="75" height="32"/>
+                        <buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="5pj-EG-tmU">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+DQ
+</string>
+                        </buttonCell>
+                        <connections>
+                            <action selector="buttonClicked_Action:" target="-2" id="zpF-T3-a6t"/>
+                        </connections>
+                    </button>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="trailing" secondItem="ry0-kd-mg3" secondAttribute="trailing" constant="24" id="7Av-f2-oJO"/>
+                    <constraint firstItem="ry0-kd-mg3" firstAttribute="leading" secondItem="l42-pQ-rSZ" secondAttribute="leading" id="9X3-pO-YU0"/>
+                    <constraint firstAttribute="trailing" secondItem="x5y-RO-Lmv" secondAttribute="trailing" constant="14" id="D6Q-bI-Xh9"/>
+                    <constraint firstItem="l42-pQ-rSZ" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="18" id="EQb-qq-tfG"/>
+                    <constraint firstItem="ry0-kd-mg3" firstAttribute="top" secondItem="l42-pQ-rSZ" secondAttribute="bottom" constant="8" id="W21-yo-QVO"/>
+                    <constraint firstItem="x5y-RO-Lmv" firstAttribute="top" secondItem="ry0-kd-mg3" secondAttribute="bottom" constant="8" id="WzS-9m-BQr"/>
+                    <constraint firstAttribute="bottom" secondItem="x5y-RO-Lmv" secondAttribute="bottom" constant="18" id="Z74-pW-WEo"/>
+                    <constraint firstItem="l42-pQ-rSZ" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="24" id="a2c-AF-SJc"/>
+                </constraints>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
+            </connections>
+            <point key="canvasLocation" x="-147.5" y="107"/>
+        </window>
+    </objects>
+</document>

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

@@ -0,0 +1,106 @@
+//
+//  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

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

@@ -0,0 +1,393 @@
+//
+//  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

+ 93 - 0
PDF Office/PDF Master/Class/Batch/WindowController/PasswordWindowController.swift

@@ -0,0 +1,93 @@
+//
+//  PasswordWindowController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/11/2.
+//
+
+import Cocoa
+
+@objc(PasswordWindowDelegate)
+protocol PasswordWindowDelegate: AnyObject {
+    @objc optional func didFinshedUnlockFile(_ passwordWindowCtr: PasswordWindowController, password: String)
+    @objc optional func didCancelUnlockFile(_ passwordWindowCtr: PasswordWindowController)
+}
+
+@objc class PasswordWindowController: NSWindowController{
+    var fileUrl: URL?
+    var delegate: PasswordWindowDelegate?
+    var tag: Int = 0
+    var password: String?
+    @IBOutlet var passwordTextField: NSSecureTextField!
+    
+    @IBOutlet var titleTextField: NSTextField!
+    
+    @IBOutlet var textField: NSTextField!
+    
+    @IBOutlet var openButton: NSButton!
+    @IBOutlet var cancelButton: NSButton!
+    override init(window: NSWindow?) {
+        super.init(window: window)
+        
+    }
+    
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+    }
+    
+    override func windowDidLoad() {
+        super.windowDidLoad()
+        titleTextField.stringValue = fileUrl?.lastPathComponent ?? ""
+        textField.stringValue = NSLocalizedString("This PDF is password protected. Please enter the password below to access this PDF.", comment: "")
+        openButton.title = NSLocalizedString("Open", comment: "")
+        cancelButton.title = NSLocalizedString("Cancel", comment: "")
+    }
+    
+    @IBAction func cancelAction(_ sender: NSButton) {
+        self.close()
+    }
+    
+    @IBAction func OKAction(_ sender: NSButton) {
+        let pdfDoc = PDFDocument(url: fileUrl!)
+        if pdfDoc != nil {
+            let isOk = pdfDoc?.unlock(withPassword: passwordTextField.stringValue)
+            if isOk! {
+                if pdfDoc?.permissionsStatus == .owner {
+                    self.password = passwordTextField.stringValue
+                    self.close()
+                } else{ 
+                    self.incorrectPasswordAlert()
+                }
+            } else {
+                self.incorrectPasswordAlert()
+            }
+        }
+    }
+    
+    func incorrectPasswordAlert() {
+        let alert = NSAlert()
+        alert.alertStyle = .critical
+        alert.messageText = NSLocalizedString("Incorrect password. Please check your password and try again.", comment: "")
+        alert.runModal()
+    }
+    
+    @objc func didEndSheet(_ sheet: NSWindow, returnCode: NSInteger, contextInfo: UnsafeMutableRawPointer?) {
+        if contextInfo != nil {
+            let handler = contextInfo!.assumingMemoryBound(to: ((String) -> Void).self).pointee
+            handler(password ?? "")
+        }
+    }
+    func beginSheetModalForWindow(_ window: NSWindow, completionHandler handler: ((String) -> Void)?) {
+//        self.window?.beginSheet(window)
+        NSApp.beginSheet(self.window!,
+                         modalFor: window,
+                         modalDelegate: self,
+                         didEnd: #selector(didEndSheet(_:returnCode:contextInfo:)),
+                         contextInfo: handler != nil ? unsafeBitCast(handler, to: UnsafeMutableRawPointer.self) : nil)
+    }
+    
+    override func close() {
+        NSApp.endSheet(self.window!)
+        self.window?.orderOut(self)
+    }
+}

+ 16 - 11
PDF Office/PDF Master/Class/Merge/OCPart/PasswordWindowController.xib

@@ -1,18 +1,23 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="PasswordWindowController">
+        <customObject id="-2" userLabel="File's Owner" customClass="PasswordWindowController" customModule="PDF_Master" customModuleProvider="target">
             <connections>
                 <outlet property="_cancelButton" destination="10" id="2Rq-Y5-VcA"/>
                 <outlet property="_openButton" destination="9" id="AOP-hG-el8"/>
                 <outlet property="_passwordTextField" destination="7" id="42"/>
                 <outlet property="_textField" destination="8" id="Pcr-bw-2m1"/>
                 <outlet property="_titleTextField" destination="45" id="55"/>
+                <outlet property="cancelButton" destination="10" id="LnY-wb-9IH"/>
+                <outlet property="openButton" destination="9" id="ry0-hN-OF4"/>
+                <outlet property="passwordTextField" destination="7" id="kMA-iN-LOA"/>
+                <outlet property="textField" destination="8" id="rvG-TA-6Xf"/>
+                <outlet property="titleTextField" destination="45" id="sbf-Cc-xq2"/>
                 <outlet property="window" destination="5" id="40"/>
             </connections>
         </customObject>
@@ -51,14 +56,11 @@ Gw
 </string>
                         </buttonCell>
                         <connections>
-                            <action selector="cancelAction:" target="-2" id="43"/>
+                            <action selector="cancelAction:" target="-2" id="ezk-NS-fla"/>
                         </connections>
                     </button>
                     <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9">
                         <rect key="frame" x="300" y="7" width="67" height="32"/>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="20" id="Xf5-5t-kUy"/>
-                        </constraints>
                         <buttonCell key="cell" type="push" title="Open" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="15">
                             <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                             <font key="font" metaFont="system"/>
@@ -66,11 +68,14 @@ Gw
 DQ
 </string>
                         </buttonCell>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="20" id="Xf5-5t-kUy"/>
+                        </constraints>
                         <connections>
-                            <action selector="OKAction:" target="-2" id="44"/>
+                            <action selector="OKAction:" target="-2" id="ZAZ-9I-KPf"/>
                         </connections>
                     </button>
-                    <secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7">
+                    <secureTextField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7">
                         <rect key="frame" x="124" y="80" width="199" height="22"/>
                         <constraints>
                             <constraint firstAttribute="width" constant="199" id="9Gd-ba-hvr"/>
@@ -85,7 +90,7 @@ DQ
                             </allowedInputSourceLocales>
                         </secureTextFieldCell>
                     </secureTextField>
-                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="45">
+                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="45">
                         <rect key="frame" x="89" y="161" width="278" height="16"/>
                         <textFieldCell key="cell" lineBreakMode="charWrapping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="46">
                             <font key="font" metaFont="system"/>
@@ -93,7 +98,7 @@ DQ
                             <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
                         </textFieldCell>
                     </textField>
-                    <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="8">
+                    <textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="8">
                         <rect key="frame" x="89" y="112" width="278" height="48"/>
                         <constraints>
                             <constraint firstAttribute="width" constant="274" id="tBH-cN-Iys"/>

+ 0 - 1
PDF Office/PDF Master/Class/Merge/OCPart/KMPDFEditAppendWindow.m

@@ -7,7 +7,6 @@
 //
 
 #import "KMPDFEditAppendWindow.h"
-#import "PasswordWindowController.h"
 #import <Quartz/Quartz.h>
 #import <Masonry/Masonry.h>
 #import <PDF_Master-Swift.h>

+ 0 - 41
PDF Office/PDF Master/Class/Merge/OCPart/PasswordWindowController.h

@@ -1,41 +0,0 @@
-//
-//  PasswordWindowController.h
-//  PDF Reader
-//
-//  Created by wangshuai on 13-12-3.
-//  Copyright (c) 2013年 zhangjie. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-
-@class PasswordWindowController;
-@protocol PasswordWindowDelegate <NSObject>
-@optional
-- (void)didFinshedUnlockFile:(PasswordWindowController*)passwordWindowCtr withPassword:(NSString*)password;
-- (void)didCancelUnlockFile:(PasswordWindowController*)passwordWindowCtr;
-
-@end
-
-@interface PasswordWindowController : NSWindowController{
-    NSURL *_fileURL;
-//    id<PasswordWindowDelegate> _passwordDelegate;
-    NSInteger _tag;
-    
-    IBOutlet NSTextField *_passwordTextField;
-    IBOutlet NSTextField *_titleTextField;
-    IBOutlet NSTextField *_textField;
-    
-    IBOutlet NSButton *_openButton;
-    IBOutlet NSButton *_cancelButton;
-}
-@property (nonatomic,retain) NSURL *fileURL;
-@property (nonatomic,weak) id<PasswordWindowDelegate> passwordDelegate;
-@property (nonatomic,assign) NSInteger tag;
-
-- (IBAction)cancelAction:(id)sender;
-- (IBAction)OKAction:(id)sender;
-
-- (void)beginSheetModalForWindow:(NSWindow *)window completionHandler:(void (^)(NSString *password))handler;
-
-
-@end

+ 0 - 98
PDF Office/PDF Master/Class/Merge/OCPart/PasswordWindowController.m

@@ -1,98 +0,0 @@
-//
-//  PasswordWindowController.m
-//  PDF Reader
-//
-//  Created by wangshuai on 13-12-3.
-//  Copyright (c) 2013年 zhangjie. All rights reserved.
-//
-
-#import "PasswordWindowController.h"
-#import <Quartz/Quartz.h>
-
-@interface PasswordWindowController ()
-@property (nonatomic,retain) NSString *password;
-
-@end
-
-@implementation PasswordWindowController
-@synthesize fileURL = _fileURL;
-@synthesize passwordDelegate = _passwordDelegate;
-@synthesize tag = _tag;
-
-- (id)initWithWindow:(NSWindow *)window
-{
-    self = [super initWithWindow:window];
-    if (self) {
-        // Initialization code here.
-    }
-    return self;
-}
-
-- (void)windowDidLoad
-{
-    [super windowDidLoad];
-    
-    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
-    _titleTextField.stringValue = [_fileURL lastPathComponent]?:@"";
-    _textField.stringValue = NSLocalizedString(@"This PDF is password protected. Please enter the password below to access this PDF.", nil);
-    _openButton.title = NSLocalizedString(@"Open", nil);
-    _cancelButton.title = NSLocalizedString(@"Cancel", nil);
-}
-
-- (void)dealloc
-{
-    _passwordDelegate = nil;
-}
-
-- (void)close
-{
-//    [super close];
-    [NSApp endSheet:self.window];
-    [[self window] orderOut:self];
-
-}
-
-- (IBAction)cancelAction:(id)sender
-{
-    [self close];
-//    if ([_passwordDelegate respondsToSelector:@selector(didCancelUnlockFile:)]) {
-//        [_passwordDelegate didCancelUnlockFile:self];
-//    }
-}
-
-- (IBAction)OKAction:(id)sender
-{
-    PDFDocument *pdfDoc = [[PDFDocument alloc] initWithURL:_fileURL];
-    if (pdfDoc) {
-        if ([pdfDoc unlockWithPassword:[_passwordTextField stringValue]]) {
-            self.password = [_passwordTextField stringValue];
-             [self close];
-        }else{
-            NSAlert *alert = [[NSAlert alloc] init];
-            [alert setAlertStyle:NSAlertStyleCritical];
-            [alert setMessageText:NSLocalizedString(@"Incorrect password. Please check your password and try again.", nil)];
-            [alert runModal];
-        }
-    }
-}
-
-#pragma mark Show Methods
-- (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
-    if (contextInfo != NULL) {
-        void (^handler)(NSString *password) = (void(^)(NSString *password))CFBridgingRelease(contextInfo);
-        handler(_password);
-    }
-}
-
-- (void)beginSheetModalForWindow:(NSWindow *)window completionHandler:(void (^)(NSString *password))handler{
-//    [self retain]; // make sure we stay around long enough
-    
-    [NSApp beginSheet:[self window]
-       modalForWindow:window
-        modalDelegate:self
-       didEndSelector:@selector(didEndSheet:returnCode:contextInfo:)
-          contextInfo:handler ? CFBridgingRetain(handler) : NULL];
-}
-
-
-@end