فهرست منبع

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

jiajie 1 سال پیش
والد
کامیت
87a781c44d
16فایلهای تغییر یافته به همراه1790 افزوده شده و 309 حذف شده
  1. 64 0
      PDF Office/PDF Master.xcodeproj/project.pbxproj
  2. 231 0
      PDF Office/PDF Master/Class/PDFTools/Compare/Model/KMCompareFilesConfig.swift
  3. 76 0
      PDF Office/PDF Master/Class/PDFTools/Compare/View/CompareFilesView/KMCompareFilesView.swift
  4. 466 3
      PDF Office/PDF Master/Class/PDFTools/Compare/View/KMCompareView.swift
  5. 37 6
      PDF Office/PDF Master/Class/PDFTools/Compare/View/KMCompareView.xib
  6. 77 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFDocumentExtensions/CPDFDocument+KMExtension.swift
  7. 27 0
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMBotaEnum.swift
  8. 423 250
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController.swift
  9. 8 3
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMSegmentedControl.swift
  10. 7 14
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/LeftSideView.xib
  11. 113 0
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Search/KMBotaSearchViewController.swift
  12. 233 0
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Search/KMBotaSearchViewController.xib
  13. 22 0
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Search/View/KMFindTableviewCell.swift
  14. 5 5
      PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift
  15. 0 23
      PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+UI.swift
  16. 1 5
      PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController.swift

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

@@ -1906,6 +1906,12 @@
 		ADE86ACC2B034CC000414DFA /* KMAddBackgroundView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADE86ACB2B034CC000414DFA /* KMAddBackgroundView.xib */; };
 		ADE86ACD2B034CC000414DFA /* KMAddBackgroundView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADE86ACB2B034CC000414DFA /* KMAddBackgroundView.xib */; };
 		ADE86ACE2B034CC000414DFA /* KMAddBackgroundView.xib in Resources */ = {isa = PBXBuildFile; fileRef = ADE86ACB2B034CC000414DFA /* KMAddBackgroundView.xib */; };
+		ADE86AD12B04BAEA00414DFA /* KMCompareFilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE86AD02B04BAEA00414DFA /* KMCompareFilesView.swift */; };
+		ADE86AD22B04BAEA00414DFA /* KMCompareFilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE86AD02B04BAEA00414DFA /* KMCompareFilesView.swift */; };
+		ADE86AD32B04BAEA00414DFA /* KMCompareFilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE86AD02B04BAEA00414DFA /* KMCompareFilesView.swift */; };
+		ADE86AD62B05A52B00414DFA /* KMCompareFilesConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE86AD52B05A52B00414DFA /* KMCompareFilesConfig.swift */; };
+		ADE86AD72B05A52B00414DFA /* KMCompareFilesConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE86AD52B05A52B00414DFA /* KMCompareFilesConfig.swift */; };
+		ADE86AD82B05A52B00414DFA /* KMCompareFilesConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE86AD52B05A52B00414DFA /* KMCompareFilesConfig.swift */; };
 		ADE8BC2529F7CCA600570F89 /* KMPageNumberDisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE8BC2429F7CCA600570F89 /* KMPageNumberDisplayView.swift */; };
 		ADE8BC2629F7CCA600570F89 /* KMPageNumberDisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE8BC2429F7CCA600570F89 /* KMPageNumberDisplayView.swift */; };
 		ADE8BC2729F7CCA600570F89 /* KMPageNumberDisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADE8BC2429F7CCA600570F89 /* KMPageNumberDisplayView.swift */; };
@@ -2438,6 +2444,12 @@
 		BB35C49F2975362900D46EE2 /* KMRedactTopToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB35C49E2975362900D46EE2 /* KMRedactTopToolBar.swift */; };
 		BB35C4A02975362900D46EE2 /* KMRedactTopToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB35C49E2975362900D46EE2 /* KMRedactTopToolBar.swift */; };
 		BB35C4A12975362900D46EE2 /* KMRedactTopToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB35C49E2975362900D46EE2 /* KMRedactTopToolBar.swift */; };
+		BB3A668C2B06FD0100575343 /* KMBotaEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A668B2B06FD0100575343 /* KMBotaEnum.swift */; };
+		BB3A668D2B06FD0100575343 /* KMBotaEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A668B2B06FD0100575343 /* KMBotaEnum.swift */; };
+		BB3A668E2B06FD0100575343 /* KMBotaEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A668B2B06FD0100575343 /* KMBotaEnum.swift */; };
+		BB3A66902B07099F00575343 /* KMFindTableviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A668F2B07099F00575343 /* KMFindTableviewCell.swift */; };
+		BB3A66912B07099F00575343 /* KMFindTableviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A668F2B07099F00575343 /* KMFindTableviewCell.swift */; };
+		BB3A66922B07099F00575343 /* KMFindTableviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A668F2B07099F00575343 /* KMFindTableviewCell.swift */; };
 		BB3A81AC2AC2A4E4006FC66C /* NSTextView+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A81AB2AC2A4E4006FC66C /* NSTextView+KMExtension.swift */; };
 		BB3A81AD2AC2A4E4006FC66C /* NSTextView+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A81AB2AC2A4E4006FC66C /* NSTextView+KMExtension.swift */; };
 		BB3A81AE2AC2A4E4006FC66C /* NSTextView+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3A81AB2AC2A4E4006FC66C /* NSTextView+KMExtension.swift */; };
@@ -3373,6 +3385,12 @@
 		BBC8A76D2B05EDDF00FA9377 /* KMThumbnail.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC8A76C2B05EDDE00FA9377 /* KMThumbnail.swift */; };
 		BBC8A76E2B05EDDF00FA9377 /* KMThumbnail.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC8A76C2B05EDDE00FA9377 /* KMThumbnail.swift */; };
 		BBC8A76F2B05EDDF00FA9377 /* KMThumbnail.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC8A76C2B05EDDE00FA9377 /* KMThumbnail.swift */; };
+		BBC8A7712B06408600FA9377 /* KMBotaSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC8A7702B06408600FA9377 /* KMBotaSearchViewController.swift */; };
+		BBC8A7722B06408600FA9377 /* KMBotaSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC8A7702B06408600FA9377 /* KMBotaSearchViewController.swift */; };
+		BBC8A7732B06408600FA9377 /* KMBotaSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC8A7702B06408600FA9377 /* KMBotaSearchViewController.swift */; };
+		BBC8A7752B0640C200FA9377 /* KMBotaSearchViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBC8A7742B0640C200FA9377 /* KMBotaSearchViewController.xib */; };
+		BBC8A7762B0640C200FA9377 /* KMBotaSearchViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBC8A7742B0640C200FA9377 /* KMBotaSearchViewController.xib */; };
+		BBC8A7772B0640C200FA9377 /* KMBotaSearchViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = BBC8A7742B0640C200FA9377 /* KMBotaSearchViewController.xib */; };
 		BBCE57102A72712200508EFC /* NSWindowController+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCE570F2A72712200508EFC /* NSWindowController+KMExtension.swift */; };
 		BBCE57112A72712200508EFC /* NSWindowController+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCE570F2A72712200508EFC /* NSWindowController+KMExtension.swift */; };
 		BBCE57122A72712200508EFC /* NSWindowController+KMExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCE570F2A72712200508EFC /* NSWindowController+KMExtension.swift */; };
@@ -4529,6 +4547,8 @@
 		ADE86ABF2B034C7100414DFA /* KMBackgroundWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMBackgroundWindowController.xib; sourceTree = "<group>"; };
 		ADE86AC72B034CB200414DFA /* KMAddBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMAddBackgroundView.swift; sourceTree = "<group>"; };
 		ADE86ACB2B034CC000414DFA /* KMAddBackgroundView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMAddBackgroundView.xib; sourceTree = "<group>"; };
+		ADE86AD02B04BAEA00414DFA /* KMCompareFilesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMCompareFilesView.swift; sourceTree = "<group>"; };
+		ADE86AD52B05A52B00414DFA /* KMCompareFilesConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMCompareFilesConfig.swift; sourceTree = "<group>"; };
 		ADE8BC2429F7CCA600570F89 /* KMPageNumberDisplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPageNumberDisplayView.swift; sourceTree = "<group>"; };
 		ADE8BC2929F7CDB000570F89 /* KMPageNumberDisplayView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMPageNumberDisplayView.xib; sourceTree = "<group>"; };
 		ADE8BC2E29F8CD7200570F89 /* KMPDFThumbnailModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KMPDFThumbnailModel.swift; sourceTree = "<group>"; };
@@ -4771,6 +4791,8 @@
 		BB332D522995D8B500CABB58 /* KMCloudDocumentTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMCloudDocumentTools.swift; sourceTree = "<group>"; };
 		BB35732C2AF4F07B004CDA92 /* BatchImage.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = BatchImage.xcassets; sourceTree = "<group>"; };
 		BB35C49E2975362900D46EE2 /* KMRedactTopToolBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMRedactTopToolBar.swift; sourceTree = "<group>"; };
+		BB3A668B2B06FD0100575343 /* KMBotaEnum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBotaEnum.swift; sourceTree = "<group>"; };
+		BB3A668F2B07099F00575343 /* KMFindTableviewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMFindTableviewCell.swift; sourceTree = "<group>"; };
 		BB3A81AB2AC2A4E4006FC66C /* NSTextView+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+KMExtension.swift"; sourceTree = "<group>"; };
 		BB3A81AF2AC2B82A006FC66C /* KMPageSizeTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPageSizeTool.swift; sourceTree = "<group>"; };
 		BB3A81B42AC2C0F4006FC66C /* NSObject+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSObject+KMExtension.swift"; sourceTree = "<group>"; };
@@ -5116,6 +5138,8 @@
 		BBC8A7632B05C93900FA9377 /* KMThumbnailTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMThumbnailTableView.swift; sourceTree = "<group>"; };
 		BBC8A7672B05EB8000FA9377 /* KMThumbnailTableviewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMThumbnailTableviewCell.swift; sourceTree = "<group>"; };
 		BBC8A76C2B05EDDE00FA9377 /* KMThumbnail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMThumbnail.swift; sourceTree = "<group>"; };
+		BBC8A7702B06408600FA9377 /* KMBotaSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBotaSearchViewController.swift; sourceTree = "<group>"; };
+		BBC8A7742B0640C200FA9377 /* KMBotaSearchViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KMBotaSearchViewController.xib; sourceTree = "<group>"; };
 		BBCE570F2A72712200508EFC /* NSWindowController+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSWindowController+KMExtension.swift"; sourceTree = "<group>"; };
 		BBCE57132A72713A00508EFC /* NSViewController+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSViewController+KMExtension.swift"; sourceTree = "<group>"; };
 		BBCE57172A72723600508EFC /* NSResponder+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSResponder+KMExtension.swift"; sourceTree = "<group>"; };
@@ -5443,6 +5467,8 @@
 			children = (
 				ADE3C1A729A3A05400793B13 /* View */,
 				8942F7EE2926087200389627 /* KMSearchViewController.swift */,
+				BBC8A7702B06408600FA9377 /* KMBotaSearchViewController.swift */,
+				BBC8A7742B0640C200FA9377 /* KMBotaSearchViewController.xib */,
 				8942F7EF2926087200389627 /* KMSearchViewController.xib */,
 				89752E1C2942CB03003FF08E /* KMSearchMode.swift */,
 			);
@@ -5579,6 +5605,7 @@
 				BBC8A75F2B05C87600FA9377 /* KMBotaTableView.swift */,
 				BBC8A7632B05C93900FA9377 /* KMThumbnailTableView.swift */,
 				BBC8A7672B05EB8000FA9377 /* KMThumbnailTableviewCell.swift */,
+				BB3A668B2B06FD0100575343 /* KMBotaEnum.swift */,
 				899700F128F40308009AF911 /* Annotation */,
 				899700F228F40308009AF911 /* BookMarks */,
 				899700F028F40308009AF911 /* From */,
@@ -7394,6 +7421,7 @@
 				89752E182941FD48003FF08E /* KMSearchCellView.swift */,
 				ADE8BC3229F9261900570F89 /* KMSearchCellView.xib */,
 				ADE3C19E29A3894900793B13 /* KMSearchTableRowView.swift */,
