KMInfoWindowController.swift 29 KB

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