Parcourir la source

标记密文-跨页面重复标记密文窗口和其功能的实现

tangchao il y a 2 ans
Parent
commit
c2fb07e062

+ 16 - 0
PDF Office/PDF Office.xcodeproj/project.pbxproj

@@ -1552,6 +1552,12 @@
 		BBB14A532978DD5400936EDB /* KMRedactTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A522978DD5400936EDB /* KMRedactTools.swift */; };
 		BBB14A542978DD5400936EDB /* KMRedactTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A522978DD5400936EDB /* KMRedactTools.swift */; };
 		BBB14A552978DD5400936EDB /* KMRedactTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A522978DD5400936EDB /* KMRedactTools.swift */; };
+		BBB14A572978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A562978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift */; };
+		BBB14A582978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A562978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift */; };
+		BBB14A592978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A562978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift */; };
+		BBB14A5B2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A5A2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift */; };
+		BBB14A5C2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A5A2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift */; };
+		BBB14A5D2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB14A5A2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift */; };
 		BBC2BCC6295DA8F30036B983 /* KMCropPreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC2BCC4295DA8F30036B983 /* KMCropPreviewController.swift */; };
 		BBC2BCC7295DA8F30036B983 /* KMCropPreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC2BCC4295DA8F30036B983 /* KMCropPreviewController.swift */; };
 		BBC2BCC8295DA8F30036B983 /* KMCropPreviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC2BCC4295DA8F30036B983 /* KMCropPreviewController.swift */; };
@@ -2638,6 +2644,8 @@
 		BBA8B7AE293600D70097D183 /* KMPasswordInputWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPasswordInputWindow.swift; sourceTree = "<group>"; };
 		BBA8B7B2293635D80097D183 /* KMPasswordInputWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMPasswordInputWindow.xib; sourceTree = "<group>"; };
 		BBB14A522978DD5400936EDB /* KMRedactTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMRedactTools.swift; sourceTree = "<group>"; };
+		BBB14A562978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMRedactMutilPageFlagWindowController.swift; sourceTree = "<group>"; };
+		BBB14A5A2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMRedactMutilPageFlagContentView.swift; sourceTree = "<group>"; };
 		BBC2BCC4295DA8F30036B983 /* KMCropPreviewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMCropPreviewController.swift; sourceTree = "<group>"; };
 		BBC2BCC5295DA8F30036B983 /* KMCropPreviewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMCropPreviewController.xib; sourceTree = "<group>"; };
 		BBC347FC295448DE008D2CD1 /* KMWatermarkTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMWatermarkTemplateModel.swift; sourceTree = "<group>"; };
@@ -4403,6 +4411,7 @@
 				BB4EEF3B29764578003A3537 /* KMRedactPropertyContentView.swift */,
 				BB4EEF472976504C003A3537 /* KMRedactColorView.swift */,
 				BB4EEF4B2976544F003A3537 /* KMRedactAligementView.swift */,
+				BBB14A5A2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -4459,6 +4468,7 @@
 				BB4EEF3329764166003A3537 /* KMRedactPropertyWindowController.swift */,
 				BB24D4A52977BE6700041659 /* KMRedactConfirmWindowController.swift */,
 				BB24D4A62977BE6700041659 /* KMRedactConfirmWindowController.xib */,
+				BBB14A562978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift */,
 			);
 			path = Window;
 			sourceTree = "<group>";
@@ -6211,6 +6221,7 @@
 				89DB5DA9291B8DE70029624F /* KMOutlineEditViewController.swift in Sources */,
 				BB6DD80C29347F77001F0544 /* KMSecureEncryptWindowController.swift in Sources */,
 				F3732311292DF9410013862C /* CPDFSignatureWidgetAnnotation+PDFListView.m in Sources */,
+				BBB14A572978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */,
 				899E0B092919244500B13D34 /* KMCustomTableRowView.swift in Sources */,
 				BB89722E294B08DE0045787C /* KMWatermarkViewController.swift in Sources */,
 				89E9B406295D268E00AEFA61 /* KMEditImagePropertyViewController.swift in Sources */,
@@ -6315,6 +6326,7 @@
 				BBF38A5E294F42FF0086D025 /* KMWatermarkAdjectiveStepper.swift in Sources */,
 				BB1EC7FE2967B26700EC0BC3 /* KMPDFEditViewController.swift in Sources */,
 				89752DB82936F9B9003FF08E /* NSButton+TitleColor.m in Sources */,
