Browse Source

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

niehaoyu 2 months ago
parent
commit
cc5f05003f
45 changed files with 1515 additions and 675 deletions
  1. 3 3
      PDF Office/PDF Master/Class/PDFTools/Compress/Manager/KMCompressManager.swift
  2. 67 2
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFMarkupAnnotation+PDFListView.swift
  3. 11 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/Fill/CSelfSignAnnotation+PDFListView.swift
  4. 12 1
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFListViewExtension/CPDFListView+AnnotationsCompare.swift
  5. 85 26
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFListViewExtension/CPDFListView+Event.m
  6. 3 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.h
  7. 7 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.m
  8. BIN
      PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/ComPDFKit
  9. BIN
      PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/Assets.car
  10. BIN
      PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/CPDFUnlockViewController.nib/keyedobjects-101300.nib
  11. BIN
      PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/CPDFUnlockViewController.nib/keyedobjects.nib
  12. 7 7
      PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/Info.plist
  13. BIN
      PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/default.metallib
  14. 15 15
      PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/_CodeSignature/CodeResources
  15. 9 0
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Tools/KMNoteReplyHanddler.swift
  16. 41 10
      PDF Office/PDF Master/KMClass/KMPDFViewController/KMMainViewController.swift
  17. 12 0
      PDF Office/PDF Master/KMClass/KMPDFViewController/KMPDFMenuConfig.swift
  18. 0 2
      PDF Office/PDF Master/KMClass/KMPDFViewController/RightSideController/Views/OCR/Tool/Manager/KMOCRManager.swift
  19. 2 0
      PDF Office/PDF Master/KMClass/KMPDFViewController/Toolbar/Model/KMPDFToolbarManager.swift
  20. 15 0
      PDF Office/PDF Master/KMClass/Left/Annotaion/Controller/KMLeftSideViewController+Note.swift
  21. 382 47
      PDF Office/PDF Master/KMClass/Left/Annotaion/Controller/KMLeftSideViewController.swift
  22. 2 0
      PDF Office/PDF Master/KMClass/Left/Annotaion/Model/KMAnnotationModel.swift
  23. 24 0
      PDF Office/PDF Master/KMClass/Left/Annotaion/View/KMBotaTableRowView.swift
  24. 1 1
      PDF Office/PDF Master/KMClass/Left/Annotaion/View/KMNoteFooterCellView.swift
  25. 0 20
      PDF Office/PDF Master/KMClass/NewBatch/KMBatchManager/KMBatchManager.swift
  26. 3 1
      PDF Office/PDF Master/KMClass/NewBatch/KMBatchWindowController.swift
  27. 643 0
      PDF Office/PDF Master/KMClass/NewBatch/Manager/KMBatchManager.swift
  28. 12 0
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/KMBatchProcessingView.swift
  29. 2 1
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/KMBatchProcessingTableViewModel/KMBatchProcessingTableViewModel.swift
  30. 17 1
      PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingStateTableCell.swift
  31. 9 0
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/BatchRemove/KMBatchRemoveView.swift
  32. 9 0
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/Compress/KMBatchCompressView.swift
  33. 9 0
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/ConvertPDF/KMBatchConvertPDFView.swift
  34. 13 0
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/KMBatchBatchSettingItemView/KMBatchSettingItemView.swift
  35. 9 487
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/KMBatchSettingView.swift
  36. 9 0
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/OCR/KMBatchOCRView.swift
  37. 9 0
      PDF Office/PDF Master/KMClass/NewBatch/View/Setting/Security/KMBatchSecurityView.swift
  38. 4 1
      PDF Office/PDF Master/KMClass/PDFListView/Mode/KMNAnnotationPopMode.swift
  39. 4 4
      PDF Office/PDF Master/KMClass/PDFListView/ViewController/KMNPopDetailsViewController.xib
  40. 31 13
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopAnnotationWindowController.swift
  41. 12 11
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopAnnotationWindowController.xib
  42. 1 1
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.swift
  43. 10 10
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.xib
  44. 8 8
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopOperationWindowController.xib
  45. 3 3
      PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

+ 3 - 3
PDF Office/PDF Master/Class/PDFTools/Compress/Manager/KMCompressManager.swift

