KMCloudDocumentsViewController.swift 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. //
  2. // KMCloudDocumentsViewController.swift
  3. // PDF Master
  4. //
  5. // Created by wanjun on 2022/11/23.
  6. //
  7. import Cocoa
  8. enum KMCloudDocumentState : Int {
  9. case Box = 0
  10. case DropBox
  11. case GoogleDrive
  12. case OneDrive
  13. public func string() -> String {
  14. switch self {
  15. case .Box:
  16. return "Box"
  17. case .DropBox:
  18. return "DropBox"
  19. case .GoogleDrive:
  20. return "GoogleDrive"
  21. case .OneDrive:
  22. return "OneDrive"
  23. }
  24. }
  25. }
  26. class KMCloudAccountListTableviewCell: NSTableCellView {
  27. @IBOutlet weak var accountLabel: NSTextField!
  28. }
  29. class KMCloudFileNameListTableviewCell: NSTableCellView {
  30. @IBOutlet weak var fileImageView: NSImageView!
  31. @IBOutlet weak var titleLabel: NSTextField!
  32. @IBOutlet weak var subtitleLabel: NSTextField!
  33. }
  34. class KMCloudFileModifyTimeListTableviewCell: NSTableCellView {
  35. @IBOutlet weak var modifyTimeLabel: NSTextField!
  36. }
  37. class KMCloudFileSizeListTableviewCell: NSTableCellView {
  38. @IBOutlet weak var sizeLabel: NSTextField!
  39. }
  40. class KMCloudDocumentsViewController: NSViewController {
  41. @IBOutlet weak var topBox: NSBox!
  42. @IBOutlet weak var cloudDocumentsLabel: NSTextField!
  43. @IBOutlet weak var addCloudsBox: KMBox!
  44. @IBOutlet weak var addCloudsLabel: NSTextField!
  45. @IBOutlet weak var addCloudsImageView: NSImageView!
  46. @IBOutlet weak var mainBox: NSBox!
  47. @IBOutlet weak var emptyScrollView: NSScrollView!
  48. @IBOutlet weak var emptyCollectionView: KMCollectionView!
  49. @IBOutlet weak var cloudSplitView: NSSplitView!
  50. @IBOutlet weak var cloudLeftBox: NSBox!
  51. @IBOutlet weak var cloudRightBox: NSBox!
  52. @IBOutlet weak var accountListTableView: NSTableView!
  53. @IBOutlet weak var fileListTableView: KMMenuTableView!
  54. @IBOutlet weak var fileNameTableColumn: NSTableColumn!
  55. @IBOutlet weak var fileModifyTimeTableColumn: NSTableColumn!
  56. @IBOutlet weak var fileSizeTableColumn: NSTableColumn!
  57. @IBOutlet weak var pathControl: NSPathControl!
  58. @IBOutlet weak var pathBox: NSBox!
  59. var myPathControl = KMCloudPathControl()
  60. var pathString: String = ""
  61. var cloudPlates: [KMCloudDocumentState] = [.DropBox, .GoogleDrive]
  62. var accounts: [Any] = []
  63. var cloudFiles: [Any] = []
  64. var currentAccount: KMCloudServer?
  65. var filepaths: [KMServicesCloudFile] = []
  66. override func viewDidLoad() {
  67. super.viewDidLoad()
  68. // Do view setup here.
  69. let serverArr = KMCloudServer.getAllLoginServer()
  70. for server in serverArr! {
  71. self.accounts.append(server)
  72. }
  73. emptyCollectionView.register(KMCloudEmptyCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMCloudEmptyCollectionViewItem"))
  74. emptyCollectionView.isSelectable = true
  75. self.fileListTableView.menuDelegate = self
  76. initializeUI()
  77. initLocalization()
  78. self.pathControl.url = URL(fileURLWithPath: "Cloud Documents\\Test\\Test2")
  79. self.pathControl.pathStyle = .popUp
  80. addCloudsBox.downCallback = { [weak self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
  81. if self != nil {
  82. if downEntered {
  83. self!.addCloudsAction()
  84. }
  85. }
  86. }
  87. }
  88. override func viewDidAppear() {
  89. super.viewDidAppear()
  90. reloadData()
  91. }
  92. override func viewWillLayout() {
  93. super.viewWillLayout()
  94. if (self.emptyCollectionView.isHidden == false) {
  95. self.emptyCollectionView.reloadData()
  96. }
  97. }
  98. // MARK: Init
  99. func initializeUI() -> Void {
  100. let menu = NSMenu()
  101. let item = NSMenuItem(title: NSLocalizedString("Delete", comment: ""), action: #selector(accountListTableView_itemClick), target: self)
  102. menu.addItem(item!)
  103. self.accountListTableView.menu = menu
  104. self.accountListTableView.allowsEmptySelection = false
  105. self.fileListTableView.doubleAction = #selector(fileListTableViewDoubleAction)
  106. let pathControl = self.myPathControl
  107. self.pathBox.contentView?.addSubview(pathControl)
  108. pathControl.frame = self.pathBox.contentView!.bounds
  109. pathControl.autoresizingMask = [.width, .height]
  110. self.pathString = NSLocalizedString("Cloud Documents", comment: "")
  111. pathControl.urlString = self.pathString
  112. pathControl.itemClick = { [weak self] index in
  113. if (index == 0) {
  114. self!.updateFilesList((self?.currentAccount)!, nil)
  115. } else {
  116. self!.updateFilesList((self?.currentAccount)!, self?.filepaths[index-1])
  117. }
  118. }
  119. }
  120. func initLocalization() -> Void {
  121. cloudDocumentsLabel.stringValue = NSLocalizedString("Cloud Documents", comment: "")
  122. addCloudsLabel.stringValue = NSLocalizedString("Add Account", comment: "")
  123. addCloudsBox.toolTip = NSLocalizedString("Add Account", comment: "")
  124. fileNameTableColumn.title = NSLocalizedString("File Name", comment: "")
  125. fileModifyTimeTableColumn.title = NSLocalizedString("Change time", comment: "")
  126. fileSizeTableColumn.title = NSLocalizedString("Size", comment: "")
  127. }
  128. // MARK: private
  129. func reloadData() -> Void {
  130. DispatchQueue.main.async {
  131. if (KMCloudServer.isConnectionAvailable()) {
  132. self.hiddenNotNetworkView()
  133. self.emptyCollectionView.isHidden = true
  134. self.cloudSplitView.isHidden = true
  135. if self.accounts.count > 0 {
  136. self.cloudSplitView.isHidden = false
  137. self.accountListTableView.reloadData()
  138. self.fileListTableView.reloadData()
  139. } else {
  140. self.emptyCollectionView.isHidden = false
  141. self.emptyCollectionView.reloadData()
  142. }
  143. } else {
  144. self.showNotNetworkView()
  145. }
  146. }
  147. }
  148. // MARK: Action
  149. func loginCloud(state: KMCloudDocumentState) -> Void {
  150. switch state {
  151. case .Box:
  152. break
  153. case .DropBox:
  154. let serverArray = KMCloudServer.getAllLoginServer()
  155. var dropboxIsLogin: Bool = false
  156. for server in serverArray! {
  157. if (server.serverType == KMDropbox) {
  158. dropboxIsLogin = true
  159. break
  160. }
  161. }
  162. if (dropboxIsLogin) {
  163. self.logoutAccount(self.currentAccount!)
  164. } else {
  165. let server = KMCloudServer(cloudWith: KMDropbox)
  166. server?.authorizedLoginCompletion({ cloudFiles, finished in
  167. if (!finished) { /// 登录失败
  168. return
  169. }
  170. let serverArr = KMCloudServer.getAllLoginServer()
  171. var currentServer: KMCloudServer?
  172. for server in serverArr! {
  173. if ((server as! KMCloudServer).serverType == KMDropbox) {
  174. currentServer = server
  175. break
  176. }
  177. }
  178. // let userData: KMDropboxUserMetadata = cloudFiles as! KMDropboxUserMetadata
  179. if (currentServer != nil) {
  180. self.accounts.append(currentServer)
  181. self.reloadData()
  182. }
  183. })
  184. }
  185. break
  186. case .GoogleDrive:
  187. let serverArray = KMCloudServer.getAllLoginServer()
  188. var isLogin: Bool = false
  189. for server in serverArray! {
  190. if (server.serverType == KMGoogleDrive) {
  191. isLogin = true
  192. break
  193. }
  194. }
  195. if (isLogin) {
  196. self.logoutAccount(self.currentAccount!)
  197. } else {
  198. let server = KMCloudServer(cloudWith: KMGoogleDrive)
  199. server?.authorizedLoginCompletion({ cloudFiles, finished in
  200. if (!finished) { /// 登录失败
  201. return
  202. }
  203. let serverArr = KMCloudServer.getAllLoginServer()
  204. var currentServer: KMCloudServer?
  205. for server in serverArr! {
  206. if ((server as! KMCloudServer).serverType == KMGoogleDrive) {
  207. currentServer = server
  208. break
  209. }
  210. }
  211. // let userData: KMDropboxUserMetadata = cloudFiles as! KMDropboxUserMetadata
  212. if (currentServer != nil) {
  213. self.accounts.append(currentServer)
  214. self.reloadData()
  215. }
  216. })
  217. }
  218. break
  219. case .OneDrive:
  220. break
  221. }
  222. }
  223. func addCloudsAction() -> Void {
  224. var popViewDataArr: [String] = []
  225. for plate in self.cloudPlates {
  226. popViewDataArr.append(plate.string())
  227. }
  228. let vc: KMHomePopViewController = KMHomePopViewController().initWithPopViewDataArr(popViewDataArr)
  229. let createFilePopover: NSPopover = NSPopover.init()
  230. createFilePopover.contentViewController = vc
  231. createFilePopover.animates = true
  232. createFilePopover.behavior = .transient
  233. createFilePopover.setValue(true, forKey: "shouldHideAnchor")
  234. createFilePopover.show(relativeTo: CGRect(x: addCloudsBox.bounds.origin.x, y: 10, width: addCloudsBox.bounds.size.width, height: addCloudsBox.bounds.size.height), of: addCloudsBox, preferredEdge: .minY)
  235. vc.downCallback = { [weak self](downEntered: Bool, count: String) -> Void in
  236. if self != nil {
  237. if downEntered {
  238. var state: KMCloudDocumentState = .Box
  239. if count == NSLocalizedString("Box", comment: "") {
  240. state = .Box
  241. } else if count == NSLocalizedString("DropBox", comment: "") {
  242. state = .DropBox
  243. } else if count == NSLocalizedString("GoogleDrive", comment: "") {
  244. state = .GoogleDrive
  245. } else if count == NSLocalizedString("OneDrive", comment: "") {
  246. state = .OneDrive
  247. }
  248. self!.loginCloud(state: state)
  249. }
  250. }
  251. }
  252. }
  253. private func showNotNetworkView() {
  254. self.hiddenNotNetworkView()
  255. self.emptyCollectionView.isHidden = true
  256. self.cloudSplitView.isHidden = true
  257. let superview = self.emptyCollectionView.superview
  258. let view = KMCloudNoNetworkView()
  259. let viewH: CGFloat = 220
  260. view.frame = NSMakeRect(0, (NSHeight(superview!.bounds)-viewH)*0.5, (superview?.bounds.size.width)!, viewH)
  261. view.autoresizingMask = [.width, .minYMargin]
  262. superview?.addSubview(view)
  263. view.itemClick = { [weak self] index in
  264. /// 刷新
  265. self?.hiddenNotNetworkView()
  266. self?.reloadData()
  267. }
  268. }
  269. private func hiddenNotNetworkView() {
  270. let superview = self.emptyCollectionView.superview
  271. var flagView: KMCloudNoNetworkView?
  272. for view in superview!.subviews {
  273. if (view is KMCloudNoNetworkView) {
  274. flagView = (view as! KMCloudNoNetworkView)
  275. break
  276. }
  277. }
  278. if (flagView == nil) {
  279. return
  280. }
  281. flagView?.removeFromSuperview()
  282. }
  283. private func showCloudFileEmptyView() {
  284. self.hiddenCloudFileEmptyView()
  285. let superview = self.fileListTableView.enclosingScrollView?.superview
  286. self.fileListTableView.enclosingScrollView!.isHidden = true
  287. let view = KMCloudFileEmptyView()
  288. let viewH: CGFloat = 220
  289. view.frame = NSMakeRect(0, (NSHeight(superview!.bounds)-viewH)*0.5, (superview?.bounds.size.width)!, viewH)
  290. view.autoresizingMask = [.width, .minYMargin]
  291. superview?.addSubview(view)
  292. }
  293. private func hiddenCloudFileEmptyView() {
  294. let superview = self.fileListTableView.enclosingScrollView?.superview
  295. self.fileListTableView.enclosingScrollView!.isHidden = false
  296. var flagView: KMCloudFileEmptyView?
  297. for view in superview!.subviews {
  298. if (view is KMCloudFileEmptyView) {
  299. flagView = (view as! KMCloudFileEmptyView)
  300. break
  301. }
  302. }
  303. if (flagView == nil) {
  304. return
  305. }
  306. flagView?.removeFromSuperview()
  307. }
  308. @objc func accountListTableView_itemClick(sender: NSMenuItem) {
  309. if (self.accountListTableView.selectedRow < self.accounts.count) {
  310. self.logoutAccount(self.accounts[self.accountListTableView.selectedRow] as! KMCloudServer)
  311. }
  312. }
  313. @objc func openFileMenuClick(sender: NSMenuItem) {
  314. if (self.currentAccount == nil) {
  315. return
  316. }
  317. let file: KMServicesCloudFile = self.cloudFiles[sender.tag] as! KMServicesCloudFile
  318. self.fileListBeginLoading()
  319. KMCloudDocumentTools.downloadDocument(self.currentAccount!, file) { finished, fileUrl in
  320. self.fileListEndLoading()
  321. if (finished) {
  322. if !fileUrl.path.isPDFValid() {
  323. let alert = NSAlert()
  324. alert.alertStyle = .critical
  325. alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
  326. alert.runModal()
  327. return
  328. }
  329. NSDocumentController.shared.openDocument(withContentsOf: fileUrl, display: true) { document, result, error in
  330. (document as! KMMainDocument).cloud = true
  331. (document as! KMMainDocument).cloudUploadHanddler = { callback in
  332. KMCloudDocumentTools.uploadDocument(self.currentAccount!, file) { finished, fileUrl in
  333. callback(finished, "")
  334. }
  335. }
  336. }
  337. }
  338. }
  339. }
  340. @objc func openFolderMenuClick(sender: NSMenuItem) {
  341. if (self.currentAccount == nil) {
  342. return
  343. }
  344. let file: KMServicesCloudFile = self.cloudFiles[sender.tag] as! KMServicesCloudFile
  345. self.updateFilesList(self.currentAccount!, file)
  346. }
  347. @objc func fileListTableViewDoubleAction(sender: Any) {
  348. let indexs = self.fileListTableView.selectedRowIndexes
  349. for index in indexs {
  350. let file: KMServicesCloudFile = self.cloudFiles[index] as! KMServicesCloudFile
  351. if (file.filetype == .file) {
  352. if (self.currentAccount == nil) {
  353. continue
  354. }
  355. if (!KMCloudDocumentTools.canOpenDocument(file)) {
  356. continue
  357. }
  358. self.fileListBeginLoading()
  359. KMCloudDocumentTools.downloadDocument(self.currentAccount!, file) { finished, fileUrl in
  360. self.fileListEndLoading()
  361. if (finished) {
  362. NSDocumentController.shared.openDocument(withContentsOf: fileUrl, display: true) { document, result, error in
  363. (document as! KMMainDocument).cloud = true
  364. (document as! KMMainDocument).cloudUploadHanddler = { callback in
  365. KMCloudDocumentTools.uploadDocument(self.currentAccount!, file) { finished, fileUrl in
  366. callback(finished, "")
  367. }
  368. }
  369. }
  370. }
  371. }
  372. } else {
  373. if (self.currentAccount == nil) {
  374. continue
  375. }
  376. self.updateFilesList(self.currentAccount!, file)
  377. }
  378. }
  379. }
  380. private func logoutAccount(_ account: KMCloudServer) {
  381. DispatchQueue.main.async {
  382. let alert = NSAlert()
  383. alert.messageText = NSLocalizedString("Are you Sure Delete“\(account.userEmail!)”?", comment: "")
  384. alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
  385. alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
  386. let response = alert.runModal()
  387. if (response == .alertSecondButtonReturn) { /// 取消
  388. return
  389. }
  390. account.authorizedLogoutCompletion({ [weak self] finished in
  391. if (!finished) {
  392. return
  393. }
  394. var i: Int = 0
  395. for account_ in self!.accounts {
  396. if ((account_ as! KMCloudServer).serverType == account.serverType) {
  397. break
  398. }
  399. i += 1
  400. }
  401. self!.accounts.remove(at: i)
  402. self!.cloudFiles.removeAll()
  403. self!.reloadData()
  404. })
  405. }
  406. }
  407. private func updateFilesList(_ server: KMCloudServer, _ file: KMServicesCloudFile?) {
  408. self.myPathControl.enabled = false
  409. self.fileListBeginLoading()
  410. server.getListWithFilePath(file) { [weak self] fileList, serviceType, error in
  411. if (error != nil) {
  412. self!.myPathControl.enabled = true
  413. return
  414. }
  415. if (fileList == nil) {
  416. self!.myPathControl.enabled = true
  417. return
  418. }
  419. if (file == nil) { /// 切换账号
  420. self?.filepaths.removeAll()
  421. self?.currentAccount = server
  422. } else {
  423. let index = self?.filepaths.firstIndex(of: file!)
  424. if (index == nil) {
  425. self?.filepaths.append(file!)
  426. } else {
  427. let count = self?.filepaths.count
  428. for i in 0 ..< count! {
  429. if (i <= index!) {
  430. continue
  431. }
  432. self?.filepaths.remove(at: i)
  433. }
  434. }
  435. }
  436. self!.pathString = NSLocalizedString("Cloud Documents", comment: "")
  437. for filepath in self!.filepaths {
  438. self!.pathString = self!.pathString.appending("\\\(filepath.fileName!)")
  439. }
  440. self!.myPathControl.urlString = self?.pathString
  441. self?.cloudFiles.removeAll()
  442. for file in fileList! {
  443. self?.cloudFiles.append(file)
  444. }
  445. /// 排序
  446. self?.cloudFiles.sort(by: { file1, file2 in
  447. if ((file1 as! KMServicesCloudFile).filetype == .file) {
  448. if ((file2 as! KMServicesCloudFile).filetype == .file) {
  449. return (file1 as! KMServicesCloudFile).fileName.caseInsensitiveCompare((file2 as! KMServicesCloudFile).fileName) == .orderedAscending
  450. } else {
  451. return false
  452. }
  453. } else {
  454. if ((file2 as! KMServicesCloudFile).filetype == .file) {
  455. return true
  456. } else {
  457. return (file1 as! KMServicesCloudFile).fileName.caseInsensitiveCompare((file2 as! KMServicesCloudFile).fileName) == .orderedAscending
  458. }
  459. }
  460. })
  461. DispatchQueue.main.async {
  462. self?.fileListTableView.reloadData()
  463. if (self?.cloudFiles.count == 0) {
  464. self?.showCloudFileEmptyView()
  465. } else {
  466. self?.hiddenCloudFileEmptyView()
  467. }
  468. self!.myPathControl.enabled = true
  469. self?.fileListEndLoading()
  470. }
  471. }
  472. }
  473. private func fileListBeginLoading() {
  474. self.fileListTableView.enclosingScrollView?.superview!.beginLoading()
  475. }
  476. private func fileListEndLoading() {
  477. self.fileListTableView.enclosingScrollView?.superview?.endLoading()
  478. }
  479. }
  480. // MARK: - NSSplitViewDelegate
  481. extension KMCloudDocumentsViewController: NSSplitViewDelegate {
  482. func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  483. return 170.0
  484. }
  485. func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  486. return 170.0
  487. }
  488. func splitView(_ splitView: NSSplitView, shouldAdjustSizeOfSubview view: NSView) -> Bool {
  489. return false
  490. }
  491. func splitViewDidResizeSubviews(_ notification: Notification) {
  492. let rect = self.cloudSplitView.frame
  493. self.cloudLeftBox.setFrameSize(CGSize(width: 170, height: rect.size.height))
  494. self.cloudRightBox.frame = CGRect(origin: CGPoint(x: 171.0, y: 0), size: CGSize(width: rect.width - 171.0, height: rect.height))
  495. }
  496. func splitView(_ splitView: NSSplitView, constrainSplitPosition proposedPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
  497. return proposedPosition
  498. }
  499. func splitView(_ splitView: NSSplitView, canCollapseSubview subview: NSView) -> Bool {
  500. return false
  501. }
  502. func splitView(_ splitView: NSSplitView, shouldCollapseSubview subview: NSView, forDoubleClickOnDividerAt dividerIndex: Int) -> Bool {
  503. return false
  504. }
  505. func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
  506. return splitView.isEqual(to: self.cloudSplitView)
  507. }
  508. func splitView(_ splitView: NSSplitView, effectiveRect proposedEffectiveRect: NSRect, forDrawnRect drawnRect: NSRect, ofDividerAt dividerIndex: Int) -> NSRect {
  509. return proposedEffectiveRect
  510. }
  511. func splitView(_ splitView: NSSplitView, additionalEffectiveRectOfDividerAt dividerIndex: Int) -> NSRect {
  512. return NSMakeRect(0, 0, 0, 0)
  513. }
  514. }
  515. // MARK: - NSCollectionViewDataSource
  516. extension KMCloudDocumentsViewController: NSCollectionViewDataSource {
  517. func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
  518. if collectionView.isEqual(to: emptyCollectionView) {
  519. return self.cloudPlates.count
  520. }
  521. return 0
  522. }
  523. func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
  524. if collectionView.isEqual(to: emptyCollectionView) {
  525. let item: KMCloudEmptyCollectionViewItem = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMCloudEmptyCollectionViewItem"), for: indexPath) as! KMCloudEmptyCollectionViewItem
  526. let state = self.cloudPlates[indexPath.item]
  527. item.refreshUI(item: state.rawValue)
  528. return item
  529. }
  530. return NSCollectionViewItem.init()
  531. }
  532. }
  533. // MARK: - NSCollectionViewDelegate
  534. extension KMCloudDocumentsViewController: NSCollectionViewDelegate {
  535. func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
  536. if collectionView.isEqual(to: emptyCollectionView) {
  537. let state = self.cloudPlates[indexPaths.first!.item]
  538. loginCloud(state: state)
  539. }
  540. }
  541. }
  542. // MARK: - NSCollectionViewDelegateFlowLayout
  543. extension KMCloudDocumentsViewController: NSCollectionViewDelegateFlowLayout {
  544. func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
  545. if collectionView.isEqual(to: emptyCollectionView) {
  546. return self.emptyCollectionView.itemSize
  547. }
  548. return CGSize(width: 218, height: 224)
  549. }
  550. func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
  551. if collectionView.isEqual(to: emptyCollectionView) {
  552. return self.emptyCollectionView.minimumLineSpacing
  553. }
  554. return 14
  555. }
  556. func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
  557. if collectionView.isEqual(to: emptyCollectionView) {
  558. return self.emptyCollectionView.minimumInteritemSpacing
  559. }
  560. return 14
  561. }
  562. func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, insetForSectionAt section: Int) -> NSEdgeInsets {
  563. if (collectionView.isEqual(to: self.emptyCollectionView)) {
  564. let width: CGFloat = NSWidth(collectionView.superview!.frame)
  565. let height: CGFloat = NSHeight(collectionView.superview!.frame)
  566. let itemSize = self.emptyCollectionView.itemSize
  567. let itemCount: Int = self.emptyCollectionView.numberOfItems(inSection: 0)
  568. let itemHSpace = self.emptyCollectionView.minimumLineSpacing
  569. let itemVSpace = self.emptyCollectionView.minimumInteritemSpacing
  570. var left: CGFloat = (width - itemSize.width * CGFloat(itemCount) - itemHSpace * CGFloat(itemCount-1)) * 0.5
  571. if (left < 0) {
  572. left = 0
  573. }
  574. var top: CGFloat = (height - itemSize.height * CGFloat(itemCount) - itemVSpace * CGFloat(itemCount-1)) * 0.5
  575. if (top < 0) {
  576. top = 0
  577. }
  578. return NSEdgeInsetsMake(top, left, top, left)
  579. }
  580. return NSEdgeInsetsZero
  581. }
  582. }
  583. // MARK: NSTableViewDelegate
  584. extension KMCloudDocumentsViewController: NSTableViewDelegate {
  585. func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
  586. if tableView.isEqual(to: accountListTableView) {
  587. return 57
  588. } else if tableView.isEqual(to: fileListTableView) {
  589. return 75
  590. }
  591. return 0;
  592. }
  593. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  594. let identifier = tableColumn?.identifier
  595. if tableView.isEqual(to: accountListTableView) {
  596. let server: KMCloudServer = self.accounts[row] as! KMCloudServer
  597. let cellView: KMCloudAccountListTableviewCell = tableView.makeView(withIdentifier:identifier!, owner: self) as! KMCloudAccountListTableviewCell
  598. cellView.accountLabel.stringValue = server.userEmail ?? ""
  599. cellView.toolTip = server.userEmail
  600. return cellView
  601. } else if tableView.isEqual(to: fileListTableView) {
  602. let file: KMServicesCloudFile = self.cloudFiles[row] as! KMServicesCloudFile
  603. if identifier == NSUserInterfaceItemIdentifier("name") {
  604. let cellView: KMCloudFileNameListTableviewCell = tableView.makeView(withIdentifier:identifier!, owner: self) as! KMCloudFileNameListTableviewCell
  605. if (file.filetype == .file) {
  606. let fileType = KMCloudDocumentTools.getFileType(self.currentAccount!, file)
  607. let image = NSWorkspace.shared.icon(forFileType: fileType)
  608. cellView.fileImageView.image = image
  609. cellView.subtitleLabel.stringValue = fileType
  610. } else {
  611. cellView.fileImageView.image = NSImage(named: NSImage.folderName)
  612. cellView.subtitleLabel.stringValue = "Folders"
  613. }
  614. cellView.titleLabel.stringValue = file.fileName
  615. return cellView
  616. } else if identifier == NSUserInterfaceItemIdentifier("modifyTime") {
  617. let cellView: KMCloudFileModifyTimeListTableviewCell = tableView.makeView(withIdentifier:identifier!, owner: self) as! KMCloudFileModifyTimeListTableviewCell
  618. if (file.fileModiDateString != nil) {
  619. cellView.modifyTimeLabel.stringValue = KMCloudDocumentTools.parseDate(file.fileModiDate)
  620. } else {
  621. cellView.modifyTimeLabel.stringValue = ""
  622. }
  623. return cellView
  624. } else if identifier == NSUserInterfaceItemIdentifier("size") {
  625. let cellView: KMCloudFileSizeListTableviewCell = tableView.makeView(withIdentifier:identifier!, owner: self) as! KMCloudFileSizeListTableviewCell
  626. if (file.filetype == .file) {
  627. cellView.sizeLabel.stringValue = file.fileSizeString
  628. } else {
  629. cellView.sizeLabel.stringValue = ""
  630. }
  631. return cellView
  632. } else {
  633. let cellView: KMCloudFileNameListTableviewCell = tableView.makeView(withIdentifier:identifier!, owner: self) as! KMCloudFileNameListTableviewCell
  634. return cellView
  635. }
  636. } else {
  637. let cellView: KMCloudAccountListTableviewCell = tableView.makeView(withIdentifier:identifier!, owner: self) as! KMCloudAccountListTableviewCell
  638. return cellView
  639. }
  640. }
  641. func tableViewSelectionDidChange(_ notification: Notification) {
  642. let tableView = notification.object as! NSTableView
  643. if tableView.isEqual(to: accountListTableView) {
  644. let server: KMCloudServer = self.accounts[self.accountListTableView.selectedRow] as! KMCloudServer
  645. self.updateFilesList(server, nil)
  646. self.pathString = NSLocalizedString("Cloud Documents", comment: "")
  647. self.myPathControl.urlString = self.pathString
  648. } else if tableView.isEqual(to: fileListTableView) {}
  649. }
  650. }
  651. // MARK: NSTableViewDataSource
  652. extension KMCloudDocumentsViewController: NSTableViewDataSource {
  653. func numberOfRows(in tableView: NSTableView) -> Int {
  654. if tableView.isEqual(to: accountListTableView) {
  655. return self.accounts.count
  656. } else if tableView.isEqual(to: fileListTableView) {
  657. return self.cloudFiles.count
  658. }
  659. return 0
  660. }
  661. }
  662. extension KMCloudDocumentsViewController: KMLoadingProtocol {
  663. func beginLoading() {
  664. self.view.beginLoading()
  665. }
  666. func endLoading() {
  667. self.view.endLoading()
  668. }
  669. }
  670. extension KMCloudDocumentsViewController: KMMenuTableViewDelegate {
  671. func km_menu(for event: NSEvent) -> NSMenu? {
  672. let point = self.fileListTableView.convert(event.locationInWindow, from: nil)
  673. let index = self.fileListTableView.row(at: point)
  674. if (index < 0) { /// 空白处
  675. return nil
  676. }
  677. let file: KMServicesCloudFile = self.cloudFiles[index] as! KMServicesCloudFile
  678. if (file.filetype == .folder) {
  679. let menu = NSMenu(title: "")
  680. let editItem = NSMenuItem(title: NSLocalizedString("Open Folder", comment: ""), action: #selector(openFolderMenuClick), keyEquivalent: "")
  681. editItem.target = self
  682. editItem.tag = index
  683. menu.addItem(editItem)
  684. return menu
  685. }
  686. if (file.filetype == .file) {
  687. let fileExtension: String = file.fileName.components(separatedBy: ".").last!
  688. if (fileExtension.lowercased() != "pdf") {
  689. return nil
  690. }
  691. let menu = NSMenu(title: "")
  692. let editItem = NSMenuItem(title: NSLocalizedString("Open File", comment: ""), action: #selector(openFileMenuClick), keyEquivalent: "")
  693. editItem.target = self
  694. editItem.tag = index
  695. menu.addItem(editItem)
  696. return menu
  697. }
  698. return nil
  699. }
  700. }