+				BBB14A5B2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift in Sources */,
 				9F1FE4B729406E4700E952CA /* CTBrowserFrameView.m in Sources */,
 				ADCB98C92924741B00B51A03 /* KMBatchProcessingView.swift in Sources */,
 				BB4EEF3C29764578003A3537 /* KMRedactPropertyContentView.swift in Sources */,
@@ -6693,6 +6705,7 @@
 				ADCB98D22924771600B51A03 /* KMBatchProcessingNameTableCell.swift in Sources */,
 				F34BF9542953DA91002C25A2 /* NSGeometry+PDFListView.m in Sources */,
 				89D2D30429504E5E00BFF5FE /* KMSharingServicePicker+ESSSharingServicePickerMenu.m in Sources */,
+				BBB14A582978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */,
 				ADCB9908292B6AC000B51A03 /* KMImageToPDFChooseModel.swift in Sources */,
 				BB8B17332907B63D001C5EA5 /* CipherTextView.swift in Sources */,
 				89E9B407295D268E00AEFA61 /* KMEditImagePropertyViewController.swift in Sources */,
@@ -6797,6 +6810,7 @@
 				BB2C6ACE28F41B9F00478A33 /* CPDFListView.m in Sources */,
 				BB1EC7FF2967B26700EC0BC3 /* KMPDFEditViewController.swift in Sources */,
 				9F1FE4E529406E4700E952CA /* GTMNSColor+Luminance.m in Sources */,
+				BBB14A5C2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift in Sources */,
 				ADCB996C292C65EE00B51A03 /* KMGOCRManager.m in Sources */,
 				89752DB92936F9B9003FF08E /* NSButton+TitleColor.m in Sources */,
 				BB4EEF3D29764578003A3537 /* KMRedactPropertyContentView.swift in Sources */,
@@ -7169,10 +7183,12 @@
 				899700F828F4051B009AF911 /* KMAnnotationViewController.swift in Sources */,
 				ADB1FE4A2970264500ED072D /* KMBatchCollectionViewPrensenter.swift in Sources */,
 				F36AD77929642FE80015AD53 /* CPDFListView+UndoManager.m in Sources */,
+				BBB14A5D2978EBBE00936EDB /* KMRedactMutilPageFlagContentView.swift in Sources */,
 				8942F7C12923670F00389627 /* KMBOTAManagerClass.swift in Sources */,
 				ADCB98F829274B6B00B51A03 /* KMBatchProcessingTableView.swift in Sources */,
 				89E4E75C296429CF002DBA6F /* NSShadow_SKExtensions.m in Sources */,
 				F37322F5292DF9410013862C /* CSelfSignAnnotationFreeText.m in Sources */,
+				BBB14A592978E75D00936EDB /* KMRedactMutilPageFlagWindowController.swift in Sources */,
 				899700E128F3A9F2009AF911 /* KMHomeWindowController.swift in Sources */,
 				89D2D30529504E5E00BFF5FE /* KMSharingServicePicker+ESSSharingServicePickerMenu.m in Sources */,
 				BB8F4578295AFA2D0037EA22 /* KMHeaderFooterAdjectiveInfoBaseView.swift in Sources */,

BIN
PDF Office/PDF Office.xcodeproj/project.xcworkspace/xcuserdata/kdanmobile.xcuserdatad/UserInterfaceState.xcuserstate


+ 16 - 0
PDF Office/PDF Office.xcodeproj/xcuserdata/kdanmobile.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -276,5 +276,21 @@
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "BC6672F7-B3CC-4061-83B5-0BBEA7C01DB3"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "PDF Office/Class/PDFWindowController/PDFListView/CPDFListView.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "239"
+            endingLineNumber = "239"
+            landmarkName = "-addAnnotationWithType:selection:page:bounds:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>

+ 7 - 4
PDF Office/PDF Office/Class/PDFTools/Redact/Base/KMRedactBaseWindowController.swift