@@ -15,7 +15,7 @@ class KMCompressManager: NSObject {
                   password: String = "",
                   limit: Bool = false,
                   model: KMCompressSettingModel,
-                  view: NSView,
+                  view: NSView?,
                   completionHandler: (@escaping (Bool, URL) -> Void)) {
         DispatchQueue.main.async {
             NSPanel.savePanel(NSWindow.currentWindow(), true) { panel in
@@ -27,7 +27,7 @@ class KMCompressManager: NSObject {
                     return
                 }
                 
-                view.beginLoading()
+                view?.beginLoading()
                 DispatchQueue.global().async {
                     self.compress(documentURL: documentURL, fileURL: url!, password: password, limit: limit, model: model) { currentPage, totalPages in
                             
@@ -35,7 +35,7 @@ class KMCompressManager: NSObject {
                             return false
                         } completionHandler: { [unowned self] isFinish in
                             DispatchQueue.main.async {
-                                view.endLoading()
+                                view?.endLoading()
                                 if (isFinish) {
                                     if isOpen { /// 开启文档
                                         NSDocumentController.shared.km_safe_openDocument(withContentsOf: url!, display: true) { _, _, _ in

+ 67 - 2
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/CPDFMarkupAnnotation+PDFListView.swift

@@ -233,15 +233,80 @@ class CPDFAnnotationMarkupExtraIvars: NSObject {
             if(isHover) {
                 var length = [CGFloat](repeating: 5, count: 2)
                 KMContextSetLineDash(context, 0, length, 2)
-                KMContextStrokeRectWithWidth(context, KMRectInset(NSRectToCGRect(rect), lineWidth, lineWidth), lineWidth)
+                let dirtyRect = KMRectInset(NSRectToCGRect(rect), lineWidth, lineWidth)
+                let cornerRadius = min(abs(dirtyRect.size.width)/2.0, abs(dirtyRect.size.height)/6.0); // 设置圆角半径
+                
+                // 移动到起始点
+                context.move(to: CGPoint(x: dirtyRect.minX + cornerRadius, y: dirtyRect.minY))
+                
+                // 添加直线
+                context.addLine(to: CGPoint(x: dirtyRect.maxX - cornerRadius, y: dirtyRect.minY))
+                
+                // 添加右上角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.maxX, y: dirtyRect.minY), tangent2End: CGPoint(x: dirtyRect.maxX, y: dirtyRect.minY + cornerRadius), radius: cornerRadius)
+                
+                // 添加右边直线
+                context.addLine(to: CGPoint(x: dirtyRect.maxX, y: dirtyRect.maxY - cornerRadius))
+                
+                // 添加右下角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.maxX, y: dirtyRect.maxY), tangent2End: CGPoint(x: dirtyRect.maxX - cornerRadius, y: dirtyRect.maxY), radius: cornerRadius)
+                
+                // 添加底边直线
+                context.addLine(to: CGPoint(x: dirtyRect.minX + cornerRadius, y: dirtyRect.maxY))
+                
+                // 添加左下角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.minX, y: dirtyRect.maxY), tangent2End: CGPoint(x: dirtyRect.minX, y: dirtyRect.maxY - cornerRadius), radius: cornerRadius)
+                
+                // 添加左边直线
+                context.addLine(to: CGPoint(x: dirtyRect.minX, y: dirtyRect.minY + cornerRadius))
+                
+                // 添加左上角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.minX, y: dirtyRect.minY), tangent2End: CGPoint(x: dirtyRect.minX + cornerRadius, y: dirtyRect.minY), radius: cornerRadius)
+                
+                // 关闭路径
+                context.closePath()
+                context.strokePath()
             } else {
-                KMContextStrokeRect(context, KMRectInset(NSRectToCGRect(rect), lineWidth, lineWidth))
+                let dirtyRect = KMRectInset(NSRectToCGRect(rect), lineWidth, lineWidth)
+                let cornerRadius = min(abs(dirtyRect.size.width)/2.0, abs(dirtyRect.size.height)/6.0); // 设置圆角半径
+                
+                // 移动到起始点
+                context.move(to: CGPoint(x: dirtyRect.minX + cornerRadius, y: dirtyRect.minY))
+                
+                // 添加直线
+                context.addLine(to: CGPoint(x: dirtyRect.maxX - cornerRadius, y: dirtyRect.minY))
+                
+                // 添加右上角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.maxX, y: dirtyRect.minY), tangent2End: CGPoint(x: dirtyRect.maxX, y: dirtyRect.minY + cornerRadius), radius: cornerRadius)
+                
+                // 添加右边直线
+                context.addLine(to: CGPoint(x: dirtyRect.maxX, y: dirtyRect.maxY - cornerRadius))
+                
+                // 添加右下角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.maxX, y: dirtyRect.maxY), tangent2End: CGPoint(x: dirtyRect.maxX - cornerRadius, y: dirtyRect.maxY), radius: cornerRadius)
+                
+                // 添加底边直线
+                context.addLine(to: CGPoint(x: dirtyRect.minX + cornerRadius, y: dirtyRect.maxY))
+                
+                // 添加左下角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.minX, y: dirtyRect.maxY), tangent2End: CGPoint(x: dirtyRect.minX, y: dirtyRect.maxY - cornerRadius), radius: cornerRadius)
+                
+                // 添加左边直线
+                context.addLine(to: CGPoint(x: dirtyRect.minX, y: dirtyRect.minY + cornerRadius))
+                
+                // 添加左上角圆弧
+                context.addArc(tangent1End: CGPoint(x: dirtyRect.minX, y: dirtyRect.minY), tangent2End: CGPoint(x: dirtyRect.minX + cornerRadius, y: dirtyRect.minY), radius: cornerRadius)
+                
+                // 关闭路径
+                context.closePath()
+                context.strokePath()
             }
             
         }
         KMContextRestoreGState(context)
     }
     
+    
     override func hitTest(_ point: NSPoint) -> Bool {
         if super.hitTest(point) == false {
             return false

+ 11 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFAnnotationExtensions/Fill/CSelfSignAnnotation+PDFListView.swift

@@ -195,6 +195,17 @@ extension CSelfSignAnnotation {
             CPDFAnnotationConfig.setDefaultFloatValue(lineWidth, toKey: CAnnotationSelfSignLineLineWidthKey)
         } 
     }
+    
+    private static var _sf_keys: Set<AnyHashable>?
+    override func keysForValuesToObserveForUndo() -> Set<AnyHashable>! {
+        if (CSelfSignAnnotation._sf_keys == nil) {
+            CSelfSignAnnotation._sf_keys = super.keysForValuesToObserveForUndo()
+            _ = CSelfSignAnnotation._sf_keys?.insert(CPDFSelfSignLineColorKey)
+            _ = CSelfSignAnnotation._sf_keys?.insert(CPDFSelfSignLineOpacityKey)
+            _ = CSelfSignAnnotation._sf_keys?.insert(CPDFSelfSignLineAnnotationWidthKey)
+        }
+        return CSelfSignAnnotation._sf_keys
+    }
 }
 
 //MARK: - Compare

+ 12 - 1
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFListViewExtension/CPDFListView+AnnotationsCompare.swift

@@ -72,7 +72,18 @@ extension CPDFListView {
         case .color:
             for annotation in annotations {
                 if firstAnnotation != annotation {
-                    if CPDFListView.isTheSameColor(firstAnnotation.color, anotherColor: annotation.color) == false{
+                    var firstTColor = firstAnnotation.color
+                    var annotationColor = annotation.color
+                    
+                    if let selfAnnotation = firstAnnotation as? CSelfSignAnnotation {
+                        firstTColor = selfAnnotation.lineColor
+                    }
+                    
+                    if let selfAnnotation = annotation as? CSelfSignAnnotation {
+                        annotationColor = selfAnnotation.lineColor
+                    }
+
+                    if CPDFListView.isTheSameColor(firstTColor, anotherColor: annotationColor) == false{
                         multiInfo = true
                         break
                     }

+ 85 - 26
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFKitExtensions/CPDFListViewExtension/CPDFListView+Event.m

@@ -249,7 +249,16 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
                     }
                 }
             }
-            [self doFormWithEvent:theEvent];
+            if (CAnnotationTypeUnkown == self.annotationType) {
+                [self updateActiveAnnotations:@[]];
+                if (!(area & CPDFTextArea)) {
+                    [self doDragBoundsWithEvent:theEvent];
+                    [super mouseDown:theEvent];
+                }
+            } else {
+                [self doFormWithEvent:theEvent];
+
+            }
         } else {
             [self doDragAddAnnotationWithEvent:theEvent];
             if (self.annotationType == CAnnotationTypeStamp ||
@@ -3580,8 +3589,9 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
     
     CGRect orgBounds = self.multiplAnnotationObject.drawRect;
     NSRect newBounds = orgBounds;
-    CGRect pageBounds = page.bounds;
-    
+    NSRect pageBounds = [page boundsForBox:[self displayBox]];
+    CGFloat offsetPageSet = [CPDFListViewConfig defaultManager].annotationBorderOffset.floatValue ;
+
     CRectEdges resizeHandle = *resizeHandlePtr;
     CGFloat minWidth = MIN_NOTE_SIZE;
     CGFloat minHeight = MIN_NOTE_SIZE;
@@ -3594,6 +3604,10 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
     if ((resizeHandle & CMaxXEdgeMask) && (resizeHandle & CMinYEdgeMask)) {
         CGFloat y = CGRectGetHeight(newBounds);
         newBounds.size.width += relPoint.x;
+        if (NSMaxX(newBounds)+offsetPageSet > NSMaxX(pageBounds)) {
+            newBounds.size.width = NSMaxX(pageBounds) - NSMinX(newBounds)-offsetPageSet;
+        }
+
         newBounds.size.height -= relPoint.y;
         
         newBounds.size.height = newBounds.size.width*scale;
@@ -3601,53 +3615,99 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
         newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
         
         newBounds.origin.y-= (newBounds.size.height- y);
+        if(newBounds.origin.y - offsetPageSet < NSMinY(pageBounds)) {
+            newBounds.origin.y = offsetPageSet;
+            newBounds.size.height = y;
+        }
     } else if ((resizeHandle & CMaxXEdgeMask) && (resizeHandle & CMaxYEdgeMask)) {
         newBounds.size.width += relPoint.x;
-        newBounds.size.height += relPoint.y;
-        
+        if (NSMaxX(newBounds)+offsetPageSet > NSMaxX(pageBounds)) {
+            newBounds.size.width = NSMaxX(pageBounds) - NSMinX(newBounds)-offsetPageSet;
+        }
         newBounds.size.height = newBounds.size.width*scale;
+        if (NSMaxY(newBounds)+ offsetPageSet > NSMaxY(pageBounds)) {
+            newBounds.size.height = NSMaxY(pageBounds) - NSMinY(newBounds)- offsetPageSet;
+        }
         newBounds.size.width = MAX(newBounds.size.width, minWidth);
         newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
     } else if ((resizeHandle & CMinXEdgeMask) && (resizeHandle & CMaxYEdgeMask)) {
         CGFloat x = CGRectGetWidth(newBounds);
-        
         newBounds.size.width -= relPoint.x;
-        newBounds.size.height += relPoint.y;
         
-        newBounds.size.height = newBounds.size.width*scale;
         newBounds.size.width = MAX(newBounds.size.width, 5.0);
-        newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
         newBounds.origin.x-= (newBounds.size.width- x);
+        if (NSMinX(newBounds)-offsetPageSet < NSMinX(pageBounds)) {
+            newBounds.size.width = NSMaxX(newBounds) - NSMinX(pageBounds)-offsetPageSet;
+            newBounds.origin.x = NSMinX(pageBounds)+offsetPageSet;
+        }
+
+        newBounds.size.height = newBounds.size.width*scale;
+        if (NSMaxY(newBounds)+ offsetPageSet > NSMaxY(pageBounds)) {
+            newBounds.size.height = NSMaxY(pageBounds) - NSMinY(newBounds)- offsetPageSet;
+        }
+        newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
     } else if ((resizeHandle & CMinXEdgeMask) && (resizeHandle & CMinYEdgeMask)) {
         CGFloat y = CGRectGetHeight(newBounds);
         CGFloat x = CGRectGetWidth(newBounds);
         
         newBounds.size.width -= relPoint.x;
-        newBounds.size.height -= relPoint.y;
-        
-        newBounds.size.height = newBounds.size.width*scale;
         newBounds.size.width = MAX(newBounds.size.width, minWidth);
+
+        newBounds.size.height = newBounds.size.width*scale;
         newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
         newBounds.origin.y-= (newBounds.size.height- y);
+        if(newBounds.origin.y - offsetPageSet < NSMinY(pageBounds)) {
+            newBounds.origin.y = offsetPageSet;
+            newBounds.size.height = y;
+        }
+        
         newBounds.origin.x-= (newBounds.size.width- x);
+        if (NSMinX(newBounds)-offsetPageSet < NSMinX(pageBounds)) {
+            newBounds.size.width = NSMaxX(newBounds) - NSMinX(pageBounds)-offsetPageSet;
+            newBounds.origin.x = NSMinX(pageBounds)+offsetPageSet;
+        }
     } else if (resizeHandle & CMinXEdgeMask) {
         newBounds.size.width -= relPoint.x;
-        newBounds.size.width = MAX(newBounds.size.width, minWidth);
         newBounds.origin.x += relPoint.x;
+        if (NSMinX(newBounds)-offsetPageSet < NSMinX(pageBounds)) {
+            newBounds.size.width = NSMaxX(newBounds) - NSMinX(pageBounds)-offsetPageSet;
+            newBounds.origin.x = NSMinX(pageBounds)+offsetPageSet;
+        }
+        if (NSWidth(newBounds) < minWidth) {
+            newBounds.origin.x = NSMaxX(newBounds) - minWidth;
+            newBounds.size.width = minWidth;
+        }
+        newBounds.size.width = MAX(newBounds.size.width, minWidth);
     } else if (resizeHandle & CMaxXEdgeMask) {
-        CGFloat height = CGRectGetHeight(newBounds);
-        
         newBounds.size.width += relPoint.x;
+        if (NSMaxX(newBounds)+offsetPageSet > NSMaxX(pageBounds))
+            newBounds.size.width = NSMaxX(pageBounds) - NSMinX(newBounds)-offsetPageSet;
+        if (NSWidth(newBounds) < minWidth) {
+            newBounds.size.width = minWidth;
+        }
         newBounds.size.width = MAX(newBounds.size.width, minWidth);
         
     } else if (resizeHandle & CMinYEdgeMask) {
-        
         newBounds.size.height -= relPoint.y;
-        newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
         newBounds.origin.y += relPoint.y;
+        if (NSMinY(newBounds)-offsetPageSet < NSMinY(pageBounds)) {
+            newBounds.size.height = NSMaxY(newBounds) - NSMinY(pageBounds)-offsetPageSet;
+            newBounds.origin.y = NSMinY(pageBounds)+offsetPageSet;
+        }
+        if (NSHeight(newBounds) < minHeight) {
+            newBounds.origin.y = NSMaxY(newBounds) - minHeight;
+            newBounds.size.height = minHeight;
+        }
+
+        newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
     } else if (resizeHandle & CMaxYEdgeMask) {
-        
         newBounds.size.height += relPoint.y;
+        if (NSMaxY(newBounds)+ offsetPageSet > NSMaxY(pageBounds)) {
+            newBounds.size.height = NSMaxY(pageBounds) - NSMinY(newBounds)- offsetPageSet;
+        }
+        if (NSHeight(newBounds) < minHeight) {
+            newBounds.size.height = minHeight;
+        }
         newBounds.size.height = MAX(newBounds.size.height, minHeight*scale);
     }
     
@@ -4679,10 +4739,10 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
             break;
         } else if ([theEvent type] == NSEventTypeLeftMouseDragged) {
             point = NSZeroPoint;
-            [self pageAndPoint:&point forEvent:theEvent nearest:YES];
-            
+            CPDFPage *currentTPage = [self pageAndPoint:&point forEvent:theEvent nearest:YES];
+
             NSPoint lastPoint = NSZeroPoint;
-            [self pageAndPoint:&lastPoint forEvent:lastMouseEvent nearest:YES];
+            CPDFPage *lastTPage = [self pageAndPoint:&lastPoint forEvent:lastMouseEvent nearest:YES];
             
             CGRect zRect = CGRectMake(pagePoint.x-2*mouseOffset, pagePoint.y-2*mouseOffset, 4*mouseOffset, 4*mouseOffset);
             if (CGRectContainsPoint(zRect, point)) {continue;}
@@ -4691,7 +4751,10 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
             CGRect borderRect = self.multiplAnnotationObject.drawRect;
             //            [self.dragHoverPoints addObjectsFromArray:[self dragHoverPointsForRect:borderRect forPage:page resizeHandle:resizeHandle]];
             [self dragAnnotationReferenceLine:self.activeAnnotation];
-            NSPoint relPoint = CPDFListViewSubstractPoints(point, lastPoint);
+            NSPoint relPoint = CGPointZero;
+            if(currentTPage.pageIndex == lastTPage.pageIndex) {
+                relPoint = CPDFListViewSubstractPoints(point, lastPoint);
+            }
             
             if(resizeHandle == CEditInEdgeMask) {
                 CGRect originalRect = self.multiplAnnotationObject.drawRect;
@@ -5081,7 +5144,6 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
                     }
                     
                     CGRect borderRect = [newActiveAnnotation borderRecctForView:self];
-                    //                    [self.dragHoverPoints addObjectsFromArray:[self dragHoverPointsForRect:borderRect forPage:page resizeHandle:resizeHandle]];
                     [self dragAnnotationReferenceLine:newActiveAnnotation];
                     
                     [self setNeedsDisplayAnnotationViewForPage:page];
@@ -5110,9 +5172,6 @@ static inline CPDFAreaOfInterest CAreaOfInterestForResizeHandle(CRectEdges mask,
             for(CPDFAnnotation *annotation in [activePage annotations]){
                 if ([annotation annotationShouldDisplay] && NSIntersectsRect(annotation.bounds, selectBounds) &&
                     ![annotation isKindOfClass:[CPDFLinkAnnotation class]] &&
-                    ![annotation isKindOfClass:[CPDFButtonWidgetAnnotation class]] &&
-                    ![annotation isKindOfClass:[CPDFTextWidgetAnnotation class]] &&
-                    ![annotation isKindOfClass:[CPDFChoiceWidgetAnnotation class]] &&
                     ![annotation isKindOfClass:[CPDFRedactAnnotation class]]) {
                     [self.activeAnnotations addObject:annotation];
                     if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewChangeatioActiveAnnotations:forActiveAnnotations:isRightMenu:)])

+ 3 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.h

@@ -395,4 +395,7 @@ enum {
 
 - (BOOL)PDFListViewSplitModeShowBar;
 
+- (void)PDFListViewAnnotationEditModeChange:(CPDFListView *)pdfListView forAnnotation:(CPDFAnnotation *)anotation;
+
+
 @end

+ 7 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.m

@@ -1357,6 +1357,10 @@ void CPDFListViewOCDrawLineHandles(CGContextRef context, CGRect rect, CGFloat ra
             _popOver.animates = YES;
             _popOver.behavior = NSPopoverBehaviorTransient;
             [_popOver showRelativeToRect:[self convertRect:annotation.bounds fromPage:annotation.page] ofView:self preferredEdge:NSMaxXEdge];
+            
+            if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewAnnotationEditModeChange:forAnnotation:)]) {
+                [self.pdfListViewDelegate PDFListViewAnnotationEditModeChange:self forAnnotation:annotation];
+            }
         }
     }
 }
@@ -1856,6 +1860,9 @@ void CPDFListViewOCDrawLineHandles(CGContextRef context, CGRect rect, CGFloat ra
             [self setNeedsDisplayAnnotation:annotation];
         }
 
+        if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewAnnotationEditModeChange:forAnnotation:)]) {
+            [self.pdfListViewDelegate PDFListViewAnnotationEditModeChange:self forAnnotation:annotation];
+        }
     }
     self.popOver = nil;
 }

BIN
PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/ComPDFKit


BIN
PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/Assets.car


BIN
PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/CPDFUnlockViewController.nib/keyedobjects-101300.nib


BIN
PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/CPDFUnlockViewController.nib/keyedobjects.nib


+ 7 - 7
PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/Info.plist

@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
 	<key>BuildMachineOSBuild</key>
-	<string>21E230</string>
+	<string>21G72</string>
 	<key>CFBundleDevelopmentRegion</key>
 	<string>en</string>
 	<key>CFBundleExecutable</key>
@@ -27,19 +27,19 @@
 	<key>DTCompiler</key>
 	<string>com.apple.compilers.llvm.clang.1_0</string>
 	<key>DTPlatformBuild</key>
-	<string>13A233</string>
+	<string>14B47b</string>
 	<key>DTPlatformName</key>
 	<string>macosx</string>
 	<key>DTPlatformVersion</key>
-	<string>11.3</string>
+	<string>13.0</string>
 	<key>DTSDKBuild</key>
-	<string>20E214</string>
+	<string>22A372</string>
 	<key>DTSDKName</key>
-	<string>macosx11.3</string>
+	<string>macosx13.0</string>
 	<key>DTXcode</key>
-	<string>1300</string>
+	<string>1410</string>
 	<key>DTXcodeBuild</key>
-	<string>13A233</string>
+	<string>14B47b</string>
 	<key>LSMinimumSystemVersion</key>
 	<string>10.11</string>
 </dict>

BIN
PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/Resources/default.metallib


+ 15 - 15
PDF Office/PDF Master/Class/PDFWindowController/PDFSDK/ComPDFKit.framework/Versions/A/_CodeSignature/CodeResources

@@ -6,15 +6,15 @@
 	<dict>
 		<key>Resources/Assets.car</key>
 		<data>
-		Lsv7/Q81njxGwXBA8bI9Dpf4F1w=
+		KyEk4oxSvC32RjwMCvnVaepFm7Q=
 		</data>
 		<key>Resources/CPDFUnlockViewController.nib/keyedobjects-101300.nib</key>
 		<data>
-		e/XSIlGXrK/XQ3MPSq17IjdvEEo=
+		ULC3lJLcrnOnCBivTpSe8w8O/VQ=
 		</data>
 		<key>Resources/CPDFUnlockViewController.nib/keyedobjects.nib</key>
 		<data>
-		Dv5ax23hZ/GohlG6yLpCpgKtmBE=
+		0H15nmzgJVoRpoNxPw6ZO38r4Xs=
 		</data>
 		<key>Resources/Cert/0d264c89.0</key>
 		<data>
@@ -46,11 +46,11 @@
 		</data>
 		<key>Resources/Info.plist</key>
 		<data>
-		Hoq1bHhFMnOVJoMAfRXpu6wD6fY=
+		eUAIWe8Jd6faz17Btb4tXx/y96U=
 		</data>
 		<key>Resources/default.metallib</key>
 		<data>
-		OW1waXyR5Kz59kYzU5PENdarCTU=
+		jzLBEgCveMkMFXwcYUGaOyq4TKI=
 		</data>
 		<key>Resources/empty_password.png</key>
 		<data>
@@ -1142,33 +1142,33 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			Lsv7/Q81njxGwXBA8bI9Dpf4F1w=
+			KyEk4oxSvC32RjwMCvnVaepFm7Q=
 			</data>
 			<key>hash2</key>
 			<data>
-			PHXwNJNPYSsfT1XIPEdwX2PrSmexDOCEb4tCnkhHshk=
+			GfS4+ScTn233MwqT18qLBXcX4Y1TClZTntUE75vTPwY=
 			</data>
 		</dict>
 		<key>Resources/CPDFUnlockViewController.nib/keyedobjects-101300.nib</key>
 		<dict>
 			<key>hash</key>
 			<data>
-			e/XSIlGXrK/XQ3MPSq17IjdvEEo=
+			ULC3lJLcrnOnCBivTpSe8w8O/VQ=
 			</data>
 			<key>hash2</key>
 			<data>
-			Cci8sTloeOT1JTL92WrgtxN/YiPEzExX+pbP8X68m+Q=
+			WE60TS6kbusEaTyP03p7VENFKl+sD8oqeeumuSb/Kyw=
 			</data>
 		</dict>
 		<key>Resources/CPDFUnlockViewController.nib/keyedobjects.nib</key>
 		<dict>
 			<key>hash</key>
 			<data>
-			Dv5ax23hZ/GohlG6yLpCpgKtmBE=
+			0H15nmzgJVoRpoNxPw6ZO38r4Xs=
 			</data>
 			<key>hash2</key>
 			<data>
-			u30610+slEfn4T8al/uF0uaEk6zWaMgecsgOru7puII=
+			crpgU0SlPe67g5lOUe+Pn4AZLeVkBFKS9oSX5WNWDjo=
 			</data>
 		</dict>
 		<key>Resources/Cert/0d264c89.0</key>
@@ -1252,22 +1252,22 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			Hoq1bHhFMnOVJoMAfRXpu6wD6fY=
+			eUAIWe8Jd6faz17Btb4tXx/y96U=
 			</data>
 			<key>hash2</key>
 			<data>
-			BdRjiKJrHT45/uoFJgLCbbEa2fI7njv5yVbGEohAhqY=
+			y4EMlFXQfBV2O/aopxyZiZIYDDT1LhnIofrQyQghkNA=
 			</data>
 		</dict>
 		<key>Resources/default.metallib</key>
 		<dict>
 			<key>hash</key>
 			<data>
-			OW1waXyR5Kz59kYzU5PENdarCTU=
+			jzLBEgCveMkMFXwcYUGaOyq4TKI=
 			</data>
 			<key>hash2</key>
 			<data>
-			IWxLuwqEZ9Pnv1OTOt5tixhIqu82+kdo59Ff6hmjuaM=
+			Jk0Hy+FQsbG3BwetLpjotIY/w8Oqm9cX+sP+Qc1ZOQw=
 			</data>
 		</dict>
 		<key>Resources/empty_password.png</key>

+ 9 - 0
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Tools/KMNoteReplyHanddler.swift

@@ -309,6 +309,15 @@ class KMNoteReplyHanddler: NSObject {
         model.annoModel?.footerModel?.replyModel = model
     }
     
+    func editAnnotation(annotationModel: KMBotaAnnotationModel?) {
+        guard let model = annotationModel else {
+            return
+        }
+        
+        model.footerModel?.isExpand = true
+        model.footerModel?.editAnnoModel = annotationModel
+    }
+    
     func removeReplyAnnotation(_ anno: CPDFAnnotation?) {
         guard let theAnno = anno else {
             return

+ 41 - 10
PDF Office/PDF Master/KMClass/KMPDFViewController/KMMainViewController.swift

@@ -1798,14 +1798,16 @@ struct KMNMWCFlags {
             }
             toggleClosePopUIWindow()
         } else if(listView.isEditing() == false) {
-            let activeAnnotations:[CPDFAnnotation] = listView.activeAnnotations as! [CPDFAnnotation]
-            if(activeAnnotations.count > 0) {
-                if let page = activeAnnotations.first?.page {
-                    let pageRect = listView.selectionMultipleBounds(with: activeAnnotations)
-                    let positioningRect = listView.convert(pageRect, from: page)
-                    if (CGRectIntersectsRect(positioningRect, listView.frame)) {
-                        reloadPopUIActiveAnnotations(activeAnnotations: activeAnnotations)
-                        return
+            if(listView.popOver == nil || listView.popOver?.isShown == false) {
+                let activeAnnotations:[CPDFAnnotation] = listView.activeAnnotations as! [CPDFAnnotation]
+                if(activeAnnotations.count > 0) {
+                    if let page = activeAnnotations.first?.page {
+                        let pageRect = listView.selectionMultipleBounds(with: activeAnnotations)
+                        let positioningRect = listView.convert(pageRect, from: page)
+                        if (CGRectIntersectsRect(positioningRect, listView.frame)) {
+                            reloadPopUIActiveAnnotations(activeAnnotations: activeAnnotations)
+                            return
+                        }
                     }
                 }
             }
@@ -3836,20 +3838,30 @@ extension KMMainViewController: KMPDFToolbarControllerDelegate {
                 listView.resetFormAnnotation()
             } else if itemIdentifier == KMPDFToolbar_form_Align_Left_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .left)
+                listView.setNeedsDisplayForVisiblePages()
             } else if itemIdentifier == KMPDFToolbar_form_Align_Hori_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .horizontally)
+                listView.setNeedsDisplayForVisiblePages()
             } else if itemIdentifier == KMPDFToolbar_form_Align_Right_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .right)
+                listView.setNeedsDisplayForVisiblePages()
             } else if itemIdentifier == KMPDFToolbar_form_Align_Top_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .top)
