KMInfoWindowController.swift 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. //
  2. // KMInfoWindowController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2023/10/10.
  6. //
  7. import Cocoa
  8. /*
  9. #define SKInfoWindowFrameAutosaveName @"SKInfoWindow"
  10. #define LABEL_COLUMN_ID @"label"
  11. #define VALUE_COLUMN_ID @"value"
  12. */
  13. private let LABEL_COLUMN_ID = "label"
  14. private let VALUE_COLUMN_ID = "value"
  15. private let KMInfoVersionKey = "Version"
  16. private let KMInfoPageCountKey = "PageCount"
  17. private let KMInfoPageSizeKey = "PageSize"
  18. private let KMInfoPageWidthKey = "PageWidth"
  19. private let KMInfoPageHeightKey = "PageHeight"
  20. private let KMInfoKeywordsStringKey = "Keywords"
  21. private let KMInfoEncryptedKey = "Encrypted"
  22. private let KMInfoAllowsPrintingKey = "AllowsPrinting"
  23. private let KMInfoAllowsCopyingKey = "AllowsCopying"
  24. private let KMInfoAllowsDocumentAssemblyKey = "AllowsDocumentAssembly"
  25. private let KMInfoAllowsContentAccessibilityKey = "AllowsContentAccessibility"
  26. private let KMInfoAllowsCommentingKey = "AllowsCommenting"
  27. private let KMInfoAllowsFormFieldEntryKey = "AllowsFormFieldEntry"
  28. private let KMInfoFileNameKey = "FileName"
  29. private let KMInfoFileSizeKey = "FileSize"
  30. private let KMInfoPhysicalSizeKey = "PhysicalSize"
  31. private let KMInfoLogicalSizeKey = "LogicalSize"
  32. private let KMInfoTagsKey = "Tags"
  33. private let KMInfoRatingKey = "Rating"
  34. private let kKMWindowDidBecomeMainNotificationName = Notification.Name(rawValue: "KMWindowDidBecomeMainNotificationName")
  35. typealias KMInfoWindowC = KMInfoWindowController
  36. class KMInfoWindowController: NSWindowController {
  37. public static let windowDidBecomeMainNotification = kKMWindowDidBecomeMainNotificationName
  38. @IBOutlet weak var summaryTableView: NSTableView!
  39. @IBOutlet weak var attributesTableView: NSTableView!
  40. @IBOutlet weak var tabView: NSTabView!
  41. var info: NSDictionary?
  42. var editDictionary: NSMutableDictionary = NSMutableDictionary()
  43. private var _summaryKeys: [String] = []
  44. var summaryKeys: [String] {
  45. get {
  46. return self._summaryKeys
  47. }
  48. }
  49. private var _attributesKeys: [String] = []
  50. var attributesKeys: [String] {
  51. get {
  52. return self._attributesKeys
  53. }
  54. }
  55. private var _labels: [String : String] = [:]
  56. var labels: [String : String] {
  57. get {
  58. return self._labels
  59. }
  60. }
  61. private weak var _currentDocument: NSDocument?
  62. deinit {
  63. NotificationCenter.default.removeObserver(self)
  64. Swift.debugPrint("KMInfoWindowController 已释放")
  65. }
  66. static let shared = KMInfoWindowController()
  67. convenience init() {
  68. self.init(windowNibName: "InfoWindow")
  69. self.info = nil;
  70. self._summaryKeys = [KMInfoFileNameKey,
  71. KMInfoFileSizeKey,
  72. KMInfoPageSizeKey,
  73. KMInfoPageCountKey,
  74. KMInfoVersionKey,
  75. "",
  76. KMInfoEncryptedKey,
  77. KMInfoAllowsPrintingKey,
  78. KMInfoAllowsCopyingKey,
  79. KMInfoAllowsDocumentAssemblyKey,
  80. KMInfoAllowsContentAccessibilityKey,
  81. KMInfoAllowsCommentingKey,
  82. KMInfoAllowsFormFieldEntryKey]
  83. self._attributesKeys = [PDFDocumentAttribute.titleAttribute.rawValue,
  84. PDFDocumentAttribute.authorAttribute.rawValue,
  85. PDFDocumentAttribute.subjectAttribute.rawValue,
  86. PDFDocumentAttribute.creatorAttribute.rawValue,
  87. PDFDocumentAttribute.producerAttribute.rawValue,
  88. PDFDocumentAttribute.creationDateAttribute.rawValue,
  89. PDFDocumentAttribute.modificationDateAttribute.rawValue,
  90. KMInfoKeywordsStringKey]
  91. self._labels = [KMInfoFileNameKey : KMLocalizedString("File name:", ""),
  92. KMInfoFileSizeKey : KMLocalizedString("File size:", ""),
  93. KMInfoPageSizeKey : KMLocalizedString("Page size:", ""),
  94. KMInfoPageCountKey : KMLocalizedString("Page count:", ""),
  95. KMInfoVersionKey : KMLocalizedString("PDF Version:", ""),
  96. KMInfoEncryptedKey : KMLocalizedString("Encrypted:", ""),
  97. KMInfoAllowsPrintingKey : KMLocalizedString("Printing:", ""),
  98. KMInfoAllowsCopyingKey : KMLocalizedString("Content Copying:", ""),
  99. KMInfoAllowsDocumentAssemblyKey : KMLocalizedString("Document Assembly:", ""),
  100. KMInfoAllowsContentAccessibilityKey : KMLocalizedString("Content Copying for Accessibility:", ""),
  101. KMInfoAllowsCommentingKey : KMLocalizedString("Commenting:", ""),
  102. KMInfoAllowsFormFieldEntryKey : KMLocalizedString("Filling of form fields:", ""),
  103. PDFDocumentAttribute.titleAttribute.rawValue : KMLocalizedString("Title:", ""),
  104. PDFDocumentAttribute.authorAttribute.rawValue : KMLocalizedString("Author:", ""),
  105. PDFDocumentAttribute.subjectAttribute.rawValue : KMLocalizedString("Subject:", ""),
  106. PDFDocumentAttribute.creatorAttribute.rawValue : KMLocalizedString("Content Creator:", ""),
  107. PDFDocumentAttribute.producerAttribute.rawValue : KMLocalizedString("PDF Producer:", ""),
  108. PDFDocumentAttribute.creationDateAttribute.rawValue : KMLocalizedString("Creation date:", ""),
  109. PDFDocumentAttribute.modificationDateAttribute.rawValue : KMLocalizedString("Modification date:", ""),
  110. KMInfoKeywordsStringKey : KMLocalizedString("Keywords:", "")]
  111. }
  112. override func loadWindow() {
  113. super.loadWindow()
  114. self.window?.localizeStrings(fromTable: self.windowNibName)
  115. }
  116. override func windowDidLoad() {
  117. super.windowDidLoad()
  118. self.window?.title = NSLocalizedString("Document Info", comment: "")
  119. self.updateForDocument(NSApp.mainWindow?.windowController?.document as? NSDocument)
  120. self.summaryTableView.selectionHighlightStyle = .none
  121. self.attributesTableView.selectionHighlightStyle = .none
  122. for item in self.tabView.tabViewItems {
  123. if item.isEqual(to: self.tabView.tabViewItems.first) {
  124. item.label = NSLocalizedString("Summary", comment: "")
  125. } else {
  126. item.label = NSLocalizedString("Attributes", comment: "")
  127. }
  128. }
  129. self.tabView.selectTabViewItem(at: 1)
  130. NotificationCenter.default.addObserver(self, selector: #selector(_handleViewFrameDidChangeNotification), name: NSView.frameDidChangeNotification, object: self.attributesTableView.enclosingScrollView)
  131. NotificationCenter.default.addObserver(self, selector: #selector(_handleWindowDidBecomeMainNotification), name: NSWindow.didBecomeMainNotification, object: nil)
  132. NotificationCenter.default.addObserver(self, selector: #selector(_handleWindowDidResignMainNotification), name: NSWindow.didResignMainNotification, object: nil)
  133. // // [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handlePDFDocumentInfoDidChangeNotification:)
  134. // // name: SKPDFPageBoundsDidChangeNotification object: nil];
  135. // // [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleDocumentFileURLDidChangeNotification:)
  136. // // name: SKDocumentFileURLDidChangeNotification object: nil];
  137. NotificationCenter.default.addObserver(self, selector: #selector(_handlePDFDocumentInfoDidChangeNotification), name: NSNotification.Name.PDFDocumentDidUnlock, object: nil)
  138. NotificationCenter.default.addObserver(self, selector: #selector(_handleWindowWillCloseNotification), name: NSWindow.willCloseNotification, object: nil)
  139. NotificationCenter.default.addObserver(self, selector: #selector(_km_handleWindowDidBecomeMainNotification), name: KMInfoWindowC.windowDidBecomeMainNotification, object: nil)
  140. }
  141. func updateForDocument(_ doc: NSDocument?) {
  142. self._currentDocument = doc
  143. let info = self._infoForDocument(doc)
  144. var dic = NSMutableDictionary(dictionary: info)
  145. for key in self.editDictionary.allKeys {
  146. dic.setObject(self.editDictionary[key], forKey: key as! NSCopying)
  147. }
  148. self.info = dic
  149. self.summaryTableView.reloadData()
  150. self.attributesTableView.reloadData()
  151. }
  152. // MARK: - Private Methods
  153. private func _infoForDocument(_ doc: NSDocument?) -> NSDictionary {
  154. var dictionary: NSMutableDictionary = NSMutableDictionary()
  155. var logicalSize: Int64 = 0
  156. var physicalSize: Int64 = 0
  157. if let data = doc, data.isKind(of: KMMainDocument.self) {
  158. if let pdfDoc = (data as! KMMainDocument).mainViewController?.document {
  159. dictionary.addEntries(from: pdfDoc.documentAttributes())
  160. dictionary.setValue(String(format: "%ld.%ld", pdfDoc.majorVersion, pdfDoc.minorVersion), forKey: KMInfoVersionKey)
  161. dictionary.setValue(NSNumber(value: pdfDoc.pageCount), forKey: KMInfoPageCountKey)
  162. if (pdfDoc.pageCount > 0) {
  163. let page: CPDFPage = pdfDoc.page(at:0)!
  164. let cropSize = page.bounds(for: .cropBox).size
  165. let mediaSize = page.bounds(for: .mediaBox).size
  166. dictionary.setValue(KMSizeString(cropSize, mediaSize), forKey: KMInfoPageSizeKey)
  167. dictionary.setValue(NSNumber(value: cropSize.width), forKey: KMInfoPageWidthKey)
  168. dictionary.setValue(NSNumber(value: cropSize.height), forKey: KMInfoPageHeightKey)
  169. }
  170. if let keyworks = dictionary.value(forKey: CPDFDocumentAttribute.keywordsAttribute.rawValue) {
  171. if (keyworks as AnyObject).isKind(of: NSArray.self) {
  172. dictionary.setValue(keyworks, forKey: KMInfoKeywordsStringKey)
  173. }
  174. }
  175. dictionary.setValue(NSNumber(booleanLiteral: pdfDoc.isEncrypted), forKey: KMInfoEncryptedKey)
  176. dictionary.setValue(NSNumber(booleanLiteral: pdfDoc.allowsPrinting), forKey: KMInfoAllowsPrintingKey)
  177. dictionary.setValue(NSNumber(booleanLiteral: pdfDoc.allowsCopying), forKey: KMInfoAllowsCopyingKey)
  178. // dictionary.setValue(NSNumber(booleanLiteral: pdfDoc.allowsContentAccessibility), forKey: KMInfoAllowsContentAccessibilityKey)
  179. dictionary.setValue(NSNumber(booleanLiteral: pdfDoc.allowsCommenting), forKey: KMInfoAllowsCommentingKey)
  180. dictionary.setValue(NSNumber(booleanLiteral: pdfDoc.allowsFormFieldEntry), forKey: KMInfoAllowsDocumentAssemblyKey)
  181. dictionary.setValue(NSNumber(booleanLiteral: pdfDoc.allowsFormFieldEntry), forKey: KMInfoAllowsFormFieldEntryKey)
  182. }
  183. }
  184. dictionary.setValue(doc?.fileURL?.path.lastPathComponent, forKey: KMInfoFileNameKey)
  185. // [dictionary setValue:SKFileSizeStringForFileURL([doc fileURL], &physicalSize, &logicalSize) forKey:SKInfoFileSizeKey];
  186. dictionary.setValue(NSNumber(value: physicalSize), forKey: KMInfoPhysicalSizeKey)
  187. dictionary.setValue(NSNumber(value: logicalSize), forKey: KMInfoLogicalSizeKey)
  188. return dictionary
  189. }
  190. @objc private func _handleViewFrameDidChangeNotification(_ sender: Notification) {
  191. self.attributesTableView.noteHeightOfRows(withIndexesChanged: IndexSet(integer: self.attributesKeys.count-1))
  192. }
  193. @objc private func _handleWindowDidBecomeMainNotification(_ sender: Notification) {
  194. self.editDictionary.removeAllObjects()
  195. self.updateForDocument((sender.object as? NSWindow)?.windowController?.document as? NSDocument)
  196. }
  197. @objc private func _handleWindowDidResignMainNotification(_ sender: Notification) {
  198. self.editDictionary.removeAllObjects()
  199. self.updateForDocument(nil)
  200. }
  201. @objc private func _handlePDFDocumentInfoDidChangeNotification(_ sender: Notification) {
  202. guard let doc = NSApp.mainWindow?.windowController?.document else {
  203. return
  204. }
  205. if (doc.isKind(of: KMMainDocument.self)) {
  206. guard let pdfDocument = (doc as! KMMainDocument).mainViewController?.document else {
  207. return
  208. }
  209. if (pdfDocument.isEqual(to: sender.object)) {
  210. self.editDictionary.removeAllObjects()
  211. self.updateForDocument((doc as! NSDocument))
  212. }
  213. }
  214. }
  215. @objc private func _handleWindowWillCloseNotification(_ sender: Notification) {
  216. if let object = sender.object as? AnyObject, object.isEqual(self.window) {
  217. if (self.editDictionary.count > 0) {
  218. if let windowController = NSApp.mainWindow?.windowController, windowController.isKind(of: KMBrowserWindowController.self) {
  219. let document = (windowController as! KMBrowserWindowController).document as? KMMainDocument
  220. var dic: NSMutableDictionary = NSMutableDictionary(dictionary: document?.mainViewController?.document?.documentAttributes() ?? [:])
  221. var isSave = false
  222. for key in self.editDictionary.allKeys {
  223. if let data = key as? NSString, data.isEqual(to: KMInfoKeywordsStringKey) {
  224. let string = self.editDictionary[key]
  225. if let data = string as? NSString, data.isEqual(to: dic[PDFDocumentAttribute.keywordsAttribute.rawValue]) {
  226. isSave = true
  227. dic.setObject(string as Any, forKey: CPDFDocumentAttribute.keywordsAttribute.rawValue as NSCopying)
  228. }
  229. } else {
  230. if let data = dic[key] as? NSString, data.isEqual(to: self.editDictionary[key]) == false {
  231. isSave = true
  232. dic.setObject(self.editDictionary[key] as Any, forKey: key as! NSCopying)
  233. }
  234. }
  235. }
  236. if (isSave) {
  237. document?.mainViewController?.document?.setDocumentAttributes(dic as? [CPDFDocumentAttribute : Any])
  238. document?.save(nil)
  239. }
  240. }
  241. }
  242. self.editDictionary.removeAllObjects()
  243. }
  244. }
  245. @objc private func _km_handleWindowDidBecomeMainNotification(_ sender: Notification) {
  246. self.editDictionary.removeAllObjects()
  247. self.updateForDocument(sender.object as? NSDocument)
  248. }
  249. /*
  250. - (void)handlePDFDocumentInfoDidChangeNotification:(NSNotification *)notification {
  251. [self.editDictionary removeAllObjects];
  252. NSDocument *doc = [[[NSApp mainWindow] windowController] document];
  253. if ([doc isKindOfClass:[KMMainDocument class]]) {
  254. CPDFDocument *pdfDocument = ((KMMainDocument *)doc).mainViewController.document;
  255. if ([pdfDocument isEqual:notification.object]) {
  256. [self updateForDocument:doc];
  257. }
  258. }
  259. }
  260. - (void)handleDocumentFileURLDidChangeNotification:(NSNotification *)notification {
  261. [self.editDictionary removeAllObjects];
  262. NSDocument *doc = [[[NSApp mainWindow] windowController] document];
  263. if ([doc isEqual:[notification object]])
  264. [self updateForDocument:doc];
  265. }
  266. */
  267. override func showWindow(_ sender: Any?) {
  268. super.showWindow(sender)
  269. self.editDictionary.removeAllObjects()
  270. self.attributesTableView.reloadData()
  271. }
  272. /*
  273. #define BYTE_FACTOR 1024
  274. #define BYTE_FACTOR_F 1024.0f
  275. #define BYTE_SHIFT 10
  276. static NSString *SKFileSizeStringForFileURL(NSURL *fileURL, unsigned long long *physicalSizePtr, unsigned long long *logicalSizePtr) {
  277. if (fileURL == nil)
  278. return @"";
  279. FSRef fileRef;
  280. FSCatalogInfo catalogInfo;
  281. unsigned long long size, logicalSize = 0;
  282. BOOL gotSize = NO, isDir = NO;
  283. NSMutableString *string = [NSMutableString string];
  284. Boolean gotRef = CFURLGetFSRef((CFURLRef)fileURL, &fileRef);
  285. if (gotRef && noErr == FSGetCatalogInfo(&fileRef, kFSCatInfoDataSizes | kFSCatInfoRsrcSizes | kFSCatInfoNodeFlags, &catalogInfo, NULL, NULL, NULL)) {
  286. size = catalogInfo.dataPhysicalSize + catalogInfo.rsrcPhysicalSize;
  287. logicalSize = catalogInfo.dataLogicalSize + catalogInfo.rsrcLogicalSize;
  288. isDir = (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask) != 0;
  289. gotSize = YES;
  290. }
  291. if (gotSize == NO) {
  292. // this seems to give the logical size
  293. NSDictionary *fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:NULL];
  294. logicalSize = size = [[fileAttrs objectForKey:NSFileSize] unsignedLongLongValue];
  295. isDir = [[fileAttrs fileType] isEqualToString:NSFileTypeDirectory];
  296. }
  297. if (isDir) {
  298. NSString *path = [fileURL path];
  299. unsigned long long componentSize;
  300. unsigned long long logicalComponentSize;
  301. for (NSString *file in [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:NULL]) {
  302. SKFileSizeStringForFileURL([NSURL fileURLWithPath:[path stringByAppendingPathComponent:file]], &componentSize, &logicalComponentSize);
  303. size += componentSize;
  304. logicalSize += logicalComponentSize;
  305. }
  306. }
  307. if (physicalSizePtr)
  308. *physicalSizePtr = size;
  309. if (logicalSizePtr)
  310. *logicalSizePtr = logicalSize;
  311. if (size < BYTE_FACTOR) {
  312. [string appendFormat:@"%qu %@", size, NSLocalizedString(@"bytes", @"size unit")];
  313. } else {
  314. #define numUnits 6
  315. NSString *units[numUnits] = {NSLocalizedString(@"kB", @"size unit"), NSLocalizedString(@"MB", @"size unit"), NSLocalizedString(@"GB", @"size unit"), NSLocalizedString(@"TB", @"size unit"), NSLocalizedString(@"PB", @"size unit"), NSLocalizedString(@"EB", @"size unit")};
  316. NSUInteger i;
  317. for (i = 0; i < numUnits; i++, size >>= BYTE_SHIFT) {
  318. if ((size >> BYTE_SHIFT) < BYTE_FACTOR || i == numUnits - 1) {
  319. [string appendFormat:@"%.1f %@", size / BYTE_FACTOR_F, units[i]];
  320. break;
  321. }
  322. }
  323. }
  324. NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
  325. [formatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
  326. [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
  327. [string appendFormat:@" (%@ %@)", [formatter stringFromNumber:[NSNumber numberWithUnsignedLongLong:logicalSize]], NSLocalizedString(@"bytes", @"size unit")];
  328. return string;
  329. }
  330. - (NSArray *)keys {
  331. return [attributesKeys arrayByAddingObjectsFromArray:summaryKeys];
  332. }
  333. */
  334. }
  335. extension KMInfoWindowController: NSTableViewDelegate, NSTableViewDataSource {
  336. func numberOfRows(in tableView: NSTableView) -> Int {
  337. if (tableView.isEqual(to: self.summaryTableView)) {
  338. return self.summaryKeys.count
  339. } else if (tableView.isEqual(to: self.attributesTableView)) {
  340. return self.attributesKeys.count
  341. }
  342. return 0
  343. }
  344. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  345. var shortDateFormatter = DateFormatter()
  346. shortDateFormatter.dateStyle = .short
  347. shortDateFormatter.timeStyle = .none
  348. var keys: [String]?
  349. if (tableView.isEqual(to: self.summaryTableView)) {
  350. keys = self.summaryKeys
  351. } else if (tableView.isEqual(to: self.attributesTableView)) {
  352. keys = self.attributesKeys
  353. }
  354. let key = keys![row]
  355. let tcID = tableColumn?.identifier.rawValue
  356. var value: Any?
  357. if (key.isEmpty) {
  358. value = ""
  359. } else {
  360. if let data = tcID, data == LABEL_COLUMN_ID {
  361. value = self.labels[key] != nil ? self.labels[key] : key.appending(":")
  362. } else if let data = tcID, data == VALUE_COLUMN_ID {
  363. value = self.info?.object(forKey: key)
  364. if (value == nil) {
  365. value = "-"
  366. } else if let data = value as? NSDate {
  367. value = shortDateFormatter.string(from: data as Date)
  368. } else if let data = value as? NSNumber {
  369. if (key == KMInfoEncryptedKey) {
  370. value = data.boolValue ? KMLocalizedString("Yes", "") : KMLocalizedString("No", "")
  371. } else {
  372. value = key == KMInfoPageCountKey ? data.stringValue : (data.boolValue ? KMLocalizedString("Allowed", "") : KMLocalizedString("Not Allowed", ""))
  373. }
  374. }
  375. }
  376. }
  377. let cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: tcID ?? ""), owner: self) as? NSTableCellView
  378. cellView?.textField?.stringValue = (value as? String) ?? ""
  379. if (tableView.isEqual(to: self.attributesTableView) && tableColumn?.identifier.rawValue == VALUE_COLUMN_ID) {
  380. if (row == 0 || row == 1 || row == 2 || row == 3 || row == 7) {
  381. cellView?.textField?.bezelStyle = .squareBezel
  382. cellView?.textField?.isEditable = true
  383. cellView?.textField?.isSelectable = true
  384. cellView?.textField?.isBordered = true
  385. cellView?.textField?.isBezeled = true
  386. cellView?.textField?.drawsBackground = true
  387. cellView?.textField?.delegate = self
  388. if (row == 1) {
  389. let cell = tableView.view(atColumn: 1, row: 0, makeIfNecessary: true) as? NSTableCellView
  390. cell?.textField?.nextKeyView = cellView!.textField
  391. } else if (row == 2) {
  392. let cell = tableView.view(atColumn: 1, row: 1, makeIfNecessary: true) as? NSTableCellView
  393. cell?.textField?.nextKeyView = cellView!.textField
  394. } else if (row == 3) {
  395. let cell = tableView.view(atColumn: 1, row: 2, makeIfNecessary: true) as? NSTableCellView
  396. cell?.textField?.nextKeyView = cellView!.textField
  397. } else if (row == 7) {
  398. let cell = tableView.view(atColumn: 1, row: 3, makeIfNecessary: true) as? NSTableCellView
  399. cell?.textField?.nextKeyView = cellView!.textField
  400. }
  401. } else {
  402. cellView?.textField?.isEditable = false
  403. cellView?.textField?.isSelectable = false
  404. cellView?.textField?.isBordered = false
  405. cellView?.textField?.isBezeled = false
  406. cellView?.textField?.drawsBackground = false
  407. cellView?.textField?.delegate = nil;
  408. }
  409. cellView?.textField?.tag = row
  410. }
  411. return cellView
  412. }
  413. func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
  414. var rowHeight = tableView.rowHeight
  415. if (tableView.isEqual(to: self.attributesTableView) && row == tableView.numberOfRows-1) {
  416. // }
  417. // if ([tv isEqual:attributesTableView] && row == [tv numberOfRows] - 1)
  418. rowHeight = fmax(rowHeight, NSHeight(tableView.enclosingScrollView?.bounds ?? NSZeroRect) - tableView.numberOfRows.cgFloat * (rowHeight + tableView.intercellSpacing.height) + rowHeight)
  419. }
  420. return rowHeight
  421. }
  422. /*
  423. - (id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
  424. static NSDateFormatter *shortDateFormatter = nil;
  425. if(shortDateFormatter == nil) {
  426. shortDateFormatter = [[NSDateFormatter alloc] init];
  427. [shortDateFormatter setDateStyle:NSDateFormatterShortStyle];
  428. [shortDateFormatter setTimeStyle:NSDateFormatterNoStyle];
  429. }
  430. NSArray *keys = nil;
  431. if ([tv isEqual:summaryTableView])
  432. keys = summaryKeys;
  433. else if ([tv isEqual:attributesTableView])
  434. keys = attributesKeys;
  435. NSString *key = [keys objectAtIndex:row];
  436. NSString *tcID = [tableColumn identifier];
  437. id value = nil;
  438. if ([key length]) {
  439. if ([tcID isEqualToString:LABEL_COLUMN_ID]) {
  440. value = [labels objectForKey:key] ?: [key stringByAppendingString:@":"];
  441. } else if ([tcID isEqualToString:VALUE_COLUMN_ID]) {
  442. value = [info objectForKey:key];
  443. if (value == nil)
  444. value = @"-";
  445. else if ([value isKindOfClass:[NSDate class]])
  446. value = [shortDateFormatter stringFromDate:value];
  447. else if ([value isKindOfClass:[NSNumber class]]){
  448. if ([key isEqualToString:SKInfoEncryptedKey]) {
  449. value = [value boolValue] ? NSLocalizedString(@"Yes", @"") : NSLocalizedString(@"No", @"");
  450. } else {
  451. value = ([key isEqualToString:SKInfoPageCountKey] ? [value stringValue] : ([value boolValue] ? NSLocalizedString(@"Allowed", @"") : NSLocalizedString(@"Not Allowed", @"")));
  452. }
  453. }
  454. }
  455. }
  456. return value;
  457. }
  458. - (void)tableView:(NSTableView *)tv willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
  459. if ([tv isEqual:attributesTableView] && [[tableColumn identifier] isEqualToString:LABEL_COLUMN_ID])
  460. [cell setLineBreakMode:row == [tv numberOfRows] - 1 ? NSLineBreakByWordWrapping : NSLineBreakByTruncatingTail];
  461. }
  462. - (CGFloat)tableView:(NSTableView *)tv heightOfRow:(NSInteger)row {
  463. CGFloat rowHeight = [tv rowHeight];
  464. if ([tv isEqual:attributesTableView] && row == [tv numberOfRows] - 1)
  465. rowHeight = fmax(rowHeight, NSHeight([[tv enclosingScrollView] bounds]) - [tv numberOfRows] * (rowHeight + [tv intercellSpacing].height) + rowHeight);
  466. return rowHeight;
  467. }
  468. - (BOOL)tableView:(NSTableView *)tv shouldSelectRow:(NSInteger)row {
  469. return YES;
  470. }
  471. - (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(nullable NSTabViewItem *)tabViewItem
  472. {
  473. if ([tabView indexOfTabViewItem:tabViewItem] == 1) {
  474. if (self.currentDocument) {
  475. NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:[self infoForDocument:self.currentDocument]];
  476. for (NSString *key in self.editDictionary.allKeys) {
  477. [dic setObject:self.editDictionary[key] forKey:key];
  478. }
  479. [self setInfo:dic];
  480. }
  481. [self.attributesTableView reloadData];
  482. } else {
  483. [self.summaryTableView reloadData];
  484. }
  485. }
  486. */
  487. }
  488. extension KMInfoWindowController: NSTextFieldDelegate {
  489. func controlTextDidChange(_ obj: Notification) {
  490. if let textField = obj.object as? NSTextField {
  491. if (textField.tag == 0) {
  492. self.editDictionary.setObject(textField.stringValue, forKey: PDFDocumentAttribute.titleAttribute.rawValue as NSCopying)
  493. } else if (textField.tag == 1) {
  494. self.editDictionary.setObject(textField.stringValue, forKey: PDFDocumentAttribute.authorAttribute.rawValue as NSCopying)
  495. } else if (textField.tag == 2) {
  496. self.editDictionary.setObject(textField.stringValue, forKey: PDFDocumentAttribute.subjectAttribute.rawValue as NSCopying)
  497. } else if (textField.tag == 3) {
  498. self.editDictionary.setObject(textField.stringValue, forKey: PDFDocumentAttribute.creatorAttribute.rawValue as NSCopying)
  499. } else if (textField.tag == 7) {
  500. self.editDictionary.setObject(textField.stringValue, forKey: KMInfoKeywordsStringKey as NSCopying)
  501. }
  502. }
  503. }
  504. }
  505. private let CM_PER_POINT = 0.035277778
  506. private let INCH_PER_POINT = 0.013888889
  507. private func KMSizeString(_ size: NSSize, _ altSize: NSSize) -> String {
  508. var useMetric = false
  509. if let data = ((NSLocale.current as NSLocale).object(forKey: .usesMetricSystem) as? NSNumber) {
  510. useMetric = data.boolValue
  511. }
  512. let factor = useMetric ? CM_PER_POINT : INCH_PER_POINT
  513. let units = useMetric ? KMLocalizedString("cm", "size unit") : KMLocalizedString("in", "size unit")
  514. if (NSEqualSizes(size, altSize)) {
  515. return String(format: "%.2f x %.2f %@", size.width * factor, size.height * factor, units)
  516. } else {
  517. return String(format: "%.2f x %.2f %@ (%.2f x %.2f %@)", size.width * factor, size.height * factor, units, altSize.width * factor, altSize.height * factor, units)
  518. }
  519. }