KMInfoWindowController.swift 29 KB

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