KMToolbarCustomViewController.swift 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. //
  2. // KMToolbarCustomViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by tangchao on 2023/10/26.
  6. //
  7. import Cocoa
  8. private let KMPasteboardTypeAllowedIndexSet: NSPasteboard.PasteboardType = NSPasteboard.PasteboardType(rawValue: "KMPasteboardTypeAllowedIndexSet")
  9. private let KMPasteboardTypeDefaultIndexSet: NSPasteboard.PasteboardType = NSPasteboard.PasteboardType(rawValue: "KMPasteboardTypeDefaultIndexSet")
  10. private let KMToolbarImageToPDFItemIdentifier = "KMToolbarImageToPDFItemIdentifier"
  11. private let KMToolbarRotateRightItemIdentifier = "KMToolbarRotateRightItemIdentifier"
  12. private let KMToolbarRotateLeftItemIdentifier = "KMToolbarRotateLeftItemIdentifier"
  13. private let KMToolbarPageBreaksItemIdentifier = "KMToolbarPageBreaksItemIdentifier"
  14. private let KMToolbarViewModeItemIdentifier = "KMToolbarViewModeItemIdentifier"
  15. private let KMToolbarDisplayModeItemIdentifier = "KMToolbarDisplayModeItemIdentifier"
  16. private let KMToolbarSpaceItemIdentifier = "KMToolbarSpaceItemIdentifier"
  17. //private let KMImageNameToolbarSpace = "KMImageNameToolbarSpace"
  18. private let KMToolbarFormAlignmentIdentifier = "KMToolbarFormAlignmentIdentifier"
  19. let KMToolbarCustomChangeNotification: Notification.Name = Notification.Name(rawValue: "KMToolbarCustomChangeNotification")
  20. class KMToolbarCellView: NSTableCellView {
  21. @IBOutlet weak var tickImageView: NSImageView!
  22. }
  23. class KMToolbarCustomViewController: NSViewController {
  24. @IBOutlet weak var titleLabel: NSTextField!
  25. @IBOutlet weak var leftLabel: NSTextField!
  26. @IBOutlet weak var rightLabel: NSTextField!
  27. @IBOutlet weak var subTitleLabel: NSTextField!
  28. @IBOutlet weak var okButton: NSButton!
  29. @IBOutlet weak var cancelButton: NSButton!
  30. @IBOutlet weak var resetButton: NSButton!
  31. @IBOutlet weak var addButton: NSButton!
  32. @IBOutlet weak var removeButton: NSButton!
  33. @IBOutlet weak var allowedItemsTableView: NSTableView!
  34. @IBOutlet weak var defaultItemsTableView: NSTableView!
  35. private var _allowedItems: [String] = []
  36. private var _defaultItems: [String] = []
  37. weak var toolbar: KMToolbarView?
  38. override func loadView() {
  39. super.loadView()
  40. self.titleLabel.stringValue = KMLocalizedString("Customize Toolbar", nil)
  41. self.subTitleLabel.stringValue = String(format: "%@", KMLocalizedString("Drag-and-drop tools to change their order", nil))
  42. self.leftLabel.stringValue = KMLocalizedString("Choose tools to add:", nil)
  43. self.rightLabel.stringValue = KMLocalizedString("Tools to show in Toolbar:", nil)
  44. self.okButton.title = KMLocalizedString("Done", nil)
  45. self.cancelButton.title = KMLocalizedString("Cancel", nil)
  46. self.resetButton.title = KMLocalizedString("Reset", nil)
  47. self.resetButton.toolTip = KMLocalizedString("Reset Toolbars", nil)
  48. self.addButton.title = String(format: "%@ >>", KMLocalizedString("Add", nil))
  49. self.addButton.toolTip = KMLocalizedString("Add to Toolbar", nil)
  50. self.removeButton.title = String(format: "<< %@", KMLocalizedString("Remove", nil))
  51. self.removeButton.toolTip = KMLocalizedString("Remove from Toolbar", nil)
  52. var color = NSColor(red: 51.0/255.0, green: 51.0/255.0, blue: 51.0/255.0, alpha: 1.0)
  53. if (KMAppearance.isSupportNewColor()) {
  54. if (KMAppearance.isDarkMode()) {
  55. color = NSColor(red: 1, green: 1, blue: 1, alpha: 0.5)
  56. }
  57. }
  58. self.titleLabel.textColor = color
  59. self.subTitleLabel.textColor = color
  60. self.leftLabel.textColor = color
  61. self.rightLabel.textColor = color
  62. self.addButton.wantsLayer = true
  63. self.addButton.layer?.borderColor = NSColor(red: 153.0/255.0, green: 153.0/255.0, blue: 153.0/255.0, alpha: 1).cgColor
  64. self.addButton.layer?.borderWidth = 1.0
  65. self.addButton.layer?.cornerRadius = 4.0
  66. self.removeButton.wantsLayer = true
  67. self.removeButton.layer?.borderColor = NSColor(red: 153.0/255.0, green: 153.0/255.0, blue: 153.0/255.0, alpha: 1).cgColor
  68. self.removeButton.layer?.borderWidth = 1.0
  69. self.removeButton.layer?.cornerRadius = 4.0
  70. self.addButton.isEnabled = false
  71. self.removeButton.isEnabled = false
  72. self.defaultItemsTableView.registerForDraggedTypes([KMPasteboardTypeAllowedIndexSet, KMPasteboardTypeDefaultIndexSet])
  73. self._loadAllowedItems()
  74. self._loadDefaultItems()
  75. }
  76. override func viewDidLoad() {
  77. super.viewDidLoad()
  78. // Do view setup here.
  79. }
  80. @IBAction @objc func okButtonAction(_ sender: NSButton) {
  81. NSApp.endSheet(self.view.window!)
  82. self.view.window?.close()
  83. if self.toolbar?.toolbarIdentifier != nil && self._defaultItems.count > 0 {
  84. if let data = self.toolbar?.toolbarIdentifier {
  85. UserDefaults.standard.set(self._defaultItems, forKey: data)
  86. }
  87. NotificationCenter.default.post(name: KMToolbarCustomChangeNotification, object: self.toolbar)
  88. }
  89. }
  90. @IBAction @objc func cancelButtonAction(_ sender: NSButton) {
  91. NSApp.endSheet(self.view.window!)
  92. self.view.window?.close()
  93. }
  94. @IBAction @objc func resetButtonAction(_ sender: NSButton) {
  95. if let data = self.toolbar?.toolbarIdentifier {
  96. UserDefaults.standard.removeObject(forKey: data)
  97. NotificationCenter.default.post(name: KMToolbarCustomChangeNotification, object: self.toolbar)
  98. }
  99. self._loadDefaultItems()
  100. self.allowedItemsTableView.reloadData()
  101. self.defaultItemsTableView.reloadData()
  102. }
  103. @IBAction @objc func addButtonAction(_ sender: NSButton) {
  104. let selectedRowIndexes = self.allowedItemsTableView.selectedRowIndexes
  105. if (selectedRowIndexes.count <= 0) {
  106. return
  107. }
  108. var itemIdentifiers: [String] = []
  109. for index in selectedRowIndexes {
  110. itemIdentifiers.append(self._allowedItems[index])
  111. }
  112. if (itemIdentifiers.count > 0) {
  113. var isAdded = false
  114. for itemIdentifier in itemIdentifiers {
  115. if self._defaultItems.contains(itemIdentifier) == false || itemIdentifier == KMToolbarSpaceItemIdentifier {
  116. self._defaultItems.append(itemIdentifier)
  117. isAdded = true
  118. }
  119. }
  120. if (isAdded) {
  121. self.allowedItemsTableView.reloadData()
  122. self.defaultItemsTableView.reloadData()
  123. self.defaultItemsTableView.scrollRowToVisible(self._defaultItems.count-1)
  124. self.addButton.isEnabled = false
  125. } else {
  126. }
  127. }
  128. }
  129. @IBAction @objc func removeButtonAction(_ sender: NSButton) {
  130. let selectedRowIndexes = self.defaultItemsTableView.selectedRowIndexes
  131. if (selectedRowIndexes.count <= 0) {
  132. return
  133. }
  134. for index in selectedRowIndexes {
  135. if index < self._defaultItems.count {
  136. self._defaultItems.remove(at: index)
  137. }
  138. }
  139. self.allowedItemsTableView.reloadData()
  140. self.defaultItemsTableView.reloadData()
  141. self.removeButton.isEnabled = false
  142. }
  143. @objc func delete(_ sender: Any?) {
  144. if self.defaultItemsTableView.isEqual(to: self.view.window?.firstResponder) {
  145. self.removeButtonAction(self.removeButton)
  146. }
  147. }
  148. }
  149. extension KMToolbarCustomViewController: NSTableViewDelegate, NSTableViewDataSource {
  150. func numberOfRows(in tableView: NSTableView) -> Int {
  151. var rows = 0
  152. if (self.allowedItemsTableView.isEqual(to: tableView)) {
  153. rows = self._allowedItems.count
  154. } else if (self.defaultItemsTableView.isEqual(to: tableView)) {
  155. rows = self._defaultItems.count
  156. }
  157. return rows
  158. }
  159. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  160. var cellView: NSTableCellView?
  161. var itemIdentifier: String?
  162. if (self.allowedItemsTableView == tableView) {
  163. cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMAllowedItemsCell"), owner: self) as! NSTableCellView
  164. itemIdentifier = self._allowedItems[row]
  165. } else if (self.defaultItemsTableView == tableView) {
  166. cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMDefaultItemsCell"), owner: self) as! NSTableCellView
  167. itemIdentifier = self._defaultItems[row]
  168. }
  169. if itemIdentifier == KMToolbarSpaceItemIdentifier || itemIdentifier == KMNewToolbarSpaceItemIdentifier {
  170. cellView?.textField?.stringValue = KMLocalizedString("", nil)
  171. cellView?.imageView?.image = NSImage(named: KMImageNameToolbarSpace)
  172. } else {
  173. if let data = self.toolbar?.delegate?.toolbar?(self.toolbar!, itemFor: itemIdentifier!) {
  174. if itemIdentifier == KMToolbarFormAlignmentIdentifier {
  175. cellView?.textField?.stringValue = KMLocalizedString("Alignment", nil)
  176. } else {
  177. cellView?.textField?.stringValue = data.titleName ?? ""
  178. }
  179. cellView?.imageView?.image = data.image
  180. }
  181. }
  182. if let data = cellView?.isKind(of: KMToolbarCellView.self), data {
  183. if self._defaultItems.contains(itemIdentifier!) && itemIdentifier != KMToolbarSpaceItemIdentifier {
  184. (cellView as? KMToolbarCellView)?.tickImageView.image = NSImage(named: "KMImageNameToolbarSelected")
  185. } else {
  186. (cellView as? KMToolbarCellView)?.tickImageView.image = nil
  187. }
  188. }
  189. return cellView;
  190. }
  191. func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
  192. if (self.allowedItemsTableView == tableView) {
  193. let itemIdentifier = self._allowedItems[row]
  194. if (self._defaultItems.contains(itemIdentifier) && itemIdentifier != KMToolbarSpaceItemIdentifier) {
  195. return false
  196. }
  197. }
  198. return true
  199. }
  200. func tableViewSelectionDidChange(_ notification: Notification) {
  201. self.allowedItemsTableView.delegate = nil
  202. self.defaultItemsTableView.delegate = nil
  203. let tableView = notification.object as? NSTableView
  204. if (self.allowedItemsTableView == tableView) {
  205. self.addButton.isEnabled = tableView!.selectedRowIndexes.count > 0 ? true : false
  206. let set = NSIndexSet()
  207. self.defaultItemsTableView.selectRowIndexes(set as IndexSet, byExtendingSelection: false)
  208. self.removeButton.isEnabled = false
  209. } else if (self.defaultItemsTableView == tableView) {
  210. self.removeButton.isEnabled = tableView!.selectedRowIndexes.count > 0 ? true : false
  211. let set = NSIndexSet()
  212. self.allowedItemsTableView.selectRowIndexes(set as IndexSet, byExtendingSelection: false)
  213. self.addButton.isEnabled = false
  214. }
  215. self.allowedItemsTableView.delegate = self
  216. self.defaultItemsTableView.delegate = self
  217. }
  218. func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
  219. let indexSetData = NSKeyedArchiver.archivedData(withRootObject: rowIndexes)
  220. if (self.allowedItemsTableView == tableView) {
  221. pboard.declareTypes([KMPasteboardTypeAllowedIndexSet], owner: self)
  222. pboard.setData(indexSetData, forType: KMPasteboardTypeAllowedIndexSet)
  223. } else if (self.defaultItemsTableView == tableView) {
  224. pboard.declareTypes([KMPasteboardTypeDefaultIndexSet], owner: self)
  225. pboard.setData(indexSetData, forType: KMPasteboardTypeDefaultIndexSet)
  226. }
  227. return true
  228. }
  229. func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
  230. if (self.defaultItemsTableView == tableView) {
  231. if (dropOperation == .on) {
  232. return NSDragOperation(rawValue: 0)
  233. }
  234. return .move
  235. }
  236. return NSDragOperation(rawValue: 0)
  237. }
  238. func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
  239. if (self.defaultItemsTableView == tableView) {
  240. let pboard = info.draggingPasteboard
  241. if pboard.availableType(from: [KMPasteboardTypeAllowedIndexSet]) != nil {
  242. let rowData = pboard.data(forType: KMPasteboardTypeAllowedIndexSet)
  243. let rowIndexes: IndexSet = NSKeyedUnarchiver.unarchiveObject(with: rowData!) as! IndexSet
  244. var isAdded = false
  245. for idx in rowIndexes.reversed() {
  246. let itemIdentifier = self._allowedItems[idx]
  247. if self._defaultItems.contains(itemIdentifier) == false || itemIdentifier == KMToolbarSpaceItemIdentifier {
  248. self._defaultItems.insert(itemIdentifier, at: row)
  249. isAdded = true
  250. }
  251. }
  252. if (isAdded) {
  253. self.allowedItemsTableView.reloadData()
  254. self.defaultItemsTableView.reloadData()
  255. return true
  256. } else {
  257. }
  258. } else if pboard.availableType(from: [KMPasteboardTypeDefaultIndexSet]) != nil {
  259. let rowData = pboard.data(forType: KMPasteboardTypeDefaultIndexSet)
  260. let indexes: IndexSet = NSKeyedUnarchiver.unarchiveObject(with: rowData!) as! IndexSet
  261. var items: [String] = []
  262. for item in self._defaultItems {
  263. items.append(item)
  264. }
  265. var moveItems: [String] = []
  266. for index in indexes {
  267. moveItems.append(self._defaultItems[index])
  268. }
  269. var index = 0
  270. for index in indexes {
  271. self._defaultItems.remove(at: index)
  272. }
  273. var _row = row
  274. if (_row > 0) {
  275. var item: String? = items[row-1]
  276. while (moveItems.contains(item ?? "")) {
  277. _row -= 1
  278. if (_row < 0) {
  279. item = nil
  280. break
  281. } else {
  282. item = items[_row]
  283. }
  284. }
  285. if (item != nil) {
  286. index = self._defaultItems.firstIndex(of: item!)!+1
  287. }
  288. }
  289. for i in 0 ..< moveItems.count {
  290. self._defaultItems.insert(moveItems[i], at: index+i)
  291. }
  292. self.allowedItemsTableView.reloadData()
  293. self.defaultItemsTableView.reloadData()
  294. return true
  295. }
  296. }
  297. return false
  298. }
  299. }
  300. extension KMToolbarCustomViewController: NSMenuItemValidation {
  301. func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
  302. if (menuItem.action == #selector(delete)) {
  303. if (self.defaultItemsTableView != self.view.window!.firstResponder) {
  304. return false
  305. }
  306. }
  307. return true
  308. }
  309. }
  310. // MARK: - Private Methods
  311. extension KMToolbarCustomViewController {
  312. private func _loadAllowedItems() {
  313. if let data = self.toolbar?.delegate?.toolbarAllowedItemIdentifiers?(self.toolbar!) {
  314. self._allowedItems = data
  315. }
  316. let itemArray = [KMToolbarImageToPDFItemIdentifier, KMToolbarRotateRightItemIdentifier, KMToolbarRotateLeftItemIdentifier, KMToolbarPageBreaksItemIdentifier, KMToolbarViewModeItemIdentifier, KMToolbarDisplayModeItemIdentifier, KMToolbarDividerItemIdentifier, KMToolbarShowToolbarItemIdentifier]
  317. for itemStr in itemArray {
  318. if (self._allowedItems.contains(itemStr)) {
  319. self._allowedItems.removeObject(itemStr)
  320. }
  321. }
  322. }
  323. private func _loadDefaultItems() {
  324. var itemIdentifiers: [String]? = self.toolbar?.toolbarIdentifier != nil ? (UserDefaults.standard.object(forKey: self.toolbar!.toolbarIdentifier!) as? [String]) : []
  325. if itemIdentifiers == nil || itemIdentifiers!.count <= 0 {
  326. if let items = self.toolbar?.delegate?.toolbarDefaultItemIdentifiers?(self.toolbar!) {
  327. itemIdentifiers = items
  328. }
  329. }
  330. self._defaultItems.removeAll()
  331. if (itemIdentifiers != nil) {
  332. for itemI in itemIdentifiers! {
  333. if itemI != KMToolbarDividerItemIdentifier {
  334. self._defaultItems.append(itemI)
  335. }
  336. }
  337. } else {
  338. self._defaultItems = []
  339. }
  340. }
  341. }