// // KMToolbarConfigModel.swift // PDF Reader Pro // // Created by tangchao on 2024/5/28. // import Cocoa class KMToolbarConfigModel: NSObject { var leftCellIdentifiers: [String]? { didSet { let ids = self.leftCellIdentifiers ?? [] self.leftWidth = 0 if ids.isEmpty == false { self.leftWidth += self.leftMargin + 5 } for itemId in ids { let item = KMToolbarItemView(itemIdentifier: itemId) self.setupMainItem(item) self.leftWidth += (item.itemWidth + 5) } } } var leftCount: Int { get { return self.leftCellIdentifiers?.count ?? 0 } } var centerCellIdentifiers: [String]? { didSet { let ids = self.centerCellIdentifiers ?? [] self.centerWidth = 0 for itemId in ids { let item = KMToolbarItemView(itemIdentifier: itemId) self.setupMainItem(item) self.centerWidth += (item.itemWidth + 5) } } } var centerCount: Int { get { return self.centerCellIdentifiers?.count ?? 0 } } var rightCellIdentifiers: [String]? { didSet { let ids = self.rightCellIdentifiers ?? [] self.rightWidth = 0 if ids.isEmpty == false { self.rightWidth += self.rightMargin + 5 } for itemId in ids { let item = KMToolbarItemView(itemIdentifier: itemId) self.setupMainItem(item) self.rightWidth += (item.itemWidth + 5) } } } var rightCount: Int { get { return self.rightCellIdentifiers?.count ?? 0 } } var defaultCellIdentifiers: [String]? var allowedCellIdentifiers: [String]? { get { let left = self.leftCellIdentifiers ?? [] let center = self.centerCellIdentifiers ?? [] let right = self.rightCellIdentifiers ?? [] return left + center + right } } var removedCellIdentifiers: [String]? { get { let ids = self.defaultCellIdentifiers ?? [] if ids.isEmpty { return [KMToolbarFixedSpaceItemIdentifier] } var removedIds: [String] = [] for itemId in ids { if self.allowedCellIdentifiers?.contains(itemId) == false { removedIds.append(itemId) } } removedIds.insert(KMToolbarFixedSpaceItemIdentifier, at: 0) return removedIds } } var leftWidth: CGFloat = 0 var centerWidth: CGFloat = 0 var rightWidth: CGFloat = 0 var leftMargin: CGFloat = 10 var rightMargin: CGFloat = 10 var itemH: CGFloat = 48 var contentWidth: CGFloat { get { return self.leftWidth + self.centerWidth + self.rightWidth } } var windowWidth: CGFloat = 1480 var segItemWidth: CGFloat { get { return max((self.windowWidth - self.contentWidth - 26 * 2) * 0.5, 20) } } func isLeft(at idx: Int) -> Bool { if self.leftCount <= 0 { return false } let stardIdx = 0 let endIdx = self.leftCount if idx >= stardIdx && idx < endIdx { return true } return false } func isCenter(at idx: Int) -> Bool { if self.centerCount <= 0 { return false } let stardIdx = self.leftCount+1 let endIdx = stardIdx+self.centerCount if idx >= stardIdx && idx < endIdx { return true } return false } func isRight(at idx: Int) -> Bool { if self.rightCount <= 0 { return false } let stardIdx = self.leftCount+self.centerCount+2 let endIdx = stardIdx+self.rightCount if idx >= stardIdx && idx < endIdx { return true } return false } func isFirstSegI(at idx: Int) -> Bool { return idx == self.leftCount } func isSecondSegI(at idx: Int) -> Bool { return idx == (self.leftCount+self.centerCount+1) } func isSeg(at idx: Int) -> Bool { if self.isFirstSegI(at: idx) || self.isSecondSegI(at: idx) { return true } return false } func findAllowedItem(at idx: Int) -> String? { if self.isLeft(at: idx) { return self.leftCellIdentifiers?[idx] } if self.isCenter(at: idx) { let theIdx = idx-self.leftCount-1 return self.centerCellIdentifiers?[theIdx] } if self.isRight(at: idx) { let theIdx = idx-self.leftCount-self.centerCount-2 return self.rightCellIdentifiers?[theIdx] } return nil } func removeItem(at idx: Int) -> Bool { if self.isLeft(at: idx) { self.leftCellIdentifiers?.remove(at: idx) return true } if self.isCenter(at: idx) { let theIdx = idx-self.leftCount-1 self.centerCellIdentifiers?.remove(at: theIdx) return true } if self.isRight(at: idx) { let theIdx = idx-self.leftCount-self.centerCount-2 self.rightCellIdentifiers?.remove(at: theIdx) return true } return false } func addItem(itemId: String, at idx: Int) -> Bool { let isFixedSpaceItem = itemId == KMToolbarFixedSpaceItemIdentifier if self.isLeft(at: idx) || idx == self.leftCount { let contains = self.leftCellIdentifiers?.contains(itemId) ?? false if contains == false || isFixedSpaceItem { self.leftCellIdentifiers?.insert(itemId, at: idx) } return true } if self.isCenter(at: idx) || idx == (self.leftCount+self.centerCount+1) { let theIdx = idx-self.leftCount-1 let contains = self.centerCellIdentifiers?.contains(itemId) ?? false if contains == false || isFixedSpaceItem { self.centerCellIdentifiers?.insert(itemId, at: theIdx) } return true } if self.isRight(at: idx) || idx == (self.leftCount+self.centerCount+self.rightCount+2) { let theIdx = idx-self.leftCount-self.centerCount-2 let contains = self.rightCellIdentifiers?.contains(itemId) ?? false if contains == false || isFixedSpaceItem { self.rightCellIdentifiers?.insert(itemId, at: theIdx) } return true } return false } func moveItem(itemIdx: Int, to idx: Int) -> Bool { if self.isLeft(at: itemIdx) { // left if self.isLeft(at: idx) { // left -> left [ || idx == self.leftCount] self.leftCellIdentifiers?.swapAt(itemIdx, idx) return true } else if self.isCenter(at: idx) || idx == (self.leftCount+self.centerCount+1) { // left -> center if let itemId = self.findAllowedItem(at: itemIdx) { _ = self.addItem(itemId: itemId, at: idx) self.leftCellIdentifiers?.remove(at: itemIdx) return true } } else if self.isRight(at: idx) || idx == self.leftCount+self.centerCount+self.rightCount+2 { // left -> right if let itemId = self.findAllowedItem(at: itemIdx) { _ = self.addItem(itemId: itemId, at: idx) self.leftCellIdentifiers?.remove(at: itemIdx) return true } } } else if self.isCenter(at: itemIdx) { // center if self.isLeft(at: idx) || idx == self.leftCount { // center -> left if let itemId = self.findAllowedItem(at: itemIdx) { _ = self.removeItem(at: itemIdx) _ = self.addItem(itemId: itemId, at: idx) return true } } else if self.isCenter(at: idx) { // center -> center [|| idx == (self.leftCount+self.centerCount+1] let offset = self.leftCount+1 self.centerCellIdentifiers?.swapAt(itemIdx-offset, idx-offset) return true } else if self.isRight(at: idx) || idx == self.leftCount+self.centerCount+self.rightCount+2 { // center -> right if let itemId = self.findAllowedItem(at: itemIdx) { _ = self.addItem(itemId: itemId, at: idx) _ = self.removeItem(at: itemIdx) return true } } } else if self.isRight(at: itemIdx) { // right if self.isLeft(at: idx) || idx == self.leftCount { // right -> left if let itemId = self.findAllowedItem(at: itemIdx) { _ = self.removeItem(at: itemIdx) _ = self.addItem(itemId: itemId, at: idx) return true } } else if self.isCenter(at: idx) || idx == (self.leftCount+self.centerCount+1) { // right -> center if let itemId = self.findAllowedItem(at: itemIdx) { _ = self.removeItem(at: itemIdx) _ = self.addItem(itemId: itemId, at: idx) return true } } else if self.isRight(at: idx) { // right -> right [|| idx == self.leftCount+self.centerCount+self.rightCount+2] let offset = self.leftCount+self.centerCount+2 self.rightCellIdentifiers?.swapAt(itemIdx-offset, idx-offset) return true } } return false } } extension KMToolbarConfigModel { func setupMainItem(_ item: KMToolbarItemView?) { let identifier = item?.itemIdentifier if identifier == KMLeftControlToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameUXIconBtnTriLeftNor") item?.titleName = NSLocalizedString("Panel", comment: "") // item?.toolTip = NSLocalizedString("View Settings", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentZoomViewToolbarItemIdentifier{ item?.titleName = NSLocalizedString("Zoom", comment: "") let view = KMToolbarZoomItemView(zoomView: nil) item?.customizeView = view } else if identifier == KMDocumentPreviousPageToolbarItemIdentifier { item?.titleName = NSLocalizedString("Zoom", comment: "") let view = KMToolbarPreviousNextItemView() item?.customizeView = view } else if identifier == KMDocumentHomeToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameToolbarHomeNor") item?.titleName = NSLocalizedString("Home", comment: "") // item?.toolTip = NSLocalizedString("A Welcome Gift from Us", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentAnnotationToolbarItemIdentifier { item?.titleName = NSLocalizedString("Tools", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarMytoolsNor") // item?.toolTip = String(format: "%@: %@, %@, %@, %@", KMLocalizedString("Tool Mode"),KMLocalizedString("Annotate"),KMLocalizedString("Scroll"),KMLocalizedString("Magnify"),KMLocalizedString("Select")) item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentPageToolbarItemIdentifier { item?.titleName = NSLocalizedString("Page Edit", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarPageeditNor") // item?.toolTip = NSLocalizedString("PDF page editor: insert, delete, extract, rotate, reposition, and replace pages in a PDF", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentConversonToolbarItemIdentifier { item?.titleName = NSLocalizedString("Converter", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarConvertNor") // item?.toolTip = NSLocalizedString("Convert PDFs to Microsoft Word, PowerPoint, Excel, RTF, Text, Image, CSV, and more Offline", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentScanOCRToolbarItemIdentifier { item?.titleName = NSLocalizedString("OCR", comment: "") item?.image = NSImage(named: "KMImageNameToolbarOCRNor") item?.boxImagePosition = .imageAbove // item?.toolTip = NSLocalizedString("Recognize text from Image-based or Scanned PDF with OCR", comment: "") item?.selectBackgroundType = .imageBox } else if identifier == KMToolbarToolEnhancedScanIdentifier { item?.image = NSImage(named: "KMImageNameMainToolEnhancedScan") // item?.toolTip = NSLocalizedString("Enhanced Scan", comment: "") item?.titleName = NSLocalizedString("Enhanced Scan", comment: "") item?.boxImagePosition = .imageLeft item?.selectBackgroundType = .imageBox } else if identifier == KMToolbarToolOCRTextIdentifier { item?.image = NSImage(named: "KMImageNameMainToolOCRText") // item?.toolTip = NSLocalizedString("OCR Text Recognition", comment: "") item?.titleName = NSLocalizedString("OCR Text Recognition", comment: "") item?.boxImagePosition = .imageLeft item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentEditToolbarItemIdentifier { item?.titleName = NSLocalizedString("Edit PDF", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarEditNor") item?.boxImagePosition = .imageAbove // item?.toolTip = NSLocalizedString("Edit text and image in PDF ", comment: "") item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentFormToolbarItemIdentifier { item?.titleName = NSLocalizedString("Forms", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarFormNor") item?.boxImagePosition = .imageAbove // item?.toolTip = NSLocalizedString("Edit PDF Form", comment: "") item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentFillSginToolbarItemIdentifier { item?.titleName = NSLocalizedString("Fill & Sign", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarFillsignNor") item?.boxImagePosition = .imageAbove // item?.toolTip = NSLocalizedString("Fill and sign forms", comment: "") item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentToolToolbarItemIdentifier { item?.titleName = NSLocalizedString("Editor", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarEdittoolNor") item?.boxImagePosition = .imageAbove // item?.toolTip = NSLocalizedString("Edit, delete, cut, copy, paste, and insert text in PDFs", comment: "") item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentRedactToolbarItemIdentifier { item?.titleName = NSLocalizedString("Redact Text", comment: "") item?.image = NSImage(named: "KMImageNameUXIconToolbarRedactNor") item?.boxImagePosition = .imageAbove // item?.toolTip = NSLocalizedString("Mark for redaction", comment: "") item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentAITranslationToolbarItemIdentifier { item?.image = NSImage(named: "ic_function_other_AITranslation") item?.titleName = "AI Translation" // item?.toolTip = NSLocalizedString("AI Translation", comment: "") item?.boxImagePosition = .imageOnly } else if identifier == KMDocumentPrintToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameToolbarPrintNor") item?.titleName = "Print" // item?.toolTip = NSLocalizedString("Print", comment: "") item?.boxImagePosition = .imageOnly } else if identifier == KMDocumentViewDisplayToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameUXIconToolbarPageviewNor") item?.titleName = NSLocalizedString("Page Display", comment: "") // item?.toolTip = NSLocalizedString("Page Display", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentAIToolsToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameUXIconAINor") item?.titleName = NSLocalizedString("AI Tools", comment: "") // item?.toolTip = NSLocalizedString("AI Tools", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentShareToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameUXIconToolbarShareNor") item?.titleName = NSLocalizedString("Share", comment: "") // item?.toolTip = NSLocalizedString("Share the file with others", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMDocumentSearchToolbarItemIdentifier { item?.titleName = NSLocalizedString("Search", comment: "") let view = NSView() view.frame = NSMakeRect(0, 0, 150, 40) let boxView = NSView() boxView.frame = NSMakeRect(0, 16, 150, 22) view.addSubview(boxView) let searchView = NSSearchField() searchView.frame = NSMakeRect(0, 0, 150, 22) searchView.placeholderString = NSLocalizedString("Search", comment: "") searchView.sendsWholeSearchString = true searchView.sendsSearchStringImmediately = true searchView.drawsBackground = false boxView.addSubview(searchView) let titleLabel = NSTextField(labelWithString: NSLocalizedString("Search", comment: "")) view.addSubview(titleLabel) titleLabel.frame = NSMakeRect(0, 0, 130, 14) titleLabel.alignment = .center titleLabel.textColor = KMAppearance.subtitleColor() titleLabel.font = KMToolbarMainItemView.textFont item?.customizeView = view } else if identifier == KMDocumentPageInputToolbarItemIdentifier { item?.titleName = NSLocalizedString("Page", comment: "") let view = KMToolbarPageInputItemView() item?.customizeView = view view.totalNumber = 0 } else if identifier == KMRightControlToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameUXIconBtnTriRightNor") item?.titleName = NSLocalizedString("Properties", comment: "") // item?.toolTip = NSLocalizedString("Show/Hide Annotation Properties Panel", comment: "") item?.boxImagePosition = .imageAbove item?.selectBackgroundType = .imageBox } else if identifier == KMToolbarToolRedactItemIdentifier { item?.image = NSImage(named: "KMImageNameMainToolsRedact") // item?.toolTip = NSLocalizedString("Redact", comment: "") item?.titleName = NSLocalizedString("Redact", comment: "") item?.selectBackgroundType = .imageBox } // else if identifier == KMDocumentDigitalSignToolbarItemIdentifier { // item?.image = NSImage(named: "DigitalSign_icon") //// item?.toolTip = NSLocalizedString("Digital signature ensures the authenticity and integrity of digital files. Click and drag the cursor to create a signature field on the page.", comment: "") // item?.titleName = NSLocalizedString("Digital Sign", comment: "") // item?.selectBackgroundType = .imageBox // item?.boxImagePosition = .imageAbove // } else if identifier == KMDocumentSignToolbarItemIdentifier { item?.image = NSImage(named: "DigitalSign_icon") // item?.toolTip = NSLocalizedString("Digital signature ensures the authenticity and integrity of digital files. Click and drag the cursor to create a signature field on the page.", comment: "") item?.titleName = NSLocalizedString("Signature", comment: "") item?.selectBackgroundType = .imageBox item?.boxImagePosition = .imageAbove } else if identifier == KMDocumentPreviousBackToolbarItemIdentifier { item?.titleName = NSLocalizedString("Zoom", comment: "") let view = KMToolbarPreviousBackItemView() item?.customizeView = view } else if identifier == KMDocumentFirstLastToolbarItemIdentifier { item?.titleName = NSLocalizedString("Zoom", comment: "") let view = KMToolbarFirstLastItemView() item?.customizeView = view } else if identifier == KMDocumentPageIndicatorToolbarItemIdentifier { item?.titleName = NSLocalizedString("Zoom", comment: "") let view = KMToolbarPageIndicatorItemView(zoomView: nil) item?.customizeView = view } else if identifier == KMDocumentPresentationToolbarItemIdentifier { item?.image = NSImage(named: "KMImageNameToolbarSlideshowNor") item?.titleName = NSLocalizedString("Presentation", comment: "") item?.selectBackgroundType = .imageBox item?.boxImagePosition = .imageAbove } else if identifier == KMToolbarFixedSpaceItemIdentifier { let view = NSView() view.frame = NSMakeRect(0, 0, 36, 36) view.wantsLayer = true view.layer?.borderWidth = 1 item?.customizeView = view } } }