// // KMNThumnailViewController.swift // PDF Reader Pro // // Created by 丁林圭 on 2024/11/2. // import Cocoa import KMComponentLibrary @objc protocol KMNThumnailViewControllerDelegate: AnyObject { @objc optional func enterPageEditThumnailViewController(thumnailViewController:KMNThumnailViewController) } let subThumleftOffser: CGFloat = 40.0 //左右间隔 let suborgWidthOff: CGFloat = 264.0 class KMNThumnailViewController: KMNThumbnailBaseViewController { let ThumbnailMenuIdentifier_PageEdit = "ThumbnailMenuIdentifier_PageEdit" weak open var thumnailViewDelegate: KMNThumnailViewControllerDelegate? private var groupView: ComponentGroup? = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle()) override func viewDidLoad() { flowLayout.register(KMNThumDecorationView.self, forDecorationViewOfKind: NSUserInterfaceItemIdentifier("Line").rawValue) super.viewDidLoad() collectionView.menuClickedAction = {[weak self] point in let menuStruct = self?.clickMenu(point: point) if self?.groupView != nil { self?.groupView?.clickedAutoHide = false self?.groupView?.groupDelegate = self self?.groupView?.frame = CGRectMake(0, 0, 180, menuStruct?.viewHeight ?? 0) self?.groupView?.updateGroupInfo(menuStruct?.menuitems ?? []) self?.groupView?.showWithPoint(CGPoint(x: point.x, y: point.y - (menuStruct?.viewHeight ?? 0)), relativeTo: self?.collectionView) } return NSMenu() } } override func updateUILanguage() { super.updateUILanguage() self.groupView?.reloadData() } override func updateUIThemeColor() { super.updateUIThemeColor() self.view.wantsLayer = true self.view.layer?.backgroundColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/popUp").cgColor } // MARK: - public public func changeDocument(document: CPDFDocument) { changeDocument = document } public func updateThumbnailSize() { collectionView.reloadData() } override func clickMenu(point:NSPoint)->ThumbnailMenuStruct { let menuStruct = super.clickMenu(point: point) var viewHeight: CGFloat = menuStruct.viewHeight var menuItemArr: [ComponentMenuitemProperty] = menuStruct.menuitems let items: [(String, String)] = [("", ""),("Page Edit", ThumbnailMenuIdentifier_PageEdit)] for (i, value) in items { if value.count == 0 { let property: ComponentMenuitemProperty = ComponentMenuitemProperty.divider() menuItemArr.append(property) viewHeight += 8 } else { let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false, itemSelected: false, isDisabled: false, keyEquivalent: nil, text: KMLocalizedString(i), identifier: value) menuItemArr.append(properties_Menuitem) viewHeight += 36 } } let newMenuStruct = ThumbnailMenuStruct(menuitems: menuItemArr, viewHeight: viewHeight) return newMenuStruct } @objc public func pageEditMenuItemAction() { thumnailViewDelegate?.enterPageEditThumnailViewController?(thumnailViewController: self) } // MARK: - NSCollectionViewDelegateFlowLayout override func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize { let thumbnailMode: KMNThumbnail = thumbnails[indexPath.item] var orgPageHeight = thumbnailMode.pageSize.height var orgPagewidth = thumbnailMode.pageSize.width if (thumbnailMode.thumbnaiPage?.rotation ?? 0) % 180 != 0 { orgPageHeight = thumbnailMode.pageSize.width orgPagewidth = thumbnailMode.pageSize.height } let cellWidth = self.view.bounds.width - subThumleftOffser * 2 - infoThumTitleBottom * 2 var cellHeight = cellWidth * (orgPageHeight / orgPagewidth) let scal = cellWidth / (suborgWidthOff - subThumleftOffser * 2 - infoThumTitleBottom * 2) if cellHeight > maxCellHeight * scal { cellHeight = maxCellHeight * scal } else if(cellHeight < minCellHeight * scal) { cellHeight = minCellHeight * scal } if(isShowPageSize) { cellHeight += infoThumTitleHeight } return CGSize(width: cellWidth + infoThumTitleBottom * 2, height: cellHeight + infoThumTitleBottom + infoThumTitleHeight + topThumOffset * 2) } override func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return 20.0 } override func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { return 40.0 } public override func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, insetForSectionAt section: Int) -> NSEdgeInsets { return NSEdgeInsetsMake(8.0, 0, 8.0, 0) } //MARK: - NSCollectionViewDelegate override func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndexPath proposedDropIndexPath: AutoreleasingUnsafeMutablePointer, dropOperation proposedDropOperation: UnsafeMutablePointer) -> NSDragOperation { let dropTargetIndexPath = proposedDropIndexPath.pointee as IndexPath let targetFrame = collectionView.frameForItem(at: dropTargetIndexPath.item) flowLayout.showLine(at: dropTargetIndexPath, below: targetFrame) return super.collectionView(collectionView, validateDrop: draggingInfo, proposedIndexPath: proposedDropIndexPath, dropOperation: proposedDropOperation) } override func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, indexPath: IndexPath, dropOperation: NSCollectionView.DropOperation) -> Bool { flowLayout.hideLine() return super.collectionView(collectionView, acceptDrop: draggingInfo, indexPath: indexPath, dropOperation: dropOperation) } override func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, dragOperation operation: NSDragOperation) { flowLayout.hideLine() super.collectionView(collectionView, draggingSession: session, endedAt: screenPoint, dragOperation: operation) } } //MARK: - ComponentSelectDelegate extension KMNThumnailViewController: ComponentGroupDelegate { func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) { if menuItemProperty?.identifier == ThumbnailMenuIdentifier_Copy { copyMenuItemAciton() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_Cut) { cutMenuItemAciton() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_Paste) { if(menuItemProperty != nil) { pastMenuItemAciton(menuitemProperty: menuItemProperty!) } } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_Delete) { cutMenuItemAciton() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_RotateRight) { rotatePageRightAction() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_RotateLeft) { rotatePageLeftAction() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_InsertFile) { insertFromPDFAction() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_InsertBlank) { insertFromBlankAction() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_Export) { extractPDFAction() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_Share) { let indexpaths = collectionView.selectionIndexPaths let doucument = showDocument let filename : String = doucument?.documentURL.lastPathComponent ?? "" let folderPath = (NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(filename)) ?? "" try? FileManager.default.removeItem(atPath: folderPath) let pdfdocument = CPDFDocument() let ret = pdfdocument?.importPages(KMNTools.indexpathsToIndexs(indexpaths: indexpaths), from: doucument, at: 0) ?? false let url = URL(fileURLWithPath: folderPath) if ret { let _ = pdfdocument?.write(toFile: folderPath) let selects: [URL] = [url] let picker = NSSharingServicePicker.init(items: selects) if(groupView != nil) { let rect = CGRectMake(CGRectGetMaxX(groupView!.bounds), CGRectGetMinY(groupView!.bounds) + 35.0 * 2, 1, 1) picker.show(relativeTo: rect, of: groupView!, preferredEdge: NSRectEdge.maxX) } } } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_PageEdit) { pageEditMenuItemAction() } else if (menuItemProperty?.identifier == ThumbnailMenuIdentifier_FileShowSize) { displayPageSizeAction() } } func componentGroupDidDismiss(group: ComponentGroup?) { } }