SettingsGeneralView.swift 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. //
  2. // SettingsGeneralView.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by Niehaoyu on 2024/9/26.
  6. //
  7. import Cocoa
  8. import AppKit
  9. import KMComponentLibrary
  10. class SettingsGeneralView: BaseXibView {
  11. @IBOutlet weak var appearanceLabel: NSTextField!
  12. @IBOutlet weak var authorLabel: NSTextField!
  13. @IBOutlet weak var authorInputView: ComponentInput!
  14. @IBOutlet weak var defaultSettingLabel: NSTextField!
  15. @IBOutlet weak var defaultPDFViewerCheckbox: ComponentCheckBox!
  16. @IBOutlet weak var reopenFileCheckBox: ComponentCheckBox!
  17. @IBOutlet weak var autosaveCheckBox: ComponentCheckBox!
  18. @IBOutlet weak var autosaveInputNumberView: ComponentInputNumber!
  19. @IBOutlet weak var autosaveLabel: NSTextField!
  20. @IBOutlet weak var defaultViewerBoxWidthConst: NSLayoutConstraint!
  21. @IBOutlet weak var reopenBoxWidthConst: NSLayoutConstraint!
  22. @IBOutlet weak var autosaveBoxWidthConst: NSLayoutConstraint!
  23. @IBOutlet weak var filelistLabel: NSTextField!
  24. @IBOutlet weak var filelistInputNumberView: ComponentInputNumber!
  25. @IBOutlet weak var filelistSubLabel: NSTextField!
  26. @IBOutlet weak var languageLabel: NSTextField!
  27. @IBOutlet weak var languageSelectView: ComponentSelect!
  28. @IBOutlet weak var sepDividerView: ComponentDivider!
  29. @IBOutlet weak var resetWarningLabel: NSTextField!
  30. @IBOutlet weak var resetWarningButton: ComponentButton!
  31. @IBOutlet weak var resetWarningBtnWidthConst: NSLayoutConstraint!
  32. @IBOutlet weak var savePasswordLabel: NSTextField!
  33. @IBOutlet weak var savePWAskRadio: ComponentRadio!
  34. @IBOutlet weak var savePWAlwaysRadio: ComponentRadio!
  35. @IBOutlet weak var savePWNeverRadio: ComponentRadio!
  36. @IBOutlet weak var savePWAskRadioWidthConst: NSLayoutConstraint!
  37. @IBOutlet weak var savePWAlwaysRadioWidthConst: NSLayoutConstraint!
  38. deinit {
  39. NotificationCenter.default.removeObserver(self)
  40. }
  41. override func draw(_ dirtyRect: NSRect) {
  42. super.draw(dirtyRect)
  43. // Drawing code here.
  44. self.setUp()
  45. self.reloadData()
  46. }
  47. public required init?(coder decoder: NSCoder) {
  48. super.init(coder: decoder)
  49. }
  50. override init(frame frameRect: NSRect) {
  51. super.init(frame: frameRect)
  52. }
  53. public override func awakeFromNib() {
  54. super.awakeFromNib()
  55. }
  56. override func updateUIThemeColor() {
  57. super.updateUIThemeColor()
  58. self.setUp()
  59. }
  60. func setUp() {
  61. var titleLabelColor: NSColor = NSColor.labelColor
  62. if let value = ComponentLibrary.shared.getComponentValueFromKey("colorText/2") {
  63. let currentValue = value as! [String : Any]
  64. titleLabelColor = ComponentLibrary.shared.getColor(rgbaDict: currentValue)
  65. }
  66. var titleLabelFont: NSFont = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
  67. //Appearance
  68. self.appearanceLabel.stringValue = KMLocalizedString("Appearance", comment: "")
  69. self.appearanceLabel.textColor = titleLabelColor
  70. self.appearanceLabel.font = titleLabelFont
  71. //Author
  72. self.authorLabel.stringValue = KMLocalizedString("Author", comment: "")
  73. self.authorLabel.textColor = titleLabelColor
  74. self.authorLabel.font = titleLabelFont
  75. self.authorInputView.properties = ComponentInputProperty(size: .s,
  76. state: .normal,
  77. isError: false,
  78. showPrefix: false,
  79. showSuffix: false,
  80. showClear: true,
  81. isDisabled: false,
  82. placeholder: KMLocalizedString("Author", comment: ""),
  83. text: SettingsManager.sharedInstance.author,
  84. alignment: .left)
  85. authorInputView.delegate = self
  86. // Default Settings
  87. defaultSettingLabel.stringValue = KMLocalizedString("Default Settings", comment: "")
  88. defaultSettingLabel.textColor = titleLabelColor
  89. defaultSettingLabel.font = titleLabelFont
  90. defaultPDFViewerCheckbox.properties = ComponentCheckBoxProperty(size: .s,
  91. state: .normal,
  92. isDisabled: false,
  93. showhelp: false,
  94. text: KMLocalizedString("Set PDF Reader Pro as the default PDF viewer", comment: ""),
  95. checkboxType: SettingsManager.sharedInstance.defaultPDFViewer ? .selected : .normal)
  96. reopenFileCheckBox.properties = ComponentCheckBoxProperty(size: .s,
  97. state: .normal,
  98. isDisabled: false,
  99. showhelp: false,
  100. text: KMLocalizedString("Reopen last open files at startup", comment: ""),
  101. checkboxType: SettingsManager.sharedInstance.reopenFileWhenAppStart ? .selected : .normal)
  102. autosaveCheckBox.properties = ComponentCheckBoxProperty(size: .s,
  103. state: .normal,
  104. isDisabled: false,
  105. showhelp: false,
  106. text: KMLocalizedString("Automatically save the document every", comment: ""),
  107. checkboxType: SettingsManager.sharedInstance.autoSaveFile ? .selected : .normal)
  108. autosaveInputNumberView.properties = ComponentInputNumberProperty(alignment: .left,
  109. size: .s,
  110. state: .normal,
  111. isError: false,
  112. showErrorInfo: false,
  113. isDisabled: SettingsManager.sharedInstance.autoSaveFile == false,
  114. showPrefix: false,
  115. showSuffix: false,
  116. minSize: 5,
  117. maxSize: 99,
  118. text: SettingsManager.sharedInstance.autoSaveMinutes)
  119. autosaveInputNumberView.delegate = self
  120. autosaveLabel.stringValue = KMLocalizedString("minutes(5-99)", comment: "")
  121. defaultViewerBoxWidthConst.constant = defaultPDFViewerCheckbox.properties.propertyInfo.viewWidth
  122. reopenBoxWidthConst.constant = reopenFileCheckBox.properties.propertyInfo.viewWidth
  123. autosaveBoxWidthConst.constant = autosaveCheckBox.properties.propertyInfo.viewWidth
  124. filelistLabel.stringValue = KMLocalizedString("Documents in recently used list:", comment: "")
  125. filelistInputNumberView.properties = ComponentInputNumberProperty(alignment: .left,
  126. size: .s,
  127. state: .normal,
  128. isError: false,
  129. showErrorInfo: false,
  130. isDisabled: false,
  131. showPrefix: false,
  132. showSuffix: false,
  133. minSize: 10,
  134. maxSize: 50,
  135. text: String(SettingsManager.sharedInstance.fileListCount))
  136. filelistInputNumberView.delegate = self
  137. filelistSubLabel.stringValue = "(10-50)"
  138. defaultPDFViewerCheckbox.setTarget(self, action: #selector(defaultSettingAction(_:)))
  139. reopenFileCheckBox.setTarget(self, action: #selector(defaultSettingAction(_:)))
  140. autosaveCheckBox.setTarget(self, action: #selector(defaultSettingAction(_:)))
  141. // Language
  142. languageLabel.stringValue = KMLocalizedString("Language", comment: "")
  143. languageLabel.textColor = titleLabelColor
  144. languageLabel.font = titleLabelFont
  145. languageSelectView.properties = ComponentSelectProperties(size: .s,
  146. state: .normal,
  147. isDisabled: false,
  148. isError: false,
  149. leftIcon: false,
  150. placeholder: nil,
  151. errorText: nil,
  152. creatable: false,
  153. text: "English")
  154. if true {
  155. let languageArr = ["Follow System", "English", "Chinese_CN", "Chinese_TW", "Dutch", "French", "Spanish", "German", "Russian", "Italian", "Japanese"]
  156. var menuItemArr: [ComponentMenuitemProperty] = []
  157. for language in languageArr {
  158. let itemProperty: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
  159. itemSelected: false,
  160. isDisabled: false,
  161. keyEquivalent: nil,
  162. text: language)
  163. menuItemArr.append(itemProperty)
  164. }
  165. languageSelectView.updateMenuItemsArr(menuItemArr)
  166. }
  167. languageSelectView.delegate = self
  168. sepDividerView.properties = ComponentDividerProperty(type: .horizontal, dash: false)
  169. resetWarningLabel.stringValue = KMLocalizedString("Reset All Warnings:", comment: "")
  170. if let value = ComponentLibrary.shared.getComponentValueFromKey("comp-form/colorText-label") {
  171. let currentValue = value as! [String : Any]
  172. resetWarningLabel.textColor = ComponentLibrary.shared.getColor(rgbaDict: currentValue)
  173. } else {
  174. resetWarningLabel.textColor = NSColor.labelColor
  175. }
  176. resetWarningButton.properties = ComponentButtonProperty(type: .default_tertiary,
  177. size: .s,
  178. state: .normal,
  179. isDisable: false,
  180. onlyIcon: false,
  181. showLeftIcon: false,
  182. showRightIcon: false,
  183. buttonText: KMLocalizedString("Reset"),
  184. keepPressState: false)
  185. resetWarningBtnWidthConst.constant = resetWarningButton.properties.propertyInfo.viewWidth
  186. resetWarningButton.setTarget(self, action: #selector(resetWarningAction(_:)))
  187. //
  188. savePasswordLabel.stringValue = KMLocalizedString("Save passwords in Keychain:", comment: "")
  189. savePasswordLabel.textColor = resetWarningLabel.textColor
  190. savePWAskRadio.properties = ComponentCheckBoxProperty(size: .s,
  191. state: .normal,
  192. isDisabled: false,
  193. showhelp: false,
  194. text: KMLocalizedString("Ask", comment: ""),
  195. checkboxType: .normal)
  196. savePWAlwaysRadio.properties = ComponentCheckBoxProperty(size: .s,
  197. state: .normal,
  198. isDisabled: false,
  199. showhelp: false,
  200. text: KMLocalizedString("Always", comment: ""),
  201. checkboxType: .normal)
  202. savePWNeverRadio.properties = ComponentCheckBoxProperty(size: .s,
  203. state: .normal,
  204. isDisabled: false,
  205. showhelp: false,
  206. text: KMLocalizedString("Never", comment: ""),
  207. checkboxType: .normal)
  208. savePWAskRadioWidthConst.constant = savePWAskRadio.properties.propertyInfo.viewWidth
  209. savePWAlwaysRadioWidthConst.constant = savePWAlwaysRadio.properties.propertyInfo.viewWidth
  210. savePWAskRadio.setTarget(self, action: #selector(savePWClicked(_:)))
  211. savePWAlwaysRadio.setTarget(self, action: #selector(savePWClicked(_:)))
  212. savePWNeverRadio.setTarget(self, action: #selector(savePWClicked(_:)))
  213. }
  214. func reloadData() {
  215. //Default Settings
  216. defaultPDFViewerCheckbox.properties.checkboxType = SettingsManager.sharedInstance.defaultPDFViewer ? .selected : .normal
  217. defaultPDFViewerCheckbox.reloadData()
  218. reopenFileCheckBox.properties.checkboxType = SettingsManager.sharedInstance.reopenFileWhenAppStart ? .selected : .normal
  219. reopenFileCheckBox.reloadData()
  220. resetWarningButton.properties.isDisabled = SettingsManager.sharedInstance.resetDefaultWaringKeyEnable() ? false : true
  221. resetWarningButton.reloadData()
  222. autosaveCheckBox.properties.checkboxType = SettingsManager.sharedInstance.autoSaveFile ? .selected : .normal
  223. autosaveCheckBox.reloadData()
  224. autosaveInputNumberView.properties.isDisabled = SettingsManager.sharedInstance.autoSaveFile == false
  225. autosaveInputNumberView.properties.text = SettingsManager.sharedInstance.autoSaveMinutes
  226. autosaveInputNumberView.reloadData()
  227. filelistInputNumberView.properties.text = String(SettingsManager.sharedInstance.fileListCount)
  228. filelistInputNumberView.reloadData()
  229. languageSelectView.selectItemAtIndex(SettingsManager.sharedInstance.language.rawValue)
  230. savePWAskRadio.properties.checkboxType = .normal
  231. savePWAlwaysRadio.properties.checkboxType = .normal
  232. savePWNeverRadio.properties.checkboxType = .normal
  233. if SettingsManager.sharedInstance.keychainType == .ask {
  234. savePWAskRadio.properties.checkboxType = .selected
  235. } else if SettingsManager.sharedInstance.keychainType == .always {
  236. savePWAlwaysRadio.properties.checkboxType = .selected
  237. } else if SettingsManager.sharedInstance.keychainType == .never {
  238. savePWNeverRadio.properties.checkboxType = .selected
  239. }
  240. savePWAskRadio.reloadData()
  241. savePWAlwaysRadio.reloadData()
  242. savePWNeverRadio.reloadData()
  243. }
  244. func close() {
  245. SettingsManager.sharedInstance.author = authorInputView.properties.text
  246. }
  247. //MARK: - Action
  248. @objc func defaultSettingAction(_ sender: NSView) {
  249. if sender == defaultPDFViewerCheckbox {
  250. SettingsManager.sharedInstance.defaultPDFViewer = defaultPDFViewerCheckbox.properties.checkboxType == .selected
  251. } else if sender == reopenFileCheckBox {
  252. SettingsManager.sharedInstance.reopenFileWhenAppStart = reopenFileCheckBox.properties.checkboxType == .selected
  253. } else if sender == autosaveCheckBox {
  254. SettingsManager.sharedInstance.autoSaveFile = autosaveCheckBox.properties.checkboxType == .selected
  255. }
  256. self.reloadData()
  257. }
  258. @objc func savePWClicked(_ sender: NSView) {
  259. if sender == savePWAskRadio {
  260. SettingsManager.sharedInstance.keychainType = .ask
  261. } else if sender == savePWAlwaysRadio {
  262. SettingsManager.sharedInstance.keychainType = .always
  263. } else if sender == savePWNeverRadio {
  264. SettingsManager.sharedInstance.keychainType = .never
  265. }
  266. self.reloadData()
  267. }
  268. @objc func resetWarningAction(_ sender: ComponentButton) {
  269. let alert = NSAlert()
  270. alert.alertStyle = .warning
  271. alert.messageText = KMLocalizedString("Are you sure you want to reset all Warnings?")
  272. alert.addButton(withTitle: KMLocalizedString("Confirm"))
  273. alert.addButton(withTitle: KMLocalizedString("Cancel"))
  274. alert.beginSheetModal(for: self.window!, completionHandler: { (response) in
  275. if response == .alertFirstButtonReturn {
  276. for string in SettingsManager.sharedInstance.resetDefaultWaringKeys {
  277. UserDefaults.standard.removeObject(forKey: string)
  278. }
  279. UserDefaults.standard.synchronize()
  280. self.reloadData()
  281. }
  282. })
  283. }
  284. //MARK: - Mouse Event
  285. override func mouseDown(with event: NSEvent) {
  286. super.mouseDown(with: event)
  287. self.window?.makeFirstResponder(nil)
  288. }
  289. }
  290. extension SettingsGeneralView: ComponentInputDelegate {
  291. func componentInputDidEndEditing(inputView: ComponentInput) {
  292. if inputView == authorInputView {
  293. SettingsManager.sharedInstance.author = inputView.properties.text
  294. }
  295. }
  296. }
  297. extension SettingsGeneralView: ComponentInputNumberDelegate {
  298. func componentInputNumberDidValueChanged(inputNumber: ComponentInputNumber?) {
  299. if inputNumber == autosaveInputNumberView {
  300. SettingsManager.sharedInstance.autoSaveMinutes = autosaveInputNumberView.properties.text
  301. } else if inputNumber == filelistInputNumberView {
  302. let text: String = filelistInputNumberView.properties.text
  303. SettingsManager.sharedInstance.fileListCount = Int(text)!
  304. }
  305. self.reloadData()
  306. }
  307. }
  308. extension SettingsGeneralView: ComponentSelectDelegate {
  309. func componentSelectDidSelect(view: ComponentSelect?, menuItemProperty: ComponentMenuitemProperty?) {
  310. let selectIndex: NSInteger = view?.indexOfSelect() ?? 0
  311. if let _ = menuItemProperty {
  312. if selectIndex >= 0 {
  313. let language = settingsLanguage(rawValue: selectIndex) ?? .FollowSystem
  314. if SettingsManager.sharedInstance.language != language {
  315. SettingsManager.sharedInstance.language = language
  316. NotificationCenter.default.post(name: APPLanguageChangedNotificationName, object: nil)
  317. self.setUp()
  318. self.reloadData()
  319. }
  320. }
  321. }
  322. }
  323. }