source: launchers/macosx/I2PLauncher/Utils/Preferences.swift @ 36a5790

Last change on this file since 36a5790 was 36a5790, checked in by meeh <meeh@…>, 2 years ago

Mac OS X Launcher: Misc minor updates to Preferences

  • Property mode set to 100644
File size: 8.7 KB
Line 
1//
2//  Preferences.swift
3//  I2PLauncher
4//
5//  Created by Mikal Villa on 01/12/2018.
6//  Copyright © 2018 The I2P Project. All rights reserved.
7//
8
9import Foundation
10
11class PreferenceRow {
12  var name: String?
13  var defaultValue: Any?
14  var selectedValue: Any?
15 
16  init(_ name: String, _ value: Any?, _ defaultVal: Any? = "") {
17    self.name = name
18    self.selectedValue = value
19    self.defaultValue = defaultVal
20  }
21 
22  func asRawValue() -> Any {
23    return self.selectedValue ?? self.defaultValue!
24  }
25}
26
27class Preferences  : NSObject {
28  private var prefObject: Dictionary<String,Any> = Dictionary<String,Any>()
29  private var prefDict = Dictionary<String,PreferenceRow>()
30  private var prefDefaultDict: Dictionary<String,Any> = Dictionary<String,Any>()
31 
32  var count: Int = 0
33 
34  // Interface with a string setting in background
35  var showAsIconMode: PreferencesViewController.ShowAsMode {
36    get {
37      var mode = self["I2Pref_showAsIconMode"]
38      if (mode == nil) {
39        mode = "bothIcon"
40      }
41      switch (mode as! String) {
42      case "bothIcon":
43        return PreferencesViewController.ShowAsMode.bothIcon
44      case "dockIcon":
45        return PreferencesViewController.ShowAsMode.dockIcon
46      case "menubarIcon":
47        return PreferencesViewController.ShowAsMode.menubarIcon
48      default:
49        return PreferencesViewController.ShowAsMode.bothIcon
50      }
51    }
52    set(newVal) {
53      //
54      var newMode: String = "bothIcon"
55      switch newVal {
56      case .bothIcon:
57        newMode = "bothIcon"
58      case .menubarIcon:
59        newMode = "menubarIcon"
60      case .dockIcon:
61        newMode = "dockIcon"
62      }
63      self["I2Pref_showAsIconMode"] = newMode
64      self.syncPref()
65    }
66  }
67
68  // Lookup by name
69  subscript(prefName:String) -> Any? {
70    get  {
71      return prefObject[prefName]
72    }
73    set(newValue) {
74      prefObject[prefName] = newValue
75      prefDict[prefName] = PreferenceRow(prefName, newValue, prefDefaultDict[prefName])
76      self.syncPref()
77    }
78  }
79 
80  func syncPref() {
81    UserDefaults.standard.setPersistentDomain(self.prefObject, forName: APPDOMAIN)
82    UserDefaults.standard.synchronize()
83  }
84 
85  // Lookup by index
86  subscript(index:Int) -> PreferenceRow? {
87    get  {
88      return prefDict[Array(prefDict.keys)[index]]
89    }
90    set(newValue) {
91      let pKey = Array(prefDefaultDict.keys)[index]
92      prefDict[pKey] = newValue!
93      prefObject[pKey] = newValue!.asRawValue()
94    }
95  }
96 
97  private static var sharedPreferences: Preferences = {
98    let preferences = Preferences()
99   
100    // Setup defaults
101   
102    var home = NSHomeDirectory()
103    // Add default values
104    var defaults = Dictionary<String,Any>()
105    defaults["I2Pref_enableLogging"] = true
106    defaults["I2Pref_enableVerboseLogging"] = true
107    defaults["I2Pref_autoStartRouterAtBoot"] = false
108    defaults["I2Pref_startLauncherAtLogin"] = false
109    defaults["I2Pref_startRouterAtStartup"] = true
110    defaults["I2Pref_stopRouterAtShutdown"] = true
111    defaults["I2Pref_letRouterLiveEvenLauncherDied"] = false
112    defaults["I2Pref_allowAdvancedPreferences"] = false
113    defaults["I2Pref_alsoStartFirefoxOnLaunch"] = true
114    defaults["I2Pref_firefoxBundlePath"] = "/Applications/Firefox.app"
115    defaults["I2Pref_consolePortCheckNum"] = 7657
116    defaults["I2Pref_i2pBaseDirectory"] = NSString(format: "%@/Library/I2P", home)
117    defaults["I2Pref_i2pLogDirectory"] = NSString(format: "%@/Library/Logs/I2P", home)
118    defaults["I2Pref_showAsIconMode"] = "bothIcon"
119    defaults["I2Pref_javaCommandPath"] = "/usr/libexec/java_home -v 1.7+ --exec java "
120    defaults["I2Pref_javaCommandOptions"] = "-Xmx512M -Xms128m"
121    defaults["I2Pref_featureToggleExperimental"] = false
122    preferences.prefDefaultDict = defaults
123   
124    /*if (preferences.prefDict.isEmpty) {
125      print("Stored new user defaults")
126      preferences.addDictToPrefTable(defaults)
127    }*/
128    for name in Array(preferences.prefDefaultDict.keys) {
129      let potentialValue = UserDefaults.standard.object(forKey: name)
130      //preferences.prefDict[name] = PreferenceRow(name, potentialValue, preferences.prefDefaultDict[name])
131      preferences[name] = potentialValue
132    }
133    preferences.count = preferences.prefDict.keys.count
134    UserDefaults.standard.register(defaults: defaults)
135    UserDefaults.standard.setPersistentDomain(preferences.prefObject, forName: APPDOMAIN)
136    UserDefaults.standard.synchronize()
137   
138    print("User Preferences loaded - Got \(preferences.count) items.")
139   
140    return preferences
141  }()
142 
143  // MARK: -
144 
145  func addDictToPrefTable(_ dict: Dictionary<String,Any>, _ emptyFirst: Bool = true) {
146    if (emptyFirst) {
147      self.prefDict.removeAll()
148    }
149    for (pKey, pVal) in dict {
150      if (pKey.starts(with: "I2P")) {
151        print("Preference -> \(pKey)")
152        self[pKey] = pVal
153      } else {
154        print("Skipping preference -> \(pKey)")
155      }
156    }
157  }
158 
159  // Initialization
160 
161  private override init() {
162    super.init()
163    let fromDisk = UserDefaults.standard.persistentDomain(forName: APPDOMAIN) ?? Dictionary<String,Any>()
164    for (pKey, pVal) in fromDisk {
165      if (pKey.starts(with: "I2P")) {
166        print("Preference -> \(pKey)")
167        self[pKey] = pVal
168      } else {
169        print("Skipping preference -> \(pKey)")
170      }
171    }
172    print("Preferences size from disk is: \(prefObject.count).")
173    self.syncPref()
174  }
175 
176  // TODO: Make menubar icon optional
177  func getMenubarIconStateIsShowing() -> Bool {
178    return true
179  }
180 
181  // MARK: - Accessors
182 
183  class func shared() -> Preferences {
184    return sharedPreferences
185  }
186 
187  func redrawPrefTableItems() {
188    self.addDictToPrefTable(self.prefObject, false)
189  }
190 
191 
192  // MARK: - Accessors for Application Preferences
193 
194  var startRouterOnLauncherStart: Bool {
195    get {
196      let dfl = self.prefDefaultDict["I2Pref_startRouterAtStartup"] as! Bool
197      return (self["I2Pref_startRouterAtStartup"] as? Bool ?? dfl)
198    }
199    set(newValue) {
200      self["I2Pref_startRouterAtStartup"] = newValue
201      self.syncPref()
202    }
203  }
204 
205  var stopRouterOnLauncherShutdown: Bool {
206    get {
207      let dfl = self.prefDefaultDict["I2Pref_stopRouterAtShutdown"] as! Bool
208      return (self["I2Pref_stopRouterAtShutdown"] as? Bool ?? dfl)
209    }
210    set(newValue) {
211      self["I2Pref_stopRouterAtShutdown"] = newValue
212      self.syncPref()
213    }
214  }
215 
216  var allowAdvancedPreferenceEdit: Bool {
217    get {
218      let dfl = self.prefDefaultDict["I2Pref_allowAdvancedPreferences"] as! Bool
219      return (self["I2Pref_allowAdvancedPreferences"] as? Bool ?? dfl)
220    }
221    set(newValue) {
222      self["I2Pref_allowAdvancedPreferences"] = newValue
223      self.syncPref()
224    }
225  }
226 
227  var alsoStartFirefoxOnLaunch: Bool {
228    get {
229      let dfl = self.prefDefaultDict["I2Pref_alsoStartFirefoxOnLaunch"] as! Bool
230      return (self["I2Pref_alsoStartFirefoxOnLaunch"] as? Bool ?? dfl)
231    }
232    set(newValue) {
233      self["I2Pref_alsoStartFirefoxOnLaunch"] = newValue
234      self.syncPref()
235    }
236  }
237 
238  var featureToggleExperimental: Bool {
239    get {
240      let dfl = self.prefDefaultDict["I2Pref_featureToggleExperimental"] as! Bool
241      return (self["I2Pref_featureToggleExperimental"] as? Bool ?? dfl)
242    }
243    set(newValue) {
244      self["I2Pref_featureToggleExperimental"] = newValue
245      self.syncPref()
246    }
247  }
248 
249  var i2pBaseDirectory: String {
250    get {
251      let dfl = self.prefDefaultDict["I2Pref_i2pBaseDirectory"] as! String
252      return (self["I2Pref_i2pBaseDirectory"] as? String ?? dfl)
253    }
254    set(newValue) {
255      // TODO: Check if string is a valid directory path, and that it exists.
256      self["I2Pref_i2pBaseDirectory"] = newValue
257      self.syncPref()
258    }
259  }
260 
261  var i2pLogDirectory: String {
262    get {
263      let dfl = self.prefDefaultDict["I2Pref_i2pLogDirectory"] as! String
264      return (self["I2Pref_i2pLogDirectory"] as? String ?? dfl)
265    }
266    set(newValue) {
267      // TODO: Check if string is a valid java command path, check if it executes with -version.
268      self["I2Pref_i2pLogDirectory"] = newValue
269      self.syncPref()
270    }
271  }
272 
273  var javaCommandPath: String {
274    get {
275      let dfl = self.prefDefaultDict["I2Pref_javaCommandPath"] as! String
276      return (self["I2Pref_javaCommandPath"] as? String ?? dfl)
277    }
278    set(newValue) {
279      // TODO: Check if string is a valid java command path, check if it executes with -version.
280      self["I2Pref_javaCommandPath"] = newValue
281      self.syncPref()
282    }
283  }
284 
285  var javaCommandOptions: String {
286    get {
287      let dfl = self.prefDefaultDict["I2Pref_javaCommandOptions"] as! String
288      return (self["I2Pref_javaCommandOptions"] as? String ?? dfl)
289    }
290    set(newValue) {
291      // TODO: Check if string is a valid set of java options
292      self["I2Pref_javaCommandOptions"] = newValue
293      self.syncPref()
294    }
295  }
296 
297 
298}
299
Note: See TracBrowser for help on using the repository browser.