+				BB3A668F2B07099F00575343 /* KMFindTableviewCell.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -7536,6 +7564,7 @@
 		ADE86A992B031FB500414DFA /* Compare */ = {
 			isa = PBXGroup;
 			children = (
+				ADE86AD42B05A4E700414DFA /* Model */,
 				ADE86A9A2B031FBC00414DFA /* View */,
 				ADE86A9B2B031FDB00414DFA /* KMCompareWindowController.swift */,
 				ADE86A9C2B031FDB00414DFA /* KMCompareWindowController.xib */,
@@ -7546,6 +7575,7 @@
 		ADE86A9A2B031FBC00414DFA /* View */ = {
 			isa = PBXGroup;
 			children = (
+				ADE86ACF2B04BAC800414DFA /* CompareFilesView */,
 				ADE86AA32B031FF000414DFA /* KMCompareView.swift */,
 				ADE86AA72B031FFA00414DFA /* KMCompareView.xib */,
 			);
@@ -7590,6 +7620,22 @@
 			path = View;
 			sourceTree = "<group>";
 		};
+		ADE86ACF2B04BAC800414DFA /* CompareFilesView */ = {
+			isa = PBXGroup;
+			children = (
+				ADE86AD02B04BAEA00414DFA /* KMCompareFilesView.swift */,
+			);
+			path = CompareFilesView;
+			sourceTree = "<group>";
+		};
+		ADE86AD42B05A4E700414DFA /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				ADE86AD52B05A52B00414DFA /* KMCompareFilesConfig.swift */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
 		ADE8BC2329F7CA5900570F89 /* Views */ = {
 			isa = PBXGroup;
 			children = (
@@ -10198,6 +10244,7 @@
 				BBA2109429ACC10F00E6B346 /* signlist_add.pdf in Resources */,
 				BBFDFAAA2AF389B700E08AA2 /* PasswordWindowController.xib in Resources */,
 				ADE86A7B2B0221E100414DFA /* KMSecurityWindowController.xib in Resources */,
+				BBC8A7752B0640C200FA9377 /* KMBotaSearchViewController.xib in Resources */,
 				BB65A0742AF8DE4F003A27A0 /* SyncPreferences.xib in Resources */,
 				9F0201992A1F352100C9B673 /* KMAITranslationConfirmWindowController.xib in Resources */,
 				BB89721B294AED6C0045787C /* KMWatermarkAdjectivePreViewBaseController.xib in Resources */,
@@ -10632,6 +10679,7 @@
 				ADAFDA1D2AE8DD6600F084BC /* KMAdvertisementTableView.xib in Resources */,
 				9F0CB4B92977BC1000007028 /* KMPropertiesPanelPreviewSubVC.xib in Resources */,
 				BBF62C752B0347D1007B7E86 /* SplitWindowController.xib in Resources */,
+				BBC8A7762B0640C200FA9377 /* KMBotaSearchViewController.xib in Resources */,
 				BB96A0B52AFCD56B00559E24 /* KMToolCompareWindowController.xib in Resources */,
 				9F8539FD2947137500DF644E /* throbber_waiting.png in Resources */,
 				9F8539E42947126000DF644E /* KMChromiumToolbar.xib in Resources */,
@@ -11079,6 +11127,7 @@
 				89316857296E45CA0073EA59 /* KMImageAccessoryController.xib in Resources */,
 				9FBA0EEB28FFC2FE001117AF /* Image.xcassets in Resources */,
 				9F3D819829A33A290087B5AD /* KMDesignDropdown.xib in Resources */,
+				BBC8A7772B0640C200FA9377 /* KMBotaSearchViewController.xib in Resources */,
 				8997010B28F4082C009AF911 /* KMFromViewController.xib in Resources */,
 				9F0CB4642966C9E200007028 /* KMFormPropertPanelViewController.xib in Resources */,
 				BBFBE74B28DD7DDE008B2335 /* Main.storyboard in Resources */,
@@ -11400,6 +11449,7 @@
 				ADDEEA7A2AD3F4C800EF675D /* KMPopUpButton.swift in Sources */,
 				BB1BFF792AEA0B8E003EB179 /* KMBatchOperateRightViewController.swift in Sources */,
 				ADAFDA282AE8DE1B00F084BC /* KMAdvertisementModelTransition.swift in Sources */,
+				BB3A66902B07099F00575343 /* KMFindTableviewCell.swift in Sources */,
 				ADC63E482A49BEDD00854E02 /* KMSubscribeWaterMarkCollectionItem.swift in Sources */,
 				89752E1D2942CB03003FF08E /* KMSearchMode.swift in Sources */,
 				AD3A3587294C11ED00D72802 /* KMPrintPreviewPresenter.swift in Sources */,
@@ -11548,6 +11598,7 @@
 				ADAFDA302AE8E45000F084BC /* KMAdvertisementConfig.swift in Sources */,
 				9FAAA325290A69920046FFCE /* KMToolSetScroller.swift in Sources */,
 				AD0FA51229A9FA8600EDEB50 /* KMResetPasswordView.swift in Sources */,
+				BB3A668C2B06FD0100575343 /* KMBotaEnum.swift in Sources */,
 				9FDD0F882952FCC6000C4DAD /* KMCompLightParser.swift in Sources */,
 				9F1FE4C629406E4700E952CA /* CTUtil.m in Sources */,
 				BB147035299DC0D200784A6A /* OIDRegistrationResponse.m in Sources */,
@@ -11921,11 +11972,13 @@
 				9F1FE4A229406E4700E952CA /* CTToolbarController.m in Sources */,
 				BB147041299DC0D200784A6A /* OIDClientMetadataParameters.m in Sources */,
 				ADDEEA6A2AD3CF3A00EF675D /* KMDrawView.swift in Sources */,
+				BBC8A7712B06408600FA9377 /* KMBotaSearchViewController.swift in Sources */,
 				BB1A34A8295EA30100B80B3E /* NSBitmapImageRep_SKExtensions.m in Sources */,
 				9F0CB4FD298655F600007028 /* KMDesignToken+BorderColor.swift in Sources */,
 				BBB1A3A629F6B66400E54E47 /* NSPanel+KMExtension.swift in Sources */,
 				BB3A81AC2AC2A4E4006FC66C /* NSTextView+KMExtension.swift in Sources */,
 				BB65A0802AF8FE7A003A27A0 /* KMBatchOperateRemoveHeaderFooterViewController.swift in Sources */,
+				ADE86AD62B05A52B00414DFA /* KMCompareFilesConfig.swift in Sources */,
 				BB147047299DC0D200784A6A /* OIDServiceConfiguration.m in Sources */,
 				BB89726D294DB67D0045787C /* KMWatermarkAdjectiveBaseView.swift in Sources */,
 				9F1FE4FF29406E4700E952CA /* CTTabStripModel.m in Sources */,
@@ -11957,6 +12010,7 @@
 				BB74DA772AC41182006EDFE7 /* NSFont+KMExtension.swift in Sources */,
 				BB6DD8252934D056001F0544 /* KMSecureEncryptSuccessTipView.swift in Sources */,
 				BB6B43662A04919200E02B54 /* KMBaseViewController.swift in Sources */,
+				ADE86AD12B04BAEA00414DFA /* KMCompareFilesView.swift in Sources */,
 				BB146FCF299DC0D100784A6A /* GTMMIMEDocument.m in Sources */,
 				9F1F82EA2935D02E0092C4B4 /* KMComboBox.swift in Sources */,
 				ADDEEA722AD3EFE200EF675D /* KMButton.swift in Sources */,
@@ -12182,6 +12236,7 @@
 				BB7648ED29ECEEF400931039 /* KMAppearance.swift in Sources */,
 				8997010728F4082C009AF911 /* KMFromViewController.swift in Sources */,
 				AD5999372AD7D9C200412F8B /* KMPropertiesViewPopController.swift in Sources */,
+				ADE86AD72B05A52B00414DFA /* KMCompareFilesConfig.swift in Sources */,
 				9F1F82F329373D6E0092C4B4 /* String+KMExtensions.swift in Sources */,
 				ADDEEA5F2AD39DC500EF675D /* KMSignatureManager.swift in Sources */,
 				9FD0FA4C29D43D6800F2AB0D /* KMDeviceBrowserWindowController.swift in Sources */,
@@ -12363,6 +12418,7 @@
 				BB14701E299DC0D100784A6A /* OIDIDToken.m in Sources */,
 				9F53D5482AD664C300CCF9D8 /* CPDFListHoverAnnotationViewController.swift in Sources */,
 				9FCFEC8D2AD10A4400EAD2CB /* KMTextFieldSheetController.swift in Sources */,
+				BBC8A7722B06408600FA9377 /* KMBotaSearchViewController.swift in Sources */,
 				BB49ECF2293F40F500C82CA2 /* KMConvertPageRangeSettingItemView.swift in Sources */,
 				9F1FE4F429406E4700E952CA /* FastResizeView.m in Sources */,
 				9F1FE4FD29406E4700E952CA /* CTTabStripController.m in Sources */,
@@ -12795,6 +12851,7 @@
 				9F1FE4A329406E4700E952CA /* CTToolbarController.m in Sources */,
 				BB6719FA2AD2CC05003D44D5 /* CPDFSignatureWidgetAnnotation+PDFListView.swift in Sources */,
 				BB2EDF71296ECE17003BCF58 /* KMPageEditThumbnailView.swift in Sources */,
+				BB3A668D2B06FD0100575343 /* KMBotaEnum.swift in Sources */,
 				9FD0FA2A29CD3ED400F2AB0D /* KMRightSideEmptyVC.swift in Sources */,
 				BB65A0792AF8E2F2003A27A0 /* KMSyncPreferences.swift in Sources */,
 				9F78EFC328F7E395001E66F4 /* KMHomeViewController+Action.swift in Sources */,
@@ -12832,6 +12889,7 @@
 				9F0CB4E22986556400007028 /* KMDesignToken+PaddingTop.swift in Sources */,
 				ADDEEA9B2AD7BB2D00EF675D /* KMAnnotationPropertiesColorManager.swift in Sources */,
 				BB6013812AD38E0100A76FB2 /* CPDFTextAnnotation+PDFListView.swift in Sources */,
+				BB3A66912B07099F00575343 /* KMFindTableviewCell.swift in Sources */,
 				AD0FA4FA29A8DD6F00EDEB50 /* KMRegisterSuccessView.swift in Sources */,
 				BB146FFA299DC0D100784A6A /* OIDExternalUserAgentMac.m in Sources */,
 				BB9DCCA02A0A2B0A0024A6F1 /* KMConvertSettingView.swift in Sources */,
@@ -12873,6 +12931,7 @@
 				BB146FEE299DC0D100784A6A /* GTLRBatchResult.m in Sources */,
 				ADE8BC3C29F9458700570F89 /* KMRecommondManager.m in Sources */,
 				BB897272294DB6BE0045787C /* KMWatermarkAdjectivePlainView.swift in Sources */,
+				ADE86AD22B04BAEA00414DFA /* KMCompareFilesView.swift in Sources */,
 				9F0CB49829683E1000007028 /* KMPropertiesPanelTextSubVC.swift in Sources */,
 				9F1FE4AC29406E4700E952CA /* CTBrowserWindow.m in Sources */,
 				9FF816DE2AFA5B8E0087EFC5 /* KMAnnotationTableViewController.swift in Sources */,
@@ -12931,6 +12990,7 @@
 				9F1F82DC292F84D60092C4B4 /* KMHomeInsertActionViewController.swift in Sources */,
 				ADB5E5142A371131007110A8 /* KMSubscribeWaterMarkWindowController.swift in Sources */,
 				ADE86ACA2B034CB200414DFA /* KMAddBackgroundView.swift in Sources */,
+				BBC8A7732B06408600FA9377 /* KMBotaSearchViewController.swift in Sources */,
 				9F1FE51329407B4000E952CA /* KMFileSearchView.swift in Sources */,
 				BBEC00B1295C2AF300A26C98 /* KMBatesPreviewController.swift in Sources */,
 				BB897260294C5DDA0045787C /* KMWatermarkPropertyInfoController.swift in Sources */,
@@ -13160,6 +13220,7 @@
 				BB49ED1B293F4D4E00C82CA2 /* KMConvertCSVSettingView.swift in Sources */,
 				89752E1B2941FD48003FF08E /* KMSearchCellView.swift in Sources */,
 				BB146FC8299DC0D100784A6A /* GTMSessionFetcherService.m in Sources */,
+				ADE86AD82B05A52B00414DFA /* KMCompareFilesConfig.swift in Sources */,
 				BB6DD81E29348F31001F0544 /* KMSecureTextFiled.swift in Sources */,
 				BB2EDF7B296ECE17003BCF58 /* KMPageEditThumbnailItem.swift in Sources */,
 				9FD0FA4D29D43D6800F2AB0D /* KMDeviceBrowserWindowController.swift in Sources */,
@@ -13228,6 +13289,7 @@
 				BB897248294C19980045787C /* KMWatermarkAdjectiveListController.swift in Sources */,
 				BBD1F795296FE92500343885 /* KMPageEditSplitSettingView.swift in Sources */,
 				BBEC00DB295C39FD00A26C98 /* KMBatesPropertyInfoController.swift in Sources */,
+				BB3A66922B07099F00575343 /* KMFindTableviewCell.swift in Sources */,
 				BB0A551A2A3074F400B6E84B /* KMHoverView.swift in Sources */,
 				9F1FE4AA29406E4700E952CA /* CTBrowserWindowController.m in Sources */,
 				ADAFDA6A2AEB46F500F084BC /* KMHomeHistoryListView.swift in Sources */,
@@ -13371,6 +13433,7 @@
 				9FCFECA22AD17B8A00EAD2CB /* SKProgressController.swift in Sources */,
 				9F0CB4612966C9E200007028 /* KMFormPropertPanelViewController.swift in Sources */,
 				9F1FE4EF29406E4700E952CA /* ThrobberView.m in Sources */,
+				BB3A668E2B06FD0100575343 /* KMBotaEnum.swift in Sources */,
 				AD867F9229D9554F00F00440 /* KMBOTAOutlineItem.swift in Sources */,
 				BBB9B327299A5D6D004F3235 /* GTMKeychain_macOS.m in Sources */,
 				9F0CB5072986561E00007028 /* KMDesignToken+BorderRight.swift in Sources */,
@@ -13478,6 +13541,7 @@
 				9F0CB533298656EA00007028 /* KMDesignToken+BorderWidthBottom.swift in Sources */,
 				BB49ED23293F527700C82CA2 /* KMConvertExcelSettingView.swift in Sources */,
 				9F0CB52B298656C900007028 /* KMDesignToken+BorderWidthTop.swift in Sources */,
+				ADE86AD32B04BAEA00414DFA /* KMCompareFilesView.swift in Sources */,
 				ADA9102C2A272CE2003352F0 /* KMEditPDFTextManager.swift in Sources */,
 				BB146FD4299DC0D100784A6A /* GTLRDateTime.m in Sources */,
 				BB5F8A2129BB15AD00365ADB /* KMEmailSubWindowController.m in Sources */,

+ 231 - 0
PDF Office/PDF Master/Class/PDFTools/Compare/Model/KMCompareFilesConfig.swift

@@ -0,0 +1,231 @@
+//
+//  KMCompareFilesConfig.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/11/16.
+//
+
+import Cocoa
+let PDFCompareISCompareTextFilesKey =  "PDFCompareISCompareTextFiles1"
+let PDFCompareISCompareImageFilesKey = "PDFCompareISCompareImageFiles1"
+let PDFCompareInsertColorFilesKey =    "PDFCompareInsertColorFiles"
+let PDFCompareInsertOpacityFilesKey =    "PDFCompareInsertOpacityFiles"
+let PDFCompareDeleteColorFilesKey =    "PDFCompareDeleteColorFiles"
+let PDFCompareDeleteOpacityFilesKey =    "PDFCompareDeleteOpacityFiles"
+let PDFCompareReplaceColorFilesKey =   "PDFCompareReplaceColorFiles"
+let PDFCompareReplaceOpacityFilesKey =   "PDFCompareReplaceOpacityFiles"
+let PDFCompareOldStrokeColorFilesKey = "PDFCompareOldStrokeColorFiles"
+let PDFCompareNewStrokeColorFilesKey = "PDFCompareNewStrokeColorFiles"
+let PDFCompareNewStrokeOpacityFilesKey = "PDFCompareNewStrokeOpacityFiles"
+let PDFCompareOldStrokeOpacityFilesKey = "PDFCompareOldStrokeOpacityFiles"
+let PDFCompareNewFillOpacityFilesKey = "PDFCompareNewFillOpacityFiles"
+let PDFCompareOldFillOpacityFilesKey = "PDFCompareOldFillOpacityFiles"
+let PDFCompareIsNOFillFilesKey = "PDFCompareIsNOFillFiles"
+let PDFComparePDFBlendModeFilesKey = "PDFComparePDFBlendModeFiles"
+
+class KMCompareFilesConfig {
+
+    static let defaultConfig: KMCompareFilesConfig = KMCompareFilesConfig()
+
+    var fileNewAttribute: KMFileAttribute = KMFileAttribute()
+    var fileOldAttribute: KMFileAttribute = KMFileAttribute()
+    
+    func setColor(_ color: NSColor?, forKey key: String) {
+        let data = color != nil ? NSArchiver.archivedData(withRootObject: color!) : NSArchiver.archivedData(withRootObject: NSColor.red)
+        UserDefaults.standard.set(data, forKey: key)
+    }
+
+    func colorForKey(_ key: String) -> NSColor? {
+        var color: NSColor?
+        if let data = UserDefaults.standard.data(forKey: key) {
+            color = NSUnarchiver.unarchiveObject(with: data) as? NSColor
+        } else if let array = UserDefaults.standard.array(forKey: key), array.count > 0 {
+            var red, green, blue, alpha: CGFloat
+            red =  CGFloat(array[0] as! Double)
+            green = CGFloat(array[0] as! Double)
+            blue = CGFloat(array[0] as! Double)
+            
+            if array.count > 2 {
+                green = CGFloat(array[1] as! Double)
+                blue = CGFloat(array[2] as! Double)
+            }
+            if array.count == 2 {
+                alpha = CGFloat(array[1] as! Double)
+            } else if array.count > 3 {
+                alpha = CGFloat(array[3] as! Double)
+            } else {
+                alpha = 1.0
+            }
+            color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: alpha)
+        }
+        return color
+    }
+
+    func setIsCompareText(_ isCompareText: Bool) {
+        UserDefaults.standard.set(isCompareText, forKey: PDFCompareISCompareTextFilesKey)
+    }
+
+    func isCompareText() -> Bool {
+        return UserDefaults.standard.bool(forKey: PDFCompareISCompareTextFilesKey)
+    }
+
+    func setIsCompareImage(_ isCompareImage: Bool) {
+        UserDefaults.standard.set(isCompareImage, forKey: PDFCompareISCompareImageFilesKey)
+    }
+
+    func isCompareImage() -> Bool {
+        return UserDefaults.standard.bool(forKey: PDFCompareISCompareImageFilesKey)
+    }
+
+    func setInsertColor(_ insertColor: NSColor?) {
+        setColor(insertColor, forKey: PDFCompareInsertColorFilesKey)
+    }
+
+    func insertColor() -> NSColor {
+        guard let color = colorForKey(PDFCompareInsertColorFilesKey) else {
+            return NSColor.green
+        }
+        return color
+    }
+
+    func setInsertOpacity(_ insertOpacity: CGFloat) {
+        UserDefaults.standard.set(insertOpacity, forKey: PDFCompareInsertOpacityFilesKey)
+    }
+
+    func insertOpacity() -> CGFloat {
+        if let value = UserDefaults.standard.value(forKey: PDFCompareInsertOpacityFilesKey) as? CGFloat {
+            return value
+        }
+        return 0.2
+    }
+
+    func setDeleteColor(_ deleteColor: NSColor?) {
+        setColor(deleteColor, forKey: PDFCompareDeleteColorFilesKey)
+    }
+
+    func deleteColor() -> NSColor {
+        guard let color = colorForKey(PDFCompareDeleteColorFilesKey) else {
+            return NSColor.red
+        }
+        return color
+    }
+
+    func setDeleteOpacity(_ deleteOpacity: CGFloat) {
+        UserDefaults.standard.set(deleteOpacity, forKey: PDFCompareDeleteOpacityFilesKey)
+    }
+
+    func deleteOpacity() -> CGFloat {
+        if let value = UserDefaults.standard.value(forKey: PDFCompareDeleteOpacityFilesKey) as? CGFloat {
+            return value
+        }
+        return 0.2
+    }
+
+    func setReplaceColor(_ replaceColor: NSColor?) {
+        setColor(replaceColor, forKey: PDFCompareReplaceColorFilesKey)
+    }
+
+    func replaceColor() -> NSColor {
+        guard let color = colorForKey(PDFCompareReplaceColorFilesKey) else {
+            return NSColor.blue
+        }
+        return color
+    }
+
+    func setReplaceOpacity(_ replaceOpacity: CGFloat) {
+        UserDefaults.standard.set(replaceOpacity, forKey: PDFCompareReplaceOpacityFilesKey)
+    }
+
+    func replaceOpacity() -> CGFloat {
+        if let value = UserDefaults.standard.value(forKey: PDFCompareReplaceOpacityFilesKey) as? CGFloat {
+            return value
+        }
+        return 0.2
+    }
+
+    func setOldStrokeColor(_ oldStrokeColor: NSColor?) {
+        setColor(oldStrokeColor, forKey: PDFCompareOldStrokeColorFilesKey)
+    }
+
+    func oldStrokeColor() -> NSColor {
+        guard let color = colorForKey(PDFCompareOldStrokeColorFilesKey) else {
+            return NSColor(calibratedRed: 245.0/255.0, green: 40.0/255.0, blue: 27.0/255.0, alpha: 1.0)
+        }
+        return color
+    }
+
+    func setNewStrokeColor(_ newStrokeColor: NSColor?) {
+        setColor(newStrokeColor, forKey: PDFCompareNewStrokeColorFilesKey)
+    }
+
+    func newStrokeColor() -> NSColor {
+        guard let color = colorForKey(PDFCompareNewStrokeColorFilesKey) else {
+            return NSColor(calibratedRed: 49.0/255.0, green: 193.0/255.0, blue: 255.0/255.0, alpha: 1.0)
+        }
+        return color
+    }
+
+    func setNewStrokeOpacity(_ newStrokeOpacity: CGFloat) {
+        UserDefaults.standard.set(newStrokeOpacity, forKey: PDFCompareNewStrokeOpacityFilesKey)
+    }
+
+    func newStrokeOpacity() -> CGFloat {
+        if let value = UserDefaults.standard.value(forKey: PDFCompareNewStrokeOpacityFilesKey) as? CGFloat {
+            return value
+        }
+        return 1.0
+    }
+
+    func setOldStrokeOpacity(_ oldStrokeOpacity: CGFloat) {
+        UserDefaults.standard.set(oldStrokeOpacity, forKey: PDFCompareOldStrokeOpacityFilesKey)
+    }
+
+    func oldStrokeOpacity() -> CGFloat {
+        if let value = UserDefaults.standard.value(forKey: PDFCompareOldStrokeOpacityFilesKey) as? CGFloat {
+            return value
+        }
+        return 1.0
+    }
+
+    func setNewFillOpacity(_ newFillOpacity: CGFloat) {
+        UserDefaults.standard.set(newFillOpacity, forKey: PDFCompareNewFillOpacityFilesKey)
+    }
+
+    func newFillOpacity() -> CGFloat {
+        if let value = UserDefaults.standard.value(forKey: PDFCompareNewFillOpacityFilesKey) as? CGFloat {
+            return value
+        }
+        return 1.0
+    }
+
+    func setOldFillOpacity(_ oldFillOpacity: CGFloat) {
+        UserDefaults.standard.set(oldFillOpacity, forKey: PDFCompareOldFillOpacityFilesKey)
+    }
+
+    func oldFillOpacity() -> CGFloat {
+        if let value = UserDefaults.standard.value(forKey: PDFCompareOldFillOpacityFilesKey) as? CGFloat {
+            return value
+        }
+        return 1.0
+    }
+
+    func setIsNOFill(_ isNOFill: Bool) {
+        UserDefaults.standard.set(isNOFill, forKey: PDFCompareIsNOFillFilesKey)
+    }
+
+    func isNOFill() -> Bool {
+        return UserDefaults.standard.bool(forKey: PDFCompareIsNOFillFilesKey)
+    }
+
+    func setBlendMod(_ blendMod: CPDFBlendMode) {
+        UserDefaults.standard.set(blendMod.rawValue, forKey: PDFComparePDFBlendModeFilesKey)
+    }
+
+    func blendMod() -> CPDFBlendMode {
+        if let value = UserDefaults.standard.value(forKey: PDFComparePDFBlendModeFilesKey) as? Int,
+           let blendMode = CPDFBlendMode(rawValue: value) {
+            return blendMode
+        }
+        return CPDFBlendMode.darken
+    }
+}

+ 76 - 0
PDF Office/PDF Master/Class/PDFTools/Compare/View/CompareFilesView/KMCompareFilesView.swift

@@ -0,0 +1,76 @@
+//
+//  KMCompareFilesView.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/11/15.
+//
+
+import Cocoa
+
+typealias KMCompareFilesViewDragEnteredCallBack = (Bool) -> Void
+typealias KMCompareFilesViewDragSuccessCallBack = (String) -> Void
+typealias KMCompareFilesViewMouseUpCallBack = (KMCompareFilesView) -> Void
+
+class KMCompareFilesView: NSView {
+
+    var dragEnteredBlock: KMCompareFilesViewDragEnteredCallBack?
+    var dragSuccessBlock: KMCompareFilesViewDragSuccessCallBack?
+    var mouseUpBack: KMCompareFilesViewMouseUpCallBack?
+
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        registerForDraggedTypes([NSPasteboard.PasteboardType.fileURL])
+    }
+
+    override func draggingExited(_ sender: NSDraggingInfo?) {
+        if let block = dragEnteredBlock {
+            block(false)
+        }
+    }
+
+    override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
+        if let block = dragEnteredBlock {
+            block(true)
+        }
+
+        guard let pboard = sender.draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType.fileURL) as? [String: Any],
+              let fileNames = pboard[NSPasteboard.PasteboardType.fileURL.rawValue] as? [String],
+              let path = fileNames.first, (path as NSString).pathExtension.lowercased() == "pdf" else {
+            self.layer?.borderColor = NSColor.clear.cgColor
+            return []
+        }
+
+        return NSDragOperation.copy
+    }
+
+    override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool {
+        guard let pboard = sender.draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType.fileURL) as? [String: Any],
+              let fileNames = pboard[NSPasteboard.PasteboardType.fileURL.rawValue] as? [String],
+              let path = fileNames.first, (path as NSString).pathExtension.lowercased() == "pdf" else {
+            return false
+        }
+
+        #if VERSION_DMG
+            // Add code for VERSION_DMG
+        #else
+//            let url = URL(fileURLWithPath: path)
+//            if let bookmarkData = try? url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil) {
+//                AppSandboxFileAccess.fileAccess().bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, forURL: url)
+//                AppSandboxFileAccess.fileAccess().bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, forURL: URL(fileURLWithPath: url.path ?? url.absoluteString))
+//            }
+        #endif
+
+        if let block = dragSuccessBlock {
+            block(path)
+        }
+
+        return true
+    }
+
+    override func mouseUp(with event: NSEvent) {
+        super.mouseUp(with: event)
+        if let block = mouseUpBack {
+            block(self)
+        }
+    }
+}

