瀏覽代碼

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

niehaoyu 4 月之前
父節點
當前提交
88f5597b34
共有 27 個文件被更改,包括 1307 次插入310 次删除
  1. 22 0
      PDF Office/PDF Master/Class/Appearance/Image.xcassets/Other/Empty/KMEmptyIcon.imageset/Contents.json
  2. 二進制
      PDF Office/PDF Master/Class/Appearance/Image.xcassets/Other/Empty/KMEmptyIcon.imageset/pic-empty 1.pdf
  3. 二進制
      PDF Office/PDF Master/Class/Appearance/Image.xcassets/Other/Empty/KMEmptyIcon.imageset/pic-empty.pdf
  4. 21 0
      PDF Office/PDF Master/Class/Appearance/Image.xcassets/PDF Tools/ImageToPDF/ImageToPDFDropdownButtonIcon.imageset/Contents.json
  5. 90 0
      PDF Office/PDF Master/Class/Appearance/Image.xcassets/PDF Tools/ImageToPDF/ImageToPDFDropdownButtonIcon.imageset/dropdownButton.pdf
  6. 1 1
      PDF Office/PDF Master/Class/Batch/WindowController/Base/KMBatchOperateBaseViewController.swift
  7. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateBaseViewController.xib
  8. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateBaseWindowController.swift
  9. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateBaseWindowController.xib
  10. 362 33
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.swift
  11. 24 25
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.xib
  12. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateRightViewController.swift
  13. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateRightViewController.xib
  14. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateSplitViewController.swift
  15. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateSplitViewController.xib
  16. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateWindowController.swift
  17. 8 6
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.xib
  18. 239 44
      PDF Office/PDF Master/Class/Batch/WindowController/VC/KMBatchOperateImageToPDFViewController.swift
  19. 176 20
      PDF Office/PDF Master/Class/Batch/WindowController/VC/KMBatchOperateImageToPDFViewController.xib
  20. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Model/KMBatchOperateFile.swift
  21. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Tools/KMImageToPDFMethod.swift
  22. 27 12
      PDF Office/PDF Master/Class/Batch/View/KMBatchTableCellView.swift
  23. 1 1
      PDF Office/PDF Master/Class/Batch/View/KMLongerButton.swift
  24. 112 0
      PDF Office/PDF Master/KMClass/ImageToPDF/View/KMNTableHeaderCellView.swift
  25. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/View/KMTableHeaderCell.swift
  26. 0 0
      PDF Office/PDF Master/KMClass/ImageToPDF/Window/KMBatchWindow.swift
  27. 224 168
      PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

+ 22 - 0
PDF Office/PDF Master/Class/Appearance/Image.xcassets/Other/Empty/KMEmptyIcon.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "filename" : "pic-empty.pdf",
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "filename" : "pic-empty 1.pdf",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

二進制
PDF Office/PDF Master/Class/Appearance/Image.xcassets/Other/Empty/KMEmptyIcon.imageset/pic-empty 1.pdf


二進制
PDF Office/PDF Master/Class/Appearance/Image.xcassets/Other/Empty/KMEmptyIcon.imageset/pic-empty.pdf


+ 21 - 0
PDF Office/PDF Master/Class/Appearance/Image.xcassets/PDF Tools/ImageToPDF/ImageToPDFDropdownButtonIcon.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "dropdownButton.pdf",
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 90 - 0
PDF Office/PDF Master/Class/Appearance/Image.xcassets/PDF Tools/ImageToPDF/ImageToPDFDropdownButtonIcon.imageset/dropdownButton.pdf

@@ -0,0 +1,90 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
+0.945098 0.945098 0.949020 scn
+0.000000 32.000000 m
+28.000000 32.000000 l
+30.209139 32.000000 32.000000 30.209139 32.000000 28.000000 c
+32.000000 4.000000 l
+32.000000 1.790861 30.209139 0.000000 28.000000 0.000000 c
+0.000000 0.000000 l
+0.000000 32.000000 l
+h
+f
+n
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 10.166504 12.503937 cm
+0.509804 0.741176 1.000000 scn
+0.244078 6.585314 m
+0.569515 6.910751 1.097152 6.910751 1.422589 6.585314 c
+5.833333 2.174569 l
+10.244078 6.585314 l
+10.569514 6.910751 11.097152 6.910751 11.422588 6.585314 c
+11.748026 6.259877 11.748026 5.732239 11.422588 5.406803 c
+6.422589 0.406803 l
+6.097152 0.081366 5.569514 0.081366 5.244078 0.406803 c
+0.244078 5.406803 l
+-0.081359 5.732239 -0.081359 6.259877 0.244078 6.585314 c
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  844
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 32.000000 32.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000934 00000 n
+0000000956 00000 n
+0000001129 00000 n
+0000001203 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+1262
+%%EOF

+ 1 - 1
PDF Office/PDF Master/Class/Batch/WindowController/Base/KMBatchOperateBaseViewController.swift

@@ -9,7 +9,7 @@ import Cocoa
 
 //var kBatchQueueOperationsChanged = "kBatchQueueOperationsChanged"
 private var kBatchQueueOperationsChanged = 0x000101