@@ -20,12 +20,15 @@ class KMRedactBaseWindowController: NSWindowController {
     @IBOutlet weak var contentHeightConst: NSLayoutConstraint!
     
     var contentView: KMRedactContentBaseView!
+    var pageCount: Int = 0
     
     var annotation: CPDFRedactAnnotation?
-    convenience init(_ annotation: CPDFRedactAnnotation?) {
-        self.init(windowNibName: "KMRedactBaseWindowController")
-        self.annotation = annotation
-    }
+//    class func init(_ annotation: CPDFRedactAnnotation?) {
+//        self.init(windowNibName: "KMRedactBaseWindowController")
+//        self.annotation = annotation
+//    }
+//    func initWithWindowNibName
+    
     
     var itemClick: KMRedactBaseWindowItemClick!
     

+ 88 - 2
PDF Office/PDF Office/Class/PDFTools/Redact/Base/KMRedactBaseWindowController.xib

@@ -10,8 +10,8 @@
             <connections>
                 <outlet property="cancelButton" destination="24f-Hm-50n" id="4CK-Lc-R5o"/>
                 <outlet property="contentBox" destination="Rag-Ok-KH1" id="oOm-bf-2K0"/>
-                <outlet property="contentHeightConst" destination="IN9-TF-mcW" id="fEt-WU-k6a"/>
-                <outlet property="contentWidthConst" destination="BGp-bj-uNG" id="Ycg-RL-RzR"/>
+                <outlet property="contentHeightConst" destination="BGp-bj-uNG" id="BRu-4d-PkE"/>
+                <outlet property="contentWidthConst" destination="IN9-TF-mcW" id="2Bg-yE-Oyj"/>
                 <outlet property="funcButton" destination="4HG-ei-BTS" id="BJX-EP-tBq"/>
                 <outlet property="titleLabel" destination="SGk-C0-wVt" id="Gwe-SR-1M6"/>
                 <outlet property="topLine" destination="SjR-bh-aVa" id="MHd-Uv-cXV"/>
@@ -371,5 +371,91 @@
             </connections>
             <point key="canvasLocation" x="168" y="570"/>
         </customView>
+        <customView id="RXY-U8-FFz" customClass="KMRedactMutilPageFlagContentView" customModule="PDF_Office" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="404" height="221"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8U4-aQ-fd2">
+                    <rect key="frame" x="14" y="174" width="61" height="18"/>
+                    <buttonCell key="cell" type="radio" title="Radio" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="R0y-Jx-4jl">
+                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                        <font key="font" metaFont="system"/>
+                    </buttonCell>
+                </button>
+                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hmb-2v-ENI">
+                    <rect key="frame" x="14" y="145" width="61" height="18"/>
+                    <buttonCell key="cell" type="radio" title="Radio" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="DqD-6X-ypD">
+                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                        <font key="font" metaFont="system"/>
+                    </buttonCell>
+                </button>
+                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6lp-co-Lhs">
+                    <rect key="frame" x="14" y="116" width="61" height="18"/>
+                    <buttonCell key="cell" type="radio" title="Radio" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="vTE-95-90f">
+                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                        <font key="font" metaFont="system"/>
+                    </buttonCell>
+                </button>
+                <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Wtr-Y4-bag">
+                    <rect key="frame" x="14" y="87" width="61" height="18"/>
+                    <buttonCell key="cell" type="radio" title="Radio" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="val-w1-t9H">
+                        <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                        <font key="font" metaFont="system"/>
+                    </buttonCell>
+                </button>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="862-GZ-ikw">
+                    <rect key="frame" x="87" y="80" width="140" height="32"/>
+                    <subviews>
+                        <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0GQ-6B-8nf">
+                            <rect key="frame" x="14" y="8" width="112" height="16"/>
+                            <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" id="GBO-Dv-cSf">
+                                <font key="font" usesAppearanceFont="YES"/>
+                                <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                    </subviews>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="140" id="2bN-p8-lXR"/>
+                        <constraint firstAttribute="height" constant="32" id="QBo-hk-1Er"/>
+                        <constraint firstAttribute="trailing" secondItem="0GQ-6B-8nf" secondAttribute="trailing" constant="16" id="Qpd-VF-gNA"/>
+                        <constraint firstItem="0GQ-6B-8nf" firstAttribute="centerY" secondItem="862-GZ-ikw" secondAttribute="centerY" id="d35-aD-1yF"/>
+                        <constraint firstItem="0GQ-6B-8nf" firstAttribute="leading" secondItem="862-GZ-ikw" secondAttribute="leading" constant="16" id="tGQ-jD-lLE"/>
+                    </constraints>
+                </customView>
+                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bbh-sk-rmJ">
+                    <rect key="frame" x="237" y="88" width="37" height="16"/>
+                    <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="odo-Ls-2nb">
+                        <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="6lp-co-Lhs" firstAttribute="leading" secondItem="RXY-U8-FFz" secondAttribute="leading" constant="16" id="1vm-ew-NFe"/>
+                <constraint firstItem="8U4-aQ-fd2" firstAttribute="top" secondItem="RXY-U8-FFz" secondAttribute="top" constant="30" id="3Mh-pK-pul"/>
+                <constraint firstItem="Bbh-sk-rmJ" firstAttribute="leading" secondItem="862-GZ-ikw" secondAttribute="trailing" constant="12" id="73k-Qh-1Le"/>
+                <constraint firstItem="8U4-aQ-fd2" firstAttribute="leading" secondItem="RXY-U8-FFz" secondAttribute="leading" constant="16" id="7f3-DF-Aqh"/>
+                <constraint firstItem="862-GZ-ikw" firstAttribute="leading" secondItem="Wtr-Y4-bag" secondAttribute="trailing" constant="12" id="Ioj-HP-Wi5"/>
+                <constraint firstItem="6lp-co-Lhs" firstAttribute="top" secondItem="hmb-2v-ENI" secondAttribute="bottom" constant="13" id="Kz9-Ej-pIv"/>
+                <constraint firstItem="Wtr-Y4-bag" firstAttribute="top" secondItem="6lp-co-Lhs" secondAttribute="bottom" constant="13" id="Loc-UM-qLn"/>
+                <constraint firstItem="862-GZ-ikw" firstAttribute="centerY" secondItem="Wtr-Y4-bag" secondAttribute="centerY" id="Nex-WE-2RT"/>
+                <constraint firstItem="hmb-2v-ENI" firstAttribute="top" secondItem="8U4-aQ-fd2" secondAttribute="bottom" constant="13" id="PG7-CM-p4a"/>
+                <constraint firstItem="Wtr-Y4-bag" firstAttribute="leading" secondItem="RXY-U8-FFz" secondAttribute="leading" constant="16" id="RPQ-1f-k9u"/>
+                <constraint firstItem="hmb-2v-ENI" firstAttribute="leading" secondItem="RXY-U8-FFz" secondAttribute="leading" constant="16" id="jwF-Lk-ZhH"/>
+                <constraint firstItem="Bbh-sk-rmJ" firstAttribute="centerY" secondItem="862-GZ-ikw" secondAttribute="centerY" id="vDC-Of-d56"/>
+            </constraints>
+            <connections>
+                <outlet property="allPageRadio" destination="8U4-aQ-fd2" id="okd-rJ-wXQ"/>
+                <outlet property="customPageRadio" destination="Wtr-Y4-bag" id="XPK-DT-3Yo"/>
+                <outlet property="evenPageRadio" destination="6lp-co-Lhs" id="mtn-1E-aNX"/>
+                <outlet property="inputTextField" destination="0GQ-6B-8nf" id="6XX-Hg-Y9s"/>
+                <outlet property="inputView" destination="862-GZ-ikw" id="byF-l8-Fub"/>
+                <outlet property="oddPageRadio" destination="hmb-2v-ENI" id="2pB-gn-oKX"/>
+                <outlet property="totalPageNumberLabel" destination="Bbh-sk-rmJ" id="TfO-fG-uVD"/>
+            </connections>
+            <point key="canvasLocation" x="109" y="959"/>
+        </customView>
     </objects>
 </document>

+ 43 - 0
PDF Office/PDF Office/Class/PDFTools/Redact/Tools/KMRedactTools.swift

@@ -26,4 +26,47 @@ class KMRedactTools: NSObject {
         
         callback(true, nil)
     }
+    
+    class func getPageIndexs(_ type: Int, string: String, _ pageCount: Int) -> IndexSet {
+        var indexs: IndexSet = []
+        if (type == 1) { /// 所有页面
+            for i in 0 ..< pageCount {
+                indexs.insert(i)
+            }
+        } else if (type == 2) { /// 奇数页
+            for i in 0 ..< pageCount {
+                if (i % 2 == 1) {
+                    continue
+                }
+                indexs.insert(i)
+            }
+        } else if (type == 3) { /// 偶数页
+            for i in 0 ..< pageCount {
+                if (i % 2 == 0) {
+                    continue
+                }
+                indexs.insert(i)
+            }
+        } else if (type == 4) {
+            let array = KMPageRangeTools.findSelectPage(pageRangeString: string, pageCount: pageCount)
+            for i in array {
+                indexs.insert(i)
+            }
+        }
+        return indexs
+    }
+    
+    class func createRedactAnnotation(_ document: CPDFDocument, _ anno: CPDFRedactAnnotation) -> CPDFRedactAnnotation {
+        let redactAnno = CPDFRedactAnnotation(document: document)
+        redactAnno?.setInteriorColor(anno.interiorColor())
+        redactAnno?.setBorderColor(anno.borderColor())
+        redactAnno?.setOverlayText(anno.overlayText())
+        redactAnno?.setFontColor(anno.fontColor())
+        redactAnno?.setAlignment(anno.alignment())
+        redactAnno?.setFont(anno.font())
+        
+        redactAnno?.bounds = anno.bounds
+        
+        return redactAnno!
+    }
 }

+ 97 - 0
PDF Office/PDF Office/Class/PDFTools/Redact/View/KMRedactMutilPageFlagContentView.swift

@@ -0,0 +1,97 @@
+//
+//  KMRedactMutilPageFlagContentView.swift
+//  PDF Office
+//
+//  Created by tangchao on 2023/1/19.
+//
+
+import Cocoa
+
+class KMRedactMutilPageFlagContentView: KMRedactContentBaseView {
+
+    @IBOutlet weak var allPageRadio: NSButton!
+    @IBOutlet weak var oddPageRadio: NSButton!
+    @IBOutlet weak var evenPageRadio: NSButton!
+    @IBOutlet weak var customPageRadio: NSButton!
+    @IBOutlet weak var inputView: NSView!
+    @IBOutlet weak var inputTextField: NSTextField!
+    @IBOutlet weak var totalPageNumberLabel: NSTextField!
+    
+    var pageCount: Int {
+        get {
+            -1
+        }
+        set {
+            self.totalPageNumberLabel.stringValue = "/\(newValue)"
+        }
+    }
+    
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        self.allPageRadio.title = "所有页面"
+        self.oddPageRadio.title = "奇数页"
+        self.evenPageRadio.title = "偶数页"
+        self.customPageRadio.title = "指定页面范围"
+        
+        for radio in [self.allPageRadio, self.oddPageRadio, self.evenPageRadio, self.customPageRadio] {
+            radio?.target = self
+            radio?.action = #selector(radioAction)
+        }
+        
+        selectRadio(self.allPageRadio)
+        
+        self.inputView.wantsLayer = true
+        self.inputView.layer?.backgroundColor = NSColor(white: 238.0/255.0, alpha: 1.0).cgColor
+        self.inputTextField.placeholderString = "eg. 1,3-5,10"
+        self.inputTextField.focusRingType = .none
+        self.inputTextField.delegate = self
+    }
+    
+    @objc private func radioAction(sender: NSButton) {
+        selectRadio(sender)
+        
+        guard let callback = self.itemClick else {
+            return
+        }
+        
+        var index: Int = 1
+        for radio in [self.allPageRadio, self.oddPageRadio, self.evenPageRadio, self.customPageRadio] {
+            if ((radio?.isEqual(to: sender))!) {
+                break
+            }
+            index += 1
+        }
+        
+        callback(index, nil)
+    }
+    
+    private func selectRadio(_ selectedRadio: NSButton) {
+        for radio in [self.allPageRadio, self.oddPageRadio, self.evenPageRadio, self.customPageRadio] {
+            if ((radio?.isEqual(to: selectedRadio))!) {
+                radio?.state = .on
+            } else {
+                radio?.state = .off
+            }
+        }
+        
+        if (customPageRadio.state == .on) {
+            self.inputTextField.isEditable = true
+        } else {
+            self.inputTextField.isEditable = false
+        }
+    }
+}
+
+extension KMRedactMutilPageFlagContentView: NSTextFieldDelegate {
+    func controlTextDidChange(_ obj: Notification) {
+        if ((self.inputTextField.isEqual(to: obj.object)) == false) {
+            return
+        }
+        
+        guard let callback = self.itemClick else {
+            return
+        }
+        callback(5, self.inputTextField.stringValue)
+    }
+}

+ 48 - 0
PDF Office/PDF Office/Class/PDFTools/Redact/Window/KMRedactMutilPageFlagWindowController.swift

@@ -0,0 +1,48 @@
+//
+//  KMRedactMutilPageFlagWindowController.swift
+//  PDF Office
+//
+//  Created by tangchao on 2023/1/19.
+//
+
+import Cocoa
+
+class KMRedactMutilPageFlagWindowController: KMRedactBaseWindowController {
+
+    var pageType: Int = 1
+    var pageString: String = ""
+    
+    override func windowDidLoad() {
+        super.windowDidLoad()
+    
+        self.setContentSize(NSSize(width: 404, height: 266))
+        
+        self.titleLabel.stringValue = "跨页面重复标记密文"
+        self.funcButton.title = NSLocalizedString("确认", comment: "")
+        self.funcButton.layer?.backgroundColor = NSColor.black.cgColor
+        self.funcButton.attributedTitle = NSMutableAttributedString(string: self.funcButton.title, attributes: [NSAttributedString.Key.foregroundColor : NSColor.white])
+        
+        
+        let contentView = KMRedactMutilPageFlagContentView.createFromNib()
+        contentView?.frame = self.contentBox.contentView!.bounds
+        contentView?.autoresizingMask = [.width,.height]
+        self.contentBox.contentView?.addSubview(contentView!)
+        self.contentView = contentView
+        contentView?.pageCount = self.pageCount
+        
+        contentView?.itemClick = {[weak self] index, value in
+            if (index == 1) { /// 所有页面
+                self!.pageType = 1
+            } else if (index == 2) { /// 奇数页
+                self!.pageType = 2
+            } else if (index == 3) { /// 偶数页
+                self!.pageType = 3
+            } else if (index == 4) { /// 自定义页面范围
+                self!.pageType = 4
+            } else if (index == 5) { /// 自定义页面范围输入
+                self?.pageString = value as! String
+            }
+        }
+    }
+
+}

+ 44 - 1
PDF Office/PDF Office/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift

@@ -459,7 +459,8 @@ extension KMMainViewController {
     }
     
     @objc func redact_menuItemClick_setProperty(sender: NSMenuItem?) {
-        let windowController = KMRedactPropertyWindowController((self.listView.activeAnnotation as! CPDFRedactAnnotation))
+        let windowController = KMRedactPropertyWindowController(windowNibName: "KMRedactBaseWindowController")
+        windowController.annotation = (self.listView.activeAnnotation as! CPDFRedactAnnotation)
         self.view.window?.beginSheet(windowController.window!)
         self.currentWindowController = windowController
         windowController.itemClick = { [weak self] index, value in
@@ -508,7 +509,49 @@ extension KMMainViewController {
     }
     
     @objc func redact_menuItemClick_MultiPageFlag(sender: NSMenuItem?) {
+        let anno = self.listView.activeAnnotation
+        if (anno == nil || (anno?.isKind(of: CPDFRedactAnnotation.self)) == false) {
+            return
+        }
         
+        let windowController = KMRedactMutilPageFlagWindowController(windowNibName: "KMRedactBaseWindowController")
+        windowController.pageCount = Int(self.listView.document.pageCount)
+        self.currentWindowController = windowController
+        self.view.window?.beginSheet(windowController.window!)
+        windowController.itemClick = { [weak self] index, value in
+            if (index == 1) {
+                self!.view.window?.endSheet(self!.currentWindowController.window!)
+                self!.currentWindowController = nil
+                return
+            }
+            
+            let windowController_mutilPageFlag = self?.currentWindowController as! KMRedactMutilPageFlagWindowController
+            let pageType = windowController_mutilPageFlag.pageType
+            let pageString = windowController_mutilPageFlag.pageString
+            if (pageType == 4) { /// 自定义页面
+                let array = KMPageRangeTools.findSelectPage(pageRangeString: pageString, pageCount: Int((self?.listView.document.pageCount)!))
+                if (array.count == 0) {
+                    let alert = NSAlert()
+                    alert.messageText = "页面范围有误"
+                    alert.runModal()
+                    return
+                }
+            }
+            
+            self!.view.window?.endSheet(self!.currentWindowController.window!)
+            self!.currentWindowController = nil
+            
+            let indexs = KMRedactTools.getPageIndexs(pageType, string: pageString, Int((self?.listView.document.pageCount)!))
+            if (indexs.count == 0) {
+                return
+            }
+            
+            for i in indexs {
+                let page: CPDFPage = (self?.listView.document.page(at: UInt(i)))!
+                let redactAnno = KMRedactTools.createRedactAnnotation((self?.listView.document)!, anno as! CPDFRedactAnnotation)
+                self?.listView.add(redactAnno, to: page)
+            }
+        }
     }
     
     @objc func redact_menuItemClick_apply(sender: NSMenuItem?) {