+ 466 - 3
PDF Office/PDF Master/Class/PDFTools/Compare/View/KMCompareView.swift

@@ -9,18 +9,438 @@ import Cocoa
 
 typealias KMCompareViewCancelAction = (_ view: KMCompareView) -> Void
 
+enum KMCompareFilesType {
+    case content
+    case coverting
+}
+
+let CPDFOldFileQKSelectedPathsKey = "CPDFOldFileQKSelectedPathsKey"
+let CPDFNewFileQKSelectedPathsKey = "CPDFNewFileQKSelectedPathsKey"
+let CPDFMaxQKSelectedPathsCount = 5
 
 class KMCompareView: KMBaseXibView {
 
     @IBOutlet weak var cancelButton: NSButton!
     @IBOutlet weak var doneButton: NSButton!
     
+    @IBOutlet weak var compareTypeSegment: NSSegmentedControl!
+    @IBOutlet weak var typeSegWidthConst: NSLayoutConstraint!
+    
+    @IBOutlet weak var comparePreviewBox: NSBox!
+    
+    @IBOutlet weak var oldDocumentsTitle: NSTextField!
+    
+    @IBOutlet weak var compareOldPreviewView: KMCompareFilesView!
+    @IBOutlet weak var oldFileQKSelectedBox: NSComboBox!
+    @IBOutlet weak var oldFileSelectBtn: NSButton!
+    @IBOutlet weak var oldPDFView: PDFView!
+    @IBOutlet weak var currentOldPageLabel: NSTextField!
+    @IBOutlet weak var totalPaOldgeLabel: NSTextField!
+    
+    @IBOutlet weak var compareNewPreviewView: KMCompareFilesView!
+    @IBOutlet weak var documentsNewTitle: NSTextField!
+    @IBOutlet weak var fileQKNewSelectedBox: NSComboBox!
+    @IBOutlet weak var fileSelectNewBtn: NSButton!
+    @IBOutlet weak var pdfNewView: PDFView!
+    @IBOutlet weak var addFileContentView: KMCompareFilesView!
+    @IBOutlet weak var addFileImageView: NSImageView!
+    @IBOutlet weak var addFileAddImageFramView: KMCompareFilesView!
+    @IBOutlet weak var currentNewPageLabel: NSTextField!
+    @IBOutlet weak var totalPaNewgeLabel: NSTextField!
+    
+    @IBOutlet weak var addFileTitle: NSTextField!
+    @IBOutlet weak var addFileMag: NSTextField!
+    
+    @IBOutlet weak var pageRangeField: NSTextField!
+    @IBOutlet weak var oldFileRangeField: NSTextField!
+    @IBOutlet weak var pageRangeOldComboBox: NSComboBox!
+    @IBOutlet weak var fileNewRangeField: NSTextField!
+    @IBOutlet weak var pageRangeNewComboBox: NSComboBox!
+    
+    @IBOutlet weak var compareTextTypeBtn: NSButton!
+    @IBOutlet weak var compareImageTypeBtn: NSButton!
+    
+    @IBOutlet weak var compareSettingsBtn: NSButton!
+    @IBOutlet weak var settingBtnTopLayout: NSLayoutConstraint!
+    
+    var pdfCompareContent: CPDFCompareContent?
+    
+    
+    var pdfOldDocument: PDFDocument?
+    var oldFileQKSelectedPaths: [String] = []
+    
+    var pdfNewDocument: PDFDocument?
+    var fileQKNewSelectedPaths: [String] = []
+    
+    var fileType: KMCompareFilesType = .content
     var cancelAction: KMCompareViewCancelAction?
     
-    override func draw(_ dirtyRect: NSRect) {
-        super.draw(dirtyRect)
+    convenience init(pdfDocument: PDFDocument) {
+        self.init()
+        self.pdfOldDocument = pdfDocument
+        let document: CPDFDocument = CPDFDocument.init(url: pdfDocument.documentURL)
+        
+        let file: KMFileAttribute = KMFileAttribute()
+        file.pdfDocument = document
+        
+        let config: KMCompareFilesConfig = KMCompareFilesConfig.init()
+        config.fileOldAttribute = file
+    }
+    
+    convenience init(filePath: String, password: String) {
+        self.init()
+        self.pdfOldDocument = PDFDocument.init(url: NSURL(fileURLWithPath: filePath) as URL)
+        let pdfDocument = CPDFDocument.init(url: NSURL(fileURLWithPath: filePath) as URL)
+        if pdfDocument!.isLocked {
+            pdfDocument!.unlock(withPassword: password)
+        }
+        
+        if self.pdfOldDocument!.isLocked {
+            self.pdfOldDocument!.unlock(withPassword: password)
+        }
+        
+        let file: KMFileAttribute = KMFileAttribute()
+        file.pdfDocument = pdfDocument
+        
+        let config = KMCompareFilesConfig.defaultConfig
+        config.fileOldAttribute = file
+        config.fileOldAttribute.password = password
+        
+    }
+    
+    override func setup() {
+        fileQKNewSelectedBox.delegate = self
+        oldFileQKSelectedBox.delegate = self
+        
+        compareTypeSegment.action =  #selector(segmentedControlClicked)
+        compareTypeSegment.target = self
+        
+        compareTypeSegment.wantsLayer = true
+        addFileContentView.wantsLayer = true
+        
+        addFileImageView.ignoresMultiClick = true
+        
+        fileQKNewSelectedBox.isEnabled = false
+        oldFileQKSelectedBox.isEnabled = false
+        fileQKNewSelectedBox.cell!.isEnabled = false
+        oldFileQKSelectedBox.cell!.isEnabled = false
+        
+        currentOldPageLabel.delegate = self
+        currentNewPageLabel.delegate = self
+        
+        oldPDFView.wantsLayer = true
+        pdfNewView.wantsLayer = true
+//        vsMaskView.wantsLayer = true;
+        oldPDFView.layer?.backgroundColor = NSColor.clear.cgColor
+        pdfNewView.layer?.backgroundColor = NSColor.clear.cgColor
+//        vsMaskView.layer.backgroundColor = NSColor.clear.CGColor
+        
+        compareTypeSegment.wantsLayer = true
+        compareTypeSegment.layer?.cornerRadius = 5.0
+        compareTypeSegment.layer?.masksToBounds = true
+        compareTypeSegment.layer?.backgroundColor = NSColor.clear.cgColor
+        addFileContentView.wantsLayer = true
+        
+        addFileAddImageFramView.wantsLayer = true
+        addFileAddImageFramView.layer?.backgroundColor = NSColor.clear.cgColor
+        
+        self.compareOldPreviewView.dragSuccessBlock = { [unowned self] filePath in
+            self.updateDocument(filePath: filePath) { fileAttitude in
+                
+            }
+        }
+        
+        self.compareNewPreviewView.dragSuccessBlock = { [unowned self] filePath in
+            self.updateDocument(filePath: filePath, isNew: true) { fileAttitude in
+                
+            }
+        }
+        
+        self.addFileContentView.dragSuccessBlock = { [unowned self] filePath in
+            self.updateDocument(filePath: filePath, isNew: true) { fileAttitude in
+                
+            }
+        }
+        
+        self.addFileAddImageFramView.dragSuccessBlock = { [unowned self] filePath in
+            self.updateDocument(filePath: filePath, isNew: true) { fileAttitude in
+                
+            }
+        }
+        
+        self.addFileContentView.mouseUpBack = { [unowned self] view in
+            self.chooseFileAction()
+        }
+    }
+    
+    override func updateLanguage() {
+        compareTypeSegment.setLabel(NSLocalizedString("Side-by-Side View", comment: ""), forSegment: 0)
+        compareTypeSegment.setLabel(NSLocalizedString("Compare by File Overlay", comment: ""), forSegment: 1)
+        
+        compareTypeSegment.setToolTip(NSLocalizedString("Side-by-Side View", comment: ""), forSegment: 0)
+        compareTypeSegment.setToolTip(NSLocalizedString("Compare by File Overlay", comment: ""), forSegment: 1)
+
+        oldDocumentsTitle.stringValue = NSLocalizedString("Old File", comment: "")
+        documentsNewTitle.stringValue = NSLocalizedString("New File", comment: "")
+        
+        oldFileSelectBtn.title = NSLocalizedString("Choose...", comment: "")
+        fileSelectNewBtn.title = NSLocalizedString("Choose...", comment: "")
+        
+        oldFileSelectBtn.toolTip = NSLocalizedString("Choose...", comment: "")
+        fileSelectNewBtn.toolTip = NSLocalizedString("Choose...", comment: "")
+            
+        addFileTitle.stringValue = NSLocalizedString("Select File", comment: "")
+        addFileMag.stringValue = NSLocalizedString("Click to add", comment: "")
+        
+        oldFileRangeField.stringValue = NSLocalizedString("Old File:", comment: "")
+        fileNewRangeField.stringValue = NSLocalizedString("New File:", comment: "")
+        
+        pageRangeField.stringValue = NSLocalizedString("Page Range", comment: "")
+        
+        pageRangeOldComboBox.removeAllItems()
+        pageRangeOldComboBox.addItems(withObjectValues: [NSLocalizedString("All Pages", comment: ""),
+                                                              NSLocalizedString("Odd Pages Only", comment: ""),
+                                                              NSLocalizedString("Even Pages Only",comment: ""),
+                                                              NSLocalizedString("e.g. 1,3-5,10",comment: "")])
+        pageRangeOldComboBox.placeholderString = NSLocalizedString("e.g. 1,3-5,10", comment: "")
+        
+        pageRangeNewComboBox.addItems(withObjectValues: [NSLocalizedString("All Pages", comment: ""),
+                                                              NSLocalizedString("Odd Pages Only", comment: ""),
+                                                              NSLocalizedString("Even Pages Only",comment: ""),
+                                                              NSLocalizedString("e.g. 1,3-5,10",comment: "")])
+        self.pageRangeNewComboBox.placeholderString = NSLocalizedString("e.g. 1,3-5,10", comment: "")
+        
+        self.compareTextTypeBtn.title = NSLocalizedString("Compare text", comment: "")
+        self.compareImageTypeBtn.title = NSLocalizedString("Compare image", comment: "")
+        
+        let settingsString = "  " + NSLocalizedString("Settings", comment: "")
+        compareSettingsBtn.title = settingsString
+        compareSettingsBtn.state = .off
+        compareSettingsBtn.setTitleColor(KMAppearance.Layout.h1Color())
+        
+        cancelButton.title = NSLocalizedString("Cancel", comment: "")
+        doneButton.title = NSLocalizedString("Compare", comment: "")
+    }
+    
+    override func updateUI() {
+        if KMAppearance.isDarkMode() {
+            self.compareTypeSegment.layer?.backgroundColor = NSColor(red: 50.0/255.0, green: 53.0/255.0, blue: 54.0/255.0, alpha: 1).cgColor
+            self.addFileContentView.layer?.backgroundColor = NSColor.black.cgColor
+        } else {
+            self.compareTypeSegment.layer?.backgroundColor = NSColor(red: 247.0/255.0, green: 247.0/255.0, blue: 247.0/255.0, alpha: 1).cgColor
+            self.addFileContentView.layer?.backgroundColor = NSColor.white.cgColor
+        }
+    }
+    
+    override func reloadData() {
+        if(pageRangeOldComboBox.indexOfSelectedItem == 3) {
+            self.window?.makeFirstResponder(pageRangeOldComboBox)
+            pageRangeOldComboBox.stringValue = ""
+            pageRangeOldComboBox.isSelectable = true
+        }
+        
+        self.updatePageRangeData(view: pageRangeNewComboBox, file: KMCompareFilesConfig.defaultConfig.fileNewAttribute, isNew: true)
+        self.updatePageRangeData(view: pageRangeOldComboBox, file: KMCompareFilesConfig.defaultConfig.fileOldAttribute)
+        
+        if (KMCompareFilesConfig.defaultConfig.isCompareText)() {
+            self.compareTextTypeBtn.state = .on;
+        } else {
+            self.compareTextTypeBtn.state = .off;
+        }
+        if (KMCompareFilesConfig.defaultConfig.isCompareImage)() {
+            self.compareImageTypeBtn.state = .on;
+        } else {
+            self.compareImageTypeBtn.state = .off;
+        }
+        
+        self.updateSelectBoxData()
+        
+        self.updatePageState()
+        self.updatePageState(isNew: true)
+    }
+}
+
+extension KMCompareView {
+    func addFileQKSelectPath(filePath: String, isNewFile: Bool = false) {
+        let pdfdocument = CPDFDocument(url: NSURL(fileURLWithPath: filePath) as URL)
+        guard let pdfdocument = pdfdocument else { return }
+        
+        var key = ""
+        if isNewFile {
+            key = CPDFNewFileQKSelectedPathsKey
+        } else {
+            key = CPDFOldFileQKSelectedPathsKey
+        }
+        
+        var filePaths: [String] = UserDefaults.standard.object(forKey: key) as? [String] ?? []
+        if filePaths.count > CPDFMaxQKSelectedPathsCount {
+            filePaths.removeLast()
+            
+        }
+        filePaths.insert(filePath, at: 0)
+    }
+    
+    func updateSelectBoxData() {
+        self.oldFileQKSelectedPaths = self.updateSelectBoxItemData()
+        self.oldFileQKSelectedBox.removeAllItems()
+        self.oldFileQKSelectedBox.addItems(withObjectValues: self.oldFileQKSelectedPaths)
+        
+        self.fileQKNewSelectedPaths = self.updateSelectBoxItemData(isNew: true)
+        self.fileQKNewSelectedBox.removeAllItems()
+        self.fileQKNewSelectedBox.addItems(withObjectValues: self.fileQKNewSelectedPaths)
+        
+        if self.fileQKNewSelectedPaths.count > 0 {
+            self.fileQKNewSelectedBox.isEnabled = true
+        } else {
+            self.fileQKNewSelectedBox.isEnabled = false
+        }
+    }
+    
+    func updateSelectBoxItemData(isNew: Bool = false) -> [String] {
+        let defaults = UserDefaults.standard
+        var fileSelectedCachePaths: [String] = []
+        if isNew {
+            fileSelectedCachePaths = defaults.value(forKey: CPDFOldFileQKSelectedPathsKey) as? [String] ?? []
+        } else {
+            fileSelectedCachePaths = defaults.value(forKey: CPDFNewFileQKSelectedPathsKey) as? [String] ?? []
+        }
+        
+        var fileSelectedPaths: [String] = []
 
-        // Drawing code here.
+        let fileManager = FileManager.default
+        for path in fileSelectedCachePaths {
+            if fileManager.fileExists(atPath: path) {
+//                #if VERSION_DMG
+                fileSelectedPaths.append(path)
+//                #else
+//                let url = URL(fileURLWithPath: path)
+//                
+//                if let bookmarkData = try? url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil) {
+//                    AppSandboxFileAccess.fileAccess().bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, forURL: url)
+//                    AppSandboxFileAccess.fileAccess().bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, forURL: URL(fileURLWithPath: url.path ?? url.absoluteString))
+//                    
+//                    fileOldSelectedPaths.append(path)
+//                } else {
+//                    AppSandboxFileAccess.fileAccess().accessFileURL(url, persistPermission: yearMask) {
+//                        if let bookmarkData = try? url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil) {
+//                            fileOldSelectedPaths.append(path)
+//                        }
+//                    }
+//                }
+//                #endif
+            }
+        }
+        return fileSelectedPaths
+    }
+    
+    func updatePageState(isNew: Bool = false) {
+        var pageDocument = PDFDocument()
+        var pdfView = PDFView()
+        var currentPageLabel = NSTextField()
+        var totalPageLabel = NSTextField()
+        
+        guard let pdfNewDocument = pdfNewDocument else { return }
+        guard let pdfOldDocument = pdfOldDocument else { return }
+        
+        if isNew {
+            pageDocument = pdfNewDocument
+            pdfView = pdfNewView
+            currentPageLabel = currentNewPageLabel
+            totalPageLabel = totalPaNewgeLabel
+        } else {
+            pageDocument = pdfOldDocument
+            pdfView = oldPDFView
+            currentPageLabel = currentOldPageLabel
+            totalPageLabel = totalPaOldgeLabel
+        }
+        // 隐藏PDFView滑动条
+        pdfView.documentView?.enclosingScrollView?.hasVerticalScroller = false
+        pdfView.documentView?.enclosingScrollView?.hasHorizontalScroller = false
+        let pageCount = pageDocument.pageCount
+        var currentPageIndex = 0
+        if(pdfView.currentPage != nil) {
+            currentPageIndex = pageDocument.index(for: pdfView.currentPage!)
+        }
+        
+        if(pageCount > 0) {
+            currentPageLabel.stringValue = "\(currentPageIndex + 1)"
+        } else {
+            currentPageLabel.stringValue = "\(currentPageIndex)"
+        }
+        totalPageLabel.stringValue = "/ \(pageCount)"
+    }
+    
+    func updateDocument(filePath: String, isNew: Bool = false, completion: @escaping (_ fileAttitude: KMFileAttribute?) -> Void) {
+        var pdfDocument = CPDFDocument()
+        if isNew {
+            pdfDocument = KMCompareFilesConfig.defaultConfig.fileOldAttribute.pdfDocument ?? CPDFDocument()
+        } else {
+            pdfDocument = KMCompareFilesConfig.defaultConfig.fileNewAttribute.pdfDocument ?? CPDFDocument()
+        }
+        
+        guard let pdfDocument = pdfDocument else {
+            completion(nil)
+            return
+        }
+        if (pdfDocument.documentURL.path == filePath) {
+            let alert = NSAlert()
+            alert.alertStyle = NSAlert.Style.critical
+            alert.messageText = NSLocalizedString("There is no difference between the two documents.", comment: "")
+            alert.runModal()
+            completion(nil)
+            return
+        } else {
+            KMBaseWindowController.checkPassword(url: NSURL(fileURLWithPath: filePath) as URL) { success, resultPassword in
+                if success {
+                    let file = KMFileAttribute()
+                    file.pdfDocument = pdfDocument
+                    file.password = resultPassword
+                    completion(file)
+                } else {
+                    completion(nil)
+                }
+            }
+        }
+    }
+    
+    func updatePageRangeData(view: NSComboBox, file: KMFileAttribute, isNew: Bool = false) {
+        switch (file.pagesType) {
+        case .all:
+            view.selectItem(at: 0)
+            view.isEditable = false
+            view.delegate = nil
+            break;
+        case .odd:
+            view.selectItem(at: 1)
+            view.isEditable = false
+            view.delegate = nil
+            break;
+            case .even:
+            view.selectItem(at: 2)
+            view.isEditable = false
+            view.delegate = nil
+            break;
+        case .custom:
+            view.delegate = self
+            view.stringValue = file.pagesString
+            view.isEditable = true
+                break;
+        default: break
+        }
+    }
+    
+    func updateFileCompareType(fileType: KMCompareFilesType) {
+        if fileType == .content {
+            compareTypeSegment.selectedSegment = 0
+            compareTextTypeBtn.isHidden = false
+            compareImageTypeBtn.isHidden = false
+            settingBtnTopLayout.constant = 81
+        } else {
+            compareTypeSegment.selectedSegment = 1
+            compareTextTypeBtn.isHidden = true
+            compareImageTypeBtn.isHidden = true
+            settingBtnTopLayout.constant = 20
+        }
     }
 }
 
@@ -34,4 +454,47 @@ extension KMCompareView {
     @IBAction func convertButtonAction(_ sender: Any) {
         
     }
+    
+    @objc func segmentedControlClicked(sender: NSSegmentedControl) {
+        
+    }
+    
+    func chooseFileAction(isNew: Bool = false) {
+//        fileQKNewSelectedBox.resignFirstResponder()
+        self.window?.makeFirstResponder(nil)
+
+        let openPanel = NSOpenPanel()
+        openPanel.allowedFileTypes = ["pdf"]
+        openPanel.allowsMultipleSelection = false
+        openPanel.beginSheetModal(for: self.window!) { (result) in
+            if result == NSApplication.ModalResponse.OK {
+                #if VERSION_DMG
+                    // Add code for VERSION_DMG
+                #else
+//                    if let url = openPanel.url {
+//                        do {
+//                            let bookmarkData = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil)
+//                            AppSandboxFileAccess.fileAccess().bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, forURL: url)
+//                            AppSandboxFileAccess.fileAccess().bookmarkPersistanceDelegate.setBookmarkData(bookmarkData, forURL: URL(fileURLWithPath: url.path ?? url.absoluteString))
+//                        } catch {
+//                            // Handle error
+//                            print("Error creating bookmark data: \(error)")
+//                        }
+//                    }
+                #endif
+
+                if let filePath = openPanel.url?.path {
+                    self.updateDocument(filePath: filePath, isNew: isNew) { file in
+                        
+                    }
+                }
+            }
+        }
+
+    }
+}
+
+
+extension KMCompareView: NSComboBoxDelegate {
+    
 }

+ 37 - 6
PDF Office/PDF Master/Class/PDFTools/Compare/View/KMCompareView.xib

@@ -9,8 +9,39 @@
     <objects>
         <customObject id="-2" userLabel="File's Owner" customClass="KMCompareView" customModule="PDF_Master" customModuleProvider="target">
             <connections>
+                <outlet property="addFileAddImageFramView" destination="7T1-FJ-wtx" id="tPU-4J-IZd"/>
+                <outlet property="addFileContentView" destination="dU9-33-2cR" id="J7c-AP-uVZ"/>
+                <outlet property="addFileImageView" destination="LcR-ou-ANf" id="gcB-TA-0SA"/>
+                <outlet property="addFileMag" destination="3tv-r9-A6A" id="8bu-nJ-QnP"/>
+                <outlet property="addFileTitle" destination="Al8-hK-b6M" id="Rcc-KI-Hm9"/>
                 <outlet property="cancelButton" destination="VOf-35-kbQ" id="tzY-0g-1UZ"/>
+                <outlet property="compareImageTypeBtn" destination="Ry6-fx-Lsg" id="MKN-Dt-OAB"/>
+                <outlet property="compareNewPreviewView" destination="E6w-5x-3SO" id="iPv-jr-XwE"/>
+                <outlet property="compareOldPreviewView" destination="q2P-Ek-w51" id="ogk-N4-hbt"/>
+                <outlet property="comparePreviewBox" destination="Tju-1r-2vu" id="fzz-hk-rrR"/>
+                <outlet property="compareSettingsBtn" destination="ZWD-eI-OAU" id="bB2-Z7-9TS"/>
+                <outlet property="compareTextTypeBtn" destination="JAe-WW-HE0" id="mNJ-hx-LqZ"/>
+                <outlet property="compareTypeSegment" destination="Rea-rR-HQ2" id="k45-NN-wNZ"/>
+                <outlet property="currentNewPageLabel" destination="yVn-S7-pqM" id="IIj-e0-0mZ"/>
+                <outlet property="currentOldPageLabel" destination="GmQ-4n-VBd" id="SKg-Yf-Tgi"/>
+                <outlet property="documentsNewTitle" destination="CD7-aX-zab" id="5zZ-si-v3C"/>
                 <outlet property="doneButton" destination="8AD-rt-IgJ" id="xMG-Jd-7Ab"/>
+                <outlet property="fileNewRangeField" destination="H4A-gF-NRQ" id="Ftp-Y2-1DK"/>
+                <outlet property="fileQKNewSelectedBox" destination="uZv-wi-QyT" id="gNX-A6-s9A"/>
+                <outlet property="fileSelectNewBtn" destination="WSb-Q2-D3m" id="QNK-Fa-wDF"/>
+                <outlet property="oldDocumentsTitle" destination="kRr-R4-sGx" id="0sv-TO-70t"/>
+                <outlet property="oldFileQKSelectedBox" destination="jih-HW-8sA" id="NQ4-El-gOw"/>
+                <outlet property="oldFileRangeField" destination="PHA-ai-rJB" id="y8a-8f-V2L"/>
+                <outlet property="oldFileSelectBtn" destination="8h1-sv-nB8" id="i2E-kr-M8p"/>
+                <outlet property="oldPDFView" destination="jw7-gN-Ept" id="Mgz-GR-zoT"/>
+                <outlet property="pageRangeField" destination="cIk-7j-jC4" id="569-Dw-7uJ"/>
+                <outlet property="pageRangeNewComboBox" destination="edF-Wi-Can" id="F4f-yj-ecc"/>
+                <outlet property="pageRangeOldComboBox" destination="ItG-Sw-aXB" id="6S9-8T-Mq9"/>
+                <outlet property="pdfNewView" destination="O7G-En-YRx" id="bv9-cK-RJi"/>
+                <outlet property="settingBtnTopLayout" destination="kBr-3k-Ptc" id="eLk-wf-rDS"/>
+                <outlet property="totalPaNewgeLabel" destination="K8d-Wm-kVV" id="Xvz-C5-Aph"/>
+                <outlet property="totalPaOldgeLabel" destination="r1D-8W-ibR" id="4Eh-Qg-Fxo"/>
+                <outlet property="typeSegWidthConst" destination="jXd-Aa-UGk" id="ZU4-sL-okz"/>
             </connections>
         </customObject>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
@@ -44,7 +75,7 @@
                                         <rect key="frame" x="0.0" y="0.0" width="490" height="395"/>
                                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                     </customView>
-                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="q2P-Ek-w51" customClass="PDFCompareFilesView">
+                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="q2P-Ek-w51" customClass="KMCompareFilesView" customModule="PDF_Master" customModuleProvider="target">
                                         <rect key="frame" x="10" y="16" width="204" height="352"/>
                                         <subviews>
                                             <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kRr-R4-sGx">
@@ -59,7 +90,7 @@
                                                     <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                                 </textFieldCell>
                                             </textField>
-                                            <comboBox focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jih-HW-8sA" customClass="CPDFCompareComboBox">
+                                            <comboBox focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jih-HW-8sA">
                                                 <rect key="frame" x="0.0" y="297" width="129" height="23"/>
                                                 <constraints>
                                                     <constraint firstAttribute="height" constant="20" id="3hW-jQ-ebr"/>
@@ -180,7 +211,7 @@
                                             <constraint firstItem="jw7-gN-Ept" firstAttribute="top" secondItem="jih-HW-8sA" secondAttribute="bottom" constant="10" id="wwo-3R-2ff"/>
                                         </constraints>
                                     </customView>
-                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="E6w-5x-3SO" customClass="PDFCompareFilesView">
+                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="E6w-5x-3SO" customClass="KMCompareFilesView" customModule="PDF_Master" customModuleProvider="target">
                                         <rect key="frame" x="276" y="16" width="204" height="352"/>
                                         <subviews>
                                             <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CD7-aX-zab">
@@ -195,7 +226,7 @@
                                                     <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                                 </textFieldCell>
                                             </textField>
-                                            <comboBox focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uZv-wi-QyT" customClass="CPDFCompareComboBox">
+                                            <comboBox focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uZv-wi-QyT">
                                                 <rect key="frame" x="0.0" y="297" width="129" height="23"/>
                                                 <constraints>
                                                     <constraint firstAttribute="width" constant="125" id="Or4-M7-RFg"/>
@@ -225,7 +256,7 @@
                                                     <constraint firstAttribute="height" constant="254" id="lYe-PP-dsH"/>
                                                 </constraints>
                                             </pdfView>
-                                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="dU9-33-2cR" customClass="PDFCompareFilesView">
+                                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="dU9-33-2cR" customClass="KMCompareFilesView" customModule="PDF_Master" customModuleProvider="target">
                                                 <rect key="frame" x="5" y="35" width="194" height="254"/>
                                                 <subviews>
                                                     <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LcR-ou-ANf">
@@ -260,7 +291,7 @@
                                                             <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                                         </textFieldCell>
                                                     </textField>
-                                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="7T1-FJ-wtx" customClass="PDFCompareFilesView">
+                                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="7T1-FJ-wtx" customClass="KMCompareFilesView" customModule="PDF_Master" customModuleProvider="target">
                                                         <rect key="frame" x="49" y="105" width="96" height="96"/>
                                                     </customView>
                                                 </subviews>

+ 77 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFDocumentExtensions/CPDFDocument+KMExtension.swift

@@ -67,3 +67,80 @@ extension CPDFDocument {
         return result
     }
 }