-class KMBatchOperateBaseViewController: NSViewController, KMBatchOperateProtocol{
+class KMBatchOperateBaseViewController: KMNBaseViewController, KMBatchOperateProtocol{
     var operateType: KMBatchOperationType?
     var convertType: KMConvertWithPDFType?
     var files: [KMBatchOperateFile]?

PDF Office/PDF Master/Class/Batch/WindowController/Base/KMBatchOperateBaseViewController.xib → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateBaseViewController.xib


PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateBaseWindowController.swift → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateBaseWindowController.swift


PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateBaseWindowController.xib → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateBaseWindowController.xib


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

@@ -10,7 +10,7 @@ import KMComponentLibrary
 
 let KMBatchDragType = "KMBatchDragType"
 
-class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NSTableViewDataSource{
+class KMBatchOperateLeftViewController: KMNBaseViewController,NSTableViewDelegate,NSTableViewDataSource{
     
     @IBOutlet var selectFileButton: KMLongerButton!
     
@@ -47,9 +47,22 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
     var popOver: NSPopover?
     var progressInt: Int = 0
     
-    private var addFileButton_: ComponentButton?
+    private var addFileButton_: ComponentDropdown?
     private var deleteButton_: ComponentButton?
     
+    private var groupView_: ComponentGroup?
+    
+    private var emptyViewTopLine: NSView = {
+        let view = NSView()
+        view.wantsLayer = true
+        return view
+    }()
+    private var emptyView_: ComponentEmpty = {
+        let view = ComponentEmpty()
+        view.properties = ComponentEmptyProperty(emptyType: .add_File, state: .normal, image: NSImage(named: "KMEmptyIcon"), text: KMLocalizedString("Select Files"), subText: KMLocalizedString("Drop files here or Click Add Files at upper left corner. You can drag files to reorder as you need."))
+        return view
+    }()
+    
     deinit {
         NotificationCenter.default.removeObserver(self)
         DistributedNotificationCenter.default().removeObserver(self)
@@ -100,51 +113,84 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
         
 //        self.selectFileButton.containerViewController = self
         selectFileButton.title = ""
-        addFileButton_ = ComponentButton()
-        addFileButton_?.properties = ComponentButtonProperty(type: .gray, size: .s, state: .normal, showLeftIcon: true,buttonText: KMLocalizedString("Add Files"), icon: NSImage(named: "KMImageNameAddFilesIcon"))
+        addFileButton_ = ComponentDropdown()
+//        addFileButton_?.properties = ComponentButtonProperty(type: .gray, size: .s, state: .normal, showLeftIcon: true,buttonText: KMLocalizedString("Add Files"), icon: NSImage(named: "KMImageNameAddFilesIcon"))
+        addFileButton_?.properties = ComponentDropdownProperty(type: .split_graySecondary, size: .s, split: true, text: KMLocalizedString("Add Files..."))
+//        addFileButton_?.splitRightButton.properties.icon = NSImage(named: "ImageToPDFDropdownButtonIcon")
 //        addFileButton_?.setTarget(self, action: #selector(cancelButtonAction))
+        
         selectFileButton.addSubview(addFileButton_!)
         addFileButton_?.frame = selectFileButton.bounds
         addFileButton_?.autoresizingMask = [.width, .height]
+        addFileButton_?.componentDelegate = self
         
         deleteButton_ = ComponentButton()
-        deleteButton_?.properties = ComponentButtonProperty(type: .gray, size: .s, state: .normal, onlyIcon: true)
+        deleteButton_?.properties = ComponentButtonProperty(type: .text_gray_low, size: .s, state: .normal, onlyIcon: true)
         deleteButton_?.setTarget(self, action: #selector(buttonClicked_DeleteFile))
+        deleteFileButton.image = nil
         deleteFileButton.addSubview(deleteButton_!)
         deleteButton_?.frame = deleteFileButton.bounds
         deleteButton_?.autoresizingMask = [.width, .height]
         deleteButton_?.properties.propertyInfo.leftIcon_nor = NSImage(named: "KMImageNameDeleteFileIcon")
+        deleteButton_?.setTarget(self, action: #selector(buttonClicked_DeleteFile))
         
-        tableView.headerView?.wantsLayer = true
-//        tableView.headerView?.layer?.backgroundColor = NSColor.red.cgColor
-        var frame = tableView.headerView?.frame
-        frame?.size.height = 32
-        tableView.headerView?.frame = frame ?? .zero
-        
+//        tableView.headerView?.wantsLayer = true
+//        tableView.headerView?.layer?.backgroundColor = NSColor.blue.cgColor
+//        var frame = tableView.headerView?.frame
+//        frame?.size.height = 32
+//        tableView.headerView?.frame = frame ?? .zero
+        tableView.headerView = nil
         
         self.showInFinderMenuItem.title = NSLocalizedString("Show in Finder", comment: "")
         self.deleteMenuItem.title = NSLocalizedString("Delete", comment: "")
         self.blankView.wantsLayer = true
         self.blankView.layer?.backgroundColor = NSColor.clear.cgColor
-        self.blankView.titleLabel.stringValue = NSLocalizedString("Select Files", comment: "")
+        self.blankView.titleLabel.stringValue = ""
         self.blankView.imageView.isHidden = true
-        self.blankView.addButton.isHidden = false
-        self.blankView.secondTitleLabel.stringValue = NSLocalizedString("Drop files here or Click Add Files at upper left corner. You can drag files to reorder as you need.", comment: "")
+        self.blankView.addButton.isHidden = true
+        self.blankView.secondTitleLabel.stringValue = ""
         self.blankView.mouseActionCallBack = { [weak self] mouseType in
-            guard let self = self else { return }
-            if mouseType == .mouseEnter {
-                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListHov")
-            } else if mouseType == .mouseExit {
-                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListNor")
-            } else if mouseType == .mouseDown {
-                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListPre")
-                self.chooseFile()
-            } else if mouseType == .mouseUp {
-                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListHov")
-            }
+//            guard let self = self else { return }
+//            if mouseType == .mouseEnter {
+//                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListHov")
+//            } else if mouseType == .mouseExit {
+//                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListNor")
+//            } else if mouseType == .mouseDown {
+//                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListPre")
+//                self.chooseFile()
+//            } else if mouseType == .mouseUp {
+//                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListHov")
+//            }
         }
+        self.blankView.addSubview(emptyView_)
+        
+        blankView.addSubview(emptyViewTopLine)
+        emptyViewTopLine.km_add_top_constraint(constant: 4)
+        emptyViewTopLine.km_add_left_constraint(constant: 24)
+        emptyViewTopLine.km_add_right_constraint(constant: -24)
+        emptyViewTopLine.km_add_height_constraint(constant: 1)
+        emptyViewTopLine.wantsLayer = true
+        let dividerColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/divider")
+        emptyViewTopLine.layer?.backgroundColor = dividerColor.cgColor
+        
+        emptyView_.km_add_top_constraint(constant: 96)
+        emptyView_.km_add_bottom_constraint()
+        emptyView_.km_add_leading_constraint()
+        emptyView_.km_add_trailing_constraint()
+        emptyView_.setTarget(self, action: #selector(emptyAddFileAction))
+        
         updateViewColor()
     }
+    
+    override func updateUILanguage() {
+        super.updateUILanguage()
+        
+        KMMainThreadExecute {
+            self.addFileButton_?.properties.text = KMLocalizedString("Add Files...")
+            self.addFileButton_?.reloadData()
+        }
+    }
+    
     @objc func reloadData() {
         if Thread.isMainThread {
             tableView.reloadData()
@@ -371,9 +417,9 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
 //            if KMAlertWindowController.needShowRemoveAllFilesHint() {
                 let alert = NSAlert()
                 alert.alertStyle = .critical
-                alert.messageText = NSLocalizedString("Clear All Recents", comment: "")+"?"
-                alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
-                alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
+                alert.messageText = KMLocalizedString("Clear All Recents", comment: "")+"?"
+                alert.addButton(withTitle: KMLocalizedString("Delete", comment: ""))
+                alert.addButton(withTitle: KMLocalizedString("Cancel", comment: ""))
                 alert.beginSheetModal(for: self.view.window!) {[weak self] response in
                     if response == NSApplication.ModalResponse.alertFirstButtonReturn {
                         self?.files.removeAll()
@@ -501,23 +547,176 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
         }
         addFilesToList(addArray: pdfArray)
     }
+    
+    // MARK: - Actions
+    
+    @objc func emptyAddFileAction() {
+        self.chooseFile()
+    }
+    
+    //MARK: - GroupView
+    
+    func showGroupView() {
+        var viewHeight: CGFloat = 8
+        var menuItemArr: [ComponentMenuitemProperty] = []
+        for i in ["Add Files...", "Add Folder...", "Import from Clipboard...", "Import from Scanner..."] {
+            let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
+                                                                                               itemSelected: false,
+                                                                                               isDisabled: false,
+                                                                                               keyEquivalent: nil,
+                                                                                               text: KMLocalizedString(i))
+            menuItemArr.append(properties_Menuitem)
+            viewHeight += 36
+        }
+        
+        if groupView_ == nil {
+            groupView_ = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
+        }
+        groupView_?.groupDelegate = self
+        groupView_?.frame = CGRectMake(310, 0, 200, viewHeight)
+        groupView_?.updateGroupInfo(menuItemArr)
+        
+        var point = addFileButton_?.convert(addFileButton_!.frame.origin, to: nil) ?? .zero
+        point.y -= viewHeight
+        groupView_?.showWithPoint(point, relativeTo: addFileButton_)
+        
+        addFileButton_?.properties.state = .pressed
+        addFileButton_?.reloadData()
+    }
+    
+    func removeGroupView() {
+        if groupView_ != nil {
+            groupView_?.removeFromSuperview()
+        }
+        addFileButton_?.properties.state = .normal
+        addFileButton_?.reloadData()
+    }
+    
+    func openDocumentWithImageFromPasteboard(_ pboard: NSPasteboard, error outError: AutoreleasingUnsafeMutablePointer<NSError?>?) -> CPDFDocument? {
+        var document: CPDFDocument? = nil
+        var data: Data? = nil
+        
+        if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.pdf.rawValue]) {
+            data = pboard.data(forType: NSPasteboard.PasteboardType.pdf)
+        } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.postScript.rawValue]) {
+            data = pboard.data(forType: NSPasteboard.PasteboardType.postScript)
+        } else if pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.tiff.rawValue]) {
+            data = convertTIFFDataToPDF(pboard.data(forType: NSPasteboard.PasteboardType.tiff) ?? Data())
+        } else {
+            let images = pboard.readObjects(forClasses: [NSImage.self], options: [:])
+            let strings = pboard.readObjects(forClasses: [NSAttributedString.self], options: [:])
+            if images?.count ?? 0 > 0 {
+                data = convertTIFFDataToPDF((images![0] as AnyObject).tiffRepresentation!)
+            } else if strings?.count ?? 0 > 0 {
+                data = KMOCTool.convertStringsToPDF(withString: strings ?? [""]) // convertStringsToPDF(strings!)
+            }
+        }
+        
+        if let data = data {
+            document = CPDFDocument(data: data)
+            
+        } else if let outError = outError {
+            outError.pointee = NSError(domain: "SKDocumentErrorDomain", code: 3, userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Unable to load data from clipboard", comment: "Error description")])
+        }
+    
+        return document
+    }
+    
+    func convertTIFFDataToPDF(_ tiffData: Data) -> Data? {
+        guard let imsrc = CGImageSourceCreateWithData(tiffData as CFData, [kCGImageSourceTypeIdentifierHint: kUTTypeTIFF] as CFDictionary), CGImageSourceGetCount(imsrc) > 0, let cgImage = CGImageSourceCreateImageAtIndex(imsrc, 0, nil) else { return nil }
+        let pdfData = NSMutableData(capacity: tiffData.count)
+        let consumer = CGDataConsumer(data: pdfData! as CFMutableData)!
+        
+        var rect = CGRect(x: 0, y: 0, width: CGFloat(cgImage.width), height: CGFloat(cgImage.height))
+        let ctxt = CGContext(consumer: consumer, mediaBox: &rect, nil)
+        ctxt!.beginPDFPage(nil)
+        ctxt!.draw(cgImage, in: rect)
+        ctxt!.endPDFPage()
+        ctxt!.closePDF()
+        
+        return pdfData as? Data
+    }
+    
+    // MARK: - Private Methods
+    
+    private func _saveImagePath() -> String {
+        let rootPath = KMDataManager.fetchAppSupportOfBundleIdentifierDirectory()
+        let path = rootPath.appendingPathComponent("ImageToPDF").path
+        if FileManager.default.fileExists(atPath: path) == false {
+            try?FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: false)
+        }
+        return path
+    }
+    
+    private func _clearImageData() {
+        let path = self._saveImagePath()
+        if FileManager.default.fileExists(atPath: path) {
+            try?FileManager.default.removeItem(atPath: path)
+        }
+    }
+    
+    
     func numberOfRows(in tableView: NSTableView) -> Int {
         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "KMBatchFilesCountNotification"), object: self.files, userInfo: [kObjectKey : self])
         self.deleteFileButton.isEnabled = self.files.count > 0
+        deleteButton_?.properties.isDisabled = self.files.count <= 0
         self.blankView.isHidden = self.files.count > 0
-        return self.files.count;
+        if self.files.count == 0 {
+            return 0
+        }
+        return self.files.count + 1;
     }
     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
         let identifier = tableColumn?.identifier
-        let file = self.files[row]
+        
+        let rowIdx = max(0, row-1)
+        let file = self.files[rowIdx]
+        
+        let cellColor = ComponentLibrary.shared.getComponentColorFromKey("olorFill/4")
+        let dividerColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/divider")
+        let titleFont = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
+        let titleColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/1")
       
         if identifier?.rawValue == "index" {
+            if row == 0 {
+                let cellView = KMNTableHeaderCellView()
+                cellView.wantsLayer = true
+                cellView.layer?.backgroundColor = cellColor.cgColor
+//                cellView.layer?.backgroundColor = NSColor(hex: "#F6F6F8").cgColor
+
+                cellView.titleLabel.stringValue = KMLocalizedString("")
+                
+                cellView.leftLine.wantsLayer = true
+                cellView.leftLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.rightLine.wantsLayer = true
+                cellView.rightLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.bottomLine.wantsLayer = true
+                cellView.bottomLine.layer?.backgroundColor = dividerColor.cgColor
+                return cellView
+            }
             let cellView = KMBatchTableCellView(type: .Size)
             _ = row + 1
             cellView.textField?.stringValue = String(format: "%d", row + 1);
             return cellView;
         } else if identifier?.rawValue == "pageRange"{
             if (file.currentOperateType == .CreatePDF) {
+                if row == 0 {
+                    let cellView = KMNTableHeaderCellView()
+                    cellView.wantsLayer = true
+                    cellView.layer?.backgroundColor = cellColor.cgColor
+                    
+                    cellView.titleLabel.stringValue = KMLocalizedString("Dimensions")
+                    cellView.titleLabel.font = titleFont
+                    cellView.titleLabel.textColor = titleColor
+
+                    cellView.leftLine.wantsLayer = true
+                    cellView.leftLine.layer?.backgroundColor = dividerColor.cgColor
+                    cellView.rightLine.wantsLayer = true
+                    cellView.rightLine.layer?.backgroundColor = dividerColor.cgColor
+                    cellView.bottomLine.wantsLayer = true
+                    cellView.bottomLine.layer?.backgroundColor = dividerColor.cgColor
+                    return cellView
+                }
                 let cellView = KMBatchTableCellView(type: .Size)
                 
                 if (file.fileType == .Image) {
@@ -532,6 +731,23 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
                 return cellView;
             }
         } else if identifier?.rawValue == "status"{
+            if row == 0 {
+                let cellView = KMNTableHeaderCellView()
+                cellView.wantsLayer = true
+                cellView.layer?.backgroundColor = cellColor.cgColor
+
+                cellView.titleLabel.stringValue = KMLocalizedString("State")
+                cellView.titleLabel.font = titleFont
+                cellView.titleLabel.textColor = titleColor
+                
+                cellView.leftLine.wantsLayer = true
+                cellView.leftLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.rightLine.wantsLayer = true
+                cellView.rightLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.bottomLine.wantsLayer = true
+                cellView.bottomLine.layer?.backgroundColor = dividerColor.cgColor
+                return cellView
+            }
             let cellView = KMBatchTableCellView(type: .Status)
             if (file.currentOperateType == .CreatePDF) {
                 cellView.updateInterface(file: file, progress: file.progress ?? 0)
@@ -544,12 +760,51 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
             }
             return cellView;
         } else if identifier?.rawValue == "size"{
+            if row == 0 {
+                let cellView = KMNTableHeaderCellView()
+                cellView.wantsLayer = true
+                cellView.layer?.backgroundColor = cellColor.cgColor
+                
+                cellView.titleLabel.stringValue = KMLocalizedString("Size")
+                cellView.titleLabel.font = titleFont
+                cellView.titleLabel.textColor = titleColor
+
+                cellView.leftLine.wantsLayer = true
+                cellView.leftLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.rightLine.wantsLayer = true
+                cellView.rightLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.bottomLine.wantsLayer = true
+                cellView.bottomLine.layer?.backgroundColor = dividerColor.cgColor
+                return cellView
+            }
             let cellView = KMBatchTableCellView(type: .Size)
             cellView.updateInterface(file)
             return cellView;
         } else if identifier?.rawValue == "fileName"{
+            if row == 0 {
+                let cellView = KMNTableHeaderCellView()
+                cellView.wantsLayer = true
+                cellView.layer?.backgroundColor = cellColor.cgColor
+                
+                cellView.titleLabel.stringValue = KMLocalizedString("File Name")
+                cellView.titleLabel.font = titleFont
+                cellView.titleLabel.textColor = titleColor
+
+                cellView.leftLine.wantsLayer = true
+                cellView.leftLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.rightLine.wantsLayer = true
+                cellView.rightLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.bottomLine.wantsLayer = true
+                cellView.bottomLine.layer?.backgroundColor = dividerColor.cgColor
+                return cellView
+            }
             let cellView = KMBatchTableCellView(type: .FileName)
             cellView.updateInterface(file)
+            
+            cellView.fileIv?.wantsLayer = true
+            cellView.fileIv?.layer?.borderWidth = 1
+            cellView.fileIv?.layer?.borderColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/3-default").cgColor
+            
             let rowView: KMBatchTableRowView = tableView.rowView(atRow: row, makeIfNecessary: true) as! KMBatchTableRowView
             if ((file.error) != nil) {
                 rowView.backgroundColor = KMAppearance.Status.errBGColor();
@@ -560,6 +815,24 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
             cellView.updateInterface(file)
             return cellView;
         } else if identifier?.rawValue == "dimensions"{
+            if row == 0 {
+                let cellView = KMNTableHeaderCellView()
+                cellView.wantsLayer = true
+                cellView.layer?.backgroundColor = cellColor.cgColor
+                
+                cellView.titleLabel.stringValue = KMLocalizedString("Dimensions")
+                cellView.titleLabel.font = titleFont
+                cellView.titleLabel.textColor = titleColor
+
+                cellView.leftLine.wantsLayer = true
+                cellView.leftLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.rightLine.wantsLayer = true
+                cellView.rightLine.layer?.backgroundColor = dividerColor.cgColor
+                cellView.bottomLine.wantsLayer = true
+                cellView.bottomLine.layer?.backgroundColor = dividerColor.cgColor
+//                cellView.
+                return cellView
+            }
             let cellView = KMBatchTableCellView(type: .Size)
             
             if (file.fileType == .Image) {
@@ -572,12 +845,16 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
         return nil;
     }
     func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
-        let file = self.files[row]
+        let rowIdx = max(0, row-1)
+        let file = self.files[rowIdx]
         if self.type == .CreatePDF {
+            if row == 0 {
+                return 32
+            }
             if (file.error != nil) {
-                return 64
+                return 104
             } else {
-                return 40
+                return 80
             }
         } else {
             if file.fileType == .PDF {
@@ -592,6 +869,15 @@ class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NST
         }
     }
     func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
+        if row == 0 {
+            let rowView = KMBatchTableRowView()
+            rowView.selectionBackgroundColorBlock = {
+                return .clear
+            }
+            rowView.selectionHighlightStyle = .none
+            rowView.isSelected = false
+            return rowView
+        }
         let rowView = KMBatchTableRowView()
         return rowView
     }
@@ -832,3 +1118,46 @@ extension KMBatchOperateLeftViewController: NSMenuDelegate, NSMenuItemValidation
         return true
     }
 }
