KMBrowser.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. //
  2. // KMBrowser.swift
  3. // PDF Master
  4. //
  5. // Created by wanjun on 2022/12/9.
  6. //
  7. import Cocoa
  8. @objcMembers class KMBrowser: CTBrowser {
  9. var numberOfTabViewItem: Int = 0
  10. var isCloseAllTabViewItem: Bool = false
  11. var currentCloseDocument: KMMainDocument?
  12. var currentDocument: KMMainDocument?
  13. override func createBlankTabBased(on baseContents: CTTabContents?) -> CTTabContents {
  14. return KMMainDocument.init(baseTabContents: baseContents)!
  15. }
  16. func createNewBrowser() -> KMBrowser {
  17. let browser = KMBrowser.init() as KMBrowser
  18. let cls = windowController != nil ? type(of: windowController) : CTBrowserWindowController.self
  19. browser.windowController = cls.init(browser: browser)
  20. return browser
  21. }
  22. override func windowDidBeginToClose() {
  23. self.currentDocument = NSDocumentController.shared.currentDocument as? KMMainDocument
  24. numberOfTabViewItem = Int(tabCount())
  25. isCloseAllTabViewItem = true
  26. closeTabViewItem()
  27. }
  28. func closeTabViewItem() -> Void {
  29. if numberOfTabViewItem < 1 {
  30. window.orderOut(nil)
  31. tabStripModel.closeAllTabs()
  32. isCloseAllTabViewItem = false
  33. } else {
  34. let currentDocument = tabStripModel.tabContents(at: Int32(numberOfTabViewItem-1)) as! KMMainDocument
  35. if (currentDocument.isHome == false) {
  36. currentDocument.mainViewController?.savePageNumberIfNeed()
  37. if let _isEdited = currentDocument.mainViewController?.listView.isEdited(), _isEdited, !currentDocument.isDocumentEdited {
  38. currentDocument.updateChangeCount(.changeDone)
  39. }
  40. }
  41. // 清理数据 [主要清空通知]
  42. currentDocument.mainViewController?.clearData()
  43. if (currentDocument.isEqual(to: self.currentDocument)) {
  44. // 当前文档 不用提醒,在关闭窗口时已提醒过了
  45. tabStripModel.detachTabContents(at: Int32(self.numberOfTabViewItem - 1))
  46. currentDocument.close()
  47. if (self.isCloseAllTabViewItem) {
  48. self.numberOfTabViewItem = self.numberOfTabViewItem - 1
  49. self.closeTabViewItem()
  50. }
  51. return
  52. }
  53. let isPrompt = KMPreferenceManager.shared.closeFileIsPrompt()
  54. if currentDocument.isNewCreated {
  55. let exist = FileManager.default.fileExists(atPath: currentDocument.fileURL!.path)
  56. if exist {
  57. try? FileManager.default.removeItem(atPath: currentDocument.fileURL!.path)
  58. }
  59. currentCloseDocument = currentDocument
  60. currentDocument.runModalSavePanel(for: .saveAsOperation, delegate: self, didSave: #selector(saveSuccess(_:)), contextInfo: nil)
  61. } else {
  62. if currentDocument.isDocumentEdited && isPrompt {
  63. currentDocument.canClose(withDelegate: self, shouldClose: #selector(document(_:shouldClose:contextInfo:)), contextInfo: nil)
  64. } else if currentDocument.isDocumentEdited {
  65. currentDocument.save(nil)
  66. currentDocument.close()
  67. if self.isCloseAllTabViewItem {
  68. numberOfTabViewItem = numberOfTabViewItem - 1
  69. closeTabViewItem()
  70. }
  71. } else if (currentDocument.mainViewController != nil) {
  72. if (currentDocument.mainViewController!.isPDFDocumentEdited || currentDocument.mainViewController!.needSave) {
  73. if (isPrompt) {
  74. let alert = NSAlert()
  75. let message = "Do you want to save the changes made to the document “\(currentDocument.fileURL!.lastPathComponent)”?"
  76. alert.messageText = message
  77. alert.informativeText = NSLocalizedString("Your changes will be lost if you don’t save them.", comment: "")
  78. alert.addButton(withTitle: NSLocalizedString("Save", comment: ""))
  79. alert.addButton(withTitle: NSLocalizedString("Don‘t Save", comment: ""))
  80. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  81. let response = alert.runModal()
  82. if (response == .alertFirstButtonReturn) { // 保存
  83. currentDocument.save(nil)
  84. tabStripModel.detachTabContents(at: Int32(numberOfTabViewItem - 1))
  85. currentDocument.close()
  86. } else if (response == .alertSecondButtonReturn) { // 不保存
  87. tabStripModel.detachTabContents(at: Int32(numberOfTabViewItem - 1))
  88. currentDocument.close()
  89. } else { // 取消
  90. self.isCloseAllTabViewItem = false
  91. }
  92. } else {
  93. currentDocument.save(nil)
  94. currentDocument.close()
  95. }
  96. if isCloseAllTabViewItem {
  97. numberOfTabViewItem = numberOfTabViewItem - 1
  98. closeTabViewItem()
  99. }
  100. } else {
  101. tabStripModel.detachTabContents(at: Int32(numberOfTabViewItem - 1))
  102. currentDocument.close()
  103. if isCloseAllTabViewItem {
  104. numberOfTabViewItem = numberOfTabViewItem - 1
  105. closeTabViewItem()
  106. }
  107. }
  108. } else {
  109. tabStripModel.detachTabContents(at: Int32(numberOfTabViewItem - 1))
  110. currentDocument.close()
  111. if isCloseAllTabViewItem {
  112. numberOfTabViewItem = numberOfTabViewItem - 1
  113. closeTabViewItem()
  114. }
  115. }
  116. }
  117. }
  118. }
  119. override func canCloseContents(at index: Int32) -> Bool {
  120. let isPrompt = KMPreferenceManager.shared.closeFileIsPrompt()
  121. if tabContents(at: Int32(index)) != nil {
  122. let currentDocument = tabContents(at: Int32(index)) as! KMMainDocument
  123. if (currentDocument.isHome == false) {
  124. currentDocument.mainViewController?.savePageNumberIfNeed()
  125. if let _isEdited = currentDocument.mainViewController?.listView.isEdited(), _isEdited, !currentDocument.isDocumentEdited {
  126. currentDocument.updateChangeCount(.changeDone)
  127. }
  128. }
  129. var canClose = false
  130. if currentDocument.isNewCreated {
  131. let exist = FileManager.default.fileExists(atPath: currentDocument.fileURL!.path)
  132. if exist {
  133. try? FileManager.default.removeItem(atPath: currentDocument.fileURL!.path)
  134. }
  135. currentCloseDocument = currentDocument
  136. currentDocument.runModalSavePanel(for: .saveToOperation, delegate: self, didSave: #selector(saveSuccess(_:)), contextInfo: nil)
  137. } else if (currentDocument.cloud) { /// 云文档
  138. if (currentDocument.isDocumentEdited) {
  139. currentCloseDocument = currentDocument
  140. currentDocument.save(withDelegate: self, didSave: #selector(saveSuccess(_:)), contextInfo: nil)
  141. } else {
  142. currentDocument.close()
  143. canClose = true
  144. }
  145. } else {
  146. if currentDocument.isDocumentEdited && isPrompt {
  147. if currentDocument.isKind(of: KMMainDocument.self) {
  148. currentDocument.closedByUserGestureFlag = true
  149. }
  150. currentDocument.canClose(withDelegate: self, shouldClose: #selector(document(_:shouldClose:contextInfo:)), contextInfo: nil)
  151. } else if currentDocument.isDocumentEdited {
  152. currentDocument.save(nil)
  153. currentDocument.close()
  154. canClose = true
  155. } else if (currentDocument.mainViewController != nil) {
  156. if (currentDocument.mainViewController!.isPDFDocumentEdited || currentDocument.mainViewController!.needSave) {
  157. // currentCloseDocument = currentDocument
  158. // currentDocument.save(withDelegate: self, didSave: #selector(saveSuccess(_:)), contextInfo: nil)
  159. if (isPrompt) {
  160. let alert = NSAlert()
  161. let message = "Do you want to save the changes made to the document “\(currentDocument.fileURL!.lastPathComponent)”?"
  162. alert.messageText = message
  163. alert.informativeText = NSLocalizedString("Your changes will be lost if you don’t save them.", comment: "")
  164. alert.addButton(withTitle: NSLocalizedString("Save", comment: ""))
  165. alert.addButton(withTitle: NSLocalizedString("Don‘t Save", comment: ""))
  166. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  167. let response = alert.runModal()
  168. if (response == .alertFirstButtonReturn) { // 保存
  169. if let home = self.tabContents(at: 0) as? KMMainDocument, home.isHome { // 标记 home 最近列表需要强制刷新
  170. home.homeViewController?.historyFileViewController.isForceReload = true
  171. }
  172. currentDocument.save(nil)
  173. currentDocument.close()
  174. canClose = true
  175. } else if (response == .alertSecondButtonReturn) { // 不保存
  176. currentDocument.close()
  177. canClose = true
  178. } else { // 取消
  179. canClose = false
  180. }
  181. } else {
  182. currentDocument.save(nil)
  183. currentDocument.close()
  184. canClose = true
  185. }
  186. } else {
  187. currentDocument.close()
  188. canClose = true
  189. }
  190. } else {
  191. currentDocument.close()
  192. canClose = true
  193. }
  194. }
  195. if (canClose) {
  196. // 清理数据 [主要清空通知]
  197. currentDocument.mainViewController?.clearData()
  198. }
  199. return canClose
  200. }
  201. return false
  202. }
  203. func document(_ document: NSDocument?, shouldClose: Bool, contextInfo: UnsafeMutableRawPointer?) {
  204. if (document is KMMainDocument) {
  205. let iu: CloseTypes = CLOSE_USER_GESTURE
  206. if ((document as! KMMainDocument).closedByUserGestureFlag && shouldClose) {
  207. (document as! KMMainDocument).closedByUserGesture = uint(iu.rawValue)
  208. }
  209. (document as! KMMainDocument).closedByUserGestureFlag = false
  210. }
  211. if (shouldClose) {
  212. let currentDocument: KMMainDocument = document! as! KMMainDocument
  213. let index = self.tabStripModel.index(of: currentDocument)
  214. // 清空数据 [主要清理通知]
  215. currentDocument.mainViewController?.clearData()
  216. currentDocument.close()
  217. self.tabStripModel.detachTabContents(at: index)
  218. }
  219. if (self.isCloseAllTabViewItem) {
  220. self.numberOfTabViewItem = self.numberOfTabViewItem - 1
  221. self.closeTabViewItem()
  222. }
  223. }
  224. func saveSuccess(_ sender: Any) -> Void {
  225. if (currentCloseDocument != nil) {
  226. if (currentCloseDocument!.cloud) { /// 云文档
  227. currentCloseDocument!.uploadToCloud({ [weak self] finished, error in
  228. if (finished) {
  229. if (self!.currentCloseDocument == nil) {
  230. return
  231. }
  232. let index = self?.tabStripModel.index(of: self!.currentCloseDocument!)
  233. self?.tabStripModel.detachTabContents(at: index!)
  234. // self!.currentCloseDocument!.close()
  235. self!.currentCloseDocument = nil
  236. if (self!.isCloseAllTabViewItem) {
  237. self!.numberOfTabViewItem = self!.numberOfTabViewItem - 1
  238. self!.closeTabViewItem()
  239. }
  240. }
  241. })
  242. return
  243. }
  244. if let isNewCreated = currentCloseDocument?.isNewCreated, isNewCreated {
  245. if let _url = currentCloseDocument?.saveToURL { // 将新创建的空白文档将入最近列表
  246. NSDocumentController.shared.noteNewRecentDocumentURL(_url)
  247. }
  248. }
  249. let index = tabStripModel.index(of: currentCloseDocument)
  250. tabStripModel.detachTabContents(at: index)
  251. // 清空数据 [主要清理通知]
  252. currentCloseDocument?.mainViewController?.clearData()
  253. currentCloseDocument?.close()
  254. currentCloseDocument = nil
  255. }
  256. if isCloseAllTabViewItem {
  257. numberOfTabViewItem = numberOfTabViewItem - 1
  258. closeTabViewItem()
  259. }
  260. }
  261. func addNewTabContents() {
  262. if (self.tabCount() <= 0) {
  263. KMPrint("New Tab can‘t add first.")
  264. return
  265. }
  266. let contents = self.createBlankTabBased(on: nil)
  267. contents.isHome = true
  268. contents.isNewTab = true
  269. self.add(contents, at: -1, inForeground: true)
  270. }
  271. }
  272. extension KMBrowser {
  273. @objc public func canSelectNextTab() -> Bool {
  274. if (self.tabStripModel.count() < 1) {
  275. return false
  276. }
  277. if (self.tabStripModel.activeIndex >= (self.tabStripModel.count()-1)) {
  278. return false
  279. }
  280. return true
  281. }
  282. @objc public func canSelectPreviousTab() -> Bool {
  283. if (self.tabStripModel.activeIndex <= 0) {
  284. return false
  285. }
  286. return true
  287. }
  288. }