+                listView.setNeedsDisplayForVisiblePages()
             } else if itemIdentifier == KMPDFToolbar_form_Align_Vert_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .vertical)
+               listView.setNeedsDisplayForVisiblePages()
+
             } else if itemIdentifier == KMPDFToolbar_form_Align_Bottom_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .bottom)
+               listView.setNeedsDisplayForVisiblePages()
+
             } else if itemIdentifier == KMPDFToolbar_form_Distribute_Vert_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .disVertical)
+                listView.setNeedsDisplayForVisiblePages()
             } else if itemIdentifier == KMPDFToolbar_form_Distribute_Hori_Identifier {
                 listView.change(listView.activeAnnotations as? [CPDFAnnotation], alignmentType: .disHorizontally)
+                listView.setNeedsDisplayForVisiblePages()
             }
             
             if viewManager.subToolMode == .None {
@@ -3859,7 +3871,20 @@ extension KMMainViewController: KMPDFToolbarControllerDelegate {
             }
             self.refreshToolbarRightViewInfo()
             
-            toolbarViewModeChanged()
+            if itemIdentifier == KMPDFToolbar_form_HighlightFields_Identifier ||
+                itemIdentifier == KMPDFToolbar_form_ShowName_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_ClearForm_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Align_Left_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Align_Hori_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Align_Right_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Align_Top_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Align_Vert_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Align_Bottom_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Distribute_Vert_Identifier  ||
+                itemIdentifier == KMPDFToolbar_form_Distribute_Hori_Identifier  {
+            } else {
+                toolbarViewModeChanged()
+            }
         } else if toolbarManager.getSubToolItemIdentifys(KMPDFToolbar_Fill_Identifier).contains(itemIdentifier) {
             //MARK: -填充
             
@@ -5143,7 +5168,6 @@ extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
         
         //
         pdfToolbarController?.pdfViewActiveAnnotationsChanged()
-        botaViewController?.annoController.note_reloadDataIfNeed()
     }
     
     func pdfListViewMenu(forEvent pdfListView: CPDFListView!, for theEvent: NSEvent!, click menu: AutoreleasingUnsafeMutablePointer<NSMenu?>!, isMoveSelectAnno: Bool) {
@@ -5745,6 +5769,10 @@ extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
         }
         return true
     }
+    
+    func pdfListViewAnnotationEditModeChange(_ pdfListView: CPDFListView!, for anotation: CPDFAnnotation!) {
+        reloadPopUIWindow()
+    }
      
     //MARK: -Measure
     func pdfListViewAnnotationMeasureInfoChange(_ pdfListView: CPDFListView!, with annotation: CPDFAnnotation!) {
@@ -5863,6 +5891,9 @@ extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
     
     @objc private func pdfViewScrollViewDidScroll(_ noti: Notification) {
         reloadPopUIWindow()
+        if listView.popOver?.isShown == true {
+            listView.popOver?.close()
+        }
     }
     
     func pageCountChangedNotification(_ sender: Notification) {

+ 12 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/KMPDFMenuConfig.swift

@@ -192,6 +192,18 @@ let BOTAMenuIdentifier_Annotation_Export = "BOTAMenuIdentifier_Annotation_Export
 let BOTAMenuIdentifier_Annotation_RemoveAll = "BOTAMenuIdentifier_Annotation_RemoveAll"
 let BOTAMenuIdentifier_Annotation_DeleteRep = "BOTAMenuIdentifier_Annotation_DeleteRep"
 
+let BOTAMenuIdentifier_Annotation_EditNote = "BOTAMenuIdentifier_Annotation_EditNote"
+let BOTAMenuIdentifier_Annotation_AddMark = "BOTAMenuIdentifier_Annotation_AddMark"
+let BOTAMenuIdentifier_Annotation_AddRep = "BOTAMenuIdentifier_Annotation_AddRep"
+let BOTAMenuIdentifier_Annotation_RepState = "BOTAMenuIdentifier_Annotation_RepState"
+let BOTAMenuIdentifier_Annotation_RepStateNone = "BOTAMenuIdentifier_Annotation_RepStateNone"
+let BOTAMenuIdentifier_Annotation_RepStateAccepted = "BOTAMenuIdentifier_Annotation_RepStateAccepted"
+let BOTAMenuIdentifier_Annotation_RepStateRejected = "BOTAMenuIdentifier_Annotation_RepStateRejected"
+let BOTAMenuIdentifier_Annotation_RepStateCancelled = "BOTAMenuIdentifier_Annotation_RepStateCancelled"
+let BOTAMenuIdentifier_Annotation_RepStateCompleted = "BOTAMenuIdentifier_Annotation_RepStateCompleted"
+let BOTAMenuIdentifier_Annotation_DeleteSignRep = "BOTAMenuIdentifier_Annotation_DeleteSignRep"
+let BOTAMenuIdentifier_Annotation_DeleteMuteRep = "BOTAMenuIdentifier_Annotation_DeleteMuteRep"
+
 @objcMembers class KMPDFMenuConfig: NSString {
     class func aiMenuItemProperty(theEvent:NSEvent?)->ComponentMenuitemProperty {
         let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,

+ 0 - 2
PDF Office/PDF Master/KMClass/KMPDFViewController/RightSideController/Views/OCR/Tool/Manager/KMOCRManager.swift

@@ -122,8 +122,6 @@ extension KMOCRManager: KMGOCRManagerDelegate {
         self.progress = progress
         self.model = model
         
-        let pages:[Int] = self.fetchPageIndex(document: document, model: model)
-        model.pageRange = pages
         self.saveAsPDFFilePath = saveFilePath
         self.convertOCR(document: document, filePath:saveFilePath, indexs: model.pageRange, language: model.language, type: model.ocrType, saveAsPDF: true)
     }

+ 2 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/Toolbar/Model/KMPDFToolbarManager.swift

@@ -332,6 +332,8 @@ class KMPDFToolbarManager: NSObject {
                                     page_LeftRotate_Property.identifier, page_RightRotate_Property.identifier,
                                     page_Delete_Property.identifier])
             
+            ids.append(contentsOf: [page_Increase_Property.identifier,page_Reduce_Property.identifier])
+            
         } else if mainIdentify == KMPDFToolbar_Markup_Identifier {
             ids.append(contentsOf: [highlightProperty.identifier, UnderlineProperty.identifier,
                                     wavelineProperty.identifier, strikethroughProperty.identifier,

+ 15 - 0
PDF Office/PDF Master/KMClass/Left/Annotaion/Controller/KMLeftSideViewController+Note.swift

@@ -1111,6 +1111,16 @@ extension KMLeftSideViewController {
         return selectedNotes
     }
     
+    func selectedObjcNotes() -> [Any] {
+        var selectedNotes: [Any] = []
+        let rowIndexes = self.noteOutlineView.selectedRowIndexes
+        for row in rowIndexes {
+            let item = self.noteOutlineView.item(atRow: row)
+            selectedNotes.append(item)
+        }
+        return selectedNotes
+    }
+    
     func clearAnnotationFilterData() {
         if let _key = self.pdfDocument()?.documentURL?.path {
             let userDefaults = UserDefaults.standard
@@ -1182,6 +1192,11 @@ extension KMLeftSideViewController: KMNoteOutlineViewDelegate {
 
 // MARK: - NSMenuDelegate
 extension KMLeftSideViewController: NSMenuDelegate {
+    
+    func menuNeedsUpdate(_ menu: NSMenu) {
+        menu.removeAllItems()
+    }
+    
     func menuDidClose(_ menu: NSMenu) {
         if(menu == self.noteFilterMenu) {
             headerView.sortButton.properties.state = .normal

+ 382 - 47
PDF Office/PDF Master/KMClass/Left/Annotaion/Controller/KMLeftSideViewController.swift

@@ -224,6 +224,8 @@ class KMLeftSideViewController: KMSideViewController {
     }()
     
     var isRenameNoteOutline = false
+    
+    var currentItem: Any?
 
     // 所有注释
     var allAnnotations: [CPDFAnnotation] = []
@@ -250,6 +252,7 @@ class KMLeftSideViewController: KMSideViewController {
     var searchGroupView: ComponentGroup?
     var searchGroupTarget: ComponentButton?
     var moreGroupView: ComponentGroup?
+    var rightGroupView: ComponentGroup?
 
     var emptyView: ComponentEmpty = {
         let view = ComponentEmpty()
@@ -364,6 +367,36 @@ class KMLeftSideViewController: KMSideViewController {
         toolHeaderBox.contentView = headerView
     }
     
+    func updateMarkState(model:KMBotaAnnotationModel){ // Markup
+        let anno = model.anno
+        guard let state = self.noteReplyHanddler.fetchAnnoState(anno), state == .marked else {
+            self.noteReplyHanddler.markAnnotation(anno)
+            self.noteOutlineView.reloadItem(model)
+            return
+        }
+        self.noteReplyHanddler.unMarkAnnotation(anno)
+        self.noteOutlineView.reloadItem(model)
+    }
+    
+    func updateReplaState(model:KMBotaAnnotationModel,state:CPDFAnnotationState){
+        let anno = model.anno
+        noteReplyHanddler.updateAnnoState(anno: anno, state: state)
+        self.noteOutlineView.reloadData()
+    }
+    
+    func updateExpand (model:KMBotaAnnotationModel,isExpand:Bool,item: Any) {
+        // 将折叠状态记录到模型
+        model.foldType = isExpand  ? .unfold : .fold
+        
+        model.footerModel?.isExpand = isExpand
+        model.isExpand = isExpand
+        self.noteOutlineView.reloadData()
+        DispatchQueue.main.async {
+            let row = self.noteOutlineView.row(forItem: item)
+            self.noteOutlineView.scrollRowToVisible(row)
+        }
+    }
+    
     // MARK: -  Filter
     func showFilterController() {
         noteFilterAction(nil)
@@ -428,6 +461,154 @@ class KMLeftSideViewController: KMSideViewController {
         groupView?.showWithPoint(point, relativeTo: headerView.moreButton)
     }
     
+    func showRightGropView(raw: Int,event:NSEvent,view:NSView?,item:Any) {
+        let groupView = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
+        
+        currentItem = item
+        
+        var menuItemArr: [ComponentMenuitemProperty] = []
+        let rowIndexes = self.selectedObjcNotes()
+        
+        var viewHeight = 0.0
+        if(rowIndexes.count == 1) {
+            let dataItem = rowIndexes.first
+            if let data = dataItem as? KMBotaAnnotationModel {
+                if  let an = data.anno as? CPDFAnnotation {
+                    if an.isKind(of: CPDFFreeTextAnnotation.self) == true ||
+                        an.isKind(of: CPDFTextAnnotation.self)  == true {
+                    } else  {
+                        let note_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Notes"),
+                                                                                                 identifier: BOTAMenuIdentifier_Annotation_EditNote,representedObject: [data])
+                        menuItemArr.append(note_Menuitem)
+                        viewHeight += 36.0
+                    }
+                    let reply_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Reply"),
+                                                                                              identifier: BOTAMenuIdentifier_Annotation_AddRep,representedObject: [data])
+                    menuItemArr.append(reply_Menuitem)
+                    viewHeight += 36.0
+
+                    let state = self.noteReplyHanddler.fetchAnnoState(an) ?? .unMarked
+
+                    var markString = ""
+                    if state == .unMarked {
+                        markString = KMLocalizedString("Marked")
+                    } else {
+                        markString = KMLocalizedString("Unmarked")
+                    }
+                    let mark_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: markString,
+                                                                                              identifier: BOTAMenuIdentifier_Annotation_AddMark,representedObject: [data])
+                    menuItemArr.append(mark_Menuitem)
+                    viewHeight += 36.0
+                    
+                    let state_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Status"),
+                                                                                                   identifier: BOTAMenuIdentifier_Annotation_RepState)
+                    
+                    var subMenuItemArr: [ComponentMenuitemProperty] = []
+                    let property0: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("None"),identifier: BOTAMenuIdentifier_Annotation_RepStateNone,representedObject: [data])
+                    let property1: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Accepted"),identifier: BOTAMenuIdentifier_Annotation_RepStateAccepted,representedObject: [data])
+                    let property2: ComponentMenuitemProperty = ComponentMenuitemProperty(
+                                                                                                text: KMLocalizedString("Rejected"),identifier: BOTAMenuIdentifier_Annotation_RepStateRejected,representedObject: [data])
+                    let property3: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Cancelled"),identifier: BOTAMenuIdentifier_Annotation_RepStateCancelled,representedObject: [data])
+                    let property4: ComponentMenuitemProperty = ComponentMenuitemProperty(
+                                                                                                text: KMLocalizedString("Completed"),identifier: BOTAMenuIdentifier_Annotation_RepStateCompleted,representedObject: [data])
+                    subMenuItemArr.append(property0)
+                    subMenuItemArr.append(property1)
+                    subMenuItemArr.append(property2)
+                    subMenuItemArr.append(property3)
+                    subMenuItemArr.append(property4)
+                    
+                    let reviewState = noteReplyHanddler.fetchReviewState(an) ?? .none
+                    if reviewState == .none {
+                        property0.righticon = NSImage(named: "KMNImageNameMenuSelect")
+                    } else if reviewState == .completed {
+                        property4.righticon = NSImage(named: "KMNImageNameMenuSelect")
+                    } else if reviewState == .canceled {
+                        property3.righticon = NSImage(named: "KMNImageNameMenuSelect")
+                    } else if reviewState == .accepted {
+                        property1.righticon = NSImage(named: "KMNImageNameMenuSelect")
+                    } else if reviewState == .rejected {
+                        property2.righticon = NSImage(named: "KMNImageNameMenuSelect")
+                    }
+                    
+                    state_Menuitem.subPropertys = subMenuItemArr
+                    menuItemArr.append(state_Menuitem)
+                    viewHeight += 36.0
+                    
+                    menuItemArr.append(ComponentMenuitemProperty.divider())
+                    viewHeight += 8.0
+
+                    var showString = ""
+                    if data.isExpand {
+                        showString = KMLocalizedString("Collapse")
+                    } else {
+                        showString = KMLocalizedString("Expand")
+                    }
+                    
+                    let show_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: showString,
+                                                                                              identifier: PDFViewMenuIdentifier_Normal_ShowPopUI,representedObject: [data])
+                    menuItemArr.append(show_Menuitem)
+                    viewHeight += 36.0
+                    
+                    menuItemArr.append(ComponentMenuitemProperty.divider())
+                    viewHeight += 8.0
+
+                    if an.isKind(of: CPDFFreeTextAnnotation.self) == true ||
+                        an.isKind(of: CPDFTextAnnotation.self)  == true ||
+                        an.isKind(of: CPDFMarkupAnnotation.self)  == true {
+                        let copy_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Copy Text"),
+                                                                                                  identifier: PDFViewMenuIdentifier_Normal_Copy,representedObject: [data])
+                        copy_Menuitem.keyEquivalent = "⌘ C"
+
+                        menuItemArr.append(copy_Menuitem)
+                        viewHeight += 36.0
+                    }
+                    
+                    let delete_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Delete"),
+                                                                                              identifier: PDFViewMenuIdentifier_Normal_Delete,representedObject: [data])
+                    delete_Menuitem.keyEquivalent = "⌘ " + "⌫"
+                    menuItemArr.append(delete_Menuitem)
+                    viewHeight += 36.0
+                }
+            } else if let replyModel = dataItem as? KMBotaAnnotationReplyModel {
+                let note_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Notes"),
+                                                                                         identifier: BOTAMenuIdentifier_Annotation_EditNote,representedObject: [replyModel])
+                menuItemArr.append(note_Menuitem)
+                viewHeight += 36.0
+                
+                let copy_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Copy Text"),
+                                                                                          identifier: PDFViewMenuIdentifier_Normal_CopyText,representedObject: [replyModel])
+                copy_Menuitem.keyEquivalent = "⌘ C"
+                menuItemArr.append(copy_Menuitem)
+                viewHeight += 36.0
+                
+                let delete_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Delete"),
+                                                                                          identifier: BOTAMenuIdentifier_Annotation_DeleteSignRep,representedObject: [replyModel])
+                delete_Menuitem.keyEquivalent = "⌘ " + "⌫"
+
+                menuItemArr.append(delete_Menuitem)
+                viewHeight += 36.0
+            }
+        } else if rowIndexes.count > 1 {
+            let delete_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Delete"),
+                                                                                      identifier: BOTAMenuIdentifier_Annotation_DeleteMuteRep,representedObject: rowIndexes)
+            delete_Menuitem.keyEquivalent = "⌘ " + "⌫"
+
+            menuItemArr.append(delete_Menuitem)
+            viewHeight += 36.0
+        }
+        
+        rightGroupView = groupView
+        groupView?.groupDelegate = self
+        groupView?.frame = CGRectMake(310, 0, 200, viewHeight)
+        groupView?.updateGroupInfo(menuItemArr)
+        
+        var point = NSPoint(x: CGRectGetMaxX(view?.frame ?? CGRectZero), y: CGRectGetMidY(view?.frame ?? CGRectZero))
+        point = noteOutlineView.convert(point, to: nil)
+        point.y -= (groupView?.frame.size.height ?? 0)/2
+        groupView?.showWithPoint(point, relativeTo: view)
+
+    }
+    
     func showSearchGroupView(sender: ComponentButton) {
         var viewHeight: CGFloat = 8
         var menuItemArr: [ComponentMenuitemProperty] = []
@@ -675,11 +856,11 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
                 }
                 cell?.countLabel.stringValue = "\(data.itemCount / 2)"
                 
-                cell?.itemClick = { idx, _ in
+                cell?.itemClick = {[weak self] idx, _ in
                     if idx == 1 { // 收取 & 展开
                         data.isExpand = !data.isExpand
                         
-                        self.noteOutlineView.reloadData()
+                        self?.noteOutlineView.reloadData()
                     }
                 }
                 return cell
@@ -710,6 +891,11 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
                     DispatchQueue.main.async {
                         self.view.window?.makeFirstResponder(cell?.inputTextF)
                     }
+                } else if let con = data.editAnnoModel?.anno?.contents, con.isEmpty == false {
+                    cell?.inputTextF.stringValue = con
+                    DispatchQueue.main.async {
+                        self.view.window?.makeFirstResponder(cell?.inputTextF)
+                    }
                 } else {
                     if let cont = data.inputContent {
                         cell?.inputTextF.stringValue = cont
@@ -761,6 +947,22 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
                             }
                             return
                         }
+                        
+                        if let con = data.editAnnoModel?.anno?.contents, con.isEmpty == false { // 编辑
+                            let model = data.editAnnoModel
+                            model?.anno?.contents = content
+                            model?.anno?.setUserName(KMPreference.shared.author)
+                            
+                            // 置空编辑状态
+                            data.replyModel = nil
+                            data.inputContent = nil
+                            data.editAnnoModel = nil
+                            self?.noteOutlineView.reloadData()
+                            if let row = self?.noteOutlineView.row(forItem: data) {
+                                self?.noteOutlineView.scrollRowToVisible(row)
+                            }
+                            return
+                        }
                         if let replyAnno = self?.noteReplyHanddler.createReplyAnnotation(data.anno, content: content, userName: KMPreference.shared.author) {
                             let model = KMBotaAnnotationReplyModel()
                             model.anno = data.anno
@@ -827,27 +1029,14 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
             }
             cell.itemClick = { [weak self] idx , _ in
                 if idx == 1 { // Markup
-                    let anno = model?.anno
-                    guard let state = self?.noteReplyHanddler.fetchAnnoState(anno), state == .marked else {
-                        self?.noteReplyHanddler.markAnnotation(anno)
-                        self?.noteOutlineView.reloadItem(model)
-                        return
+                    if model != nil {
+                        self?.updateMarkState(model: model!)
                     }
-                    self?.noteReplyHanddler.unMarkAnnotation(anno)
-                    self?.noteOutlineView.reloadItem(model)
                 }
             }
             cell.isUnFoldNote = { [weak self] cellNote, isUnfold in
-                // 将折叠状态记录到模型
-                model?.foldType = isUnfold  ? .unfold : .fold
-                
-                model?.footerModel?.isExpand = isUnfold
-                model?.isExpand = isUnfold
-                self?.noteOutlineView.reloadData()
-                DispatchQueue.main.async {
-                    if let row = self?.noteOutlineView.row(forItem: item) {
-                        self?.noteOutlineView.scrollRowToVisible(row)
-                    }
+                if model != nil {
+                    self?.updateExpand(model: model!, isExpand: isUnfold, item: item)
                 }
             }
             return cell
@@ -882,9 +1071,27 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
             let itemView = KMBotaTableRowView()
             if let data = item as? KMBotaAnnotationBaseModel {
                 itemView.isSelected = data.isSelected
-                
-                
             }
+            let rowIndexes = self.noteOutlineView.selectedRowIndexes
+
+            itemView.rightMouseCallback = { [weak self] (view, event) in
+                if let data = item as? KMBotaAnnotationFooterModel {
+                    
+                } else {
+                    if !KMOCToolClass.arrayContains(array: self?.selectedObjcNotes(), annotation: item) ||
+                        self?.selectedObjcNotes().count == 1 {
+                        let index = self?.noteOutlineView.row(forItem: item)
+                        self?.noteOutlineView.selectRowIndexes(IndexSet(integer: IndexSet.Element(index ?? 0)), byExtendingSelection: false)
+                    }
+                    
+                    let row = outlineView.row(forItem: item)
+                    if outlineView.rowView(atRow: row, makeIfNecessary: false) != nil {
+                        let rowView = outlineView.rowView(atRow: row, makeIfNecessary: false)
+                        self?.showRightGropView(raw: row, event: event, view: rowView,item: item)
+                    }
+                }
+            }
+            
             itemView.selectCallback = { theView in
                 let isSelected = theView.isSelected
                 
@@ -930,37 +1137,12 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
     
     func outlineView(_ outlineView: NSOutlineView, selectionIndexesForProposedSelection proposedSelectionIndexes: IndexSet) -> IndexSet {
         if outlineView.isEqual(to: self.noteOutlineView) {
-            var indexs = proposedSelectionIndexes
             for i in proposedSelectionIndexes {
                 let item = self.noteOutlineView.item(atRow: i)
-                var model: KMBotaAnnotationModel?
-                if let data = item as? KMBotaAnnotationSectionModel {
-                    
-                }
-                if let data = item as? KMBotaAnnotationModel {
-                    model = data
-                }
-                if let data = item as? KMBotaAnnotationReplyModel {
-                    model = data.annoModel
-                }
                 if let data = item as? KMBotaAnnotationFooterModel {
-                    model = data.annoModel
-                }
-                
-                if let data = model {
-                    let row = self.noteOutlineView.row(forItem: data)
-                    indexs.insert(row)
-                    var i = 1
-                    if data.isExpand {
-                        for item in data.replyAnnos {
-                            indexs.insert(row+i)
-                            i += 1
-                        }
-                    }
-                    indexs.insert(row+i)
+                    return IndexSet()
                 }
             }
-            return indexs
         }
         return proposedSelectionIndexes
     }
@@ -1321,6 +1503,159 @@ extension KMLeftSideViewController: ComponentGroupDelegate {
                 removeAllAnnotations(nil)
             } else if menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_DeleteRep {
                 removeAllReplyAnnotations(nil)
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_EditNote) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        let model = models.first
+                        if model != nil {
+                            updateExpand(model: model!, isExpand: true, item: currentItem)
+                            noteReplyHanddler.editAnnotation(annotationModel: model!)
+                            DispatchQueue.main.async {
+                                let row = self.noteOutlineView.row(forItem: model?.footerModel)
+                                self.noteOutlineView.scrollRowToVisible(row)
+                            }
+                            self.noteOutlineView.reloadData()
+                        }
+                    }
+                } else if let anModels = menuItemProperty?.representedObject as? [KMBotaAnnotationReplyModel] {
+                    if anModels.first != nil {
+                        let model = anModels.first
+                        noteReplyHanddler.editReplyAnnotation(replyModel: model)
+                        DispatchQueue.main.async {
+                             let row = self.noteOutlineView.row(forItem: model?.annoModel?.footerModel)
+                            self.noteOutlineView.scrollRowToVisible(row)
+                        }
+                        self.noteOutlineView.reloadData()
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_AddRep) {
+                if let anModels = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if anModels.first != nil {
+                        if let model = anModels.first {
+                            self.updateExpand(model: model, isExpand: true, item: currentItem)
+                            if let footMode = model.footerModel {
+                                let row = self.noteOutlineView.row(forItem: footMode)
+                                let rowView = self.noteOutlineView.rowView(atRow: row, makeIfNecessary: true)
+                                if(row != nil) {
+                                    for subview in rowView!.subviews {
+                                        if let cell = subview as? KMNoteFooterCellView {
+                                            cell.inputTextF.becomeFirstResponder()
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_AddMark) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        updateMarkState(model: models.first!)
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_RepStateNone) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        updateReplaState(model:models.first! , state:.none)
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_RepStateAccepted) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        updateReplaState(model:models.first! , state:.accepted)
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_RepStateRejected) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        updateReplaState(model:models.first! , state:.rejected)
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_RepStateCancelled) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        updateReplaState(model:models.first! , state:.canceled)
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_RepStateCompleted) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        updateReplaState(model:models.first! , state:.completed)
+                    }
+                }
+            } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_ShowPopUI) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        let model = models.first
+                        updateExpand(model: model!, isExpand: !(model?.isExpand == true), item: currentItem)
+                    }
+                }
+            } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Copy) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationReplyModel] {
+                    if models.first != nil {
+                        let model = models.first
+                        let an = model?.anno
+                        var copyText:String = ""
+                        if an?.isKind(of: CPDFMarkupAnnotation.self) == true {
+                            if let markupAn = an as? CPDFMarkupAnnotation {
+                                copyText = markupAn.markupContent()
+                            }
+                        } else if an?.isKind(of: CPDFFreeTextAnnotation.self) == true ||
+                                  an?.isKind(of: CPDFTextAnnotation.self) == true {
+                            copyText = an?.contents ?? ""
+                            let pboard = NSPasteboard.general
+                            if copyText.isEmpty == false {
+                                pboard.clearContents()
+                                pboard.writeObjects([copyText as NSPasteboardWriting])
+                            }
+                        }
+                    }
+                }
+            } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_Delete) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationModel] {
+                    if models.first != nil {
+                        let model = models.first
+                        self.outlineView(self.noteOutlineView, deleteItems:[model!])
+                    }
+                }
+            } else if (menuItemProperty?.identifier == PDFViewMenuIdentifier_Normal_CopyText) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationReplyModel] {
+                    if models.first != nil {
+                        let model = models.first
+                        
+                        var copyText:String = ""
+                        copyText = model?.replyAnno?.contents ?? ""
+                        let pboard = NSPasteboard.general
+                        if copyText.isEmpty == false {
+                            pboard.clearContents()
+                            pboard.writeObjects([copyText as NSPasteboardWriting])
+                        }
+                    }
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_DeleteMuteRep) {
+                if let models = menuItemProperty?.representedObject as? [Any] {
+                    for i in 0 ..< models.count {
+                        let model = models[i]
+                        if let replyModel = model as? KMBotaAnnotationReplyModel {
+                            noteReplyHanddler.removeReplyAnnotation(replyModel.replyAnno)
+                            replyModel.annoModel?.replyAnnos.removeObject(replyModel)
+                        } else if let anModel = model as? KMBotaAnnotationModel {
+                            self.outlineView(self.noteOutlineView, deleteItems:[anModel])
+                        }
+                    }
+                    self.noteOutlineView.reloadData()
+                }
+            } else if (menuItemProperty?.identifier == BOTAMenuIdentifier_Annotation_DeleteSignRep) {
+                if let models = menuItemProperty?.representedObject as? [KMBotaAnnotationReplyModel] {
+                    if models.first != nil {
+                        let model = models.first
+                        if model != nil {
+                            noteReplyHanddler.removeReplyAnnotation(model?.replyAnno)
+                            model?.annoModel?.replyAnnos.removeObject(model!)
+                        }
+                        self.noteOutlineView.reloadData()
+                    }
+                }
             }
         }
     }