+
+//MARK: - ComponentDropdownDelegate
+
+extension KMBatchOperateLeftViewController: ComponentDropdownDelegate {
+    func componentDropdownDidShowMenuItem(dropdown: ComponentDropdown) {
+        showGroupView()
+    }
+}
+
+//MARK: - ComponentGroupDelegate
+
+extension KMBatchOperateLeftViewController: ComponentGroupDelegate {
+    func componentGroupDidDismiss(group: ComponentGroup?) {
+        
+        removeGroupView()
+    }
+    
+    func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
+        if let selItem = menuItemProperty {
+            let index = group?.menuItemArr.firstIndex(of: selItem)
+            if index == 0 {
+                chooseFile()
+            } else if index == 1 {
+                chooseFile()
+            } else if index == 2 {
+                let pboard = NSPasteboard.general
+                if let document = self.openDocumentWithImageFromPasteboard(pboard, error: nil) {
+                    // Document opened successfully
+                    if let page = document.page(at: 0) {
+                        let data = page.PDFListViewTIFFData(for: page.bounds)
+                        var path = self._saveImagePath() + "/Untitled.png"
+                        path = KMTools.getUniqueFilePath(filePath: path)
+                        try?data?.write(to: URL(fileURLWithPath: path), options: .atomic)
+                        
+                        self.addFilesToList(addArray: [path])
+                    }
+                }
+            } else if index == 3 {
+                chooseFileFromCamera()
+            }
+        }
+    }
+}

+ 24 - 25
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.xib

@@ -28,11 +28,11 @@
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
         <customView misplaced="YES" id="Hz6-mo-xeY">
-            <rect key="frame" x="0.0" y="0.0" width="698" height="464"/>
+            <rect key="frame" x="0.0" y="0.0" width="616" height="560"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
             <subviews>
                 <customView translatesAutoresizingMaskIntoConstraints="NO" id="yD5-qe-EWK">
-                    <rect key="frame" x="0.0" y="400" width="718" height="64"/>
+                    <rect key="frame" x="0.0" y="421" width="718" height="64"/>
                     <subviews>
                         <button verticalHuggingPriority="750" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9ff-Qn-trv" customClass="KMLongerButton" customModule="PDF_Reader_Pro" customModuleProvider="target">
                             <rect key="frame" x="24" y="12" width="109" height="32"/>
@@ -68,20 +68,19 @@
                         <constraint firstItem="9ff-Qn-trv" firstAttribute="leading" secondItem="yD5-qe-EWK" secondAttribute="leading" constant="24" id="ol8-K1-cmb"/>
                     </constraints>
                 </customView>
-                <scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cSo-1J-C87">
-                    <rect key="frame" x="24" y="0.0" width="670" height="400"/>
+                <scrollView autohidesScrollers="YES" horizontalLineScroll="17" horizontalPageScroll="10" verticalLineScroll="17" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cSo-1J-C87">
+                    <rect key="frame" x="24" y="0.0" width="670" height="421"/>
                     <clipView key="contentView" ambiguous="YES" id="5QZ-3D-5sN">
-                        <rect key="frame" x="1" y="1" width="668" height="398"/>
+                        <rect key="frame" x="1" y="1" width="668" height="419"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
-                            <tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="Mlr-rw-6rm" viewBased="YES" id="iqp-fI-b2v">
-                                <rect key="frame" x="0.0" y="0.0" width="740" height="373"/>
+                            <tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="fullWidth" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="Mlr-rw-6rm" viewBased="YES" id="iqp-fI-b2v">
+                                <rect key="frame" x="0.0" y="0.0" width="859" height="394"/>
                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                <size key="intercellSpacing" width="3" height="2"/>
                                 <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
                                 <color key="gridColor" red="1" green="0.64784158279075421" blue="0.26014074763814632" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                 <tableColumns>
-                                    <tableColumn identifier="index" width="72" minWidth="72" maxWidth="72" id="dvO-PE-2DL">
+                                    <tableColumn identifier="index" width="40" minWidth="40" maxWidth="40" id="dvO-PE-2DL">
                                         <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="序号">
                                             <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
                                             <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@@ -94,12 +93,12 @@
                                         <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                         <prototypeCellViews>
                                             <tableCellView id="mJ1-Fh-j8e">
-                                                <rect key="frame" x="1" y="1" width="77" height="17"/>
+                                                <rect key="frame" x="0.0" y="0.0" width="45" height="17"/>
                                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                             </tableCellView>
                                         </prototypeCellViews>
                                     </tableColumn>
-                                    <tableColumn identifier="fileName" width="100" minWidth="100" maxWidth="1000" id="TTZ-qf-vYt">
+                                    <tableColumn identifier="fileName" width="219" minWidth="219" maxWidth="1000" id="TTZ-qf-vYt">
                                         <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="文件名">
                                             <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
                                             <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
@@ -112,7 +111,7 @@
                                         <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                         <prototypeCellViews>
                                             <tableCellView id="Mgh-hp-ErW">
-                                                <rect key="frame" x="81" y="1" width="100" height="17"/>
+                                                <rect key="frame" x="46" y="0.0" width="219" height="17"/>
                                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                             </tableCellView>
                                         </prototypeCellViews>
@@ -129,12 +128,12 @@
                                         </textFieldCell>
                                         <prototypeCellViews>
                                             <tableCellView id="nlT-SK-XE6" customClass="KMBatchTableCellView" customModule="PDF_Reader_Pro" customModuleProvider="target">
-                                                <rect key="frame" x="184" y="1" width="140" height="17"/>
+                                                <rect key="frame" x="265" y="0.0" width="140" height="17"/>
                                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                             </tableCellView>
                                         </prototypeCellViews>
                                     </tableColumn>
-                                    <tableColumn identifier="size" width="80" minWidth="80" maxWidth="80" id="Jv9-CS-hrB">
+                                    <tableColumn identifier="size" width="88" minWidth="88" maxWidth="88" id="Jv9-CS-hrB">
                                         <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="大小">
                                             <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
                                             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -147,12 +146,12 @@
                                         <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                         <prototypeCellViews>
                                             <tableCellView id="TSm-ys-xdB">
-                                                <rect key="frame" x="327" y="1" width="80" height="17"/>
+                                                <rect key="frame" x="405" y="0.0" width="88" height="17"/>
                                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                             </tableCellView>
                                         </prototypeCellViews>
                                     </tableColumn>
-                                    <tableColumn identifier="status" width="78" minWidth="78" maxWidth="78" id="vhM-02-bDl">
+                                    <tableColumn identifier="status" width="56" minWidth="56" maxWidth="56" id="vhM-02-bDl">
                                         <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="状态">
                                             <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
                                             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -165,11 +164,11 @@
                                         <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                         <prototypeCellViews>
                                             <tableCellView id="sVm-ab-mJ4">
-                                                <rect key="frame" x="410" y="1" width="78" height="17"/>
+                                                <rect key="frame" x="493" y="0.0" width="56" height="17"/>
                                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                                 <subviews>
                                                     <customView translatesAutoresizingMaskIntoConstraints="NO" id="QVD-OT-qtp">
-                                                        <rect key="frame" x="0.0" y="0.0" width="78" height="17"/>
+                                                        <rect key="frame" x="0.0" y="0.0" width="56" height="17"/>
                                                     </customView>
                                                 </subviews>
                                                 <constraints>
@@ -194,12 +193,12 @@
                                         <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                         <prototypeCellViews>
                                             <tableCellView id="tdZ-lu-oAc" customClass="KMBatchTableCellView" customModule="PDF_Reader_Pro" customModuleProvider="target">
-                                                <rect key="frame" x="491" y="1" width="140" height="17"/>
+                                                <rect key="frame" x="549" y="0.0" width="140" height="17"/>
                                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                             </tableCellView>
                                         </prototypeCellViews>
                                     </tableColumn>
-                                    <tableColumn identifier="dimensions" width="100" minWidth="100" maxWidth="100" id="BoK-gf-WJ0">
+                                    <tableColumn identifier="dimensions" width="164" minWidth="164" maxWidth="164" id="BoK-gf-WJ0">
                                         <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Dimensions">
                                             <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
                                             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -212,7 +211,7 @@
                                         <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
                                         <prototypeCellViews>
                                             <tableCellView id="nvT-ce-HBH" customClass="KMBatchTableCellView" customModule="PDF_Reader_Pro" customModuleProvider="target">
-                                                <rect key="frame" x="634" y="1" width="104" height="17"/>
+                                                <rect key="frame" x="689" y="0.0" width="168" height="17"/>
                                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                             </tableCellView>
                                         </prototypeCellViews>
@@ -231,7 +230,7 @@
                         <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="670" id="LUW-2r-W1h"/>
                     </constraints>
                     <scroller key="horizontalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="RBU-7C-fCt">
-                        <rect key="frame" x="1" y="383" width="668" height="16"/>
+                        <rect key="frame" x="1" y="404" width="668" height="16"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </scroller>
                     <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="32b-Um-caF">
