TestCaseCellView.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //
  2. // TeseCaseCell.swift
  3. // KdanAuto
  4. //
  5. // Created by 朱东勇 on 2022/11/21.
  6. //
  7. import Foundation
  8. import AppKit
  9. public protocol TestCaseCellViewDelegate : NSObjectProtocol {
  10. func selectKeyDidUpdate(_ cell:NSTableCellView?)
  11. }
  12. class TestCaseCellView : NSTableCellView, NSMenuDelegate {
  13. @IBOutlet var _titleLbl : NSTextField!
  14. @IBOutlet var _markLbl : NSTextField!
  15. @IBOutlet var _keyContentView : NSView!
  16. @IBOutlet var _sepLine : NSView!
  17. @IBOutlet var _activityView : ActivityView!
  18. @IBOutlet var _reportBtn : NSButton!
  19. @IBOutlet var _toggleBtn : NSButton!
  20. var _keyViews : NSMutableArray!
  21. var _autoTestObj : AutoTest?
  22. var _title : String!
  23. var _checkKeys : NSArray!
  24. // Menu Item
  25. var m_modifyItem:NSMenuItem!
  26. var m_clearOriginItem:NSMenuItem!
  27. var m_clearCheckItem:NSMenuItem!
  28. var m_clearResultItem:NSMenuItem!
  29. var m_deleteItem:NSMenuItem!
  30. var delegate : TestCaseCellViewDelegate?
  31. class func shared() -> TestCaseCellView? {
  32. var objects : NSArray!
  33. Bundle.main.loadNibNamed("TestCaseCellView", owner: nil, topLevelObjects: &objects)
  34. for tView in objects {
  35. if let tv = tView as? TestCaseCellView {
  36. return tv
  37. }
  38. }
  39. return nil
  40. }
  41. override func awakeFromNib() {
  42. _sepLine.wantsLayer = true;
  43. _sepLine.layer?.backgroundColor = NSColor.lightGray.cgColor
  44. // Add Advanced Setting Menu
  45. let _menu = NSMenu(title: "")
  46. m_modifyItem = NSMenuItem.init(title: "高级设置",
  47. action:#selector(self.setting(_:)), keyEquivalent: "")
  48. m_modifyItem.target = self;
  49. _menu.addItem(m_modifyItem)
  50. _menu.addItem(NSMenuItem.separator())
  51. m_clearOriginItem = NSMenuItem.init(title: "清除原文件",
  52. action:#selector(self.clearOrigin(_:)), keyEquivalent: "")
  53. m_clearOriginItem.target = self;
  54. _menu.addItem(m_clearOriginItem)
  55. m_clearResultItem = NSMenuItem.init(title: "清除结果文件",
  56. action:#selector(self.clearResult(_:)), keyEquivalent: "")
  57. m_clearResultItem.target = self;
  58. _menu.addItem(m_clearResultItem)
  59. m_clearCheckItem = NSMenuItem.init(title: "清除对照文件",
  60. action:#selector(self.clearCheck(_:)), keyEquivalent: "")
  61. m_clearCheckItem.target = self;
  62. _menu.addItem(m_clearCheckItem)
  63. _menu.addItem(NSMenuItem.separator())
  64. m_deleteItem = NSMenuItem.init(title: "删除测试项",
  65. action:#selector(self.delete(_:)), keyEquivalent: "")
  66. m_deleteItem.target = self;
  67. _menu.addItem(m_deleteItem)
  68. self.menu = _menu
  69. self.menu?.delegate = self;
  70. // Add right mouse event monitor
  71. NSEvent.addLocalMonitorForEvents(matching: NSEvent.EventTypeMask.rightMouseUp) { event in
  72. var point = event.locationInWindow;
  73. if (nil != self.window?.contentView) {
  74. point = self.window!.contentView!.convert(point, to: self)
  75. if (event.type == .rightMouseUp &&
  76. CGRectContainsPoint(self.bounds, point) &&
  77. (self.autoTestObj()?.status() == .Normal ||
  78. self.autoTestObj()?.status() == .Finished)) {
  79. NSMenu.popUpContextMenu(self.menu!, with: event, for: self)
  80. return nil;
  81. }
  82. }
  83. return event
  84. }
  85. }
  86. // Setter & Getter
  87. public func setTitle(_ title:String) {
  88. _title = title;
  89. _titleLbl.stringValue = _title ?? ""
  90. let size = _titleLbl.sizeThatFits(_titleLbl.frame.size);
  91. _markLbl.frame = CGRectMake(_titleLbl.frame.origin.x + size.width,
  92. _titleLbl.frame.origin.y,
  93. _titleLbl.frame.size.width - size.width,
  94. _titleLbl.frame.size.height)
  95. }
  96. public func title() -> String? {
  97. return _title
  98. }
  99. let kTFDefaultHeight = 22.0
  100. public func setCheckKeys(_ keys:NSArray) {
  101. _checkKeys = keys;
  102. if _keyViews == nil {
  103. _keyViews = NSMutableArray()
  104. }
  105. while (_keyViews.count != _checkKeys.count) {
  106. if (_keyViews.count > _checkKeys.count) {
  107. (_keyViews.lastObject as! NSTextField).removeFromSuperview()
  108. _keyViews.removeLastObject()
  109. }else {
  110. let tf = NSTextField.init(frame: CGRectMake(0, 4, 30, kTFDefaultHeight));
  111. _keyContentView.addSubview(tf);
  112. tf.backgroundColor = .clear
  113. _keyViews.add(tf)
  114. }
  115. }
  116. var width = 0.0;
  117. // update key view's frame
  118. for tf in NSArray(array: _keyViews) {
  119. let i = _keyViews.index(of: tf)
  120. let tfView = tf as! NSTextField
  121. tfView.stringValue = _checkKeys[i] as! String;
  122. tfView.sizeToFit()
  123. tfView.setFrameOrigin(NSPoint.init(x: width, y: 0))
  124. tfView.setFrameSize(NSSize.init(width: (tfView.frame.size.width.advanced(by: 2.0)), height: kTFDefaultHeight));
  125. tfView.autoresizingMask = .maxXMargin.union(.maxYMargin)
  126. tfView.wantsLayer = true
  127. tfView.layer?.cornerRadius = 8
  128. tfView.layer?.backgroundColor = NSColor.clear.cgColor
  129. tfView.layer?.borderColor = NSColor.lightGray.withAlphaComponent(0.6).cgColor
  130. tfView.layer?.borderWidth = 1
  131. tfView.isEditable = false
  132. width = width + tfView.frame.size.width + 3
  133. }
  134. // _keyContentView.frame = NSRect(x: 0, y: 0, width: width, height: kTFDefaultHeight)
  135. // _keyContentView.setFrameSize(NSSize.init(width: width, height: kTFDefaultHeight))
  136. // update Toggle status
  137. if _checkKeys.count == 0 {
  138. _toggleBtn.image = NSImage(named: "Toggle_off.png")
  139. }else if _checkKeys.count != _autoTestObj?.keys().count {
  140. _toggleBtn.image = NSImage(named: "Toggle_half.png")
  141. }else {
  142. _toggleBtn.image = NSImage(named: "Toggle_on.png")
  143. }
  144. }
  145. public func checkKeys() -> NSArray? {
  146. return _checkKeys;
  147. }
  148. public func autoTestObj() -> AutoTest? {
  149. return _autoTestObj
  150. }
  151. public func setAutoTestObj(_ obj: AutoTest?) {
  152. _autoTestObj = obj
  153. // self.setAccessibilityEnabled((_autoTestObj?.isOriginFileExist() == true && _autoTestObj?.isCheckFileExist() == true))
  154. if nil != _autoTestObj {
  155. self.setTitle((_autoTestObj?.name())!)
  156. self.setCheckKeys((_autoTestObj?.selectedKeys())!)
  157. // set the mark for (converter of) old library
  158. let useOldLibValue = _autoTestObj?.params().value(forKey: "useOldLib")
  159. var useOldLib = false
  160. if nil != useOldLibValue {
  161. if (useOldLibValue as? String) != nil {
  162. useOldLib = NSString(string: (useOldLibValue as! String)).boolValue
  163. }else if (useOldLibValue as? NSNumber) != nil {
  164. useOldLib = (useOldLibValue as! NSNumber).boolValue
  165. }
  166. }
  167. _markLbl.isHidden = useOldLib
  168. }else {
  169. self.setTitle("")
  170. self.setCheckKeys([])
  171. _markLbl.isHidden = true;
  172. // self.wantsLayer = true
  173. // self.layer?.opacity = 0.5
  174. }
  175. updateStatus()
  176. }
  177. public func updateStatus() {
  178. _activityView.setDegree(_autoTestObj?.degree() ?? 0)
  179. _activityView.setActivityStatus(ActivityStatus(rawValue: (_autoTestObj?.status())!.rawValue) ?? .Normal)
  180. _reportBtn.isHidden = (ActivityStatus(rawValue: (_autoTestObj?.status())!.rawValue) ?? .Normal) != .Finished
  181. }
  182. // IBAction
  183. @IBAction func toggleAction(_ sender:NSButton) {
  184. if _autoTestObj != nil {
  185. if _checkKeys.count == 0 {
  186. _autoTestObj?.setSelectedKeys((_autoTestObj?.keys())!)
  187. }else if _checkKeys.count != _autoTestObj?.keys().count {
  188. _autoTestObj?.setSelectedKeys((_autoTestObj?.keys())!)
  189. }else {
  190. _autoTestObj?.setSelectedKeys([])
  191. }
  192. self.setCheckKeys((_autoTestObj?.selectedKeys())!)
  193. if delegate != nil {
  194. delegate?.selectKeyDidUpdate(self)
  195. }
  196. }
  197. }
  198. @IBAction func showCompareReportAction(_ sender:NSButton) {
  199. // show compare report
  200. let files = _autoTestObj?.compareFiles() ?? []
  201. if nil != files && files.count > 0 {
  202. if (_autoTestObj as? StringAutoTest) != nil {
  203. var compareVC = StringCompareViewController.shared()
  204. compareVC.setFiles(files)
  205. let point = sender.convert(CGPoint(x: 0, y: 0),
  206. to: self.window?.contentView ?? self)
  207. compareVC.showIn(self.window?.contentView ?? self, rect: NSRect.init(origin: point, size: sender.frame.size))
  208. }else {
  209. var compareVC = CompareViewController.shared()
  210. compareVC.setFiles(files)
  211. let point = sender.convert(CGPoint(x: 0, y: 0),
  212. to: self.window?.contentView ?? self)
  213. compareVC.showIn(self.window?.contentView ?? self, rect: NSRect.init(origin: point, size: sender.frame.size))
  214. }
  215. }
  216. return
  217. }
  218. @IBAction func setting(_ sender:NSMenuItem) {
  219. // show property setting for current test case
  220. if (_autoTestObj != nil) {
  221. let vc = AdvanceSettingViewController.shared()
  222. let info = AdvanceSettingViewController.baseInfoFor(_autoTestObj!._fileType)
  223. if (info != nil) {
  224. vc.m_fileType = _autoTestObj!._fileType
  225. vc.setBaseInfo(info!)
  226. vc.setTestCase(_autoTestObj!.m_info as! NSDictionary)
  227. vc.m_testObj = _autoTestObj
  228. let callback:(_ testObj:AutoTest?, _ property:NSDictionary) -> () = { obj, property in
  229. obj?.update(property)
  230. }
  231. vc.setCallback(callback)
  232. let point = self.convert(CGPoint(x: 0, y: 0),
  233. to: self.window?.contentView ?? self)
  234. vc.showIn(self.window?.contentView ?? self, rect: NSRect.init(origin: point, size: self.frame.size))
  235. }
  236. }
  237. }
  238. @IBAction func clearOrigin(_ sender:NSMenuItem) {
  239. // clear all origin files for current test case
  240. if (_autoTestObj != nil) {
  241. _autoTestObj?.clearOriginFiles()
  242. }
  243. }
  244. @IBAction func clearResult(_ sender:NSMenuItem) {
  245. // clear all result files for current test case
  246. if (_autoTestObj != nil) {
  247. _autoTestObj?.clearCacheFiles()
  248. }
  249. }
  250. @IBAction func clearCheck(_ sender:NSMenuItem) {
  251. // clear all refrence files for current test case
  252. if (_autoTestObj != nil) {
  253. _autoTestObj?.clearCompareFiles()
  254. }
  255. }
  256. @IBAction func delete(_ sender:NSMenuItem) {
  257. // delete current test case
  258. _autoTestObj?.delete()
  259. }
  260. }