+ 2 - 0
PDF Office/PDF Master/KMClass/Left/Annotaion/Model/KMAnnotationModel.swift

@@ -55,6 +55,8 @@ class KMBotaAnnotationFooterModel: KMBotaAnnotationBaseModel {
     
     weak var replyModel: KMBotaAnnotationReplyModel?
     
+    weak var editAnnoModel: KMBotaAnnotationModel?
+
     var inputContent: String?
     
     var isFirstResp = false

+ 24 - 0
PDF Office/PDF Master/KMClass/Left/Annotaion/View/KMBotaTableRowView.swift

@@ -8,9 +8,14 @@
 import Cocoa
 import KMComponentLibrary
 
+typealias KMAnnOutlineRowViewRightMouseCallback = (_ view: KMBotaTableRowView, _ event: NSEvent) -> Void
+
 class KMBotaTableRowView: NSTableRowView {
     var selectCallback: ((KMBotaTableRowView)->Void)?
+    var rightMouseCallback: KMAnnOutlineRowViewRightMouseCallback?
     
+    var contentBox: KMBox?
+
     convenience init() {
         self.init(frame: .zero)
         
@@ -19,6 +24,8 @@ class KMBotaTableRowView: NSTableRowView {
 
     override func draw(_ dirtyRect: NSRect) {
         super.draw(dirtyRect)
+     
+        addBox()
 
         // Drawing code here.
     }
@@ -28,6 +35,23 @@ class KMBotaTableRowView: NSTableRowView {
         self.addTrackingArea(trackingArea)
     }
     
+    func addBox() {
+        if self.contentBox == nil {
+            let rect = self.bounds
+            self.contentBox?.wantsLayer = true
+            self.contentBox = KMBox(frame: rect)
+            self.contentBox?.borderWidth = 0
+            self.contentBox?.boxType = .custom
+            self.contentBox?.autoresizingMask = [.width, .height]
+            self.contentBox?.rightDownCallback = { [unowned self] (downEntered, mouseBox, event) in
+                guard let callBack = rightMouseCallback else { return }
+                
+                callBack(self, event)
+            }
+        }
+        self.addSubview(contentBox!)
+    }
+    
     override func drawSelection(in dirtyRect: NSRect) {
         let selectionRect = self.bounds
         let color = ComponentLibrary.shared.getComponentColorFromKey("colorPrimary/bg-opacity-dark")

+ 1 - 1
PDF Office/PDF Master/KMClass/Left/Annotaion/View/KMNoteFooterCellView.swift

@@ -112,7 +112,7 @@ class KMNoteFooterCellView: NSTableCellView, NibLoadable {
         self.inputRespButton_.frame = self.inputBox.contentView?.bounds ?? .zero
         self.inputRespButton_.autoresizingMask = [.width, .height]
 
-        self.replyButton.title = KMLocalizedString("Reply")
+        self.replyButton.title = KMLocalizedString("Done")
         self.replyButton.wantsLayer = true
 
         self.replyButtonBox.cornerRadius = 1

+ 0 - 20
PDF Office/PDF Master/KMClass/NewBatch/KMBatchManager/KMBatchManager.swift

@@ -1,20 +0,0 @@
-//
-//  KMBatchManager.swift
-//  PDF Master
-//
-//  Created by lizhe on 2023/2/17.
-//
-
-import Cocoa
-
-enum KMBatchManagerSate: String, CaseIterable {
-    case unknow
-    case processing
-}
-
-class KMBatchManager: NSObject {
-    public static let manager = KMBatchManager()
-    fileprivate(set) var state: KMBatchManagerSate = .unknow
-    
-    
-}

+ 3 - 1
PDF Office/PDF Master/KMClass/NewBatch/KMBatchWindowController.swift

@@ -195,7 +195,9 @@ class KMBatchWindowController: NSWindowController {
 extension KMBatchWindowController: KMBatchProcessingViewDelegate {
     func reloadData(data: [KMBatchProcessingTableViewModel]) {
         self.batchData = data
-        self.settingView.filesData = self.batchData
+        
+        KMBatchManager.manager.filesData = data
+        self.settingView.filesData = data
     }
 }
 

+ 643 - 0
PDF Office/PDF Master/KMClass/NewBatch/Manager/KMBatchManager.swift

@@ -0,0 +1,643 @@
+//
+//  KMBatchManager.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/2/17.
+//
+
+import Cocoa
+
+enum KMBatchManagerSate: Int, CaseIterable {
+    case unknow = 0
+    case processing
+    case complete
+    case error
+}
+
+let kBacthFilesProcessNotification = "kBacthFilesProcessNotification"
+let kBacthProcessNotification = "kBacthProcessNotification"
+
+class KMBatchManager: NSObject {
+    public static let manager = KMBatchManager()
+    fileprivate(set) var state: KMBatchManagerSate = .unknow
+    
+    var filesData: [KMBatchProcessingTableViewModel] = []
+    
+    func batch(type: KMBatchCollectionViewType, data: KMBatchSettingItemViewModel) {
+        let panel = NSOpenPanel()
+        panel.canChooseFiles = false
+        panel.canChooseDirectories = true
+        panel.canCreateDirectories = true
+        panel.beginSheetModal(for: NSWindow.currentWindow()) { response in
+            if response == .cancel {
+                return
+            }
+            
+            let outputFolderPath = (panel.url?.path)!
+            //
+            self.batchUnkown()
+            
+            switch type {
+            case .convertPDF:
+                self.convertPDFExport(data: data, outputFolderPath: outputFolderPath)
+                break
+            case .OCR:
+                self.convertOCRExport(data: data, outputFolderPath: outputFolderPath)
+                break
+            case .compress:
+                self.compressExport(data: data, outputFolderPath: outputFolderPath)
+                break
+            case .security:
+                self.securityExport(data: data, outputFolderPath: outputFolderPath)
+                break
+            case .watermark:
+                
+                break
+            case .background:
+                
+                break
+            case .headerAndFooter:
+                
+                break
+            case .batesNumber:
+                
+                break
+            case .batchRemove:
+                self.removeApplay(data: data, outputFolderPath: outputFolderPath)
+                break
+            default:
+                KMPrint("找不到")
+                break
+            }
+            
+            //
+            self.batchProgress()
+        }
+    }
+}
+
+protocol KMBatchSettingViewExport {}
+extension KMBatchManager: KMBatchSettingViewExport {
+    //MARK: 转档
+    func convertPDFExport(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
+        self.convertFile(outputFolderPath: outputFolderPath, data: data, filesData: self.filesData)
+    }
+    
+    func convertFile(outputFolderPath: String, data: KMBatchSettingItemViewModel, filesData: [KMBatchProcessingTableViewModel]) {
+        if filesData.count != 0 {
+            DispatchQueue.global().async {
+                for i in 0..<filesData.count {
+                    let item = filesData[i]
+                    //创建Document
+                    let filePath = item.filePath
+                    let document = self.fetchDocument(filePath: filePath, model: item)
+                    
+                    let settingData = data as? KMBatchConvertPDFViewModel  ?? KMBatchConvertPDFViewModel()
+                    var fileName = filePath.deletingPathExtension.lastPathComponent
+                    if ((fileName.isEmpty)) {
+                        fileName = NSLocalizedString("Untitled", comment: "")
+                    }
+                    
+                    let convert = self.addConvertParameter(settingData)
+                    
+                    let pageCount = document.pageCount
+                    //获取page
+                    var pages:[Int] = []
+                    for i in 0..<pageCount {
+                        pages.append(Int(i)+1)
+                    }
+                    
+                    convert.outputFolderPath = outputFolderPath
+                    convert.filePath = filePath
+                    convert.outputFileName = fileName
+                    convert.pages = pages
+                    
+                    convert.isAllowOCR = settingData.needRecognizeText
+                    convert.ocrLanguage = settingData.languageType
+                    
+                    item.state = .clock
+                    KMPDFConvertManager.defaultManager.convert(convert: convert, progress: { [unowned self] progressValue in
+                        print("转档进度 - \(progressValue)")
+                        let progress = Float(progressValue) / Float(pageCount)
+                        self.itemProgress(item: item, processValue: progress)
+                    }, completion: { [unowned self] finished, error in
+                        if finished {
+                            if FileManager.default.fileExists(atPath: outputFolderPath) {
+                                NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputFolderPath)])
+                            }
+                            self.itemSuccess(item: item)
+                        } else {
+                            self.itemFailure(item: item, error: error! as NSError)
+                        }
+                        
+                        if i == self.filesData.count - 1 {
+                            self.batchSuccess()
+                        }
+                    })
+                }
+            }
+        }
+    }
+    
+    func addConvertParameter(_ data: KMBatchConvertPDFViewModel) -> KMPDFConvert {
+        let settingData = data
+        var convert = KMPDFConvert()
+        
+        switch settingData.convertPDFType {
+        case .word:
+            convert = KMPDFConvertWord()
+            if settingData.layoutSettingType == .flowingText {
+                convert.isAllInOneSheet = false
+            } else {
+                convert.isAllInOneSheet = true
+            }
+        case .excel:
+            convert = KMPDFConvertExcel()
+            if settingData.excelSetting == .separate {
+                convert.isAllInOneSheet = false
+                convert.isExtractTable = false
+            } else if settingData.excelSetting == .format {
+                convert.isAllInOneSheet = true
+                convert.isExtractTable = false
+            } else if settingData.excelSetting == .tables {
+                convert.isAllInOneSheet = false
+                convert.isExtractTable = true
+                
+                switch settingData.excelTablesType {
+                case .oneTable:
+                    convert.extractTableIndex = 0
+                case .pageTable:
+                    convert.extractTableIndex = 1
+                case .allTable:
+                    convert.extractTableIndex = 2
+                default:
+                    KMPrint("未找到")
+                }
+            }
+        case .ppt:
+            convert = KMPDFConvertPPT()
+        case .csv:
+            convert = KMPDFConvertCSV()
+            if settingData.csvOnlyTables {
+                convert.isExtractTable = true
+                switch settingData.excelTablesType {
+                case .oneTable:
+                    convert.extractTableIndex = 0
+                case .pageTable:
+                    convert.extractTableIndex = 1
+                case .allTable:
+                    convert.extractTableIndex = 2
+                default:
+                    KMPrint("未找到")
+                }
+            } else {
+                convert.isExtractTable = false
+            }
+        case .image:
+            convert = KMPDFConvertImage()
+            convert.convertType = data.imageType
+            
+            var dpi: Int = 150
+            if data.imageDpiIndex == 0 {
+                dpi = 50
+            } else if data.imageDpiIndex == 1 {
+                dpi = 72
+            } else if data.imageDpiIndex == 2 {
+                dpi = 96
+            } else if data.imageDpiIndex == 3 {
+                dpi = 150
+            } else if data.imageDpiIndex == 4 {
+                dpi = 300
+            } else if data.imageDpiIndex == 5 {
+                dpi = 600
+            } else {
+                dpi = 150
+            }
+            
+            if (convert.convertType == .jpeg) {
+                (convert as! KMPDFConvertImage).imageType = .JPEG
+                (convert as! KMPDFConvertImage).imageDpi = dpi
+                
+            } else if (convert.convertType == .png) {
+                (convert as! KMPDFConvertImage).imageType = .PNG
+                (convert as! KMPDFConvertImage).imageDpi = dpi
+            } else {
+                (convert as! KMPDFConvertImage).imageDpi = 150
+            }
+        case .html:
+            convert = KMPDFConvertHTML()
+        case .rtf:
+            convert = KMPDFConvertRTF()
+        case .json:
+            convert = KMPDFConvertJson()
+            if settingData.jsonType == .extractText {
+                convert.isAllInOneSheet = false
+            } else {
+                convert.isAllInOneSheet = true
+            }
+        case .text:
+            convert = KMPDFConvertText()
+            
+        default:
+            KMPrint("不清楚")
+        }
+        return convert
+    }
+    
+    //MARK: OCR
+    func convertOCRExport(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
+        self.convertOCR(outputFolderPath: outputFolderPath, data: data as! KMOCRModel, filesData: self.filesData)
+    }
+    
+    func convertOCR(outputFolderPath: String, data: KMOCRModel, filesData: [KMBatchProcessingTableViewModel]?) {
+        let filesData = self.filesData
+        for i in 0..<filesData.count {
+            let item = (filesData[i])
+            let document = CPDFDocument.init(url: URL(fileURLWithPath: item.filePath))
+            if document != nil {
+                //计算需要处理的页面
+                
+                var fileName = item.filePath.deletingPathExtension.lastPathComponent
+                if ((fileName.isEmpty)) {
+                    fileName = NSLocalizedString("Untitled", comment: "")
+                }
+                let path = outputFolderPath + "/" + fileName + ".pdf"
+                
+                KMOCRManager.manager.convertBatchOCR(document: document!, saveFilePath: path, model: data, progress: { [unowned self] progress in
+                    self.itemProgress(item: item, processValue: progress)
+                }) { [unowned self] document, text, error in
+                    if error == nil {
+                        self.itemSuccess(item: item)
+                    } else {
+                        self.itemFailure(item: item, error: error! as NSError)
+                    }
+                    
+                    if i == self.filesData.count - 1 {
+                        self.batchSuccess()
+                    }
+                }
+            }
+        }
+    }
+    
+    //MARK: 压缩
+    func compressExport(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
+        self.compressFile(outputFolderPath: outputFolderPath, data: (data as? KMCompressSettingModel)!, filesData: self.filesData)
+    }
+    
+    func compressFile(outputFolderPath: String, data: KMCompressSettingModel, filesData: [KMBatchProcessingTableViewModel]) {
+        if filesData.count != 0 {
+            for i in 0..<filesData.count {
+                let item = filesData[i]
+                let document = CPDFDocument.init(url: URL(fileURLWithPath: item.filePath))
+                if document != nil {
+                    var fileName = item.filePath.deletingPathExtension.lastPathComponent
+                    if ((fileName.isEmpty)) {
+                        fileName = NSLocalizedString("Untitled", comment: "")
+                    }
+                    let path = outputFolderPath + "/" + fileName + ".pdf"
+                    
+                    KMCompressManager.shared.compress(documentURL: URL(fileURLWithPath: item.filePath), fileURL: URL(fileURLWithPath: path), limit: false, model: data) { currentPage, totalPages in
+                        let progress = Float(currentPage) / Float(totalPages)
+                        self.itemProgress(item: item, processValue: progress)
+                    } cancelHandler: {
+                        return false
+                    } completionHandler: { [unowned self] isFinish in
+                        if isFinish {
+                            self.itemSuccess(item: item)
+                        } else {
+                            self.itemFailure(item: item, error: nil)
+                        }
+                        
+                        if i == self.filesData.count - 1 {
+                            self.batchSuccess()
+                        }
+                    }
+                }
+                
+            }
+        }
+    }
+    
+    //MARK: 安全
+    func securityExport(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
+        self.securityFile(outputFolderPath: outputFolderPath, data: data as! KMBatchSecurityViewModel, filesData: self.filesData)
+    }
+    
+    func securityFile(outputFolderPath: String, data: KMBatchSecurityViewModel, filesData: [KMBatchProcessingTableViewModel]) {
+        if filesData.count != 0 {
+            for i in 0..<filesData.count {
+                let item = filesData[i]
+                let docuemt = CPDFDocument.init(url: URL(fileURLWithPath: item.filePath))
+                if (docuemt != nil) {
+                    var fileName = item.filePath.deletingPathExtension.lastPathComponent
+                    if ((fileName.isEmpty)) {
+                        fileName = NSLocalizedString("Untitled", comment: "")
+                    }
+                    let path = outputFolderPath + "/" + fileName + ".pdf"
+                    
+                    var options: [CPDFDocumentWriteOption : Any] = [:]
+                    //开启密码
+                    if data.isOpenPassword &&
+                        !data.openPasswordString.isEmpty {
+                        options.updateValue(data.openPasswordString, forKey: .userPasswordOption)
+                    }
+//
+                    //权限密码
+                    if data.isPermission &&
+                        !data.permissionString.isEmpty {
+                        options.updateValue(data.permissionString, forKey: .ownerPasswordOption)
+                    }
+                        
+                    // 限制打印
+                    if data.restrictOptions.contains(.print) {
+                        options.updateValue(false, forKey: .allowsPrintingOption)
+                    } else {
+                        options.updateValue(true, forKey: .allowsPrintingOption)
+                    }
+                    
+                    //限制复制
+                    if data.restrictOptions.contains(.copy) {
+                        options.updateValue(false, forKey: .allowsCopyingOption)
+                    } else {
+                        options.updateValue(true, forKey: .allowsCopyingOption)
+                    }
+                    
+                    
+                    let result = docuemt!.write(toFile: path, withOptions: options)
+//                    let result = docuemt!.write(to: URL(fileURLWithPath: path), withOptions: options)
+                    if result {
+                        KMPrint("成功")
+                        self.itemSuccess(item: item)
+                    } else {
+                        KMPrint("失败")
+                        self.itemFailure(item: item, error: nil)
+                    }
+                    
+                    if i == self.filesData.count - 1 {
+                        self.batchSuccess()
+                        NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputFolderPath)])
+                    }
+                }
+            }
+        }
+    }
+    
+    
+    func waterMarkApplay(data: KMBatchSettingItemViewModel) {
+
+    }
+    
+//    func waterMarkFile(data: KMWatermarkAdjectiveBaseModel, filesData: [KMBatchProcessingTableViewModel]?) {
+//
+//    }
+    
+    func backgroundApplay(data: KMBatchSettingItemViewModel) {
+        
+    }
+    
+    func backgroundFile(outputFolderPath: String, data: KMBackgroundModel, filesData: [KMBatchProcessingTableViewModel]?) {
+        
+    }
+    
+    
+    func headAndFooterApplay(data: KMBatchSettingItemViewModel) {
+        
+    }
+    
+//    func headAndFooterFile(outputFolderPath: String, data: KMHeaderFooterModel, filesData: [KMBatchProcessingTableViewModel]?) {
+//
+//    }
+    
+    func batesApplay(data: KMBatchSettingItemViewModel) {
+        
+    }
+    
+    func batesFile(outputFolderPath: String, data: KMBatesModel, filesData: [KMBatchProcessingTableViewModel]?) {
+        
+    }
+    
+    
+    func removeApplay(data: KMBatchSettingItemViewModel, outputFolderPath: String) {
+        if (data == nil) {
+            let alert = NSAlert()
+            alert.alertStyle = .critical
+            alert.messageText = "没有找到"
+            alert.runModal()
+            return
+        }
+        
+        let panel = NSOpenPanel()
+        let button = NSButton.init(checkboxWithTitle: "保存后打开文档", target: nil, action: nil)
+        button.state = .on
+        panel.accessoryView = button
+        panel.canChooseFiles = false
+        panel.canChooseDirectories = true
+        panel.canCreateDirectories = true
+        panel.beginSheetModal(for: NSWindow.currentWindow()) { [self] response in
+            if response == .cancel {
+                return
+            }
+            let outputFolderPath = panel.url?.path
+            
+            self.removeFile(outputFolderPath: outputFolderPath!, data: data as! KMBatchRemoveViewModel, filesData: self.filesData)
+        }
+    }
+    
+    func removeFile(outputFolderPath: String, data: KMBatchRemoveViewModel, filesData: [KMBatchProcessingTableViewModel]) {
+        if filesData.count != 0 {
+            for i in 0..<filesData.count {
+                let item = filesData[i]
+//                DispatchQueue.global().async {
+                    var fileName = item.filePath.deletingPathExtension.lastPathComponent
+                    if ((fileName.isEmpty)) {
+                        fileName = NSLocalizedString("Untitled", comment: "")
+                    }
+                    
+                    let path = outputFolderPath + "/" + fileName + ".pdf"
+                    let document = CPDFDocument.init(url: URL(fileURLWithPath: item.filePath))
+                    if document != nil {
+                        if (document!.allowsPrinting == false || document!.allowsCopying == false) {
+                            let alert = NSAlert()
+                            alert.alertStyle = .critical
+                            alert.messageText = "此文档不允许修改"
+                            alert.runModal()
+                            return
+                        }
+                        
+                        if (data.options.contains(.security)) {
+                            
+                        }
+                        
+                        if (data.options.contains(.batesNumber)) {
+                            let property = document!.bates()
+                            property?.clear()
+                        }
+                        if (data.options.contains(.headerAndFooter)) {
+                            let property = document!.headerFooter()
+                            property?.clear()
+                        }
+                        if (data.options.contains(.background)) {
+                            let property = document!.background()
+                            property?.clear()
+                        }
+                        if (data.options.contains(.watermark)) {
+                            let array: Array<CPDFWatermark> = document!.watermarks() ?? []
+                            for model in array {
+                                document!.removeWatermark(model)
+                            }
+                        }
+                        
+                        if (FileManager.default.fileExists(atPath: path)) {
+                            try?FileManager.default.removeItem(atPath: path)
+                        }
+                        
+                        let result = document!.write(to: URL(fileURLWithPath: path))
+                        if (result) {
+                            KMPrint("removeFile成功")
+                            self.itemSuccess(item: item)
+                        } else {
+                            KMPrint("removeFile失败")
+                            self.itemFailure(item: item, error: nil)
+                        }
+                        if i == self.filesData.count - 1 {
+                            self.batchSuccess()
+                        }
+                        NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputFolderPath)])
+                    }
+//                }
+            }
+        }
+    }
+}
+
+//MARK: private
+extension KMBatchManager {
+    func fetchDocument(filePath: String, model: KMBatchProcessingTableViewModel) -> CPDFDocument {
+        var document = CPDFDocument(url: URL(fileURLWithPath: filePath))
+        
+        
+        if model.pageRange == .all {
+            
+        } else {
+            let data = KMOCRModel()
+            data.pageRangeType = model.pageRange
+            data.pageRangeString = model.pageRangeString
+           
+            let pages:[Int] = KMOCRManager.manager.fetchPageIndex(document: document!, model: data)
+            
+            var tempDocument = CPDFDocument()
+            for i in 0..<pages.count {
+                let page = document?.page(at: UInt(i))
+                tempDocument?.insertPageObject(page, at: tempDocument?.pageCount ?? 0)
+            }
+            
+            let fileName = filePath.deletingPathExtension.lastPathComponent
+            let isSuccess = tempDocument?.write(toFile: self.fetchTempFilePath(fileName: fileName))
+            if isSuccess != nil {
+                document = tempDocument
+            }
+        }
+        
+        return document ?? CPDFDocument()
+    }
+    
+    func fetchTempFilePath(fileName: String) -> String {
+        let floderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("BatchTemp")
+        let filePath = floderPath?.stringByAppendingPathComponent("\(fileName).pdf")
+
+        if let data = floderPath, !FileManager.default.fileExists(atPath: data) {
+            try?FileManager.default.createDirectory(atPath: data, withIntermediateDirectories: false)
+        }
+        if let data = filePath, !FileManager.default.fileExists(atPath: data) {
+            FileManager.default.createFile(atPath: data, contents: nil)
+        }
+        return filePath ?? ""
+    }
+    
+    func removeTempFilePath(filePath: String) {
+        let fileName = filePath.deletingPathExtension.lastPathComponent
+        let path = self.fetchTempFilePath(fileName: fileName)
+        
+        if (FileManager.default.fileExists(atPath: path)) {
+            try?FileManager.default.removeItem(atPath: path)
+        }
+    }
+}
+
+//MARK: Alert
+extension KMBatchManager {
+    func batchUnkown() {
+        self.state = .unknow
+        NotificationCenter.default.post(name: NSNotification.Name(kBacthProcessNotification), object: nil)
+    }
+    
+    func batchProgress() {
+        self.state = .processing
+        NotificationCenter.default.post(name: NSNotification.Name(kBacthProcessNotification), object: nil)
+    }
+    
+    func batchSuccess() {
+        self.state = .complete
+        NotificationCenter.default.post(name: NSNotification.Name(kBacthProcessNotification), object: nil)
+    }
+    
+    func batchFailure() {
+        self.state = .error
+        NotificationCenter.default.post(name: NSNotification.Name(kBacthProcessNotification), object: nil)
+    }
+    
+    func itemProgress(item: KMBatchProcessingTableViewModel, processValue: Float) {
+        if processValue > 0.7 {
+            item.state = .loading70
+        } else {
+            item.state = .loading
+        }
+        NotificationCenter.default.post(name: NSNotification.Name(kBacthFilesProcessNotification), object: item)
+    }
+    
+    func itemSuccess(item: KMBatchProcessingTableViewModel) {
+        self.removeTempFilePath(filePath: item.filePath)
+        item.state = .success
+        NotificationCenter.default.post(name: NSNotification.Name(kBacthFilesProcessNotification), object: item)
+    }
+    
+    func itemFailure(item: KMBatchProcessingTableViewModel, error: NSError?) {
+        self.removeTempFilePath(filePath: item.filePath)
+        item.state = .error
+        NotificationCenter.default.post(name: NSNotification.Name(kBacthFilesProcessNotification), object: item)
+        
+        guard let error = error else { return }
+        var errorString = ""
+        let myError: NSError = error as NSError
+        if myError.code == 1 {
+            errorString = NSLocalizedString("Password required or incorrect password. Please re-enter your password and try again", comment: "")
+        } else if myError.code == 2 {
+            errorString = NSLocalizedString("The license doesn't allow the permission", comment: "")
+        } else if myError.code == 3 {
+            errorString = NSLocalizedString("Malloc failure", comment: "")
+        } else if myError.code == 4 {
+            errorString = NSLocalizedString("Unknown error in processing conversion. Please try again later", comment: "")
+        } else if myError.code == 5 {
+            errorString = NSLocalizedString("Unknown error in processing PDF. Please try again later", comment: "")
+        } else if myError.code == 6 {
+            errorString = NSLocalizedString("File not found or could not be opened. Check if your file exists or choose another file to convert", comment: "")
+        } else if myError.code == 7 {
+            errorString = NSLocalizedString("File not in PDF format or corruptead. Change a PDF file and try again", comment: "")
+        } else if myError.code == 8 {
+            errorString = NSLocalizedString("Unsupported security scheme", comment: "")
+        } else if myError.code == 9 {
+            errorString = NSLocalizedString("Page not found or content error", comment: "")
+        } else {
+            errorString = NSLocalizedString("Table not found", comment: "")
+        }
+        
+        let alert = NSAlert()
+        alert.alertStyle = .critical
+        alert.messageText = NSLocalizedString("Conversion Failed", comment: "")
+        alert.informativeText = errorString
+        alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+        alert.runModal()
+    }
+}
+

+ 12 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/KMBatchProcessingView.swift

@@ -44,6 +44,10 @@ class KMBatchProcessingView: BaseXibView {
         // Drawing code here.
     }
     
+    deinit {
+        NotificationCenter.default.removeObserver(self)
+    }
+    
     override func setup() {
         
         self.backgroundColor(ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-low"))
@@ -94,6 +98,8 @@ class KMBatchProcessingView: BaseXibView {
         
         self.tableView.delegate = self
         self.reloadData()
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(bacthFilesProcessingNotification), name: NSNotification.Name(kBacthFilesProcessNotification), object: nil)
     }
     
     func reloadData() {
@@ -309,3 +315,9 @@ extension KMBatchProcessingView: ComponentGroupDelegate {
         self.addFilesMoreButton.reloadData()
     }
 }
+
+extension KMBatchProcessingView {
+    @objc func bacthFilesProcessingNotification() {
+        self.reloadData()
+    }
+}

+ 2 - 1
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/KMBatchProcessingTableViewModel/KMBatchProcessingTableViewModel.swift

@@ -31,6 +31,7 @@ enum KMBatchProcessingTableFileState: String, CaseIterable {
     case success = "icon_tip_success_small" //成功
     case clock = "icon_tip_clock_small" // 等待
     case loading = "icon_tip_loading_small" // 正在进行中
+    case loading70 = "progress-circle-mini" // 正在进行中
     
     static func allValues() -> [String] {
         var array: [String] = []
@@ -52,6 +53,7 @@ class KMBatchProcessingTableViewModel: NSObject {
     private(set) var size: CGSize = NSZeroSize
     private(set) var image: NSImage = NSImage()
     var state: KMBatchProcessingTableFileState = .clock
+    var progressValue: Float = 0
     
     static func initWithFilePath(url:URL) -> KMBatchProcessingTableViewModel {
         let model = KMBatchProcessingTableViewModel.init()
@@ -76,7 +78,6 @@ class KMBatchProcessingTableViewModel: NSObject {
         return model
     }
     
-    
     // MARK: 
     func moniker (x:Float) -> String {
         return x >= 1024.0 ?(x < 1048576.0 ? "M":"G"):"K"

+ 17 - 1
PDF Office/PDF Master/KMClass/NewBatch/View/KMBatchProcessingView/Tableview/Views/Tableview/Views/KMBatchProcessingStateTableCell.swift

@@ -47,11 +47,27 @@ class KMBatchProcessingStateTableCell: KMBatchProcessingTableCell {
     
     override func setup() {
         super.setup()
-        
     }
     
     override func reloadData() {
         super.reloadData()
         self.iconImageView.image = NSImage(named: self.model.state.rawValue)
+        
+        var toolTipString = "Waiting"
+        switch self.model.state {
+        case .clock:
+            toolTipString = "Waiting"
+        case .loading70:
+            toolTipString = "70%"
+        case .error:
+            toolTipString = "Error info"
+        case .loading:
+            toolTipString = "Progressing"
+        case .success:
+            toolTipString = "100%"
+        default:
+            break
+        }
+        self.iconImageView.toolTip = toolTipString
     }
 }

+ 9 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/BatchRemove/KMBatchRemoveView.swift

@@ -77,6 +77,15 @@ class KMBatchRemoveView: KMBatchSettingItemView {
             self.removeButton.properties.isDisabled = true
         }
     }
+    
+    override func bacthProcessingNotification() {
+        if KMBatchManager.manager.state == .processing {
+            self.removeButton.properties.isDisabled = true
+        } else {
+            self.removeButton.properties.isDisabled = false
+        }
+        self.removeButton.reloadData()
+    }
 }
 
 extension KMBatchRemoveView {

+ 9 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/Compress/KMBatchCompressView.swift

@@ -41,6 +41,15 @@ class KMBatchCompressView: KMBatchSettingItemView {
     override func reloadData() {
         
     }
+    
+    override func bacthProcessingNotification() {
+        if KMBatchManager.manager.state == .processing {
+            self.applyButton.properties.isDisabled = true
+        } else {
+            self.applyButton.properties.isDisabled = false
+        }
+        self.applyButton.reloadData()
+    }
 }
 
 protocol KMBatchCompressViewAction {}

+ 9 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/ConvertPDF/KMBatchConvertPDFView.swift

@@ -166,6 +166,15 @@ class KMBatchConvertPDFView: KMBatchSettingItemView {
         view.settingView?.isBatch = true
         return view
     }
+    
+    override func bacthProcessingNotification() {
+        if KMBatchManager.manager.state == .processing {
+            self.convertButton.properties.isDisabled = true
+        } else {
+            self.convertButton.properties.isDisabled = false
+        }
+        self.convertButton.reloadData()
+    }
 }
 
 protocol KMBatchConvertPDFViewAction {}

+ 13 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/KMBatchBatchSettingItemView/KMBatchSettingItemView.swift

@@ -20,6 +20,10 @@ class KMBatchSettingItemView: BaseXibView {
     }
     
     var batchExport: KMBatchSettingItemViewExport?
+    
+    deinit {
+        NotificationCenter.default.removeObserver(self)
+    }
     override func draw(_ dirtyRect: NSRect) {
         super.draw(dirtyRect)
 
@@ -29,4 +33,13 @@ class KMBatchSettingItemView: BaseXibView {
     func reloadData() {
         
     }
+    
+    override func setup() {
+        NotificationCenter.default.addObserver(self, selector: #selector(bacthProcessingNotification), name: NSNotification.Name(kBacthProcessNotification), object: nil)
+    }
+    
+    func bacthProcessingNotification() {
+        
+    }
+    
 }

+ 9 - 487
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/KMBatchSettingView.swift

@@ -75,55 +75,55 @@ class KMBatchSettingView: BaseXibView {
             case .convertPDF:
                 resultView = KMBatchConvertPDFView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.convertPDFExport(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .OCR:
                 resultView = KMBatchOCRView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.ocrExport(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .compress:
                 resultView = KMBatchCompressView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.compressExport(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .security:
                 resultView = KMBatchSecurityView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.securityExport(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .watermark:
                 resultView = KMBatchWatermarkView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.waterMarkApplay(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .background:
                 resultView = KMBatchBackgroundView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.backgroundApplay(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .headerAndFooter:
                 resultView = KMBatchHeaderAndFooterView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.headAndFooterApplay(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .batesNumber:
                 resultView = KMBatchBatesNumberView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.batesApplay(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             case .batchRemove:
                 resultView = KMBatchRemoveView.init()
                 resultView.batchExport = { [unowned self] (view, data) in
-                    self.removeApplay(data: data)
+                    KMBatchManager.manager.batch(type: type, data: data)
                 }
                 break
             default:
@@ -145,481 +145,3 @@ class KMBatchSettingView: BaseXibView {
 
 }
 
-protocol KMBatchSettingViewExport {}
-extension KMBatchSettingView: KMBatchSettingViewExport {
-    //MARK: 转档
-    func convertPDFExport(data: KMBatchSettingItemViewModel) {
-        let panel = NSOpenPanel()
-        panel.canChooseFiles = false
-        panel.canChooseDirectories = true
-        panel.canCreateDirectories = true
-        panel.beginSheetModal(for: self.window!) { response in
-            if response == .cancel {
-                return
-            }
-            let outputFolderPath = panel.url?.path
-            
-            self.convertFile(outputFolderPath: outputFolderPath!, data: data, filesData: self.filesData)
-        }
-    }
-    
-    func convertFile(outputFolderPath: String, data: KMBatchSettingItemViewModel, filesData: [KMBatchProcessingTableViewModel]?) {
-        if filesData?.count != 0 {
-            DispatchQueue.global().async {
-                for item in filesData! {
-                    //创建Document
-                    let filePath = item.filePath
-                    let document = CPDFDocument(url: URL(fileURLWithPath: filePath))
-                    
-                    let settingData = data as? KMBatchConvertPDFViewModel  ?? KMBatchConvertPDFViewModel()
-                    var fileName = filePath.deletingPathExtension.lastPathComponent
-                    if ((fileName.isEmpty)) {
-                        fileName = NSLocalizedString("Untitled", comment: "")
-                    }
-                    
-                    let convert = self.addConvertParameter(settingData)
-                    
-                    //获取page
-                    var pages:[Int] = []
-                    for i in 0..<document!.pageCount {
-                        pages.append(Int(i)+1)
-                    }
-                    
-                    convert.outputFolderPath = outputFolderPath
-                    convert.filePath = filePath
-                    convert.outputFileName = fileName
-                    convert.pages = pages
-                    
-                    convert.isAllowOCR = settingData.needRecognizeText
-                    convert.ocrLanguage = settingData.languageType
-                    
-                    KMPDFConvertManager.defaultManager.convert(convert: convert) { [unowned self] finished, error in
-                        if finished {
-                            if FileManager.default.fileExists(atPath: outputFolderPath) {
-                                NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputFolderPath)])
-                            }
-                        } else {
-                            var errorString = ""
-                            let myError: NSError = error! as NSError
-                            if myError.code == 1 {
-                                errorString = NSLocalizedString("Password required or incorrect password. Please re-enter your password and try again", comment: "")
-                            } else if myError.code == 2 {
-                                errorString = NSLocalizedString("The license doesn't allow the permission", comment: "")
-                            } else if myError.code == 3 {
-                                errorString = NSLocalizedString("Malloc failure", comment: "")
-                            } else if myError.code == 4 {
-                                errorString = NSLocalizedString("Unknown error in processing conversion. Please try again later", comment: "")
-                            } else if myError.code == 5 {
-                                errorString = NSLocalizedString("Unknown error in processing PDF. Please try again later", comment: "")
-                            } else if myError.code == 6 {
-                                errorString = NSLocalizedString("File not found or could not be opened. Check if your file exists or choose another file to convert", comment: "")
-                            } else if myError.code == 7 {
-                                errorString = NSLocalizedString("File not in PDF format or corruptead. Change a PDF file and try again", comment: "")
-                            } else if myError.code == 8 {
-                                errorString = NSLocalizedString("Unsupported security scheme", comment: "")
-                            } else if myError.code == 9 {
-                                errorString = NSLocalizedString("Page not found or content error", comment: "")
-                            } else {
-                                errorString = NSLocalizedString("Table not found", comment: "")
-                            }
-                            
-                            let alert = NSAlert()
-                            alert.alertStyle = .critical
-                            alert.messageText = NSLocalizedString("Conversion Failed", comment: "")
-                            alert.informativeText = errorString
-                            alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
-                            alert.runModal()
-                        }
-                    }
-                }
-            }
-        }
-    }
-    
-    func addConvertParameter(_ data: KMBatchConvertPDFViewModel) -> KMPDFConvert {
-        let settingData = data
-        var convert = KMPDFConvert()
-        
-        switch settingData.convertPDFType {
-        case .word:
-            convert = KMPDFConvertWord()
-            if settingData.layoutSettingType == .flowingText {
-                convert.isAllInOneSheet = false
-            } else {
-                convert.isAllInOneSheet = true
-            }
-        case .excel:
-            convert = KMPDFConvertExcel()
-            if settingData.excelSetting == .separate {
-                convert.isAllInOneSheet = false
-                convert.isExtractTable = false
-            } else if settingData.excelSetting == .format {
-                convert.isAllInOneSheet = true
-                convert.isExtractTable = false
-            } else if settingData.excelSetting == .tables {
-                convert.isAllInOneSheet = false
-                convert.isExtractTable = true
-                
-                switch settingData.excelTablesType {
-                case .oneTable:
-                    convert.extractTableIndex = 0
-                case .pageTable:
-                    convert.extractTableIndex = 1
-                case .allTable:
-                    convert.extractTableIndex = 2
-                default:
-                    KMPrint("未找到")
-                }
-            }
-        case .ppt:
-            convert = KMPDFConvertPPT()
-        case .csv:
-            convert = KMPDFConvertCSV()
-            if settingData.csvOnlyTables {
-                convert.isExtractTable = true
-                switch settingData.excelTablesType {
-                case .oneTable:
-                    convert.extractTableIndex = 0
-                case .pageTable:
-                    convert.extractTableIndex = 1
-                case .allTable:
-                    convert.extractTableIndex = 2
-                default:
-                    KMPrint("未找到")
-                }
-            } else {
-                convert.isExtractTable = false
-            }
-        case .image:
-            convert = KMPDFConvertImage()
-            convert.convertType = data.imageType
-            
-            var dpi: Int = 150
-            if data.imageDpiIndex == 0 {
-                dpi = 50
-            } else if data.imageDpiIndex == 1 {
-                dpi = 72
-            } else if data.imageDpiIndex == 2 {
-                dpi = 96
-            } else if data.imageDpiIndex == 3 {
-                dpi = 150
-            } else if data.imageDpiIndex == 4 {
-                dpi = 300
-            } else if data.imageDpiIndex == 5 {
-                dpi = 600
-            } else {
-                dpi = 150
-            }
-            
-            if (convert.convertType == .jpeg) {
-                (convert as! KMPDFConvertImage).imageType = .JPEG
-                (convert as! KMPDFConvertImage).imageDpi = dpi
-                
-            } else if (convert.convertType == .png) {
-                (convert as! KMPDFConvertImage).imageType = .PNG
-                (convert as! KMPDFConvertImage).imageDpi = dpi
-            } else {
-                (convert as! KMPDFConvertImage).imageDpi = 150
-            }
-        case .html:
-            convert = KMPDFConvertHTML()
-        case .rtf:
-            convert = KMPDFConvertRTF()
-        case .json:
-            convert = KMPDFConvertJson()
-            if settingData.jsonType == .extractText {
-                convert.isAllInOneSheet = false
-            } else {
-                convert.isAllInOneSheet = true
-            }
-        case .text:
-            convert = KMPDFConvertText()
-            
-        default:
-            KMPrint("不清楚")
-        }
-        return convert
-    }
-    
-    //MARK: OCR
-    func ocrExport(data: KMBatchSettingItemViewModel) {
-        let panel = NSOpenPanel()
-        panel.canChooseFiles = false
-        panel.canChooseDirectories = true
-        panel.canCreateDirectories = true
-        panel.beginSheetModal(for: self.window!) { response in
-            if response == .cancel {
-                return
-            }
-            let outputFolderPath = panel.url?.path
-            
-            self.convertOCR(outputFolderPath: outputFolderPath!, data: data as! KMOCRModel, filesData: self.filesData)
-        }
-    }
-    
-    func convertOCR(outputFolderPath: String, data: KMOCRModel, filesData: [KMBatchProcessingTableViewModel]?) {
-        guard let filesData = self.filesData else { return }
-        if filesData.count != 0 {
-            for item in filesData {
-                let document = CPDFDocument.init(url: URL(fileURLWithPath: item.filePath))
-                if document != nil {
-                    //计算需要处理的页面
-                    data.pageRangeType = item.pageRange
-                    data.pageRangeString = item.pageRangeString
-                   
-                    var fileName = item.filePath.deletingPathExtension.lastPathComponent
-                    if ((fileName.isEmpty)) {
-                        fileName = NSLocalizedString("Untitled", comment: "")
-                    }
-                    let path = outputFolderPath + "/" + fileName + ".pdf"
-                    
-                    KMOCRManager.manager.convertBatchOCR(document: document!, saveFilePath: path, model: data, progress: { progress in
-                        
-                    }) { document, text, error in
-                        
-                    }
-                }
-            }
-        }
-    }
-    
-    func convertOCR(document: CPDFDocument, model: KMOCRModel) {
-//        self.view.window?.windowController.beginLoading()
-        
-        //当前页面需要提前设置
-//        if model.pageRangeType == .current {
-//            model.pageRange = [self.listView.currentPageIndex]
-//        }
-        
-//        self.showProgressWindow(message: "正在转换中....")
-        KMOCRManager.manager.convertOCR(document: document, model: model, progress: { [weak self] progress in
-//            self?.progressC?.message = "正在转换中...."
-//            self?.progressC?.doubleValue = Double(progress * 100)
-        }) { [weak self] document, text, error  in
-//            self?.view.window?.windowController.endLoading()
-//            window.km_quick_endSheet()
-//            self?.hiddenProgressWindow()
-        }
-    }
-    
-    //MARK: 压缩
-    func compressExport(data: KMBatchSettingItemViewModel) {
-        self.compressFile(outputFolderPath: "", data: (data as? KMCompressSettingModel)!, filesData: self.filesData!)
-    }
-    
-    func compressFile(outputFolderPath: String, data: KMCompressSettingModel, filesData: [KMBatchProcessingTableViewModel]?) {
-        if filesData?.count != 0 {
-            for item in filesData! {
-                KMCompressManager.shared.compress(documentURL: URL(fileURLWithPath: item.filePath),
-                                                  limit: false,
-                                                  model: data,
-                                                  view: self) { [unowned self] isFinish, resultURL in
-                    if isFinish {
-                        print("压缩完成")
-                    }
-                }
-                
-            }
-            
-            NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputFolderPath)])
-        }
-    }
-    
-    //MARK: 安全
-    func securityExport(data: KMBatchSettingItemViewModel) {
-        let panel = NSOpenPanel()
-        let button = NSButton.init(checkboxWithTitle: "保存后打开文档", target: nil, action: nil)
-        button.state = .on
-        panel.accessoryView = button
-        panel.canChooseFiles = false
-        panel.canChooseDirectories = true
-        panel.canCreateDirectories = true
-        panel.beginSheetModal(for: self.window!) { [self] response in
-            if response == .cancel {
-                return
-            }
-            let outputFolderPath = panel.url?.path
-            
-            self.securityFile(outputFolderPath: outputFolderPath!, data: data as! KMBatchSecurityViewModel, filesData: self.filesData!)
-        }
-    }
-    
-    func securityFile(outputFolderPath: String, data: KMBatchSecurityViewModel, filesData: [KMBatchProcessingTableViewModel]?) {
-        if filesData?.count != 0 {
-            for item in filesData! {
-                let docuemt = CPDFDocument.init(url: URL(fileURLWithPath: item.filePath))
-                if (docuemt != nil) {
-                    var fileName = item.filePath.deletingPathExtension.lastPathComponent
-                    if ((fileName.isEmpty)) {
-                        fileName = NSLocalizedString("Untitled", comment: "")
-                    }
-                    let path = outputFolderPath + "/" + fileName + ".pdf"
-                    
-                    var options: [CPDFDocumentWriteOption : Any] = [:]
-                    //开启密码
-                    if data.isOpenPassword &&
-                        !data.openPasswordString.isEmpty {
-                        options.updateValue(data.openPasswordString, forKey: .userPasswordOption)
-                    }
-//
-                    //权限密码
-                    if data.isPermission &&
-                        !data.permissionString.isEmpty {
-                        options.updateValue(data.permissionString, forKey: .ownerPasswordOption)
-                    }
-                        
-                    // 限制打印
-                    if data.restrictOptions.contains(.print) {
-                        options.updateValue(false, forKey: .allowsPrintingOption)
-                    } else {
-                        options.updateValue(true, forKey: .allowsPrintingOption)
-                    }
-                    
-                    //限制复制
-                    if data.restrictOptions.contains(.copy) {
-                        options.updateValue(false, forKey: .allowsCopyingOption)
-                    } else {
-                        options.updateValue(true, forKey: .allowsCopyingOption)
-                    }
-                    
-                    
-                    let result = docuemt!.write(toFile: path, withOptions: options)
-//                    let result = docuemt!.write(to: URL(fileURLWithPath: path), withOptions: options)
-                    if result {
-                        KMPrint("成功")
-                    } else {
-                        KMPrint("失败")
-                    }
-                    NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputFolderPath)])
-                }
-            }
-        }
-    }
-    
-    
-    func waterMarkApplay(data: KMBatchSettingItemViewModel) {
-
-    }
-    
-//    func waterMarkFile(data: KMWatermarkAdjectiveBaseModel, filesData: [KMBatchProcessingTableViewModel]?) {
-//        
-//    }
-    
-    func backgroundApplay(data: KMBatchSettingItemViewModel) {
-        
-    }
-    
-    func backgroundFile(outputFolderPath: String, data: KMBackgroundModel, filesData: [KMBatchProcessingTableViewModel]?) {
-        
-    }
-    
-    
-    func headAndFooterApplay(data: KMBatchSettingItemViewModel) {
-        
-    }
-    
-//    func headAndFooterFile(outputFolderPath: String, data: KMHeaderFooterModel, filesData: [KMBatchProcessingTableViewModel]?) {
-//        
-//    }
-    
-    func batesApplay(data: KMBatchSettingItemViewModel) {
-        
-    }
-    
-    func batesFile(outputFolderPath: String, data: KMBatesModel, filesData: [KMBatchProcessingTableViewModel]?) {
-        
-    }
-    
-    
-    func removeApplay(data: KMBatchSettingItemViewModel) {
-        if (data == nil) {
-            let alert = NSAlert()
-            alert.alertStyle = .critical
-            alert.messageText = "没有找到"
-            alert.runModal()
-            return
-        }
-        
-        let panel = NSOpenPanel()
-        let button = NSButton.init(checkboxWithTitle: "保存后打开文档", target: nil, action: nil)
-        button.state = .on
-        panel.accessoryView = button
-        panel.canChooseFiles = false
-        panel.canChooseDirectories = true
-        panel.canCreateDirectories = true
-        panel.beginSheetModal(for: self.window!) { [self] response in
-            if response == .cancel {
-                return
-            }
-            let outputFolderPath = panel.url?.path
-            
-            self.removeFile(outputFolderPath: outputFolderPath!, data: data as! KMBatchRemoveViewModel, filesData: self.filesData!)
-        }
-    }
-    
-    func removeFile(outputFolderPath: String, data: KMBatchRemoveViewModel, filesData: [KMBatchProcessingTableViewModel]?) {
-        if filesData?.count != 0 {
-            for item in filesData! {
-//                DispatchQueue.global().async {
-                    var fileName = item.filePath.deletingPathExtension.lastPathComponent
-                    if ((fileName.isEmpty)) {
-                        fileName = NSLocalizedString("Untitled", comment: "")
-                    }
-                    
-                    let path = outputFolderPath + "/" + fileName + ".pdf"
-                    let document = CPDFDocument.init(url: URL(fileURLWithPath: item.filePath))
-                    if document != nil {
-                        if (document!.allowsPrinting == false || document!.allowsCopying == false) {
-                            let alert = NSAlert()
-                            alert.alertStyle = .critical
-                            alert.messageText = "此文档不允许修改"
-                            alert.runModal()
-                            return
-                        }
-                        
-                        if (data.options.contains(.security)) {
-                            
-                        }
-                        
-                        if (data.options.contains(.batesNumber)) {
-                            let property = document!.bates()
-                            property?.clear()
-                        }
-                        if (data.options.contains(.headerAndFooter)) {
-                            let property = document!.headerFooter()
-                            property?.clear()
-                        }
-                        if (data.options.contains(.background)) {
-                            let property = document!.background()
-                            property?.clear()
-                        }
-                        if (data.options.contains(.watermark)) {
-                            let array: Array<CPDFWatermark> = document!.watermarks() ?? []
-                            for model in array {
-                                document!.removeWatermark(model)
-                            }
-                        }
-                        
-                        if (FileManager.default.fileExists(atPath: path)) {
-                            try?FileManager.default.removeItem(atPath: path)
-                        }
-                        
-                        let result = document!.write(to: URL(fileURLWithPath: path))
-                        if (result) {
-                            KMPrint("removeFile成功")
-                        } else {
-                            KMPrint("removeFile失败")
-                        }
-                        NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: outputFolderPath)])
-                    }
-//                }
-            }
-        }
-    }
-}
-
-extension KMBatchSettingView {
-    func fetchPageRange(document: CPDFDocument, fileModel: KMBatchProcessingTableViewModel) -> [Int] {
-        return []
-    }
-}

+ 9 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/OCR/KMBatchOCRView.swift

@@ -83,6 +83,15 @@ class KMBatchOCRView: KMBatchSettingItemView {
         applyButton.properties.state = .normal
         applyButton.reloadData()
     }
+    
+    override func bacthProcessingNotification() {
+        if KMBatchManager.manager.state == .processing {
+            self.applyButton.properties.isDisabled = true
+        } else {
+            self.applyButton.properties.isDisabled = false
+        }
+        self.applyButton.reloadData()
+    }
 }
 
 //MARK: Action

+ 9 - 0
PDF Office/PDF Master/KMClass/NewBatch/View/Setting/Security/KMBatchSecurityView.swift

@@ -49,6 +49,15 @@ class KMBatchSecurityView: KMBatchSettingItemView {
             self.encryptButton.properties.isDisabled = true
         }
     }
+    
+    override func bacthProcessingNotification() {
+        if KMBatchManager.manager.state == .processing {
+            self.encryptButton.properties.isDisabled = true
+        } else {
+            self.encryptButton.properties.isDisabled = false
+        }
+        self.encryptButton.reloadData()
+    }
 }
 
 protocol KMBatchSecurityViewAction { }