@@ -239,15 +238,15 @@
                         <autoresizingMask key="autoresizingMask"/>
                     </scroller>
                     <tableHeaderView key="headerView" wantsLayer="YES" id="Mlr-rw-6rm" customClass="KMTableHeaderView" customModule="PDF_Reader_Pro" customModuleProvider="target">
-                        <rect key="frame" x="0.0" y="0.0" width="740" height="25"/>
+                        <rect key="frame" x="0.0" y="0.0" width="859" height="25"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </tableHeaderView>
                 </scrollView>
                 <customView translatesAutoresizingMaskIntoConstraints="NO" id="G6v-if-4fr" customClass="KMBlankView" customModule="PDF_Reader_Pro" customModuleProvider="target">
-                    <rect key="frame" x="0.0" y="0.0" width="718" height="400"/>
+                    <rect key="frame" x="0.0" y="0.0" width="718" height="421"/>
                     <subviews>
                         <customView translatesAutoresizingMaskIntoConstraints="NO" id="9GJ-Lf-bRA">
-                            <rect key="frame" x="222" y="105" width="275" height="190"/>
+                            <rect key="frame" x="222" y="116" width="275" height="190"/>
                             <subviews>
                                 <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="aT2-4b-2xG">
                                     <rect key="frame" x="67" y="50" width="140" height="140"/>

PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateRightViewController.swift → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateRightViewController.swift


PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateRightViewController.xib → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateRightViewController.xib


PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateSplitViewController.swift → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateSplitViewController.swift


PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateSplitViewController.xib → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateSplitViewController.xib


PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.swift → PDF Office/PDF Master/KMClass/ImageToPDF/Base/KMBatchOperateWindowController.swift


+ 8 - 6
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" 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="22155"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -13,12 +13,14 @@
         </customObject>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5" customClass="KMBatchWindow" customModule="PDF_Master" customModuleProvider="target">
+        <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5" customClass="KMBatchWindow" customModule="PDF_Reader_Pro" customModuleProvider="target">
             <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
-            <rect key="contentRect" x="463" y="248" width="480" height="270"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="contentRect" x="463" y="248" width="880" height="600"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="875"/>
+            <value key="minSize" type="size" width="880" height="600"/>
+            <value key="minFullScreenContentSize" type="size" width="880" height="600"/>
             <view key="contentView" id="se5-gp-TjO">
-                <rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
+                <rect key="frame" x="0.0" y="0.0" width="880" height="600"/>
                 <autoresizingMask key="autoresizingMask"/>
             </view>
             <connections>

+ 239 - 44
PDF Office/PDF Master/Class/Batch/WindowController/VC/KMBatchOperateImageToPDFViewController.swift