+
+extension CPDFDocument {
+    func pageLabels() -> [String] {
+        var labels: [String] = []
+        for i in 0 ..< self.pageCount {
+            labels.append("\(i+1)")
+        }
+        return labels
+        /*
+         NSUInteger pageCount = [self pageCount];
+         NSMutableArray *pageLabels = [NSMutableArray array];
+         BOOL useSequential = [[self pageClass] usesSequentialPageNumbering];
+         if (useSequential == NO) {
+             CGPDFDocumentRef doc = [self documentRef];
+             CGPDFDictionaryRef catalog = CGPDFDocumentGetCatalog(doc);
+             CGPDFDictionaryRef labelsDict = NULL;
+             CGPDFArrayRef labelsArray = NULL;
+             if (catalog) {
+                 if(false == CGPDFDictionaryGetDictionary(catalog, "PageLabels", &labelsDict)) {
+                     useSequential = YES;
+                 } else if (CGPDFDictionaryGetArray(labelsDict, "Nums", &labelsArray)) {
+                     size_t i = CGPDFArrayGetCount(labelsArray);
+                     CGPDFInteger j = pageCount;
+                     while (i > 0) {
+                         CGPDFInteger labelIndex;
+                         CGPDFDictionaryRef labelDict = NULL;
+                         const char *labelStyle;
+                         CGPDFStringRef labelPDFPrefix;
+                         NSString *labelPrefix;
+                         CGPDFInteger labelStart;
+                         if (false == CGPDFArrayGetDictionary(labelsArray, --i, &labelDict) ||
+                             false == CGPDFArrayGetInteger(labelsArray, --i, &labelIndex)) {
+                             [pageLabels removeAllObjects];
+                             break;
+                         }
+                         if (false == CGPDFDictionaryGetName(labelDict, "S", &labelStyle))
+                             labelStyle = NULL;
+                         if (CGPDFDictionaryGetString(labelDict, "P", &labelPDFPrefix))
+                             labelPrefix = [(NSString *)CGPDFStringCopyTextString(labelPDFPrefix) autorelease];
+                         else
+                             labelPrefix = nil;
+                         if (false == CGPDFDictionaryGetInteger(labelDict, "St", &labelStart))
+                             labelStart = 1;
+                         while (j > labelIndex) {
+                             NSNumber *labelNumber = [NSNumber numberWithInteger:--j - labelIndex + labelStart];
+                             NSMutableString *string = [NSMutableString string];
+                             if (labelPrefix)
+                                 [string appendString:labelPrefix];
+                             if (labelStyle) {
+                                 if (0 == strcmp(labelStyle, "D"))
+                                     [string appendFormat:@"%@", labelNumber];
+                                 else if (0 == strcmp(labelStyle, "R"))
+                                     [string appendString:[[labelNumber romanNumeralValue] uppercaseString]];
+                                 else if (0 == strcmp(labelStyle, "r"))
+                                     [string appendString:[labelNumber romanNumeralValue]];
+                                 else if (0 == strcmp(labelStyle, "A"))
+                                     [string appendString:[[labelNumber alphaCounterValue] uppercaseString]];
+                                 else if (0 == strcmp(labelStyle, "a"))
+                                     [string appendString:[labelNumber alphaCounterValue]];
+                             }
+                             [pageLabels insertObject:string atIndex:0];
+                         }
+                     }
+                 }
+             }
+         }
+         if ([pageLabels count] != pageCount) {
+             NSUInteger i;
+             [pageLabels removeAllObjects];
+             for (i = 0; i < pageCount; i++)
+                 [pageLabels addObject:useSequential ? [NSString stringWithFormat:@"%lu", (unsigned long)(i + 1)] : [[self pageAtIndex:i] displayLabel]];
+         }
+         return pageLabels;
+         
+         */
+    }
+}

+ 27 - 0
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMBotaEnum.swift

@@ -0,0 +1,27 @@
+//
+//  KMBotaEnum.swift
+//  PDF Master
+//
+//  Created by tangchao on 2023/11/17.
+//
+
+import Foundation
+
+enum KMLeftSidePaneState: Int {
+    case thumbnail = 1
+    case outline
+    case noteList
+    case snapshotList
+    case find
+}
+
+enum KMFindPaneState: Int {
+    case singular = 1
+    case grouped
+}
+
+enum KMFindState: Int {
+    case content = 1
+    case note
+    case snapshot
+}

+ 423 - 250
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController.swift

@@ -7,19 +7,6 @@
 
 import Cocoa
 
-enum KMLeftSidePaneState: Int {
-    case thumbnail = 1
-    case outline
-    case noteList
-    case snapshotList
-    case find
-}
-
-enum KMFindPaneState: Int {
-    case singular = 1
-    case grouped
-}
-
 @objc protocol KMLeftSideViewControllerDelegate {
     @objc optional func controlStateChange(_ obj: KMLeftSideViewController,show:Bool)
     @objc optional func enterEditMode(_ obj: KMLeftSideViewController, _ pages: [Int])
@@ -39,10 +26,6 @@ class KMLeftSideViewController: KMSideViewController {
 //    @IBOutlet weak var contentBox: NSBox!
 //    @IBOutlet weak var leftBox: NSBox!
     
-    lazy var thumbnailViewController : KMThumbnailViewController = {
-        let thumbnailViewController = KMThumbnailViewController()
-        return thumbnailViewController
-    }()
     lazy var outlineViewController : KMOutlineViewController = {
         let outlineViewController = KMOutlineViewController()
         return outlineViewController
@@ -62,10 +45,6 @@ class KMLeftSideViewController: KMSideViewController {
         let fromViewController = KMFromViewController()
         return fromViewController
     }()
-    lazy var searchViewController : KMSearchViewController = {
-        let searchViewController = KMSearchViewController()
-        return searchViewController
-    }()
     lazy var signatureViewController : KMSignatureViewController = {
         let signatureViewController = KMSignatureViewController()
         return signatureViewController
@@ -94,6 +73,12 @@ class KMLeftSideViewController: KMSideViewController {
     
     open weak var delegate: KMLeftSideViewControllerDelegate?
     
+    deinit {
+        KMPrint("KMLeftSideViewController deinit.")
+        
+        NotificationCenter.default.removeObserver(self)
+    }
+    
     override var nibName: NSNib.Name? {
         return "LeftSideView"
     }
@@ -117,6 +102,7 @@ class KMLeftSideViewController: KMSideViewController {
         
         
         DistributedNotificationCenter.default().addObserver(self, selector: #selector(_themeChanged), name: NSApplication.interfaceThemeChangedNotification, object: nil)
+//        self.resetThumbnails()
     }
     
     func showPanelView(show: Bool) {
@@ -192,13 +178,6 @@ class KMLeftSideViewController: KMSideViewController {
 //            self.fromViewController.reloadData()
 //        }
 //            break
-//        case .Search: do {
-//            self.searchViewController.listView = self.listView
-//            self.searchViewController.delegate = self
-////            self.contentBox.contentView = self.searchViewController.view
-////            self.searchViewController.reloadData()
-//        }
-//            break
 //        case .Signature: do {
 //            self.signatureViewController.listView = self.listView
 ////            self.contentBox.contentView = self.signatureViewController.view
@@ -378,7 +357,6 @@ class KMLeftSideViewController: KMSideViewController {
          NSArrayController *thumbnailArrayController;
          
          NSArrayController *findArrayController;
-         SKTableView *findTableView;
          
          NSArrayController *groupedFindArrayController;
          SKTableView *groupedFindTableView;
@@ -397,16 +375,17 @@ class KMLeftSideViewController: KMSideViewController {
 //    @property (nonatomic, retain) IBOutlet NSArrayController *thumbnailArrayController, *findArrayController,  *groupedFindArrayController;
 //    @property (nonatomic, retain) IBOutlet SKTocOutlineView *tocOutlineView;
 //    @property (nonatomic, retain) IBOutlet  *;
-//    @property (nonatomic, retain) IBOutlet SKTableView *findTableView;
+//    @property (nonatomic, retain) IBOutlet  *;
 //    @property (nonatomic, retain) IBOutlet SKTableView *groupedFindTableView;
     
     @IBOutlet var segmentedControl: KMSegmentedControl!
     
+    @IBOutlet var findTableView: KMBotaTableView!
     @IBOutlet var thumbnailTableView: KMThumbnailTableView!
     
     @IBOutlet weak var leftListView: NSView!
     
-//    @property (nonatomic, retain) IBOutlet KMSearchViewController *searchViewController;
+    @IBOutlet var searchViewController: KMBotaSearchViewController!
     @IBOutlet weak var toolButtonBox: NSBox!
     @IBOutlet weak var toolButtonBoxLayoutConstraint: NSLayoutConstraint!
     @IBOutlet weak var snapshotNormalView: NSView!
@@ -448,6 +427,14 @@ class KMLeftSideViewController: KMSideViewController {
     @IBOutlet weak var emptySearchBox: NSBox!
     @IBOutlet weak var emptySearchLabel: NSTextField!
     
+    var thumbnails: [KMThumbnail] = []
+    var isDisplayPageSize = false
+    var thumbnailCacheSize: CGFloat = 0
+    var findState: KMFindState = .content
+    var searchResults: [CPDFSelection] = []
+    
+    private let MIN_SIDE_PANE_WIDTH: CGFloat = 270
+    
     override func loadView() {
         super.loadView()
         
@@ -463,7 +450,7 @@ class KMLeftSideViewController: KMSideViewController {
         self.snapshotNormalView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor
         
 //        tocOutlineView.backgroundColor = [KMAppearance KMColor_Layout_L0];
-//        findTableView.backgroundColor = [KMAppearance KMColor_Layout_L0];
+        self.findTableView.backgroundColor = KMAppearance.KMColor_Layout_L0()
 //        groupedFindTableView.backgroundColor = [KMAppearance KMColor_Layout_L0];
         self.thumbnailTableView.backgroundColor = KMAppearance.Layout.l0Color()
         
@@ -620,7 +607,7 @@ class KMLeftSideViewController: KMSideViewController {
         self.noteDoneButton.toolTip = KMLocalizedString("Done", nil)
         self.noteDoneButton.setTitleColor(KMAppearance.Layout.w0Color())
         self.noteDoneButton.wantsLayer = true
-        self.noteDoneButton.layer?.backgroundColor = KMAppearance.KMColor_Interactive_A0().cgColor
+        self.noteDoneButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor
         self.noteDoneButton.layer?.cornerRadius = 4.0
 //        [self.noteDoneButton setAction:@selector(leftSideViewDoneButtonAction:)]
 //        [self.noteDoneButton setTarget:mainController];
@@ -637,7 +624,7 @@ class KMLeftSideViewController: KMSideViewController {
     //        }
     //    };
         self.noteHeaderView.wantsLayer = true
-        self.noteHeaderView.layer?.backgroundColor = KMAppearance.KMColor_Else_Text_Tag().cgColor
+        self.noteHeaderView.layer?.backgroundColor = KMAppearance.Else.textTagColor().cgColor
         self.noteHeaderView.layer?.cornerRadius = 1.0
 //        let sortType = sud.integer(forKey: KMLeftSideViewNoteSortTypeKey)
 //        if (sortType) {
@@ -653,7 +640,7 @@ class KMLeftSideViewController: KMSideViewController {
 //            _noteSortType = KMNoteSortType_Time;
 //            self.sortTypeLabel.stringValue = NSLocalizedString(@"Time", nil);
 //        }
-        self.sortTypeLabel.textColor = KMAppearance.KMColor_Layout_H1()
+        self.sortTypeLabel.textColor = KMAppearance.Layout.h1Color()
         
 //        _isAscendSort = [sud boolForKey:KMLeftSideViewAscendSortBoolKey];
 //        if (_isAscendSort) {
@@ -684,17 +671,17 @@ class KMLeftSideViewController: KMSideViewController {
 //            }
 //        };
         
-//        [searchViewController loadView];
-//        searchViewController.contentView = findTableView.enclosingScrollView;
-//        self.searchField = searchViewController.searchField;
+        self.searchViewController.loadView()
+        self.searchViewController.contentView = self.findTableView.enclosingScrollView
+        self.searchField = self.searchViewController.searchField
             
-//        [searchViewController.segmentedControl setSegmentCount:2 withWidth:25];
-//        [searchViewController.segmentedControl setImage:[NSImage imageNamed:KMImageNameUXIconBtnSidebarListNor] forSegment:0];
-//        [searchViewController.segmentedControl setImage:[NSImage imageNamed:KMImageNameUXIconBtnSidebarPageNor] forSegment:1];
-//        [searchViewController.segmentedControl setToolTip:NSLocalizedString(@"Separate search results", nil) forSegment:0];
-//        [searchViewController.segmentedControl setToolTip:NSLocalizedString(@"Group search results by page", nil) forSegment:1];
-//        [searchViewController.segmentedControl setIsBackgroundHighlighted:YES];
-//        [searchViewController.segmentedControl setSelectedSegment:0];
+        self.searchViewController.segmentedControl.setSegmentCount(2, with: 25)
+        self.searchViewController.segmentedControl.setImage(NSImage(named: KMImageNameUXIconBtnSidebarListNor)!, for: 0)
+        self.searchViewController.segmentedControl.setImage(NSImage(named: KMImageNameUXIconBtnSidebarPageNor)!, for: 1)
+        self.searchViewController.segmentedControl.setToolTip(KMLocalizedString("Separate search results", nil), for: 0)
+        self.searchViewController.segmentedControl.setToolTip(KMLocalizedString("Group search results by page", nil), for: 1)
+        self.searchViewController.segmentedControl.isBackgroundHighlighted = true
+        self.searchViewController.segmentedControl.selectedSegment = 0
 //        [mainController bind:@"findPaneState" toObject:searchViewController.segmentedControl withKeyPath:@"selectedSegment" options:nil];
 
         self.segmentedControl.segmentCount = 5
@@ -713,6 +700,25 @@ class KMLeftSideViewController: KMSideViewController {
 //        [mainController bind:@"leftSidePaneState" toObject:segmentedControl withKeyPath:@"selectedSegment" options:nil];
         self.segmentedControl.wantsLayer = true
         self.segmentedControl.layer?.backgroundColor = KMAppearance.Layout.l_1Color().cgColor
+        self.segmentedControl.block = { [unowned self] segIndex in
+            self.toolButtonBox.isHidden = false
+            self.toolButtonBoxLayoutConstraint.constant = 40.0
+            
+            if (segIndex == 0) {
+                self.toolButtonBox.contentView = self.thumbnailView
+                self.displayThumbnailViewAnimating(true)
+            } else if (segIndex == 1) {
+                self.toolButtonBox.contentView = self.outlineView
+            } else if (segIndex == 2) {
+                self.toolButtonBox.contentView = self.noteView
+            } else if (segIndex == 3) {
+                self.toolButtonBox.contentView = self.snapshotNormalView
+            } else if (segIndex == 4) {
+                self.toolButtonBox.isHidden = true
+                self.toolButtonBoxLayoutConstraint.constant = 0
+                self.displayFindViewAnimating(false)
+            }
+        }
         
 //        self.button.setHelp(KMLocalizedString("View Thumbnails", "Tool tip message"), for: KMLeftSidePaneState.thumbnail.rawValue)
 //        self.button.setHelp(KMLocalizedString("View Outline", "Tool tip message"), for: KMLeftSidePaneState.outline.rawValue)
@@ -735,11 +741,9 @@ class KMLeftSideViewController: KMSideViewController {
 //        [tocOutlineView setDelegate:mainController];
 //        [tocOutlineView setDataSource:mainController];
         self.thumbnailTableView.delegate = self
-//        [thumbnailTableView setDelegate:mainController];
-//        [thumbnailTableView setDataSource:mainController];
         self.thumbnailTableView.dataSource = self
         self.thumbnailTableView.allowsMultipleSelection = true
-//        [findTableView setDelegate:mainController];
+        self.findTableView.delegate = self
 //    //    [groupedFindTableView setDelegate:mainController];
 //        [groupedFindTableView setDataSource:mainController];
 //        [[thumbnailTableView menu] setDelegate:mainController];
@@ -780,38 +784,185 @@ class KMLeftSideViewController: KMSideViewController {
 //        [self updateViewColor];
     }
     
+    func displayThumbnailViewAnimating(_ animate: Bool) {
+        self.replaceSideView(self.thumbnailTableView.enclosingScrollView!, animate: animate)
+        
+        var frame = self.thumbnailTableView.enclosingScrollView?.frame ?? .zero
+        frame.origin.y = 0
+        frame.size.height = self.thumbnailTableView.enclosingScrollView?.superview?.frame.size.height ?? 0
+        self.thumbnailTableView.enclosingScrollView?.frame = frame
+        
+        self.resetThumbnails()
+        
+//        frame = rightSideController.noteOutlineView.enclosingScrollView.frame;
+//        frame.origin.y = 0;
+//        frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height;
+//        rightSideController.noteOutlineView.enclosingScrollView.frame = frame;
+        
+//        frame = rightSideController.snapshotTableView.enclosingScrollView.frame;
+//        frame.origin.y = 0;
+//        frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height;
+//        rightSideController.snapshotTableView.enclosingScrollView.frame = frame;
+        
+//        [self updateThumbnailSelection];
+    }
+    
+    func displayFindViewAnimating(_ animate: Bool) {
+        self.replaceSideView(self.searchViewController.view, animate: animate)
+        if (self.findState != .content) {
+            self.findState = .content
+        } else {
+            self.displayFindState()
+        }
+        
+        var frame = self.searchViewController.view.frame
+        frame.origin.y = 0
+        frame.size.height = self.searchViewController.view.superview?.frame.size.height ?? .zero
+        self.searchViewController.view.frame = frame
+        
+//        frame = rightSideController.noteOutlineView.enclosingScrollView.frame;
+//        frame.origin.y = 0;
+//        frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height;
+//        rightSideController.noteOutlineView.enclosingScrollView.frame = frame;
+        
+//        frame = rightSideController.snapshotTableView.enclosingScrollView.frame;
+//        frame.origin.y = 0;
+//        frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height;
+//        rightSideController.snapshotTableView.enclosingScrollView.frame = frame;
+//        [self.leftSideEmptyVC.emptySnapView removeFromSuperview];
+        
+//        [self updataLeftSideSnapView];
+    }
+    
+    func displayFindState() {
+        if (self.findState == .content) {
+            self.displayFind()
+        } else if (self.findState == .note) {
+//            [self displayNoteFind];
+        } else if (self.findState == .snapshot) {
+//            [self displaySnapshotFind];
+        }
+    }
     /*
-     @implementation SKLeftSideViewController
+     
+     - (void) {
+
+     }
+
+     - (void)displayGroupedFindViewAnimating:(BOOL)animate {
+         [leftSideController replaceSideView:leftSideController.searchViewController.view animate:animate];
+         if (self.findState != SKFindStateContent) {
+             self.findState = SKFindStateContent;
+         } else {
+             [leftSideController displayFindState];
+         }
+         
+         NSRect frame = leftSideController.searchViewController.view.frame;
+         frame.origin.y = 0;
+         frame.size.height = leftSideController.searchViewController.view.superview.frame.size.height;
+         leftSideController.searchViewController.view.frame = frame;
+         
+         frame = rightSideController.noteOutlineView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height;
+         rightSideController.noteOutlineView.enclosingScrollView.frame = frame;
+         
+         frame = rightSideController.snapshotTableView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height;
+         rightSideController.snapshotTableView.enclosingScrollView.frame = frame;
+         
+         [self updataLeftSideSnapView];
+     }
 
-     @synthesize tocOutlineView, thumbnailArrayController, thumbnailTableView, findArrayController, findTableView, groupedFindArrayController, groupedFindTableView;
-
-     @synthesize segmentedControl, searchViewController;
-
-     - (void)dealloc {
-         [[NSNotificationCenter defaultCenter]removeObserver:self];
-         [thumbnailTableView setDelegate:nil];
-         [thumbnailTableView setDataSource:nil];
-         [findTableView setDelegate:nil];
-     //    [groupedFindTableView setDelegate:nil];
-         [groupedFindTableView setDataSource:nil];
-         [tocOutlineView setDelegate:nil];
-         [tocOutlineView setDataSource:nil];
-         [_filterButtonLayer release];
-         [_moreButtonLayer release];
-         SKDESTROY(thumbnailArrayController);
-         SKDESTROY(findArrayController);
-         SKDESTROY(groupedFindArrayController);
-         SKDESTROY(tocOutlineView);
-         SKDESTROY(thumbnailTableView);
-         SKDESTROY(findTableView);
-         SKDESTROY(groupedFindTableView);
+     - (void)displayNoteViewAnimating:(BOOL)animate {
+         leftSideController.searchViewController.contentView = nil;
+         [leftSideController replaceSideView:rightSideController.noteOutlineView.enclosingScrollView animate:animate];
+         if (self.findState != SKFindStateNote) {
+             self.findState = SKFindStateNote;
+         } else {
+             [leftSideController displayFindState];
+         }
+         
+         NSRect frame = rightSideController.noteOutlineView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height;
+         rightSideController.noteOutlineView.enclosingScrollView.frame = frame;
          
-         SKDESTROY(segmentedControl);
-         SKDESTROY(searchViewController);
-         [super dealloc];
+         frame = rightSideController.noteOutlineView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height;
+         rightSideController.noteOutlineView.enclosingScrollView.frame = frame;
+             
+         frame = rightSideController.snapshotTableView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height;
+         rightSideController.snapshotTableView.enclosingScrollView.frame = frame;
+             
+         NSView *view = rightSideController.noteOutlineView.enclosingScrollView;
+         CGSize emptyVcSize =  self.leftSideEmptyVC.emptyAnnotationView.frame.size;
+         self.leftSideEmptyVC.emptyAnnotationView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height);
      }
 
+     - (void)displaySnapshotViewAnimating:(BOOL)animate {
+         leftSideController.searchViewController.contentView = nil;
+         [leftSideController replaceSideView:rightSideController.snapshotTableView.enclosingScrollView animate:animate];
+         if (self.findState != SKFindStateSnapshot) {
+             self.findState = SKFindStateSnapshot;
+         } else {
+             [leftSideController displayFindState];
+         }
+         
+         NSRect frame = rightSideController.snapshotTableView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height;
+         rightSideController.snapshotTableView.enclosingScrollView.frame = frame;
+         
+         frame = rightSideController.noteOutlineView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height;
+         rightSideController.noteOutlineView.enclosingScrollView.frame = frame;
+         
+         frame = leftSideController.tocOutlineView.enclosingScrollView.frame;
+         frame.origin.y = 0;
+         frame.size.height = leftSideController.tocOutlineView.enclosingScrollView.superview.frame.size.height;
+         leftSideController.tocOutlineView.enclosingScrollView.frame = frame;
+         
+         [self updateSnapshotsIfNeeded];
 
+     }
+
+     
+     */
+    
+    func displayFind() {
+        self.searchField = self.searchViewController.searchField
+        
+        let menu = NSMenu()
+//        menu.addItem(title: <#T##String#>, action: <#T##Selector?#>, target: <#T##AnyObject?#>)
+//        [menu addItemWithTitle:NSLocalizedString(@"Whole Words Only", @"Menu item title") action:@selector(toggleWholeWordSearch:) target:mainController];
+//        [menu addItemWithTitle:NSLocalizedString(@"Ignore Case", @"Menu item title") action:@selector(toggleCaseInsensitiveSearch:) target:mainController];
+//        [[searchViewController.searchField cell] setSearchMenuTemplate:menu];
+        (self.searchViewController.searchField.cell as? NSSearchFieldCell)?.placeholderString = KMLocalizedString("Search PDF", "placeholder")
+//        self.searchViewController.searchField.target =
+//        [searchViewController.searchField setAction:@selector(search:)];
+//        [searchViewController.searchField setTarget:mainController];
+
+//        if (mainController.findPaneState == SKFindPaneStateSingular) {
+        self.searchViewController.contentView = self.findTableView.enclosingScrollView;
+//        } else if (mainController.findPaneState == SKFindPaneStateGrouped) {
+//            searchViewController.contentView = groupedFindTableView.enclosingScrollView;
+//        }
+    }
+    
+    /*
+     - (void) {
+
+     }
+     
+     @implementation SKLeftSideViewController
+
+     @synthesize tocOutlineView, thumbnailArrayController, findArrayController, groupedFindArrayController, groupedFindTableView;
 
      - (BOOL)requiresAlternateButtonForView:(NSView *)aView {
          return NO;
@@ -835,23 +986,7 @@ class KMLeftSideViewController: KMSideViewController {
          }
      }
 
-     - (void)displayFind {
-         self.searchField = searchViewController.searchField;
-         
-         NSMenu *menu = [NSMenu menu];
-         [menu addItemWithTitle:NSLocalizedString(@"Whole Words Only", @"Menu item title") action:@selector(toggleWholeWordSearch:) target:mainController];
-         [menu addItemWithTitle:NSLocalizedString(@"Ignore Case", @"Menu item title") action:@selector(toggleCaseInsensitiveSearch:) target:mainController];
-         [[searchViewController.searchField cell] setSearchMenuTemplate:menu];
-         [[searchViewController.searchField cell] setPlaceholderString:NSLocalizedString(@"Search PDF", @"placeholder")];
-         [searchViewController.searchField setAction:@selector(search:)];
-         [searchViewController.searchField setTarget:mainController];
-
-         if (mainController.findPaneState == SKFindPaneStateSingular) {
-             searchViewController.contentView = findTableView.enclosingScrollView;
-         } else if (mainController.findPaneState == SKFindPaneStateGrouped) {
-             searchViewController.contentView = groupedFindTableView.enclosingScrollView;
-         }
-     }
+
 
      - (void)displayNoteFind {
          mainController.rightSideController.searchField = self.noteSearchField;
@@ -962,33 +1097,59 @@ class KMLeftSideViewController: KMSideViewController {
          [[NSNotificationCenter defaultCenter] postNotificationName:@"KMAnnotationSortTypeKeyNotification" object:self userInfo:nil];
      }
      */
-}
-
-extension KMLeftSideViewController: KMThumbnailViewControllerDelegate {
-    func gotoPageEdit(thumbnailViewController: KMThumbnailViewController, pages: [Int]) {
-        self.delegate?.enterEditMode?(self, pages)
-    }
     
-    func pageDidSelect(controller: KMThumbnailViewController, pages: [Int]) {
-        self.selectPages = pages
-    }
-    
-    func controller(controller: KMThumbnailViewController, itemClick item: Any?, itemKey: KMItemKey, params: Any?) {
-        self.delegate?.controller?(controller: self, itemClick: item, itemKey: itemKey, params: params)
+    func resetThumbnails() {
+//        [self willChangeValueForKey:THUMBNAILS_KEY];
+        
+        self.thumbnailCacheSize = 400
+        
+        self.thumbnails.removeAll()
+        let pageLabels = self.listView.document.pageLabels()
+        if (pageLabels.isEmpty == false) {
+            let isLocked = self.listView.document.isLocked
+            let firstPage = self.listView.document.page(at: 0)
+            // SKPDFPage
+            let emptyPage = CPDFPage()
+            let firstFrame = firstPage?.bounds(for: .cropBox) ?? .zero
+            let firstFrame2 = firstPage?.bounds(for: .mediaBox) ?? .zero
+            emptyPage.setBounds(firstFrame, for: .cropBox)
+            emptyPage.setBounds(firstFrame2, for: .mediaBox)
+            emptyPage.rotation = firstPage?.rotation ?? 0
+            
+            let pageImage = firstPage!.thumbnail(of: NSMakeSize(self.thumbnailCacheSize, self.thumbnailCacheSize))
+//            NSImage * = [emptyPage thumbnailWithSize:thumbnailCacheSize forBox:[pdfView displayBox]];
+            var rect: NSRect = .zero
+            rect.size = pageImage?.size ?? .zero
+            let width = 1.2 * fmin(NSWidth(rect), NSHeight(rect))
+            rect = NSInsetRect(rect, 0.5 * (NSWidth(rect) - width), 0.5 * (NSHeight(rect) - width));
+            
+            pageImage?.lockFocus()
+            NSImage(named: NSImage.applicationIconName)?.draw(in: rect, from: .zero, operation: .sourceOver, fraction: 0.5)
+            if (isLocked) {
+                NSWorkspace.shared.icon(forFileType: NSFileTypeForHFSTypeCode(OSType(kLockedBadgeIcon))).draw(in: rect, from: .zero, operation: .sourceOver, fraction: 0.5)
+                //                [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kLockedBadgeIcon)] drawInRect:rect fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:0.5];
+            }
+            pageImage?.unlockFocus()
+            
+//            __block typeof(self) blockSelf = self;
+            for (i, label) in pageLabels.enumerated() {
+                let thumbnail = KMThumbnail(image: pageImage, label: label, pageIndex: i)
+                //                thumbnail.delegate = self
+                thumbnail.dirty = true
+                self.thumbnails.append(thumbnail)
+            }
+        }
+//        [self didChangeValueForKey:THUMBNAILS_KEY];
+//        [self allThumbnailsNeedUpdate];
+        
+        DispatchQueue.main.async {
+            self.thumbnailTableView.reloadData()
+        }
     }
-}
-
-extension KMLeftSideViewController : KMSearchViewControllerDelegate {
-//    func searchAction(searchString: String,isCase:Bool) {
-//        self.delegate?.searchAction?(searchString: searchString, isCase: isCase)
-//    }
-//
-//    func searchDoneAction(viewController: KMSearchViewController) {
-//        self.type = KMLeftMethodMode()
-//        self.updateViewButtonState()
-//        self.delegate?.controlStateChange?(self,show:false)
-////        self.leftTableview.reloadData()
-//    }
+    /*
+     
+     
+     */
 }
 
 //MARK: NSTableViewDelegate,NSTableViewDataSource
@@ -1216,7 +1377,6 @@ extension KMLeftSideViewController {
         self.bookViewController.removeNotification()
         self.annotationViewController.removeNotification()
         self.outlineViewController.removeNotification()
-        self.thumbnailViewController.removeNotification()
     }
 }
 
@@ -1268,7 +1428,7 @@ extension KMLeftSideViewController {
             self.thumbnailTableView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1)
 //            groupedFindTableView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1)
 //            tocOutlineView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1)
-//            findTableView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1)
+            self.findTableView.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1)
             
             self.snapshotSearchField.layer?.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1).cgColor
             self.outlineSearchField.layer?.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1).cgColor
@@ -1289,7 +1449,7 @@ extension KMLeftSideViewController {
             self.thumbnailTableView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1)
 //            groupedFindTableView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1)
 //            tocOutlineView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1)
-//            findTableView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1)
+            self.findTableView.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1)
             
             self.snapshotSearchField.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor
             self.outlineSearchField.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor
@@ -1305,66 +1465,73 @@ extension KMLeftSideViewController {
      */
 }
 
-extension KMLeftSideViewController: KMThumbnailTableViewDelegate, NSTableViewDataSource {
+// MARK: - KMThumbnailTableViewDelegate, NSTableViewDataSource
+
+extension KMLeftSideViewController: NSTableViewDelegate, NSTableViewDataSource {
     func numberOfRows(in tableView: NSTableView) -> Int {
+        if tableView.isEqual(to: self.thumbnailTableView) {
+            return self.thumbnails.count
+        } else if tableView.isEqual(to: self.findTableView) {
+            return self.searchResults.count
+        }
         return 0
     }
     
     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
         if tableView.isEqual(to: self.thumbnailTableView) {
-//        if ([tableView isEqual:leftSideController.thumbnailTableView]) {
-//            let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMThumbnailTableviewCell"), owner: self)
-//            SKThumbnail *thumbnail = thumbnails[row];
-//            cell.pageNumLabel.stringValue = thumbnail.label;
-//            cell.thumImage.image = thumbnail.image;
-//            CGFloat multiplierHToW = thumbnail.image.size.height / thumbnail.image.size.width;
-//            CGFloat multiplierWToH = thumbnail.image.size.width / thumbnail.image.size.height;
-//            if (thumbnail.image.size.height > thumbnail.image.size.width) {
-//                [NSLayoutConstraint deactivateConstraints:@[cell.imageAspectRatioLayout]];
-//                cell.imageAspectRatioLayout = [NSLayoutConstraint constraintWithItem:cell.thumImage attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:cell.thumImage attribute:NSLayoutAttributeWidth multiplier:multiplierHToW constant:0];
-//                [NSLayoutConstraint activateConstraints:@[cell.imageAspectRatioLayout]];
-//            } else {
-//                [NSLayoutConstraint deactivateConstraints:@[cell.imageAspectRatioLayout]];
-//                cell.imageAspectRatioLayout = [NSLayoutConstraint constraintWithItem:cell.thumImage attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:cell.thumImage attribute:NSLayoutAttributeHeight multiplier:multiplierWToH constant:0];
-//                [NSLayoutConstraint activateConstraints:@[cell.imageAspectRatioLayout]];
-//            }
-//
-//            if (self.isDisplayPageSize) {
-//                cell.sizeLabel.hidden = NO;
-//
-//                //获取Page的真实尺寸
-//                PDFPage *page = [self.pdfView.document pageAtIndex:row];
-//                CGRect rect = [page boundsForBox:kPDFDisplayBoxCropBox];
-//                NSString *w =  [KMPageSizeTool conversionWithUnit:@"mm" value:(CGRectGetWidth(rect)/595 * 210)]?:@"";
-//                NSString *h =  [KMPageSizeTool conversionWithUnit:@"mm" value:(CGRectGetHeight(rect)/842 * 297)]?:@"";
-//                if (page.rotation == 90 || page.rotation == 270) {
-//                    cell.sizeLabel.stringValue = [NSString stringWithFormat:@"%.f × %.f %@",[h floatValue], [w floatValue], NSLocalizedString(@"mm", nil)];
-//                } else {
-//                    cell.sizeLabel.stringValue = [NSString stringWithFormat:@"%.f × %.f %@",[w floatValue], [h floatValue], NSLocalizedString(@"mm", nil)];
-//                }
-//            } else {
-//                cell.sizeLabel.hidden = YES;
-//            }
-//            cell.sizeTopConstant.constant = cell.sizeLabel.hidden ? -cell.sizeLabel.frame.size.height : 0;
-//            if([leftSideController.thumbnailTableView.selectedRowIndexes containsIndex:row]) {
-//                cell.isSelectCell = YES;
-//            } else {
-//                cell.isSelectCell = NO;
-//            }
-//            return cell;
+            let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMThumbnailTableviewCell"), owner: self) as! KMThumbnailTableviewCell
+            let thumbnail = self.thumbnails[row]
+            cell.pageNumLabel.stringValue = thumbnail.label
+            cell.thumImage.image = thumbnail.image
+            if let _image = thumbnail.image {
+                let multiplierHToW = _image.size.height / (_image.size.width == 0 ? 1 : _image.size.width)
+                let multiplierWToH = _image.size.width  / (_image.size.height == 0 ? 1 : _image.size.height)
+                if (_image.size.height > _image.size.width) {
+                    NSLayoutConstraint.deactivate([cell.imageAspectRatioLayout])
+                    cell.imageAspectRatioLayout = NSLayoutConstraint(item: cell.thumImage, attribute: .height, relatedBy: .equal, toItem: cell.thumImage, attribute: .width, multiplier: multiplierHToW, constant: 0)
+                    NSLayoutConstraint.activate([cell.imageAspectRatioLayout])
+                } else {
+                    NSLayoutConstraint.deactivate([cell.imageAspectRatioLayout])
+                    cell.imageAspectRatioLayout = NSLayoutConstraint(item: cell.thumImage, attribute: .width, relatedBy: .equal, toItem: cell.thumImage, attribute: .height, multiplier: multiplierWToH, constant: 0)
+                    NSLayoutConstraint.activate([cell.imageAspectRatioLayout])
+                }
+            }
+
+            if (self.isDisplayPageSize) {
+                cell.sizeLabel.isHidden = false
+                //获取Page的真实尺寸
+                let page = self.listView.document.page(at: UInt(row))
+                let rect = page?.bounds(for: .cropBox) ?? .zero
+                let w =  KMPageSizeTool.conversion(withUnit: "mm", value: (CGRectGetWidth(rect)/595 * 210))
+                let h =  KMPageSizeTool.conversion(withUnit: "mm", value: (CGRectGetHeight(rect)/842 * 297))
+                if let data = page?.rotation, data == 90 || data == 270 {
+                    cell.sizeLabel.stringValue = String(format: "%.f × %.f %@", h.stringToCGFloat(), w.stringToCGFloat(), KMLocalizedString("mm", nil))
+                } else {
+                    cell.sizeLabel.stringValue = String(format: "%.f × %.f %@", w.stringToCGFloat(), h.stringToCGFloat(), KMLocalizedString("mm", nil))
+                }
+            } else {
+                cell.sizeLabel.isHidden = true
+            }
+            cell.sizeTopConstant.constant = cell.sizeLabel.isHidden ? -cell.sizeLabel.frame.size.height : 0
+            if(self.thumbnailTableView.selectedRowIndexes.contains(row)) {
+                cell.isSelectCell = true
+            } else {
+                cell.isSelectCell = false
+            }
+            return cell
+        } else if (tableView.isEqual(to: self.findTableView)) {
+            let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMFindTableviewCell"), owner: self) as! KMFindTableviewCell
+             let selection = searchResults[row]
+            if let data = tableColumn?.identifier.rawValue, data == "results" {
+                cell.resultLabel.attributedStringValue = selection.attributedString()
+                cell.resultLabel.textColor = KMAppearance.Layout.h0Color()
+            } else if let data = tableColumn?.identifier.rawValue, data == "page" {
+                cell.resultLabel.stringValue = selection.pages().first?.label ?? ""
+                cell.resultLabel.textColor = KMAppearance.Layout.h2Color()
+            }
+            return cell
         }
-//        else if ([tableView isEqual:leftSideController.findTableView]) {
-//            KMFindTableviewCell *cell = [tableView makeViewWithIdentifier:@"KMFindTableviewCell" owner:self];
-//            PDFSelection *selection = searchResults[row];
-//            if ([tableColumn.identifier isEqualToString:@"results"]) {
-//                cell.resultLabel.attributedStringValue = [selection contextString];
-//                cell.resultLabel.textColor = [KMAppearance KMColor_Layout_H0];
-//            } else if ([tableColumn.identifier isEqualToString:@"page"]) {
-//                cell.resultLabel.stringValue = selection.pages[0].label;
-//                cell.resultLabel.textColor = [KMAppearance KMColor_Layout_H2];
-//            }
-//            return cell;
-//        } else if ([tableView isEqual:rightSideController.snapshotTableView]) {
+//            else if ([tableView isEqual:rightSideController.snapshotTableView]) {
 //
 //            KMSnapshotTableViewCell *cell = [tableView makeViewWithIdentifier:@"KMSnapshotTableViewCell" owner:self];
 //            SKSnapshotWindowController *snapshot = snapshots[row];
@@ -1396,6 +1563,89 @@ extension KMLeftSideViewController: KMThumbnailTableViewDelegate, NSTableViewDat
         return nil;
     }
     
+    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
+        if tableView.isEqual(to: self.thumbnailTableView) {
+//        if ([tv isEqual:leftSideController.thumbnailTableView]) {
+            let scaling = UserDefaults.standard.float(forKey: "KMThumbnailSizeScalingKey")
+            let thumbnailSize = self.thumbnails[row].size
+            
+            let newScaling: CGFloat = scaling.cgFloat + 0.1
+            let newThumbnailHeight = thumbnailSize.width * newScaling
+            if (newThumbnailHeight > MIN_SIDE_PANE_WIDTH) {
+                self.thumbnailZoomOutButton.isEnabled = false
+            } else {
+                self.thumbnailZoomOutButton.isEnabled = true
+            }
+            if ((scaling - 0.1) < 0.3) {
+                self.thumbnailZoomInButton.isEnabled = false
+            } else {
+                self.thumbnailZoomInButton.isEnabled = true
+            }
+            var labelHeight = 0.0
+            if (self.isDisplayPageSize) {
+                labelHeight = 56.0
+            } else {
+                labelHeight = 41.5
+            }
+            let  cellHeight = thumbnailSize.height + labelHeight
+            var thumbSize: NSSize = .zero
+            if (scaling != nil && scaling > 0) {
+                thumbSize = NSMakeSize(thumbnailSize.width * scaling.cgFloat, cellHeight * scaling.cgFloat)
+            } else {
+                thumbSize = NSMakeSize(thumbnailSize.width, cellHeight)
+            }
+            return thumbSize.height
+            
+    //        NSSize cellSize = NSMakeSize([[tv tableColumnWithIdentifier:IMAGE_COLUMNID] width], fmin(thumbSize.height, roundedThumbnailSize));
+    //        if (thumbSize.height < [tv rowHeight])
+    //            return [tv rowHeight];
+    //        else if (thumbSize.width / thumbSize.height < cellSize.width / cellSize.height)
+    //            return cellSize.height;
+    //        else
+    //            return fmax([tv rowHeight], fmin(cellSize.width, thumbSize.width) * thumbSize.height / thumbSize.width);
+        }
+//            else if ([tv isEqual:rightSideController.snapshotTableView]) {
+//            CGFloat scaling = [[NSUserDefaults standardUserDefaults] floatForKey:@"KMSnapshotSizeScalingKey"];
+//    //        NSSize snapshotSize = [[[[rightSideController.snapshotArrayController arrangedObjects] objectAtIndex:row] thumbnail] size];
+//            NSSize snapshotSize = CGSizeMake(120, 63);
+//
+//            CGFloat newScaling = scaling + 0.1;
+//            CGFloat newSnapshotHeight = snapshotSize.width * newScaling;
+//            if (newSnapshotHeight > MIN_SIDE_PANE_WIDTH) {
+//                leftSideController.snapshotNormalZoomInButton.enabled = NO;
+//            } else {
+//                leftSideController.snapshotNormalZoomInButton.enabled = YES;
+//            }
+//            if ((scaling - 0.1) < 0.3 || (newSnapshotHeight < 150.0)) {
+//                leftSideController.snapshotNormalZoomOutButton.enabled = NO;
+//            } else {
+//                leftSideController.snapshotNormalZoomOutButton.enabled = YES;
+//            }
+//
+//            CGFloat cellHeight = snapshotSize.height + 24.0;
+//            NSSize thumbSize;
+//            if (scaling && scaling > 0) {
+//                thumbSize = NSMakeSize(snapshotSize.width * scaling, cellHeight * scaling);
+//            } else {
+//                thumbSize = NSMakeSize(snapshotSize.width, cellHeight);
+//            }
+//            return thumbSize.height;
+//        }
+        else if (tableView.isEqual(to: self.findTableView)) {
+            return 40.0
+        }
+        return tableView.rowHeight
+    }
+    
+    func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
+        if (tableView.isEqual(to: self.findTableView)) {
+//        if ([tableView isEqual:leftSideController.findTableView] || [tableView isEqual:leftSideController.groupedFindTableView]) {
+            let rowView = KMCustomTableRowView()
+            return rowView
+        }
+        return nil
+    }
+    
     /*
 
 
@@ -1534,13 +1784,7 @@ extension KMLeftSideViewController: KMThumbnailTableViewDelegate, NSTableViewDat
          }
      }
 
-     - (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row {
-         if ([tableView isEqual:leftSideController.findTableView] || [tableView isEqual:leftSideController.groupedFindTableView]) {
-             KMCustomTableRowView *rowView = [[[KMCustomTableRowView alloc] init] autorelease];
-             return rowView;
-         }
-         return nil;
-     }
+
 
      #pragma mark NSTableView delegate protocol
 
@@ -1657,77 +1901,6 @@ extension KMLeftSideViewController: KMThumbnailTableViewDelegate, NSTableViewDat
          }
      }
 
-     - (CGFloat)tableView:(NSTableView *)tv heightOfRow:(NSInteger)row {
-         if ([tv isEqual:leftSideController.thumbnailTableView]) {
-             CGFloat scaling = [[NSUserDefaults standardUserDefaults] floatForKey:@"KMThumbnailSizeScalingKey"];
-             NSSize thumbnailSize = [[thumbnails objectAtIndex:row] size];
-             
-             CGFloat newScaling = scaling + 0.1;
-             CGFloat newThumbnailHeight = thumbnailSize.width * newScaling;
-             if (newThumbnailHeight > MIN_SIDE_PANE_WIDTH) {
-                 leftSideController.thumbnailZoomOutButton.enabled = NO;
-             } else {
-                 leftSideController.thumbnailZoomOutButton.enabled = YES;
-             }
-             if ((scaling - 0.1) < 0.3) {
-                 leftSideController.thumbnailZoomInButton.enabled = NO;
-             } else {
-                 leftSideController.thumbnailZoomInButton.enabled = YES;
-             }
-             CGFloat labelHeight = 0.0;
-             if (self.isDisplayPageSize) {
-                 labelHeight = 56.0;
-             } else {
-                 labelHeight = 41.5;
-             }
-             CGFloat cellHeight = thumbnailSize.height + labelHeight;
-             NSSize thumbSize;
-             if (scaling && scaling > 0) {
-                 thumbSize = NSMakeSize(thumbnailSize.width * scaling, cellHeight * scaling);
-             } else {
-                 thumbSize = NSMakeSize(thumbnailSize.width, cellHeight);
-             }
-             return thumbSize.height;
-             
-     //        NSSize cellSize = NSMakeSize([[tv tableColumnWithIdentifier:IMAGE_COLUMNID] width], fmin(thumbSize.height, roundedThumbnailSize));
-     //        if (thumbSize.height < [tv rowHeight])
-     //            return [tv rowHeight];
-     //        else if (thumbSize.width / thumbSize.height < cellSize.width / cellSize.height)
-     //            return cellSize.height;
-     //        else
-     //            return fmax([tv rowHeight], fmin(cellSize.width, thumbSize.width) * thumbSize.height / thumbSize.width);
-         } else if ([tv isEqual:rightSideController.snapshotTableView]) {
-             CGFloat scaling = [[NSUserDefaults standardUserDefaults] floatForKey:@"KMSnapshotSizeScalingKey"];
-     //        NSSize snapshotSize = [[[[rightSideController.snapshotArrayController arrangedObjects] objectAtIndex:row] thumbnail] size];
-             NSSize snapshotSize = CGSizeMake(120, 63);
-             
-             CGFloat newScaling = scaling + 0.1;
-             CGFloat newSnapshotHeight = snapshotSize.width * newScaling;
-             if (newSnapshotHeight > MIN_SIDE_PANE_WIDTH) {
-                 leftSideController.snapshotNormalZoomInButton.enabled = NO;
-             } else {
-                 leftSideController.snapshotNormalZoomInButton.enabled = YES;
-             }
-             if ((scaling - 0.1) < 0.3 || (newSnapshotHeight < 150.0)) {
-                 leftSideController.snapshotNormalZoomOutButton.enabled = NO;
-             } else {
-                 leftSideController.snapshotNormalZoomOutButton.enabled = YES;
-             }
-             
-             CGFloat cellHeight = snapshotSize.height + 24.0;
-             NSSize thumbSize;
-             if (scaling && scaling > 0) {
-                 thumbSize = NSMakeSize(snapshotSize.width * scaling, cellHeight * scaling);
-             } else {
-                 thumbSize = NSMakeSize(snapshotSize.width, cellHeight);
-             }
-             return thumbSize.height;
-         } else if ([tv isEqual:leftSideController.findTableView]) {
-             return 40.0;
-         }
-         return [tv rowHeight];
-     }
-
      - (void)tableView:(NSTableView *)tv deleteRowsWithIndexes:(NSIndexSet *)rowIndexes {
          if (![[IAPProductsManager defaultManager] isAvailableAllFunction]) {
              [[KMPurchaseCompareWindowController sharedInstance] showWindow:nil];

+ 8 - 3
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMSegmentedControl.swift

@@ -20,8 +20,13 @@ class KMSegmentedControl: NSControl {
         }
   
     }
-    var selectedSegment: UInt8 = 0 {
-        didSet {
+    private var _selectedSegment: UInt8 = 0
+    var selectedSegment: UInt8 {
+        get {
+            return self._selectedSegment
+        }
+        set {
+            self._selectedSegment = newValue
             if (self.block != nil) {
                 self.block!(self.selectedSegment)
             }
@@ -115,7 +120,7 @@ class KMSegmentedControl: NSControl {
         super.updateLayer()
         
         if #available(macOS 10.14, *) {
-            self.selectedSegment = self._segmentCount
+            self.selectedSegment = self._selectedSegment
         }
     }
     

+ 7 - 14
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/LeftSideView.xib

@@ -47,7 +47,6 @@
                 <outlet property="snapshotSearchZoomOutButton" destination="bWl-Nk-NDn" id="oZL-WQ-baS"/>
                 <outlet property="sortTypeBox" destination="dVS-ub-dou" id="kJw-h9-qkC"/>
                 <outlet property="sortTypeLabel" destination="AP9-fE-Owg" id="zBU-Fv-sAs"/>
-                <outlet property="thumbnailArrayController" destination="87" id="175"/>
                 <outlet property="thumbnailTableView" destination="101" id="180"/>
                 <outlet property="thumbnailTitleLabel" destination="4v1-rQ-o49" id="ILp-T0-v3b"/>
                 <outlet property="thumbnailView" destination="yCV-H4-Tw9" id="hrC-Qs-FEA"/>
@@ -164,7 +163,7 @@
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <clipView key="contentView" drawsBackground="NO" id="fXK-1u-PsQ">
                 <rect key="frame" x="0.0" y="0.0" width="201" height="405"/>
-                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                <autoresizingMask key="autoresizingMask"/>
                 <subviews>
                     <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" selectionHighlightStyle="none" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="86" rowSizeStyle="automatic" viewBased="YES" id="101" customClass="KMThumbnailTableView" customModule="PDF_Master" customModuleProvider="target">
                         <rect key="frame" x="0.0" y="0.0" width="201" height="405"/>
@@ -262,9 +261,6 @@
                                         </connections>
                                     </tableCellView>
                                 </prototypeCellViews>
-                                <connections>
-                                    <binding destination="87" name="value" keyPath="arrangedObjects.image" id="147"/>
-                                </connections>
                             </tableColumn>
                         </tableColumns>
                         <connections>
@@ -374,9 +370,9 @@
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <clipView key="contentView" drawsBackground="NO" id="LIi-mQ-ZiW">
                 <rect key="frame" x="0.0" y="0.0" width="204" height="400"/>
-                <autoresizingMask key="autoresizingMask"/>
+                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                 <subviews>
-                    <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="40" viewBased="YES" id="111" customClass="SKTableView">
+                    <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="40" viewBased="YES" id="111" customClass="KMBotaTableView" customModule="PDF_Master" customModuleProvider="target">
                         <rect key="frame" x="0.0" y="0.0" width="204" height="400"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <size key="intercellSpacing" width="0.0" height="2"/>
@@ -395,7 +391,7 @@
                                 </textFieldCell>
                                 <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                 <prototypeCellViews>
-                                    <tableCellView identifier="KMFindTableviewCell" id="diE-pb-2YS" customClass="KMFindTableviewCell">
+                                    <tableCellView identifier="KMFindTableviewCell" id="diE-pb-2YS" customClass="KMFindTableviewCell" customModule="PDF_Master" customModuleProvider="target">
                                         <rect key="frame" x="10" y="1" width="128" height="40"/>
                                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                         <subviews>
@@ -438,7 +434,7 @@
                                 </textFieldCell>
                                 <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                 <prototypeCellViews>
-                                    <tableCellView identifier="KMFindTableviewCell" id="yXb-0j-jyQ" customClass="KMFindTableviewCell">
+                                    <tableCellView identifier="KMFindTableviewCell" id="yXb-0j-jyQ" customClass="KMFindTableviewCell" customModule="PDF_Master" customModuleProvider="target">
                                         <rect key="frame" x="138" y="1" width="56" height="40"/>
                                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                         <subviews>
@@ -588,9 +584,6 @@
                 <string>label</string>
                 <string>rightSidePaneState</string>
             </declaredKeys>
-            <connections>
-                <binding destination="90" name="contentArray" keyPath="selection.thumbnails" id="148"/>
-            </connections>
         </arrayController>
         <arrayController objectClassName="PDFSelection" editable="NO" selectsInsertedObjects="NO" avoidsEmptySelection="NO" id="91" userLabel="FindArrayController">
             <declaredKeys>
@@ -624,7 +617,7 @@
                 <binding destination="90" name="contentArray" keyPath="selection.groupedSearchResults" id="143"/>
             </connections>
         </arrayController>
-        <customObject id="PRk-2a-DZk" customClass="KMSearchViewController"/>
+        <customObject id="PRk-2a-DZk" customClass="KMBotaSearchViewController" customModule="PDF_Master" customModuleProvider="target"/>
         <customView id="Rnt-IM-ngR">
             <rect key="frame" x="0.0" y="0.0" width="222" height="40"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
@@ -1033,7 +1026,7 @@
     <resources>
         <image name="KMImageNameBtnSidebarRankPositive" width="16" height="16"/>
         <image name="KMImageNameEmptySearch" width="140" height="140"/>
-        <image name="KMImageNameUXIconBtnArrowDown" width="17" height="16"/>
+        <image name="KMImageNameUXIconBtnArrowDown" width="16" height="16"/>
         <image name="KMImageNameUXIconBtnSidebarAddNor" width="16" height="16"/>
         <image name="KMImageNameUXIconBtnSidebarFilterNor" width="16" height="16"/>
         <image name="KMImageNameUXIconBtnSidebarMoreNor" width="16" height="16"/>

+ 113 - 0
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Search/KMBotaSearchViewController.swift

@@ -0,0 +1,113 @@
+//
+//  KMBotaSearchViewController.swift
+//  PDF Master
+//
+//  Created by tangchao on 2023/11/16.
+//
+
+import Cocoa
+
+class KMBotaSearchViewController: NSViewController {
+    @IBOutlet weak var searchField: NSSearchField!
+    @IBOutlet weak var segmentedControl: KMSegmentedControl!
+    var contentView: NSView? {
+        didSet {
+            if let view = self.contentView {
+                self.box.contentView = view
+            }
+        }
+    }
+    @IBOutlet weak var emptyBox: NSBox!
+    @IBOutlet weak var searchBox: KMBox!
+    @IBOutlet weak var searchResultsView: NSView!
+    @IBOutlet weak var searchResultsLabel: NSTextField!
+    @IBOutlet weak var searchDomeButton: NSButton!
+    
+    @IBOutlet weak var box: NSBox!
+    @IBOutlet weak var emptySearchLabel: NSTextField!
+    @IBOutlet weak var searchLabel: NSTextField!
+    @IBOutlet weak var searchTips: NSTextField!
+    @IBOutlet weak var pageLabel: NSTextField!
+    
+    deinit {
+        KMPrint("KMBotaSearchViewController deinit.")
+        
+        NotificationCenter.default.removeObserver(self)
+    }
+    
+    override func loadView() {
+        super.loadView()
+        
+        self.emptySearchLabel.stringValue = KMLocalizedString("No Results",nil)
+        self.emptySearchLabel.textColor = KMAppearance.Layout.h1Color()
+        self.emptyBox.fillColor = KMAppearance.Layout.l0Color()
+        self.searchLabel.stringValue = KMLocalizedString("Search", nil)
+        self.searchLabel.textColor = KMAppearance.Layout.h0Color()
+        self.searchTips.stringValue = KMLocalizedString("Search", nil)
+        self.searchTips.textColor = KMAppearance.Layout.h2Color()
+        self.searchResultsLabel.textColor = KMAppearance.Layout.h1Color()
+        self.pageLabel.stringValue = KMLocalizedString("Page", nil)
+        self.pageLabel.textColor = KMAppearance.Layout.h1Color()
+        self.searchResultsView.isHidden = true
+        
+        self.searchDomeButton.title = KMLocalizedString("Done", nil)
+        self.searchDomeButton.toolTip = KMLocalizedString("Done", nil)
+        self.searchDomeButton.setTitleColor(KMAppearance.Layout.w0Color())
+        self.searchDomeButton.wantsLayer = true
+        self.searchDomeButton.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor
+        self.searchDomeButton.layer?.cornerRadius = 4.0
+    //    self.searchDomeButton.hidden = YES;
+        
+        self.searchField.wantsLayer = true
+    //    self.searchField.layer.backgroundColor = [KMAppearance KMColor_Layout_L1].CGColor;
+        self.searchField.layer?.cornerRadius = 1.0
+        self.searchField.layer?.borderWidth = 1.0
+        self.searchField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor
+        
+        self.searchBox.fillColor = KMAppearance.Interactive.s0Color()
+    //    self.searchField.hidden = YES;
+//        self.searchBox.downCallback = { [unowned self] downEntered, box, _ in
+//            if (downEntered) {
+//                self.searchField.isHidden = false
+//                self.searchDomeButton.isHidden = false
+//                self.searchBox.isHidden = true
+//                self.searchField.becomeFirstResponder()
+//            }
+//        }
+        
+        self.searchBox.isHidden = true
+    }
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        // Do view setup here.
+    }
+    
+    override func viewDidAppear() {
+        super.viewDidAppear()
+        
+        self.searchField.becomeFirstResponder()
+        self.updateViewColor()
+        DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged), name: NSApplication.interfaceThemeChangedNotification, object: nil)
+    }
+    
+    func updateViewColor() {
+        if (KMAppearance.isDarkMode()) {
+            self.searchField.layer?.backgroundColor = NSColor(red: 57.0/255.0, green: 60.0/255.0, blue: 62.0/255.0, alpha: 1).cgColor
+        } else {
+            self.searchField.layer?.backgroundColor = .white
+        }
+    }
+    
+    @objc func themeChanged(_ notification: NSNotification) {
+        DispatchQueue.main.asyncAfter(deadline: .now()+0.3) {
+            self.updateViewColor()
+        }
+    }
+    
+    @IBAction func searchDomeButtonAtion(_ sender: AnyObject) {
+        self.searchField.isHidden = true
+        self.searchDomeButton.isHidden = true
+        self.searchBox.isHidden = false
+    }
+}

+ 233 - 0
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Search/KMBotaSearchViewController.xib

@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMBotaSearchViewController" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="box" destination="jTx-lq-IMO" id="3np-QT-RBm"/>
+                <outlet property="emptyBox" destination="YP3-hM-jIu" id="76W-OU-rpD"/>
+                <outlet property="emptySearchLabel" destination="RZV-VM-ubG" id="P1g-lE-xp0"/>
+                <outlet property="pageLabel" destination="DG6-KM-fPE" id="WCW-t2-N6y"/>
+                <outlet property="searchBox" destination="m5j-WZ-WP4" id="cvH-DW-gmp"/>
+                <outlet property="searchDomeButton" destination="Sot-lU-418" id="nTG-J5-bHW"/>
+                <outlet property="searchField" destination="Exf-lV-10v" id="HAb-dG-HXv"/>
+                <outlet property="searchLabel" destination="ZGS-QS-aFB" id="Uq1-gi-5tY"/>
+                <outlet property="searchResultsLabel" destination="avX-Sl-7dw" id="U6D-o9-NG9"/>
+                <outlet property="searchResultsView" destination="hP4-NA-Ala" id="srK-Ds-q65"/>
+                <outlet property="searchTips" destination="LV8-kC-pPy" id="vhL-vd-TBZ"/>
+                <outlet property="segmentedControl" destination="2OM-I5-WuT" id="hoB-xe-Aav"/>
+                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="Hz6-mo-xeY">
+            <rect key="frame" x="0.0" y="0.0" width="240" height="513"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <searchField wantsLayer="YES" verticalHuggingPriority="750" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Exf-lV-10v">
+                    <rect key="frame" x="16" y="452" width="164" height="20"/>
+                    <searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="border" usesSingleLineMode="YES" id="So1-aF-t1m">
+                        <font key="font" metaFont="system"/>
+                        <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                    </searchFieldCell>
+                </searchField>
+                <box boxType="custom" borderType="none" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="jTx-lq-IMO">
+                    <rect key="frame" x="0.0" y="0.0" width="240" height="422"/>
+                    <view key="contentView" id="Hlh-Hl-xR6">
+                        <rect key="frame" x="0.0" y="0.0" width="240" height="422"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                    </view>
+                    <color key="fillColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                </box>
+                <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="YP3-hM-jIu">
+                    <rect key="frame" x="0.0" y="0.0" width="240" height="422"/>
+                    <view key="contentView" id="fz0-9N-dbN">
+                        <rect key="frame" x="0.0" y="0.0" width="240" height="422"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="Vwh-uE-n99">
+                                <rect key="frame" x="-5" y="125" width="250" height="173"/>
+                                <subviews>
+                                    <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="fCc-bq-sMR">
+                                        <rect key="frame" x="55" y="33" width="140" height="140"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="140" id="1Zc-3B-E9k"/>
+                                            <constraint firstAttribute="width" constant="140" id="C42-wv-uSe"/>
+                                        </constraints>
+                                        <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="KMImageNameEmptySearch" id="Fgf-hM-PPL"/>
+                                    </imageView>
+                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RZV-VM-ubG">
+                                        <rect key="frame" x="8" y="0.0" width="234" height="17"/>
+                                        <constraints>
+                                            <constraint firstAttribute="width" constant="230" id="Mx1-pb-NMh"/>
+                                        </constraints>
+                                        <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" title="No Results" id="5Sf-lz-ZAg">
+                                            <font key="font" metaFont="systemSemibold" size="14"/>
+                                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
+                                            <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                    </textField>
+                                </subviews>
+                                <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="RZV-VM-ubG" secondAttribute="trailing" constant="10" id="C59-AL-Mzh"/>
+                                    <constraint firstItem="RZV-VM-ubG" firstAttribute="leading" secondItem="Vwh-uE-n99" secondAttribute="leading" constant="10" id="I0V-zQ-d37"/>
+                                    <constraint firstAttribute="bottom" secondItem="RZV-VM-ubG" secondAttribute="bottom" id="Tgc-kv-esu"/>
+                                    <constraint firstItem="RZV-VM-ubG" firstAttribute="top" secondItem="fCc-bq-sMR" secondAttribute="bottom" constant="16" id="af2-pO-ZDN"/>
+                                    <constraint firstItem="fCc-bq-sMR" firstAttribute="centerX" secondItem="Vwh-uE-n99" secondAttribute="centerX" id="eQi-pW-kKz"/>
+                                    <constraint firstItem="RZV-VM-ubG" firstAttribute="centerX" secondItem="Vwh-uE-n99" secondAttribute="centerX" id="ep9-Ce-MPS"/>
+                                    <constraint firstItem="fCc-bq-sMR" firstAttribute="top" secondItem="Vwh-uE-n99" secondAttribute="top" id="kvQ-Cb-2Fg"/>
+                                </constraints>
+                            </customView>
+                        </subviews>
+                        <constraints>
+                            <constraint firstItem="Vwh-uE-n99" firstAttribute="centerX" secondItem="fz0-9N-dbN" secondAttribute="centerX" id="GZ1-XW-XhO"/>
+                            <constraint firstItem="Vwh-uE-n99" firstAttribute="centerY" secondItem="fz0-9N-dbN" secondAttribute="centerY" id="v8f-Uo-CfG"/>
+                        </constraints>
+                    </view>
+                    <color key="borderColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                    <color key="fillColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                </box>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="2OM-I5-WuT" customClass="KMSegmentedControl" customModule="PDF_Master" customModuleProvider="target">
+                    <rect key="frame" x="184" y="480" width="50" height="25"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="50" id="4nF-ia-dJx"/>
+                        <constraint firstAttribute="height" constant="25" id="LzF-7O-4Fm"/>
+                    </constraints>
+                </customView>
+                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZGS-QS-aFB">
+                    <rect key="frame" x="14" y="484" width="40" height="17"/>
+                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Eil-0G-5lp">
+                        <font key="font" metaFont="system" size="14"/>
+                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                    </textFieldCell>
+                </textField>
+                <box boxType="custom" borderWidth="0.0" cornerRadius="1" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="m5j-WZ-WP4" customClass="KMBox">
+                    <rect key="frame" x="16" y="452" width="208" height="20"/>
+                    <view key="contentView" id="zoj-cx-Qv1">
+                        <rect key="frame" x="0.0" y="0.0" width="208" height="20"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="AuZ-iT-8Sc">
+                                <rect key="frame" x="79" y="0.0" width="50" height="20"/>
+                                <subviews>
+                                    <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="F6A-U5-mv7">
+                                        <rect key="frame" x="0.0" y="2" width="16" height="16"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="16" id="Cq1-jy-gdR"/>
+                                            <constraint firstAttribute="width" constant="16" id="akO-nn-kuV"/>
+                                        </constraints>
+                                        <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="KMImageNameUXIconBtnSearchbarSearch" id="3va-Z6-CLg"/>
+                                    </imageView>
+                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LV8-kC-pPy">
+                                        <rect key="frame" x="15" y="2" width="37" height="16"/>
+                                        <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="8F8-Ba-XlP">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                    </textField>
+                                </subviews>
+                                <constraints>
+                                    <constraint firstItem="LV8-kC-pPy" firstAttribute="leading" secondItem="F6A-U5-mv7" secondAttribute="trailing" constant="1" id="ONS-wa-eK6"/>
+                                    <constraint firstAttribute="trailing" secondItem="LV8-kC-pPy" secondAttribute="trailing" id="Y6y-4l-exs"/>
+                                    <constraint firstItem="F6A-U5-mv7" firstAttribute="leading" secondItem="AuZ-iT-8Sc" secondAttribute="leading" id="hwu-Jp-he1"/>
+                                    <constraint firstItem="F6A-U5-mv7" firstAttribute="centerY" secondItem="AuZ-iT-8Sc" secondAttribute="centerY" id="oRV-Me-PUb"/>
+                                    <constraint firstItem="LV8-kC-pPy" firstAttribute="centerY" secondItem="AuZ-iT-8Sc" secondAttribute="centerY" id="vZX-iJ-SG0"/>
+                                </constraints>
+                            </customView>
+                        </subviews>
+                        <constraints>
+                            <constraint firstItem="AuZ-iT-8Sc" firstAttribute="top" secondItem="zoj-cx-Qv1" secondAttribute="top" id="52i-Ye-JVI"/>
+                            <constraint firstAttribute="bottom" secondItem="AuZ-iT-8Sc" secondAttribute="bottom" id="5Ui-6N-ba1"/>
+                        </constraints>
+                    </view>
+                    <constraints>
+                        <constraint firstItem="AuZ-iT-8Sc" firstAttribute="centerX" secondItem="m5j-WZ-WP4" secondAttribute="centerX" id="PPE-UO-t8C"/>
+                    </constraints>
+                </box>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="hP4-NA-Ala">
+                    <rect key="frame" x="16" y="430" width="208" height="14"/>
+                    <subviews>
+                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="avX-Sl-7dw">
+                            <rect key="frame" x="-2" y="0.0" width="33" height="14"/>
+                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="aJC-Hn-dib">
+                                <font key="font" metaFont="smallSystem"/>
+                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DG6-KM-fPE">
+                            <rect key="frame" x="177" y="0.0" width="33" height="14"/>
+                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="kMU-mK-L5o">
+                                <font key="font" metaFont="smallSystem"/>
+                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="avX-Sl-7dw" firstAttribute="leading" secondItem="hP4-NA-Ala" secondAttribute="leading" id="CNl-c5-s1P"/>
+                        <constraint firstItem="DG6-KM-fPE" firstAttribute="centerY" secondItem="avX-Sl-7dw" secondAttribute="centerY" id="XAZ-BC-Zau"/>
+                        <constraint firstAttribute="bottom" secondItem="avX-Sl-7dw" secondAttribute="bottom" id="bKj-K9-CUH"/>
+                        <constraint firstItem="avX-Sl-7dw" firstAttribute="top" secondItem="hP4-NA-Ala" secondAttribute="top" id="f4d-IP-x9i"/>
+                        <constraint firstAttribute="trailing" secondItem="DG6-KM-fPE" secondAttribute="trailing" id="uCD-1a-2mT"/>
+                    </constraints>
+                </customView>
+                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Sot-lU-418">
+                    <rect key="frame" x="188" y="452" width="36" height="20"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="20" id="bAq-jA-d1x"/>
+                        <constraint firstAttribute="width" constant="36" id="nWW-zz-pQ3"/>
+                    </constraints>
+                    <buttonCell key="cell" type="square" title="Button" bezelStyle="shadowlessSquare" alignment="center" imageScaling="proportionallyDown" inset="2" id="ueG-bM-doV">
+                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                        <font key="font" metaFont="cellTitle"/>
+                    </buttonCell>
+                    <connections>
+                        <action selector="searchDomeButtonAtion:" target="-2" id="6wa-gN-8qu"/>
+                    </connections>
+                </button>
+            </subviews>
+            <constraints>
+                <constraint firstItem="hP4-NA-Ala" firstAttribute="top" secondItem="Exf-lV-10v" secondAttribute="bottom" constant="8" id="1Kg-bg-LGr"/>
+                <constraint firstItem="hP4-NA-Ala" firstAttribute="trailing" secondItem="m5j-WZ-WP4" secondAttribute="trailing" id="4if-ph-rEL"/>
+                <constraint firstItem="Exf-lV-10v" firstAttribute="top" secondItem="2OM-I5-WuT" secondAttribute="bottom" constant="8" id="Gpq-6K-sPq"/>
+                <constraint firstItem="YP3-hM-jIu" firstAttribute="centerX" secondItem="jTx-lq-IMO" secondAttribute="centerX" id="I0r-BH-fx2"/>
+                <constraint firstAttribute="trailing" secondItem="jTx-lq-IMO" secondAttribute="trailing" id="OKR-iq-2Yo"/>
+                <constraint firstItem="Sot-lU-418" firstAttribute="leading" secondItem="Exf-lV-10v" secondAttribute="trailing" constant="8" id="PHH-tq-U24"/>
+                <constraint firstAttribute="trailing" secondItem="m5j-WZ-WP4" secondAttribute="trailing" constant="16" id="RpE-ng-ElP"/>
+                <constraint firstItem="ZGS-QS-aFB" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="SOD-0k-NPp"/>
+                <constraint firstItem="YP3-hM-jIu" firstAttribute="height" secondItem="jTx-lq-IMO" secondAttribute="height" id="Swr-lv-cAz"/>
+                <constraint firstItem="m5j-WZ-WP4" firstAttribute="leading" secondItem="Exf-lV-10v" secondAttribute="leading" id="Vnk-Pc-Nhr"/>
+                <constraint firstItem="hP4-NA-Ala" firstAttribute="leading" secondItem="m5j-WZ-WP4" secondAttribute="leading" id="Wgl-cP-RDF"/>
+                <constraint firstItem="m5j-WZ-WP4" firstAttribute="top" secondItem="Exf-lV-10v" secondAttribute="top" id="Wm2-5T-Veu"/>
+                <constraint firstAttribute="trailing" secondItem="Sot-lU-418" secondAttribute="trailing" constant="16" id="XMf-el-u9F"/>
+                <constraint firstItem="2OM-I5-WuT" firstAttribute="centerY" secondItem="ZGS-QS-aFB" secondAttribute="centerY" id="Z3A-Y9-HK5"/>
+                <constraint firstItem="2OM-I5-WuT" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="8" id="d8L-Cb-uC8"/>
+                <constraint firstItem="YP3-hM-jIu" firstAttribute="width" secondItem="jTx-lq-IMO" secondAttribute="width" id="g2b-zR-cbj"/>
+                <constraint firstItem="Sot-lU-418" firstAttribute="centerY" secondItem="Exf-lV-10v" secondAttribute="centerY" id="gac-i5-Jlm"/>
+                <constraint firstItem="m5j-WZ-WP4" firstAttribute="top" secondItem="2OM-I5-WuT" secondAttribute="bottom" constant="8" id="gbI-es-zpr"/>
+                <constraint firstAttribute="trailing" secondItem="2OM-I5-WuT" secondAttribute="trailing" constant="6" id="o9z-IY-CCJ"/>
+                <constraint firstItem="jTx-lq-IMO" firstAttribute="top" secondItem="hP4-NA-Ala" secondAttribute="bottom" constant="8" id="oi4-Ow-iIw"/>
+                <constraint firstItem="Exf-lV-10v" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="qE5-qt-cCi"/>
+                <constraint firstItem="jTx-lq-IMO" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="ski-kz-g2S"/>
+                <constraint firstItem="m5j-WZ-WP4" firstAttribute="bottom" secondItem="Exf-lV-10v" secondAttribute="bottom" id="slj-io-4Ku"/>
+                <constraint firstItem="YP3-hM-jIu" firstAttribute="centerY" secondItem="jTx-lq-IMO" secondAttribute="centerY" id="vqG-Le-4nc"/>
+                <constraint firstAttribute="bottom" secondItem="jTx-lq-IMO" secondAttribute="bottom" id="yHi-h2-Tme"/>
+            </constraints>
+            <point key="canvasLocation" x="-17" y="129.5"/>
+        </customView>
+        <userDefaultsController representsSharedInstance="YES" id="vA0-OE-D4s"/>
+    </objects>
+    <resources>
+        <image name="KMImageNameEmptySearch" width="140" height="140"/>
+        <image name="KMImageNameUXIconBtnSearchbarSearch" width="16" height="16"/>
+    </resources>
+</document>

+ 22 - 0
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Search/View/KMFindTableviewCell.swift

@@ -0,0 +1,22 @@
+//
+//  KMFindTableviewCell.swift
+//  PDF Master
+//
+//  Created by tangchao on 2023/11/17.
+//
+
+import Cocoa
+
+class KMFindTableviewCell: NSTableCellView {
+    @IBOutlet var resultLabel: NSTextField!
+
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        
+        self.wantsLayer = true
+        self.layer?.backgroundColor = .clear
+        self.layer?.cornerRadius = 0.0
+        
+        self.resultLabel.textColor = KMAppearance.Layout.h0Color()
+    }
+}

+ 5 - 5
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift

@@ -15,8 +15,8 @@ extension KMMainViewController {
         }
         if searchString == "" {
             self.searchResults = []
-            self.leftSideViewController.searchViewController.searchResults = self.searchResults
-            self.leftSideViewController.searchViewController.reloadData()
+//            self.leftSideViewController.searchViewController.searchResults = self.searchResults
+//            self.leftSideViewController.searchViewController.reloadData()
         } else {
             mwcFlags.wholeWordSearch = isCase == true ? 1 : 0
             var findArray : [[CPDFSelection]]
@@ -35,8 +35,8 @@ extension KMMainViewController {
                     self.searchResults.insert(mode, at: self.searchResults.count)
                 }
             }
-            self.leftSideViewController.searchViewController.searchResults = self.searchResults
-            self.leftSideViewController.searchViewController.reloadData()
+//            self.leftSideViewController.searchViewController.searchResults = self.searchResults
+//            self.leftSideViewController.searchViewController.reloadData()
         }
     }
     
@@ -1769,7 +1769,7 @@ extension KMMainViewController {
         
         //BOTA 注释列表显示隐藏
         self.leftSideViewController.annotationViewController.annotationShowState = self.listView.hideNotes ? .hidden : .none
-        self.leftSideViewController.thumbnailViewController.annotationShowState = self.listView.hideNotes ? .hidden : .none
+//        self.leftSideViewController.thumbnailViewController.annotationShowState = self.listView.hideNotes ? .hidden : .none
     }
     
     func closeTab(_ sender: NSNotification) -> Void {

+ 0 - 23
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+UI.swift

@@ -74,29 +74,6 @@ extension KMMainViewController {
             self.readContentView.addSubview(self.tipCurrentPageBox, positioned: .above, relativeTo: self.readContentView)
         }
     }
-    
-    // MARK: - Left Side
-
-    func displayThumbnailViewAnimating(_ animate: Bool) {
-        self.leftSideViewController.replaceSideView(self.leftSideViewController.thumbnailTableView.enclosingScrollView!, animate: animate)
-        
-        var frame = self.leftSideViewController.thumbnailTableView.enclosingScrollView?.frame ?? .zero
-        frame.origin.y = 0
-        frame.size.height = self.leftSideViewController.thumbnailTableView.enclosingScrollView?.superview?.frame.size.height ?? 0
-        self.leftSideViewController.thumbnailTableView.enclosingScrollView?.frame = frame
-        
-//        frame = rightSideController.noteOutlineView.enclosingScrollView.frame;
-//        frame.origin.y = 0;
-//        frame.size.height = rightSideController.noteOutlineView.enclosingScrollView.superview.frame.size.height;
-//        rightSideController.noteOutlineView.enclosingScrollView.frame = frame;
-        
-//        frame = rightSideController.snapshotTableView.enclosingScrollView.frame;
-//        frame.origin.y = 0;
-//        frame.size.height = rightSideController.snapshotTableView.enclosingScrollView.superview.frame.size.height;
-//        rightSideController.snapshotTableView.enclosingScrollView.frame = frame;
-        
-//        [self updateThumbnailSelection];
-    }
 }
 
 extension KMMainViewController: KMToolbarControllerDelegate {

+ 1 - 5
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController.swift

@@ -359,14 +359,10 @@ import Cocoa
         #if VERSION_DMG
         KMResourceDownloadManager.manager.checkDocumentAIVersion()
         #endif
-        
-        self.displayThumbnailViewAnimating(false)
     }
        
     //MARK: - KMToolbarViewControllerDelegate
     
-    
-    
     //MARK: - PDFListView
     func initPDFLeftViewVC() {
         leftSideViewController.listView = self.listView ?? CPDFListView()
@@ -600,7 +596,7 @@ import Cocoa
                 indexSet.insert(indexPath.item)
             }
             if indexSet.count != 0 {
-                self?.leftSideViewController.thumbnailViewController.selectPages(indexs: indexSet, needScroll: true)
+//                self?.leftSideViewController.thumbnailViewController.selectPages(indexs: indexSet, needScroll: true)
 //                self?.listView.go(toPageIndex: indexSet.first!, animated: false)
             }
         }