+ 4 - 1
PDF Office/PDF Master/KMClass/PDFListView/Mode/KMNAnnotationPopMode.swift

@@ -215,7 +215,10 @@ class KMNAnnotationPopMode: NSObject {
         let isNotSameColor: Bool = CPDFListView.isAnnotationsContainMultiType(annotations, withType: .color)
 
         if isNotSameColor == false {
-            let anColor = annotation?.color
+            var anColor = annotation?.color
+            if let selfAnnotation = annotation as? CSelfSignAnnotation {
+                anColor = selfAnnotation.lineColor
+            }
             color = (anColor != nil) ? anColor : .clear
         }
         

+ 4 - 4
PDF Office/PDF Master/KMClass/PDFListView/ViewController/KMNPopDetailsViewController.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<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="22505"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -22,8 +22,8 @@
                 <outlet property="objectAlightTopButton" destination="oh5-ch-Lgt" id="kXi-q2-syj"/>
                 <outlet property="objectAlightVerButton" destination="eZX-aG-Y1P" id="VaI-RM-G7C"/>
                 <outlet property="objectAlightView" destination="NZw-tw-zQ6" id="MOD-Ql-IXw"/>
-                <outlet property="objectAverageHorButton" destination="kck-xy-Bee" id="XL9-Cp-IpY"/>
-                <outlet property="objectAverageVerButton" destination="hLk-ug-XEP" id="djj-fh-6Kx"/>
+                <outlet property="objectAverageHorButton" destination="hLk-ug-XEP" id="QUM-81-iG5"/>
+                <outlet property="objectAverageVerButton" destination="kck-xy-Bee" id="XPn-fp-ecg"/>
                 <outlet property="objectRightConstraint" destination="ogJ-4I-tNp" id="Umd-QA-ddl"/>
                 <outlet property="operationHeightConstraint" destination="M9Q-jM-CSR" id="6vR-oo-Tg5"/>
                 <outlet property="operationWidthConstraint" destination="D0E-zx-UFB" id="241-oG-H6q"/>

+ 31 - 13
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopAnnotationWindowController.swift

@@ -29,7 +29,7 @@ class KMNPopAnnotationWindowController: KMNBaseWindowController {
     
     public var popType:ListViewPopType = .popTypeNone {
         didSet {
-            rightOffsetConstraint.constant = 45.0
+            rightOffsetConstraint.constant = 49.0
             operationHeightConstraint.constant = 32.0
             paneBox.isHidden = false
             
@@ -48,9 +48,31 @@ class KMNPopAnnotationWindowController: KMNBaseWindowController {
                 operationBox.contentView = fontPopView
                 break
             case .shapeAnnotation:
+                var isContainSelfDot = false
+                for i in 0..<annotationPopMode.annotations.count {
+                    if let selfAn = annotationPopMode.annotations[i] as? CSelfSignAnnotation {
+                        if selfAn.annotationType == .signDot {
+                            isContainSelfDot = true
+                            break
+                        }
+                    }
+                }
+                
+                var width = 272.0
+                if isContainSelfDot == true {
+                    shapeRightConstraint.constant = 0
+                    widthZoomOutButton.isHidden = true
+                    widthZoomInButton.isHidden = true
+                    width = 200.0
+                } else {
+                    shapeRightConstraint.constant = 72
+                    widthZoomOutButton.isHidden = false
+                    widthZoomInButton.isHidden = false
+                }
                 shapeView.layoutSubtreeIfNeeded()
 
-                operationWidthConstraint.constant = shapeView.bounds.width
+//                operationWidthConstraint.constant = shapeView.bounds.width //刷新后未更新最后的宽度,暂时写死宽度
+                operationWidthConstraint.constant = width
                 self.window?.display() //需刷新约束才会有值,不然会变化
                 operationBox.contentView = shapeView
                 break
@@ -140,17 +162,12 @@ class KMNPopAnnotationWindowController: KMNBaseWindowController {
                     linkAnnotation = annotationPopMode.annotation as! CPDFLinkAnnotation
                 }
             } else if annotationPopType == .formAnnotation {
-                if annotationPopMode.annotationFieldName() != fildNameString {
-                    fildNameString = annotationPopMode.annotationFieldName() ?? ""
-                }
+                fildNameString = annotationPopMode.annotationFieldName() ?? ""
+
             } else if annotationPopType == .formRadioAnnotation {
-                if annotationPopMode.annotationFieldName() != fildNameString {
-                    fildNameString = annotationPopMode.annotationFieldName() ?? ""
-                }
-                
-                if annotationPopMode.annotationGropName() != gropNameString {
-                    gropNameString = annotationPopMode.annotationGropName() ?? ""
-                }
+                fildNameString = annotationPopMode.annotationFieldName() ?? ""                
+                gropNameString = annotationPopMode.annotationGropName() ?? ""
+
             }
         }
     }
@@ -396,7 +413,8 @@ class KMNPopAnnotationWindowController: KMNBaseWindowController {
     @IBOutlet var shapeColorGroup: ComponentCColorGroup!
     @IBOutlet var widthZoomOutButton: ComponentButton!
     @IBOutlet var widthZoomInButton: ComponentButton!
-    
+    @IBOutlet weak var shapeRightConstraint: NSLayoutConstraint!
+
     @IBOutlet var linkView: NSView!
     @IBOutlet var pageLinkButton: ComponentButton!
     @IBOutlet var urlLinkButton: ComponentButton!

+ 12 - 11
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopAnnotationWindowController.xib

@@ -47,6 +47,7 @@
                 <outlet property="paneSelectorItem" destination="pfZ-VY-VTh" id="0hz-zY-KKP"/>
                 <outlet property="rightOffsetConstraint" destination="TYz-c7-EYo" id="3jY-WY-4JO"/>
                 <outlet property="shapeColorGroup" destination="iMW-Yw-Qr1" id="KTl-HV-r0w"/>
+                <outlet property="shapeRightConstraint" destination="rdP-EY-2Ep" id="4eb-Rk-UiB"/>
                 <outlet property="shapeView" destination="fNe-3E-tHx" id="peC-YT-RFb"/>
                 <outlet property="urlInput" destination="uD5-qC-LES" id="EFf-gb-5Kp"/>
                 <outlet property="urlLinkButton" destination="JpI-5T-pBC" id="M2D-dd-ufE"/>
@@ -62,15 +63,15 @@
             <windowStyleMask key="styleMask" titled="YES" fullSizeContentView="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="196" y="240" width="511" height="42"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
             <view key="contentView" misplaced="YES" id="se5-gp-TjO">
-                <rect key="frame" x="0.0" y="0.0" width="511" height="42"/>
+                <rect key="frame" x="0.0" y="0.0" width="501" height="40"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="iV9-GQ-NJE">
-                        <rect key="frame" x="0.0" y="0.0" width="503" height="42"/>
+                    <box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="iV9-GQ-NJE">
+                        <rect key="frame" x="0.0" y="0.0" width="501" height="40"/>
                         <view key="contentView" id="9j5-uh-fjw">
-                            <rect key="frame" x="1" y="1" width="501" height="40"/>
+                            <rect key="frame" x="0.0" y="0.0" width="501" height="40"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
                                 <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="hK7-nm-yiB">
@@ -85,19 +86,19 @@
                                     </constraints>
                                 </box>
                                 <box boxType="custom" borderType="none" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="34L-Tp-WUP">
-                                    <rect key="frame" x="456" y="3" width="37" height="34"/>
+                                    <rect key="frame" x="452" y="3" width="41" height="34"/>
                                     <view key="contentView" id="PYw-kY-DK4">
-                                        <rect key="frame" x="0.0" y="0.0" width="37" height="34"/>
+                                        <rect key="frame" x="0.0" y="0.0" width="41" height="34"/>
                                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                         <subviews>
                                             <customView translatesAutoresizingMaskIntoConstraints="NO" id="pfZ-VY-VTh" customClass="ComponentCSelector" customModule="KMComponentLibrary">
-                                                <rect key="frame" x="5" y="0.0" width="32" height="34"/>
+                                                <rect key="frame" x="9" y="0.0" width="32" height="34"/>
                                                 <constraints>
                                                     <constraint firstAttribute="width" constant="32" id="NAx-PC-y22"/>
                                                 </constraints>
                                             </customView>
                                             <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="9xa-JY-EhU">
-                                                <rect key="frame" x="0.0" y="9" width="1" height="16"/>
+                                                <rect key="frame" x="4" y="9" width="1" height="16"/>
                                                 <view key="contentView" id="QmK-oA-Zno">
                                                     <rect key="frame" x="0.0" y="0.0" width="1" height="16"/>
                                                     <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -111,7 +112,7 @@
                                         </subviews>
                                         <constraints>
                                             <constraint firstItem="pfZ-VY-VTh" firstAttribute="leading" secondItem="9xa-JY-EhU" secondAttribute="trailing" constant="4" id="3Sg-wz-EGj"/>
-                                            <constraint firstItem="9xa-JY-EhU" firstAttribute="leading" secondItem="PYw-kY-DK4" secondAttribute="leading" id="AMb-Wj-EcT"/>
+                                            <constraint firstItem="9xa-JY-EhU" firstAttribute="leading" secondItem="PYw-kY-DK4" secondAttribute="leading" constant="4" id="AMb-Wj-EcT"/>
                                             <constraint firstItem="9xa-JY-EhU" firstAttribute="centerY" secondItem="PYw-kY-DK4" secondAttribute="centerY" id="Dyx-bM-HEA"/>
                                             <constraint firstAttribute="trailing" secondItem="pfZ-VY-VTh" secondAttribute="trailing" id="S3H-Jd-e8p"/>
                                             <constraint firstAttribute="bottom" secondItem="pfZ-VY-VTh" secondAttribute="bottom" id="cwN-Ux-8ga"/>
@@ -254,7 +255,7 @@
                 <constraint firstItem="wQe-BH-R8L" firstAttribute="leading" secondItem="ALM-CP-Hsi" secondAttribute="trailing" constant="4" id="hun-MS-DVm"/>
                 <constraint firstItem="ALM-CP-Hsi" firstAttribute="top" secondItem="fNe-3E-tHx" secondAttribute="top" id="irN-OH-H4H"/>
                 <constraint firstAttribute="trailing" secondItem="wQe-BH-R8L" secondAttribute="trailing" id="lhq-mL-Rvu"/>
-                <constraint firstItem="ALM-CP-Hsi" firstAttribute="leading" secondItem="iMW-Yw-Qr1" secondAttribute="trailing" constant="4" id="rdP-EY-2Ep"/>
+                <constraint firstAttribute="trailing" secondItem="iMW-Yw-Qr1" secondAttribute="trailing" constant="72" id="rdP-EY-2Ep"/>
             </constraints>
             <point key="canvasLocation" x="89" y="418"/>
         </customView>

+ 1 - 1
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.swift

@@ -12,7 +12,7 @@ import KMComponentLibrary
 class KMNPopContentEditWindowController: KMNBaseWindowController {
     public var editType:EditContentPopType = .editNone {
         didSet {
-            rightOffsetConstraint.constant = 45.0
+            rightOffsetConstraint.constant = 49.0
             paneBox.isHidden = false
             
             switch editType {

+ 10 - 10
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.xib

@@ -48,15 +48,15 @@
             <windowStyleMask key="styleMask" fullSizeContentView="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="196" y="240" width="480" height="270"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
             <view key="contentView" id="se5-gp-TjO">
-                <rect key="frame" x="0.0" y="0.0" width="522" height="42"/>
+                <rect key="frame" x="0.0" y="0.0" width="520" height="40"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="elC-AN-sp7">
-                        <rect key="frame" x="0.0" y="0.0" width="522" height="42"/>
+                    <box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="elC-AN-sp7">
+                        <rect key="frame" x="0.0" y="0.0" width="520" height="40"/>
                         <view key="contentView" id="vS3-lN-nYx">
-                            <rect key="frame" x="1" y="1" width="520" height="40"/>
+                            <rect key="frame" x="0.0" y="0.0" width="520" height="40"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
                                 <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="gcY-AN-rME">
@@ -71,19 +71,19 @@
                                     </constraints>
                                 </box>
                                 <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="Asu-CO-giT">
-                                    <rect key="frame" x="475" y="3" width="37" height="34"/>
+                                    <rect key="frame" x="471" y="3" width="41" height="34"/>
                                     <view key="contentView" id="IEM-hp-v4T">
-                                        <rect key="frame" x="0.0" y="0.0" width="37" height="34"/>
+                                        <rect key="frame" x="0.0" y="0.0" width="41" height="34"/>
                                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                         <subviews>
                                             <customView translatesAutoresizingMaskIntoConstraints="NO" id="2aI-ns-oxB" customClass="ComponentCSelectorItem" customModule="KMComponentLibrary">
-                                                <rect key="frame" x="5" y="0.0" width="32" height="34"/>
+                                                <rect key="frame" x="9" y="0.0" width="32" height="34"/>
                                                 <constraints>
                                                     <constraint firstAttribute="width" constant="32" id="Ige-a8-PP9"/>
                                                 </constraints>
                                             </customView>
                                             <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="Rsf-Ge-bao">
-                                                <rect key="frame" x="0.0" y="9" width="1" height="16"/>
+                                                <rect key="frame" x="4" y="9" width="1" height="16"/>
                                                 <view key="contentView" id="MHM-uo-o2D">
                                                     <rect key="frame" x="0.0" y="0.0" width="1" height="16"/>
                                                     <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -101,7 +101,7 @@
                                             <constraint firstAttribute="bottom" secondItem="2aI-ns-oxB" secondAttribute="bottom" id="YBG-JT-o51"/>
                                             <constraint firstItem="2aI-ns-oxB" firstAttribute="top" secondItem="IEM-hp-v4T" secondAttribute="top" id="a9M-Wb-Ogd"/>
                                             <constraint firstItem="Rsf-Ge-bao" firstAttribute="centerY" secondItem="IEM-hp-v4T" secondAttribute="centerY" id="sA4-Ga-cV6"/>
-                                            <constraint firstItem="Rsf-Ge-bao" firstAttribute="leading" secondItem="IEM-hp-v4T" secondAttribute="leading" id="ufx-CP-u5S"/>
+                                            <constraint firstItem="Rsf-Ge-bao" firstAttribute="leading" secondItem="IEM-hp-v4T" secondAttribute="leading" constant="4" id="ufx-CP-u5S"/>
                                         </constraints>
                                     </view>
                                 </box>

+ 8 - 8
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopOperationWindowController.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<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="22505"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -31,15 +31,15 @@
             <windowStyleMask key="styleMask" titled="YES" fullSizeContentView="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="196" y="240" width="480" height="270"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
-            <view key="contentView" id="se5-gp-TjO">
-                <rect key="frame" x="0.0" y="0.0" width="470" height="42"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
+            <view key="contentView" misplaced="YES" id="se5-gp-TjO">
+                <rect key="frame" x="0.0" y="0.0" width="468" height="40"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="yhB-Bi-Ro3">
-                        <rect key="frame" x="0.0" y="0.0" width="470" height="42"/>
+                    <box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="yhB-Bi-Ro3">
+                        <rect key="frame" x="0.0" y="0.0" width="468" height="40"/>
                         <view key="contentView" id="DQm-Zl-I4t">
-                            <rect key="frame" x="1" y="1" width="468" height="40"/>
+                            <rect key="frame" x="0.0" y="0.0" width="468" height="40"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
                                 <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="5OK-yK-3wT">

+ 3 - 3
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -8356,7 +8356,7 @@
 			children = (
 				AD8B58D92D2B777600150EA6 /* KMBatchWindowController.swift */,
 				AD8B58DA2D2B777600150EA6 /* KMBatchWindowController.xib */,
-				AD8B58DB2D2B777700150EA6 /* KMBatchManager */,
+				AD8B58DB2D2B777700150EA6 /* Manager */,
 				AD8B58D72D2B777600150EA6 /* Source */,
 				AD8B58DD2D2B777700150EA6 /* View */,
 			);
@@ -8371,12 +8371,12 @@
 			path = Source;
 			sourceTree = "<group>";
 		};
-		AD8B58DB2D2B777700150EA6 /* KMBatchManager */ = {
+		AD8B58DB2D2B777700150EA6 /* Manager */ = {
 			isa = PBXGroup;
 			children = (
 				AD8B58DC2D2B777700150EA6 /* KMBatchManager.swift */,
 			);
-			path = KMBatchManager;
+			path = Manager;
 			sourceTree = "<group>";
 		};
 		AD8B58DD2D2B777700150EA6 /* View */ = {