@@ -9,6 +9,9 @@ import Cocoa
 import KMComponentLibrary
 
 class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController, KMImageToPDFMethodDelegate, NSPopoverDelegate{
+    @IBOutlet weak var headerBox: NSBox!
+    @IBOutlet weak var titleLabel: NSTextField!
+    @IBOutlet weak var headerBottomLine: ComponentDivider!
     
     @IBOutlet var outputTypeLabel: NSTextField!
     @IBOutlet var createNewPDFBtn: NSButton!
@@ -34,6 +37,17 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
     @IBOutlet weak var appendBox: NSBox!
     @IBOutlet weak var appendBackBox: NSBox!
     
+    @IBOutlet weak var ocrSelectBox: NSBox!
+    @IBOutlet weak var languageBox: NSBox!
+    @IBOutlet weak var ocrPlanBox: NSBox!
+    @IBOutlet weak var ocrPlan2Box: NSBox!
+    @IBOutlet weak var hLine: NSView!
+    @IBOutlet weak var extractTextBox: NSBox!
+    
+    @IBOutlet weak var bottomBox: NSBox!
+    @IBOutlet weak var bottomTopLine: ComponentDivider!
+    @IBOutlet weak var applyButton: ComponentButton!
+    
     var password: String = ""
     
     lazy var method: KMImageToPDFMethod = {
@@ -81,6 +95,72 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         return view
     }()
     
+    private lazy var ocrCheckBox_: ComponentCheckBox = {
+        let view = ComponentCheckBox()
+        view.properties = ComponentCheckBoxProperty(size: .s,
+                                                                state: .normal,
+                                                                isDisabled: false,
+                                                                showhelp: false,
+                                                                text: NSLocalizedString("Recognize text if needed", comment: ""),
+                                                                checkboxType: .normal)
+        return view
+    }()
+    
+    private lazy var languageView_: ComponentSelect = {
+        let view = ComponentSelect()
+        
+        view.properties = ComponentSelectProperties(size: .s,
+                                                                state: .normal,
+                                                                isDisabled: false,
+                                                                isError: false,
+                                                                leftIcon: false,
+                                                                placeholder: nil,
+                                                                errorText: nil,
+                                                                creatable: false,
+                                                                text: KMLocalizedString("", comment: ""))
+//        view.delegate = self
+        return view
+    }()
+    
+    private var ocrPlanRadio_: ComponentRadio = {
+        let view = ComponentRadio()
+        view.properties = ComponentCheckBoxProperty(size: .s,
+                                                               state: .normal,
+                                                               isDisabled: false,
+                                                               showhelp: true,
+                                                               text: KMLocalizedString("OCR Plan 1-Online", comment: ""),
+                                                               checkboxType: .normal)
+        return view
+    }()
+    
+    private var ocrPlanRadio2_: ComponentRadio = {
+        let view = ComponentRadio()
+        view.properties = ComponentCheckBoxProperty(size: .s,
+                                                               state: .normal,
+                                                               isDisabled: false,
+                                                               showhelp: true,
+                                                               text: KMLocalizedString("OCR Plan 2-Online", comment: ""),
+                                                               checkboxType: .normal)
+        return view
+    }()
+    
+    private var vLine_: ComponentDivider = {
+        let view = ComponentDivider()
+        view.properties = ComponentDividerProperty(type: .horizontal, dash: false)
+        return view
+    }()
+    
+    private lazy var extractTextCheckBox_: ComponentCheckBox = {
+        let view = ComponentCheckBox()
+        view.properties = ComponentCheckBoxProperty(size: .s,
+                                                                state: .normal,
+                                                                isDisabled: false,
+                                                                showhelp: false,
+                                                                text: KMLocalizedString("Extract Text (.txt)", comment: ""),
+                                                                checkboxType: .normal)
+        return view
+    }()
+    
     override var interfaceStatus: KMBatchOperateInterfaceStatus?{
         set{
             super.interfaceStatus = newValue
@@ -110,15 +190,14 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
     private func _updateActionButtonEnable(_ enabled: Bool) {
         if enabled {
             self.actionButton.tag = 1
-            self.actionButton.title = NSLocalizedString("Save as PDF", comment: "")
-            self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
-            self.actionButton.isEnabled = true
-            self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
+            
+            applyButton.properties.isDisabled = false
+            applyButton.reloadData()
         } else {
             self.actionButton.tag = 0
-            self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
-            self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
-            self.actionButton.isEnabled = false
+            
+            applyButton.properties.isDisabled = true
+            applyButton.reloadData()
         }
     }
     
@@ -129,6 +208,30 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
     
     override func viewDidLoad() {
         super.viewDidLoad()
+        
+        headerBox.borderWidth = 0
+        titleLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-m-bold")
+        createNewPDFRadio_.properties.checkboxType = .selected
+        createNewPDFRadio_.reloadData()
+        
+        ocrLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
+        ocrSelectBox.borderWidth = 0
+        ocrSelectBox.contentView = ocrCheckBox_
+        ocrCheckBox_.setTarget(self, action: #selector(buttonClicked_OCRSelect))
+        languageView_.properties.isDisabled = true
+        languageView_.reloadData()
+        ocrPlanRadio_.setTarget(self, action: #selector(ocrPlanAction))
+        ocrPlanRadio_.properties.isDisabled = true
+        ocrPlanRadio_.reloadData()
+        ocrPlanRadio2_.setTarget(self, action: #selector(ocrPlanAction))
+        ocrPlanRadio2_.properties.isDisabled = true
+        ocrPlanRadio2_.reloadData()
+        extractTextCheckBox_.properties.isDisabled = true
+        extractTextCheckBox_.reloadData()
+        
+        bottomBox.borderWidth = 0
+        applyButton.properties = ComponentButtonProperty(type: .primary, size: .m, onlyIcon: false, buttonText: KMLocalizedString("Apply"))
+        
         self.localizedLanguage()
         self.configuUI()
         
@@ -145,6 +248,30 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(batchFilesCountNotification(notification:)), name: NSNotification.Name("KMBatchFilesCountNotification"), object: nil)
     }
+    
+    
+    
+    override func updateUILanguage() {
+        super.updateUILanguage()
+        
+        KMMainThreadExecute {
+            self.titleLabel.stringValue = KMLocalizedString("Image to PDF")
+            self.ocrLabel.stringValue = KMLocalizedString("Text Recognition Settings")
+        }
+    }
+    
+    override func updateUIThemeColor() {
+        super.updateUIThemeColor()
+        
+        KMMainThreadExecute {
+            let titleColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
+            self.titleLabel.textColor = titleColor
+            self.headerBottomLine.properties = ComponentDividerProperty()
+            self.ocrLabel.textColor = titleColor
+            self.bottomTopLine.properties = ComponentDividerProperty()
+        }
+    }
+    
     func localizedLanguage() {
         self.outputTypeLabel.stringValue = KMLocalizedString("Output")
         self.btnMerge.title = KMLocalizedString("Merge All")
@@ -152,7 +279,29 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         self.appendPDFBtn.title = KMLocalizedString("Append To Existing File")
         self.appendTextField.placeholderString = KMLocalizedString("Select a File")
         self.selectLanguageLabel.stringValue = KMLocalizedString("Select OCR Language:")
+        self.selectLanguageLabel.isHidden = true
         self.ocrSelectBtn.title = KMLocalizedString("OCR Plan")
+        
+        let languages = KMGOCRManager.languages() as NSArray
+        let strings = languages.value(forKeyPath: KMGOCRLanguageStringKey) as? [String]
+        var menuItemArr: [ComponentMenuitemProperty] = []
+        for language in strings ?? [] {
+            let itemProperty: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
+                                                                                    itemSelected: false,
+                                                                                    isDisabled: false,
+                                                                                    keyEquivalent: nil,
+                                                                                    text: language)
+            menuItemArr.append(itemProperty)
+        }
+
+        
+        languageView_.updateMenuItemsArr(menuItemArr)
+        
+        languageView_.selectItemAtIndex(0)
+        languageView_.properties.creatable = false
+        languageView_.properties.text = menuItemArr.first?.text
+        languageView_.reloadData()
+        
         self.updateLanguageButton((KMGOCRManager.default().selectedLanguages?.value(forKeyPath: KMGOCRLanguageStringKey) as? [String]))
         
         self.actionButton.title = KMLocalizedString("Save as PDF")
@@ -166,17 +315,9 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         appendBackView.wantsLayer = true
         appendBackView.layer?.borderWidth = 0.5
         
-        self.actionButton.wantsLayer = true
-        self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
         self.appendOtherPDFBtn.layer?.backgroundColor = KMAppearance.Interactive.s0Color().withAlphaComponent(0.4).cgColor
-        self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
-        self.actionButton.layer?.cornerRadius = 1.0
         
         createNewPDFBtn.setTitleColor(KMAppearance.Layout.h0Color())
-        ///createNewPDFBtn.superview?.addSubview( createNewPDFRadio_)
-//        self.createNewPDFBtn.setTarget(self, action: #selector(radioAction))
-        //createNewPDFRadio_.frame = createNewPDFBtn.frame
-        //createNewPDFRadio_.autoresizingMask = [.width, .height]
         newPDFBox.borderWidth = 0
         newPDFBox.contentView = createNewPDFRadio_
         createNewPDFRadio_.setTarget(self, action: #selector(buttonClicked_CreateNewPDF))
@@ -199,20 +340,36 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         self.ocrSelectBtn.setTitleColor(KMAppearance.Layout.h0Color())
         self.saveAsButton.setTitleColor(KMAppearance.Layout.h0Color())
         self.selectLanguageLabel.textColor = KMAppearance.Layout.h0Color()
-        self.languageButton.isEnabled = false
-        self.planButton.isEnabled = false
-        self.saveAsButton.isEnabled = false
+        saveAsButton.isHidden = true
+        
+        ocrSelectBtn.isHidden = true
+        
+        languageBox.borderWidth = 0
+        languageBox.contentView = languageView_
+        
+        ocrPlanBox.borderWidth = 0
+        ocrPlanBox.contentView = ocrPlanRadio_
+        
+        ocrPlan2Box.borderWidth = 0
+        ocrPlan2Box.contentView = ocrPlanRadio2_
+        
+        hLine.addSubview(vLine_)
+        vLine_.frame = hLine.bounds
+        vLine_.autoresizingMask = [.width, .height]
+        
+        extractTextBox.borderWidth = 0
+        extractTextBox.contentView = extractTextCheckBox_
         
         appendTextField.backgroundColor = KMAppearance.Layout.l1Color()
-        planButton.wantsLayer = true
         appendTextField.wantsLayer = true
-        planButton.wantsLayer = true
         appendTextField.layer?.cornerRadius = 1.0
         languageButton.layer?.backgroundColor = NSColor.clear.cgColor
         languaeBox.borderColor = KMAppearance.Interactive.s0Color()
         planBox.borderColor = KMAppearance.Interactive.s0Color()
         languaeBox.fillColor = KMAppearance.Layout.l1Color()
         planBox.fillColor = KMAppearance.Layout.l1Color()
+        languaeBox.isHidden = true
+        
         
         self.updateViewColor()
     }
@@ -230,6 +387,9 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
     func updateLanguageButton(_ languages: [String]?) {
         if languages?.count ?? 0 < 1 {
             self.languageButton.title = " " + KMLocalizedString("Auto Detection")
+            
+            self.languageView_.properties.text = " " + KMLocalizedString("Auto Detection")
+            self.languageView_.reloadData()
             return
         }
         var languageName: String = ""
@@ -247,6 +407,8 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         }
         
         self.languageButton.title = " " + languageName
+        self.languageView_.properties.text = " " + languageName
+        self.languageView_.reloadData()
     }
     func converArrType(arr: Array<KMBatchOperateFile>, keyString: String) -> [String] {
         let newArr = NSMutableArray()
@@ -283,12 +445,12 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         var isMerge = false
         var isCreatNewPDF = false
         var isOCR = false
-        if self.ocrSelectBtn.state == .on {
+        if ocrCheckBox_.properties.checkboxType == .selected {
             isOCR = true
         }
         
         var isSaveAs = false
-        if self.saveAsButton.state == .on {
+        if extractTextCheckBox_.properties.checkboxType == .selected {
             isSaveAs = true
         }
         
@@ -307,7 +469,7 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
             return
         }
         
-        if self.createNewPDFBtn.state == .on {
+        if createNewPDFRadio_.properties.checkboxType == .selected {
             if (self.choosePath.count < 1) {
                 let alert = NSAlert()
                 alert.alertStyle = .critical
@@ -319,7 +481,6 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
             path = self.choosePath
             
             if mergeAllCheckBox_.properties.checkboxType == .selected {
-//            if self.btnMerge.state == .on {
                 isMerge = true
             }
             isCreatNewPDF = true
@@ -340,7 +501,10 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         }
         
         self.languageButton.isEnabled = false
-        self.planButton.isEnabled = false
+        ocrPlanRadio_.properties.isDisabled = true
+        ocrPlanRadio_.reloadData()
+        ocrPlanRadio2_.properties.isDisabled = true
+        ocrPlanRadio2_.reloadData()
         self.method.password = self.password
         self.interfaceStatus = .Processing
         
@@ -348,7 +512,10 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         self.method.exportPDFFile(fileArray: photoArray, savePath: path, isOCR: isOCR, isCreatPDF: isCreatNewPDF, isMerge: isMerge, isSaveAsText: isSaveAs) { [weak self] savePath, errorArr, errorOCRArray in
             
             self?.languageButton.isEnabled = true
-            self?.planButton.isEnabled = true
+            self?.ocrPlanRadio_.properties.isDisabled = false
+            self?.ocrPlanRadio_.reloadData()
+            self?.ocrPlanRadio2_.properties.isDisabled = false
+            self?.ocrPlanRadio2_.reloadData()
             self?.interfaceStatus = .PrepareProcess
             if errorArr.count > 0 {
                 let dict: [String: Any] = ["isMerge": false, "isSuccess": false]
@@ -391,6 +558,19 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         workspace.activateFileViewerSelecting([url])
     }
     
+    // MARK: - Actions
+    
+    @objc func ocrPlanAction(_ sender: ComponentRadio) {
+        for radio in [ocrPlanRadio_, ocrPlanRadio2_] {
+            if radio.isEqual(to: sender) {
+                radio.properties.checkboxType = .selected
+                radio.reloadData()
+            } else {
+                radio.properties.checkboxType = .normal
+                radio.reloadData()
+            }
+        }
+    }
     
     //MARK: Notification
     @objc func OCRSelectedLanguagesChangeNotification(notification: Notification) {
@@ -408,9 +588,17 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
     func OCRSelectedPlanChangeAction() {
         let plan = UserDefaults.standard.integer(forKey: "KMOCRCurrentPlanKey")
         if plan == 0 {
-            self.planButton.title = " " + KMLocalizedString("Plan 1 (Online)")
+//            self.planButton.title = " " + KMLocalizedString("Plan 1 (Online)")
+            ocrPlanRadio_.properties.checkboxType = .selected
+            ocrPlanRadio_.reloadData()
+            ocrPlanRadio2_.properties.checkboxType = .normal
+            ocrPlanRadio2_.reloadData()
         } else {
-            self.planButton.title = " " + KMLocalizedString("Plan 2 (Offline)")
+//            self.planButton.title = " " + KMLocalizedString("Plan 2 (Offline)")
+            ocrPlanRadio_.properties.checkboxType = .normal
+            ocrPlanRadio_.reloadData()
+            ocrPlanRadio2_.properties.checkboxType = .selected
+            ocrPlanRadio2_.reloadData()
         }
         KMGOCRManager.default().selectedLanguages = NSMutableArray()
         self.updateLanguageButton(KMGOCRManager.default().selectedLanguages?.value(forKeyPath: KMGOCRLanguageStringKey) as? [String])
@@ -428,11 +616,9 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
     
     @IBAction func buttonClicked_CreateNewPDF(_ sender: ComponentRadio) {
         if (sender.properties.checkboxType == .selected) {
-            self.btnMerge.isEnabled = true
             mergeAllCheckBox_.properties.isDisabled = false
             mergeAllCheckBox_.reloadData()
             
-            self.appendPDFBtn.state = .off
             appendRadio_.properties.checkboxType = .normal
             appendRadio_.reloadData()
             self.appendOtherPDFBtn.isEnabled = false
@@ -441,11 +627,9 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
     
     @IBAction func buttonClicked_AppendOtherPDF(_ sender: ComponentRadio) {
         if (sender.properties.checkboxType == .selected) {
-            self.createNewPDFBtn.state = .off
             createNewPDFRadio_.properties.checkboxType = .normal
             createNewPDFRadio_.reloadData()
             
-            self.btnMerge.isEnabled = false
             mergeAllCheckBox_.properties.checkboxType = .normal
             mergeAllCheckBox_.properties.isDisabled = true
             mergeAllCheckBox_.reloadData()
@@ -454,21 +638,32 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
         }
     }
     
-    @IBAction func buttonClicked_OCRSelect(_ sender: NSButton) {
+    @IBAction func buttonClicked_OCRSelect(_ sender: ComponentCheckBox) {
         //MARK: 判断是否付费用户
         if IAPProductsManager.default().isAvailableAllFunction() == false {
             KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
-            self.ocrSelectBtn.state = .off
+            ocrCheckBox_.properties.checkboxType = .normal
+            ocrCheckBox_.reloadData()
             return
         }
-        if (sender.state == .on) {
-            self.languageButton.isEnabled = true
-            self.planButton.isEnabled = true
-            self.saveAsButton.isEnabled = true
+        if (sender.properties.checkboxType == .selected) {
+            languageView_.properties.isDisabled = false
+            languageView_.reloadData()
+            ocrPlanRadio_.properties.isDisabled = false
+            ocrPlanRadio_.reloadData()
+            ocrPlanRadio2_.properties.isDisabled = false
+            ocrPlanRadio2_.reloadData()
+            extractTextCheckBox_.properties.isDisabled = false
+            extractTextCheckBox_.reloadData()
         } else {
-            self.languageButton.isEnabled = false
-            self.planButton.isEnabled = false
-            self.saveAsButton.isEnabled = false
+            languageView_.properties.isDisabled = true
+            languageView_.reloadData()
+            ocrPlanRadio_.properties.isDisabled = true
+            ocrPlanRadio_.reloadData()
+            ocrPlanRadio2_.properties.isDisabled = true
+            ocrPlanRadio2_.reloadData()
+            extractTextCheckBox_.properties.isDisabled = true
+            extractTextCheckBox_.reloadData()
         }
     }
     
@@ -521,12 +716,12 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
             }
             
             var isOCR = false
-            if self.ocrSelectBtn.state == .on {
+            if ocrCheckBox_.properties.checkboxType == .selected {
                 isOCR = true
             }
             
             var isSaveAs = false
-            if self.saveAsButton.state == .on {
+            if extractTextCheckBox_.properties.checkboxType == .selected {
                 isSaveAs = true
             }
             
@@ -545,7 +740,7 @@ class KMBatchOperateImageToPDFViewController: KMBatchOperateBaseViewController,
                 return
             }
             
-            if self.createNewPDFBtn.state == .off {
+            if createNewPDFRadio_.properties.checkboxType != .selected {
                 let appenString = self.appendTextField.stringValue
                 if appenString.isEmpty {
                     let alert = NSAlert()

+ 176 - 20
PDF Office/PDF Master/Class/Batch/WindowController/VC/KMBatchOperateImageToPDFViewController.xib

@@ -15,30 +15,42 @@
                 <outlet property="appendOtherPDFBtn" destination="H4C-li-Hhm" id="kmI-0Y-YVe"/>
                 <outlet property="appendPDFBtn" destination="lwQ-xY-nsX" id="GEN-0Q-t29"/>
                 <outlet property="appendTextField" destination="AKV-3R-iGQ" id="MmJ-ov-KsS"/>
+                <outlet property="applyButton" destination="HSI-hW-pYn" id="YQY-2l-Can"/>
+                <outlet property="bottomBox" destination="dja-8H-Uup" id="udk-GK-Wkh"/>
+                <outlet property="bottomTopLine" destination="4wO-ha-sYg" id="9wl-jh-5lh"/>
                 <outlet property="btnMerge" destination="Sf1-WE-VzB" id="n9e-oY-Rpj"/>
                 <outlet property="createNewPDFBtn" destination="cYX-Yt-gnO" id="bku-Gy-hF3"/>
+                <outlet property="extractTextBox" destination="nfj-9v-ZqH" id="ErV-XO-Hur"/>
+                <outlet property="hLine" destination="wXl-jv-vC2" id="Z4J-x2-xgU"/>
+                <outlet property="headerBottomLine" destination="7MQ-kJ-8ar" id="LD2-vq-MD6"/>
+                <outlet property="headerBox" destination="yvT-Vr-HYw" id="JJC-0R-pz6"/>
                 <outlet property="languaeBox" destination="0xe-05-6j8" id="GM8-Xz-c6p"/>
+                <outlet property="languageBox" destination="6qO-Xk-6yr" id="bW6-w0-uTt"/>
                 <outlet property="languageButton" destination="Que-YG-sCE" id="Obq-iW-LWJ"/>
                 <outlet property="mergeAllBox" destination="hCw-K3-67H" id="t5s-f5-eUc"/>
                 <outlet property="newPDFBox" destination="n89-YE-ldr" id="4dT-WC-jg5"/>
                 <outlet property="ocrLabel" destination="hyp-2H-elp" id="7wX-ia-0Rp"/>
+                <outlet property="ocrPlan2Box" destination="f7o-yZ-THg" id="AE8-1e-sun"/>
+                <outlet property="ocrPlanBox" destination="f52-b5-1Ge" id="5ZG-fZ-vaS"/>
+                <outlet property="ocrSelectBox" destination="Ivj-XV-tDI" id="fgU-5z-ksd"/>
                 <outlet property="ocrSelectBtn" destination="DvB-9f-Xgt" id="UdG-6d-27f"/>
                 <outlet property="outputTypeLabel" destination="aPB-Pb-64w" id="BBp-lK-MNk"/>
                 <outlet property="planBox" destination="xu7-RV-DKR" id="ihz-bb-VhO"/>
                 <outlet property="planButton" destination="9go-Ka-u3z" id="nxW-wW-rQJ"/>
                 <outlet property="saveAsButton" destination="mXd-Rx-c3O" id="nnV-Rw-wSx"/>
                 <outlet property="selectLanguageLabel" destination="LnK-B0-rGp" id="Lb0-iZ-L6g"/>
+                <outlet property="titleLabel" destination="N3m-4e-rSU" id="X1q-p2-qWf"/>
                 <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
             </connections>
         </customObject>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
         <customView id="Hz6-mo-xeY">
-            <rect key="frame" x="0.0" y="0.0" width="480" height="436"/>
+            <rect key="frame" x="0.0" y="0.0" width="480" height="566"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
             <subviews>
                 <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aPB-Pb-64w">
-                    <rect key="frame" x="14" y="409" width="42" height="17"/>
+                    <rect key="frame" x="14" y="497" width="42" height="17"/>
                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="dr8-xu-eZp">
                         <font key="font" metaFont="systemBold" size="14"/>
                         <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -46,7 +58,7 @@
                     </textFieldCell>
                 </textField>
                 <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cYX-Yt-gnO">
-                    <rect key="frame" x="14" y="379" width="148" height="18"/>
+                    <rect key="frame" x="14" y="467" width="148" height="18"/>
                     <buttonCell key="cell" type="radio" title="New PDF Document" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="8NR-LX-ScR">
                         <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
                         <font key="font" metaFont="system"/>
@@ -56,14 +68,14 @@
                     </connections>
                 </button>
                 <button translatesAutoresizingMaskIntoConstraints="NO" id="Sf1-WE-VzB">
-                    <rect key="frame" x="32" y="345" width="87" height="29"/>
+                    <rect key="frame" x="32" y="433" width="87" height="29"/>
                     <buttonCell key="cell" type="check" title="Merge  All" bezelStyle="regularSquare" imagePosition="left" inset="2" id="Gdy-u9-gi5">
                         <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
                         <font key="font" metaFont="system"/>
                     </buttonCell>
                 </button>
                 <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lwQ-xY-nsX">
-                    <rect key="frame" x="14" y="306" width="225" height="18"/>
+                    <rect key="frame" x="14" y="394" width="225" height="18"/>
                     <buttonCell key="cell" type="radio" title="Append to existing fil or portfolio" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="BMo-hm-pTQ">
                         <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
                         <font key="font" metaFont="system"/>
@@ -73,7 +85,7 @@
                     </connections>
                 </button>
                 <customView translatesAutoresizingMaskIntoConstraints="NO" id="k0c-vv-NPP">
-                    <rect key="frame" x="34" y="279" width="430" height="24"/>
+                    <rect key="frame" x="34" y="367" width="430" height="24"/>
                     <subviews>
                         <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AKV-3R-iGQ">
                             <rect key="frame" x="-1" y="1" width="404" height="22"/>
@@ -123,7 +135,7 @@
                     </connections>
                 </button>
                 <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hyp-2H-elp">
-                    <rect key="frame" x="14" y="230" width="35" height="17"/>
+                    <rect key="frame" x="14" y="318" width="35" height="17"/>
                     <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="OCR" id="SLY-wg-469">
                         <font key="font" metaFont="systemBold" size="14"/>
                         <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -131,14 +143,14 @@
                     </textFieldCell>
                 </textField>
                 <button translatesAutoresizingMaskIntoConstraints="NO" id="mXd-Rx-c3O">
-                    <rect key="frame" x="32" y="71" width="102" height="18"/>
+                    <rect key="frame" x="32" y="159" width="102" height="18"/>
                     <buttonCell key="cell" type="check" title="Save as TXT" bezelStyle="regularSquare" imagePosition="left" inset="2" id="yMl-Im-6Oy">
                         <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
                         <font key="font" metaFont="system"/>
                     </buttonCell>
                 </button>
-                <button horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gJA-ad-BvI">
-                    <rect key="frame" x="440" y="97" width="26" height="26"/>
+                <button hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gJA-ad-BvI">
+                    <rect key="frame" x="440" y="185" width="26" height="26"/>
                     <constraints>
                         <constraint firstAttribute="width" constant="21" id="Mn0-It-ogu"/>
                         <constraint firstAttribute="height" constant="21" id="v6b-Yx-hGX"/>
@@ -152,7 +164,7 @@
                     </connections>
                 </button>
                 <box boxType="custom" cornerRadius="1" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="0xe-05-6j8">
-                    <rect key="frame" x="34" y="99" width="404" height="24"/>
+                    <rect key="frame" x="34" y="187" width="404" height="24"/>
                     <view key="contentView" id="Sfo-EK-dRW">
                         <rect key="frame" x="1" y="1" width="402" height="22"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -182,7 +194,7 @@
                     </constraints>
                 </box>
                 <button translatesAutoresizingMaskIntoConstraints="NO" id="DvB-9f-Xgt">
-                    <rect key="frame" x="14" y="195" width="84" height="18"/>
+                    <rect key="frame" x="14" y="283" width="84" height="18"/>
                     <buttonCell key="cell" type="check" title="OCR Plan" bezelStyle="regularSquare" imagePosition="left" inset="2" id="nDI-6p-sba">
                         <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
                         <font key="font" metaFont="system"/>
@@ -192,7 +204,7 @@
                     </connections>
                 </button>
                 <box boxType="custom" cornerRadius="1" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="xu7-RV-DKR">
-                    <rect key="frame" x="34" y="163" width="430" height="24"/>
+                    <rect key="frame" x="34" y="251" width="430" height="24"/>
                     <view key="contentView" id="U53-s6-6nW">
                         <rect key="frame" x="1" y="1" width="428" height="22"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -222,7 +234,7 @@
                     </constraints>
                 </box>
                 <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LnK-B0-rGp">
-                    <rect key="frame" x="32" y="131" width="37" height="16"/>
+                    <rect key="frame" x="32" y="219" width="37" height="16"/>
                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Pba-1m-xRx">
                         <font key="font" metaFont="system"/>
                         <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -230,7 +242,7 @@
                     </textFieldCell>
                 </textField>
                 <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="n89-YE-ldr">
-                    <rect key="frame" x="16" y="377" width="448" height="20"/>
+                    <rect key="frame" x="16" y="465" width="448" height="20"/>
                     <view key="contentView" id="crJ-bx-eAh">
                         <rect key="frame" x="1" y="1" width="446" height="18"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -240,7 +252,7 @@
                     </constraints>
                 </box>
                 <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="hCw-K3-67H">
-                    <rect key="frame" x="40" y="349" width="424" height="20"/>
+                    <rect key="frame" x="40" y="437" width="424" height="20"/>
                     <view key="contentView" id="yiI-lc-fK0">
                         <rect key="frame" x="1" y="1" width="422" height="18"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -250,7 +262,7 @@
                     </constraints>
                 </box>
                 <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="HpT-QS-341">
-                    <rect key="frame" x="16" y="311" width="448" height="20"/>
+                    <rect key="frame" x="16" y="399" width="448" height="20"/>
                     <view key="contentView" id="R0v-fU-j7b">
                         <rect key="frame" x="1" y="1" width="446" height="18"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -260,7 +272,7 @@
                     </constraints>
                 </box>
                 <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="ivy-HJ-F2X">
-                    <rect key="frame" x="16" y="271" width="448" height="32"/>
+                    <rect key="frame" x="16" y="359" width="448" height="32"/>
                     <view key="contentView" id="hXZ-UD-kdJ">
                         <rect key="frame" x="1" y="1" width="446" height="30"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -269,54 +281,198 @@
                         <constraint firstAttribute="height" constant="32" id="mDb-QA-Oor"/>
                     </constraints>
                 </box>
+                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="Ivj-XV-tDI">
+                    <rect key="frame" x="16" y="286" width="448" height="20"/>
+                    <view key="contentView" id="EXi-zS-eDm">
+                        <rect key="frame" x="1" y="1" width="446" height="18"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                    </view>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="20" id="axj-MY-ljb"/>
+                    </constraints>
+                </box>
+                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="6qO-Xk-6yr">
+                    <rect key="frame" x="16" y="246" width="448" height="32"/>
+                    <view key="contentView" id="k0A-6r-Dwg">
+                        <rect key="frame" x="1" y="1" width="446" height="30"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                    </view>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="32" id="zDk-wa-gZE"/>
+                    </constraints>
+                </box>
+                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="f52-b5-1Ge">
+                    <rect key="frame" x="16" y="206" width="448" height="32"/>
+                    <view key="contentView" id="0Ci-tL-ey8">
+                        <rect key="frame" x="1" y="1" width="446" height="30"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                    </view>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="32" id="cqS-bf-yFu"/>
+                    </constraints>
+                </box>
+                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="f7o-yZ-THg">
+                    <rect key="frame" x="16" y="174" width="448" height="32"/>
+                    <view key="contentView" id="Wjc-K2-hqV">
+                        <rect key="frame" x="1" y="1" width="446" height="30"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                    </view>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="32" id="JSA-2Y-Xvu"/>
+                    </constraints>
+                </box>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="wXl-jv-vC2">
+                    <rect key="frame" x="16" y="165" width="448" height="1"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="1" id="fL6-p3-0Rf"/>
+                    </constraints>
+                </customView>
+                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="nfj-9v-ZqH">
+                    <rect key="frame" x="16" y="120" width="448" height="32"/>
+                    <view key="contentView" id="uKI-2s-Sl0">
+                        <rect key="frame" x="1" y="1" width="446" height="30"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                    </view>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="32" id="Hfb-Gk-cjx"/>
+                    </constraints>
+                </box>
+                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="dja-8H-Uup">
+                    <rect key="frame" x="0.0" y="0.0" width="480" height="72"/>
+                    <view key="contentView" id="uX6-hg-iIn">
+                        <rect key="frame" x="1" y="1" width="478" height="70"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="4wO-ha-sYg" customClass="ComponentDivider" customModule="KMComponentLibrary">
+                                <rect key="frame" x="0.0" y="69" width="478" height="1"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="1" id="nJk-GK-xd7"/>
+                                </constraints>
+                            </customView>
+                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="HSI-hW-pYn" customClass="ComponentButton" customModule="KMComponentLibrary">
+                                <rect key="frame" x="16" y="16" width="446" height="38"/>
+                            </customView>
+                        </subviews>
+                        <constraints>
+                            <constraint firstAttribute="trailing" secondItem="HSI-hW-pYn" secondAttribute="trailing" constant="16" id="0Rl-C2-wUp"/>
+                            <constraint firstItem="HSI-hW-pYn" firstAttribute="leading" secondItem="uX6-hg-iIn" secondAttribute="leading" constant="16" id="1qC-Q1-6tY"/>
+                            <constraint firstAttribute="trailing" secondItem="4wO-ha-sYg" secondAttribute="trailing" id="Q74-WU-Vvw"/>
+                            <constraint firstItem="4wO-ha-sYg" firstAttribute="leading" secondItem="uX6-hg-iIn" secondAttribute="leading" id="gNK-sS-DQK"/>
+                            <constraint firstItem="4wO-ha-sYg" firstAttribute="top" secondItem="uX6-hg-iIn" secondAttribute="top" id="hs1-L9-CGh"/>
+                            <constraint firstItem="HSI-hW-pYn" firstAttribute="top" secondItem="uX6-hg-iIn" secondAttribute="top" constant="16" id="l4t-Lg-Wdn"/>
+                            <constraint firstAttribute="bottom" secondItem="HSI-hW-pYn" secondAttribute="bottom" constant="16" id="rv9-Lq-usl"/>
+                        </constraints>
+                    </view>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="72" id="L4J-pn-V8v"/>
+                    </constraints>
+                </box>
+                <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="yvT-Vr-HYw">
+                    <rect key="frame" x="0.0" y="526" width="480" height="40"/>
+                    <view key="contentView" id="kWL-fg-PgX">
+                        <rect key="frame" x="1" y="1" width="478" height="38"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="N3m-4e-rSU">
+                                <rect key="frame" x="221" y="11" width="37" height="16"/>
+                                <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Sym-H3-uOC">
+                                    <font key="font" usesAppearanceFont="YES"/>
+                                    <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                    <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                </textFieldCell>
+                            </textField>
+                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="7MQ-kJ-8ar" customClass="ComponentDivider" customModule="KMComponentLibrary">
+                                <rect key="frame" x="0.0" y="0.0" width="478" height="1"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="1" id="Sby-Oh-ryd"/>
+                                </constraints>
+                            </customView>
+                        </subviews>
+                        <constraints>
+                            <constraint firstItem="7MQ-kJ-8ar" firstAttribute="leading" secondItem="kWL-fg-PgX" secondAttribute="leading" id="1O0-je-ZDP"/>
+                            <constraint firstItem="N3m-4e-rSU" firstAttribute="centerY" secondItem="kWL-fg-PgX" secondAttribute="centerY" id="5d0-dl-3hC"/>
+                            <constraint firstAttribute="trailing" secondItem="7MQ-kJ-8ar" secondAttribute="trailing" id="OU7-cS-TMd"/>
+                            <constraint firstAttribute="bottom" secondItem="7MQ-kJ-8ar" secondAttribute="bottom" id="kag-NF-2g7"/>
+                            <constraint firstItem="N3m-4e-rSU" firstAttribute="centerX" secondItem="kWL-fg-PgX" secondAttribute="centerX" id="x7t-5L-61C"/>
+                        </constraints>
+                    </view>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="40" id="x7e-jB-MYY"/>
+                    </constraints>
+                </box>
             </subviews>
             <constraints>
                 <constraint firstItem="xu7-RV-DKR" firstAttribute="top" secondItem="DvB-9f-Xgt" secondAttribute="bottom" constant="9" id="4vj-GV-hlg"/>
                 <constraint firstItem="lwQ-xY-nsX" firstAttribute="top" secondItem="Sf1-WE-VzB" secondAttribute="bottom" constant="23" id="6Ma-jA-EeT"/>
                 <constraint firstItem="HkY-4k-ShL" firstAttribute="centerX" secondItem="Hz6-mo-xeY" secondAttribute="centerX" id="89C-67-SEc"/>
+                <constraint firstItem="f7o-yZ-THg" firstAttribute="top" secondItem="f52-b5-1Ge" secondAttribute="bottom" id="8Xt-Pa-Sgd"/>
+                <constraint firstItem="6qO-Xk-6yr" firstAttribute="top" secondItem="Ivj-XV-tDI" secondAttribute="bottom" constant="8" id="8YG-3N-WCa"/>
                 <constraint firstItem="LnK-B0-rGp" firstAttribute="leading" secondItem="xu7-RV-DKR" secondAttribute="leading" id="9x7-70-cgs"/>
+                <constraint firstAttribute="trailing" secondItem="Ivj-XV-tDI" secondAttribute="trailing" constant="16" id="AL5-lm-JS9"/>
+                <constraint firstItem="Ivj-XV-tDI" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="AZw-Ex-mSQ"/>
+                <constraint firstAttribute="trailing" secondItem="dja-8H-Uup" secondAttribute="trailing" id="DPv-In-aGx"/>
+                <constraint firstItem="f7o-yZ-THg" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="DSP-jU-5v6"/>
                 <constraint firstItem="gJA-ad-BvI" firstAttribute="leading" secondItem="0xe-05-6j8" secondAttribute="trailing" constant="5" id="F71-ii-T0z"/>
+                <constraint firstItem="wXl-jv-vC2" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="FXt-Gu-oLI"/>
                 <constraint firstItem="0xe-05-6j8" firstAttribute="leading" secondItem="Sf1-WE-VzB" secondAttribute="leading" id="Ghm-t1-ET6"/>
                 <constraint firstItem="k0c-vv-NPP" firstAttribute="leading" secondItem="Sf1-WE-VzB" secondAttribute="leading" id="INv-ai-ab9"/>
                 <constraint firstItem="0xe-05-6j8" firstAttribute="top" secondItem="LnK-B0-rGp" secondAttribute="bottom" constant="8" id="IbM-ET-fpF"/>
+                <constraint firstAttribute="trailing" secondItem="f7o-yZ-THg" secondAttribute="trailing" constant="16" id="JUv-MP-Y9l"/>
                 <constraint firstAttribute="trailing" secondItem="HpT-QS-341" secondAttribute="trailing" constant="16" id="Liv-T3-5cT"/>
                 <constraint firstItem="Sf1-WE-VzB" firstAttribute="top" secondItem="cYX-Yt-gnO" secondAttribute="bottom" constant="7" id="LkA-nk-5sh"/>
+                <constraint firstItem="nfj-9v-ZqH" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="O8F-CD-d5w"/>
                 <constraint firstItem="hCw-K3-67H" firstAttribute="top" secondItem="n89-YE-ldr" secondAttribute="bottom" constant="8" id="PSB-NV-7Vv"/>
                 <constraint firstAttribute="trailing" secondItem="ivy-HJ-F2X" secondAttribute="trailing" constant="16" id="QLZ-zy-81z"/>
                 <constraint firstItem="ivy-HJ-F2X" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="QWz-1v-vc9"/>
+                <constraint firstItem="dja-8H-Uup" firstAttribute="top" relation="greaterThanOrEqual" secondItem="nfj-9v-ZqH" secondAttribute="bottom" constant="48" id="RhM-Uu-BBI"/>
                 <constraint firstItem="cYX-Yt-gnO" firstAttribute="top" secondItem="aPB-Pb-64w" secondAttribute="bottom" constant="13" id="TeU-vK-ErS"/>
-                <constraint firstItem="aPB-Pb-64w" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="10" id="UbP-Fa-eTV"/>
+                <constraint firstItem="yvT-Vr-HYw" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="USs-od-fj8"/>
+                <constraint firstItem="aPB-Pb-64w" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="52" id="UbP-Fa-eTV"/>
+                <constraint firstAttribute="trailing" secondItem="yvT-Vr-HYw" secondAttribute="trailing" id="VAs-z3-Iqh"/>
+                <constraint firstAttribute="trailing" secondItem="f52-b5-1Ge" secondAttribute="trailing" constant="16" id="VLF-tB-JZU"/>
                 <constraint firstItem="HpT-QS-341" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="VU4-bS-vNC"/>
                 <constraint firstItem="DvB-9f-Xgt" firstAttribute="leading" secondItem="hyp-2H-elp" secondAttribute="leading" id="XyT-9R-eIO"/>
                 <constraint firstAttribute="bottom" secondItem="HkY-4k-ShL" secondAttribute="bottom" constant="20" id="YyJ-nz-wuP"/>
+                <constraint firstAttribute="trailing" secondItem="nfj-9v-ZqH" secondAttribute="trailing" constant="16" id="aOM-Mo-oU4"/>
+                <constraint firstAttribute="trailing" secondItem="wXl-jv-vC2" secondAttribute="trailing" constant="16" id="ajI-ou-mFa"/>
                 <constraint firstItem="gJA-ad-BvI" firstAttribute="centerY" secondItem="0xe-05-6j8" secondAttribute="centerY" id="b5C-zZ-uoa"/>
+                <constraint firstItem="dja-8H-Uup" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="b6T-F7-enh"/>
                 <constraint firstItem="n89-YE-ldr" firstAttribute="top" secondItem="aPB-Pb-64w" secondAttribute="bottom" constant="12" id="bk0-kf-ulW"/>
                 <constraint firstItem="aPB-Pb-64w" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="cm2-wz-AP3"/>
                 <constraint firstAttribute="trailing" secondItem="k0c-vv-NPP" secondAttribute="trailing" constant="16" id="dEN-Bs-9oC"/>
                 <constraint firstItem="xu7-RV-DKR" firstAttribute="trailing" secondItem="k0c-vv-NPP" secondAttribute="trailing" id="ePZ-m2-erM"/>
                 <constraint firstItem="mXd-Rx-c3O" firstAttribute="top" secondItem="0xe-05-6j8" secondAttribute="bottom" constant="11" id="evq-KN-Xwq"/>
+                <constraint firstItem="yvT-Vr-HYw" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="f5F-4S-nh2"/>
                 <constraint firstItem="HpT-QS-341" firstAttribute="top" secondItem="hCw-K3-67H" secondAttribute="bottom" constant="18" id="fkc-6M-xhx"/>
                 <constraint firstItem="xu7-RV-DKR" firstAttribute="leading" secondItem="Sf1-WE-VzB" secondAttribute="leading" id="fyS-0U-CJM"/>
                 <constraint firstItem="LnK-B0-rGp" firstAttribute="top" secondItem="xu7-RV-DKR" secondAttribute="bottom" constant="16" id="g6b-iG-T0X"/>
+                <constraint firstItem="nfj-9v-ZqH" firstAttribute="top" secondItem="mXd-Rx-c3O" secondAttribute="bottom" constant="8" id="gYa-8x-gff"/>
                 <constraint firstAttribute="trailing" secondItem="hCw-K3-67H" secondAttribute="trailing" constant="16" id="gew-aC-Sr2"/>
                 <constraint firstItem="n89-YE-ldr" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="hJr-kb-qE4"/>
+                <constraint firstItem="6qO-Xk-6yr" firstAttribute="top" secondItem="f52-b5-1Ge" secondAttribute="bottom" constant="-72" id="i1G-kk-ozl"/>
                 <constraint firstItem="HkY-4k-ShL" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="jIY-t3-U5D"/>
                 <constraint firstItem="k0c-vv-NPP" firstAttribute="top" secondItem="lwQ-xY-nsX" secondAttribute="bottom" constant="4" id="jUW-x8-4aX"/>
+                <constraint firstItem="wXl-jv-vC2" firstAttribute="top" secondItem="f7o-yZ-THg" secondAttribute="bottom" constant="8" id="jXt-VN-8sG"/>
+                <constraint firstItem="f52-b5-1Ge" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="jru-xm-jbV"/>
                 <constraint firstItem="lwQ-xY-nsX" firstAttribute="leading" secondItem="aPB-Pb-64w" secondAttribute="leading" id="kVr-oh-CY2"/>
                 <constraint firstItem="DvB-9f-Xgt" firstAttribute="top" secondItem="hyp-2H-elp" secondAttribute="bottom" constant="18" id="kxm-lu-bCL"/>
                 <constraint firstItem="hyp-2H-elp" firstAttribute="leading" secondItem="aPB-Pb-64w" secondAttribute="leading" id="mdU-8E-lPS"/>
                 <constraint firstItem="gJA-ad-BvI" firstAttribute="trailing" secondItem="k0c-vv-NPP" secondAttribute="trailing" id="nTH-mg-Z0g"/>
                 <constraint firstItem="hCw-K3-67H" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="40" id="pnQ-vB-MVe"/>
                 <constraint firstItem="hyp-2H-elp" firstAttribute="top" secondItem="k0c-vv-NPP" secondAttribute="bottom" constant="32" id="qP4-2t-rG9"/>
+                <constraint firstAttribute="bottom" secondItem="dja-8H-Uup" secondAttribute="bottom" id="rEm-pS-vKQ"/>
                 <constraint firstItem="mXd-Rx-c3O" firstAttribute="leading" secondItem="0xe-05-6j8" secondAttribute="leading" id="rJ4-0r-4NH"/>
                 <constraint firstItem="HkY-4k-ShL" firstAttribute="top" relation="greaterThanOrEqual" secondItem="mXd-Rx-c3O" secondAttribute="bottom" constant="20" id="rqm-ei-Qo0"/>
                 <constraint firstAttribute="trailing" secondItem="n89-YE-ldr" secondAttribute="trailing" constant="16" id="sNQ-CU-t7j"/>
                 <constraint firstItem="Sf1-WE-VzB" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="34" id="se3-wj-gNP"/>
+                <constraint firstItem="6qO-Xk-6yr" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="v0b-Qg-CLa"/>
+                <constraint firstAttribute="trailing" secondItem="6qO-Xk-6yr" secondAttribute="trailing" constant="16" id="xzz-Ta-7f4"/>
                 <constraint firstItem="cYX-Yt-gnO" firstAttribute="leading" secondItem="aPB-Pb-64w" secondAttribute="leading" id="yIs-gc-xSI"/>
                 <constraint firstItem="hyp-2H-elp" firstAttribute="top" secondItem="ivy-HJ-F2X" secondAttribute="bottom" constant="24" id="ygA-il-Zjf"/>
                 <constraint firstItem="ivy-HJ-F2X" firstAttribute="top" secondItem="HpT-QS-341" secondAttribute="bottom" constant="8" id="zMh-lw-EYt"/>
+                <constraint firstItem="Ivj-XV-tDI" firstAttribute="top" secondItem="hyp-2H-elp" secondAttribute="bottom" constant="12" id="zg4-S2-2eI"/>
             </constraints>
-            <point key="canvasLocation" x="-141" y="180.5"/>
+            <point key="canvasLocation" x="-141" y="224"/>
         </customView>
     </objects>
     <resources>

PDF Office/PDF Master/Class/Batch/Data/KMBatchOperateFile.swift → PDF Office/PDF Master/KMClass/ImageToPDF/Model/KMBatchOperateFile.swift


PDF Office/PDF Master/Class/Batch/Tools/KMImageToPDFMethod.swift → PDF Office/PDF Master/KMClass/ImageToPDF/Tools/KMImageToPDFMethod.swift


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

@@ -42,6 +42,8 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
     var indicateImageView: NSImageView?
     var comboBoxContent: String?
     
+    var fileIv: NSImageView?
+    
     deinit {
         DistributedNotificationCenter.default().removeObserver(self)
     }
@@ -76,8 +78,9 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
         self.textField?.isEditable = false
         self.addSubview(self.textField!)
         self.textField?.mas_makeConstraints({ make in
-            make?.top.equalTo()(self)?.offset()(13)
+//            make?.top.equalTo()(self)?.offset()(13)
             make?.left.equalTo()(self)
+            make?.centerY.equalTo()(self)
             
         })
         self.textField?.textColor = KMAppearance.Layout.h0Color()
@@ -126,6 +129,15 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
         }
     }
     func configuUIForFileName() {
+        var iv = NSImageView()
+        fileIv = iv
+        self.addSubview(iv)
+        iv.mas_makeConstraints { make in
+            make?.centerY.equalTo()(self)
+            make?.left.equalTo()(self)
+            make?.size.mas_equalTo()(NSMakeSize(40, 56))
+        }
+        
         var tf = NSTextField(frame: .zero)
         self.textField = tf
         self.textField?.isBordered = false
@@ -136,8 +148,9 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
         self.textField?.lineBreakMode = .byTruncatingMiddle
         self.addSubview(self.textField!)
         self.textField?.mas_makeConstraints({ make in
-            make?.top.equalTo()(self)?.offset()(13)
-            make?.left.equalTo()(self)
+//            make?.top.equalTo()(self)?.offset()(13)
+            make?.centerY.equalTo()(self)
+            make?.left.equalTo()(iv.mas_right)?.offset()(4)
             make?.right.equalTo()(self)?.offset()(-10)
         })
         self.textField?.font = NSFont.systemFont(ofSize: 12)
@@ -164,9 +177,10 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
         self.addSubview(self.statusView!)
         self.statusView?.mas_makeConstraints({ make in
             make?.left.equalTo()(self)
-            make?.top.equalTo()(self)?.offset()(12)
+//            make?.top.equalTo()(self)?.offset()(12)
             make?.width.equalTo()(16)
             make?.height.equalTo()(16)
+            make?.centerY.equalTo()(self)
         })
         self.indicateImageView = NSImageView(frame: .zero)
         self.statusView?.addSubview(self.indicateImageView!)
@@ -187,14 +201,14 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
         self.removeButton = KMButton(image: NSImage(named: KMImageNameUXIconBtnCloseNor)!, target: self, action: #selector(deleteFile(sender:)))
         self.removeButton?.isBordered = false
         self.removeButton?.isHidden = true
-        self.addSubview(self.removeButton!)
-        self.removeButton?.mas_makeConstraints({ make in
-            //            make?.left.equalTo()(self)?.offset()(10)
-            make?.centerY.equalTo()(self)
-            make?.right.equalTo()(self)?.offset()(0)
-            make?.width.equalTo()(20)
-            make?.height.equalTo()(20)
-        })
+//        self.addSubview(self.removeButton!)
+//        self.removeButton?.mas_makeConstraints({ make in
+//            //            make?.left.equalTo()(self)?.offset()(10)
+//            make?.centerY.equalTo()(self)
+//            make?.right.equalTo()(self)?.offset()(0)
+//            make?.width.equalTo()(20)
+//            make?.height.equalTo()(20)
+//        })
         self.removeButton!.mouseMoveCallback = { [weak self] mouseEntered in
             if mouseEntered {
                 self?.removeButton?.image = NSImage(named: KMImageNameUXIconBtnCloseHov)
@@ -266,6 +280,7 @@ class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
             } else {
                 self.errorTextField?.isHidden = true
             }
+            self.fileIv?.image = NSImage(contentsOfFile: file.filePath)
             self.textField?.stringValue = file.filePath.lastPathComponent
         } else if self.type == .PageRange {
             self.pageRangeCombobox?.isEnabled = self.file!.status != .processing

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

@@ -65,7 +65,7 @@ class KMLongerButton: NSButton,KMCustomButtonPopMenuViewControllerDelegate,KMCus
     }
     override func mouseEntered(with event: NSEvent) {
         super.mouseEntered(with: event)
-        self.showPop(sender: self)
+//        self.showPop(sender: self)
         self.buttonLayer?.isHidden = false
     }
     override func mouseExited(with event: NSEvent) {

+ 112 - 0
PDF Office/PDF Master/KMClass/ImageToPDF/View/KMNTableHeaderCellView.swift

@@ -0,0 +1,112 @@
+//
+//  KMNTableHeaderCellView.swift
+//  PDF Reader Pro
+//
+//  Created by User-Tangchao on 2024/11/7.
+//
+
+import Cocoa
+
+class KMNTableHeaderCellView: NSTableCellView {
+    private var contentBox: NSBox = {
+        let box = NSBox()
+        box.boxType = .custom
+        box.titlePosition = .noTitle
+        box.contentViewMargins = .zero
+        box.borderWidth = 0
+        return box
+    }()
+    
+    private var titleLabel_: NSTextField = {
+        let view = NSTextField(labelWithString: "")
+        return view
+    }()
+    
+    private var leftVLine_: NSView = {
+        let view = NSView()
+        return view
+    }()
+    
+    private var rightVLine_: NSView = {
+        let view = NSView()
+        return view
+    }()
+    
+    private var bottomLine_: NSView = {
+        let view = NSView()
+        return view
+    }()
+    
+    var titleLabel: NSTextField {
+        get {
+            return self.titleLabel_
+        }
+    }
+    
+    var leftLine: NSView {
+        get {
+            return self.leftVLine_
+        }
+    }
+    
+    var rightLine: NSView {
+        get {
+            return self.rightVLine_
+        }
+    }
+    
+    var bottomLine: NSView {
+        get {
+            return self.bottomLine_
+        }
+    }
+
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        // Drawing code here.
+    }
+    
+    convenience init() {
+        self.init(frame: .init(x: 0, y: 0, width: 40, height: 40))
+        
+        initSubviews()
+    }
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        
+        initSubviews()
+    }
+    
+    func initSubviews() {
+        addSubview(contentBox)
+        contentBox.km_add_inset_constraint()
+        
+        contentBox.contentView?.addSubview(leftVLine_)
+        contentBox.contentView?.addSubview(titleLabel_)
+        contentBox.contentView?.addSubview(rightVLine_)
+        contentBox.contentView?.addSubview(bottomLine_)
+        
+        leftVLine_.km_add_leading_constraint()
+        leftVLine_.km_add_top_constraint(constant: 4)
+        leftVLine_.km_add_bottom_constraint(constant: -4)
+        leftVLine_.km_add_width_constraint(constant: 0.5)
+        
+        titleLabel_.km_add_leading_constraint(constant: 8)
+        titleLabel_.km_add_centerY_constraint()
+        
+        rightVLine_.km_add_trailing_constraint()
+        rightVLine_.km_add_top_constraint(constant: 4)
+        rightVLine_.km_add_bottom_constraint(constant: -4)
+        rightVLine_.km_add_width_constraint(constant: 0.5)
+        
+        bottomLine_.km_add_bottom_constraint(constant: 0)
+        bottomLine_.km_add_leading_constraint(constant: 0)
+        bottomLine_.km_add_trailing_constraint(constant: 0)
+        bottomLine_.km_add_height_constraint(constant: 1)
+        
+        contentBox.fillColor = .clear
+    }
+    
+}

PDF Office/PDF Master/Class/Batch/View/KMTableHeaderCell.swift → PDF Office/PDF Master/KMClass/ImageToPDF/View/KMTableHeaderCell.swift


PDF Office/PDF Master/Class/Batch/View/KMBatchWindow.swift → PDF Office/PDF Master/KMClass/ImageToPDF/Window/KMBatchWindow.swift


File diff suppressed because it is too large
+ 224 - 168
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj