Imported Upstream version 2.2.0
[deb_libcec.git] / src / LibCecTray / settings / CECSettings.cs
CommitLineData
cbbe90dd
JB
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
6 *
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
8 *
9 * This program is dual-licensed; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
26 *
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
31 */
32
33using System.Windows.Forms;
34using CecSharp;
35using System.Collections.Generic;
36using LibCECTray.Properties;
37using Microsoft.Win32;
38
39namespace LibCECTray.settings
40{
41 class CECSettings
42 {
43 private const string RegistryCompanyName = "Pulse-Eight";
44 private const string RegistryApplicationName = "libCECTray";
45
46 #region Key names
47 public static string KeyHDMIPort = "global_hdmi_port";
48 public static string KeyConnectedToHDMIDevice = "global_connected_to_hdmi_device";
49 public static string KeyActivateSource = "global_activate_source";
50 public static string KeyAdvancedMode = "global_advanced_mode";
51 public static string KeyPhysicalAddress = "global_physical_address";
52 public static string KeyOverridePhysicalAddress = "global_override_physical_address";
53 public static string KeyDeviceType = "global_device_type";
54 public static string KeyTVVendor = "global_tv_vendor";
55 public static string KeyOverrideTVVendor = "global_override_tv_vendor";
56 public static string KeyWakeDevices = "global_wake_devices";
57 public static string KeyPowerOffDevices = "global_standby_devices";
58 public static string KeyStartHidden = "global_start_hidden";
59 #endregion
60
61 public CECSettings(CECSetting.SettingChangedHandler changedHandler)
62 {
63 _changedHandler = changedHandler;
64 Load();
65 }
66
67 /// <summary>
68 /// Resets all settings to their default values
69 /// </summary>
70 public void SetDefaultValues()
71 {
72 foreach (var setting in _settings.Values)
73 setting.ResetDefaultValue();
74 }
75
76 /// <summary>
77 /// Loads all known settings from the registry
78 /// </summary>
79 private void Load()
80 {
81 using (var subRegKey = Registry.CurrentUser.OpenSubKey(RegistryKeyName, true))
82 {
83 if (subRegKey == null) return;
84 foreach (var setting in _settings.Values)
85 if (!setting.KeyName.StartsWith("global_"))
86 setting.Load(subRegKey);
87 subRegKey.Close();
88 }
89 }
90
91 /// <summary>
92 /// Load a setting value from the registry
93 /// </summary>
94 /// <param name="setting">The setting to load</param>
95 public void Load(CECSetting setting)
96 {
97 using (var subRegKey = Registry.CurrentUser.OpenSubKey(RegistryKeyName, true))
98 {
99 if (subRegKey == null) return;
100 setting.Load(subRegKey);
101 subRegKey.Close();
102 }
103 setting.SettingChanged += OnSettingChanged;
104 }
105
106 /// <summary>
107 /// Persist all settings in the registry
108 /// </summary>
109 /// <returns>True when persisted, false otherwise</returns>
110 public bool Persist()
111 {
112 if (CreateRegistryKey())
113 {
114 using (var subRegKey = Registry.CurrentUser.OpenSubKey(RegistryKeyName, true))
115 {
116 if (subRegKey != null)
117 {
118 foreach (var setting in _settings.Values)
119 setting.Persist(subRegKey);
120 subRegKey.Close();
121 return true;
122 }
123 }
124 }
125 return false;
126 }
127
128 private bool EnableHDMIPortSetting(CECSetting setting, bool value)
129 {
130 return value && !OverridePhysicalAddress.Value;
131 }
132
133 private bool EnablePhysicalAddressSetting(CECSetting setting, bool value)
134 {
135 return value && OverridePhysicalAddress.Value;
136 }
137
138 private bool EnableSettingTVVendor(CECSetting setting, bool value)
139 {
140 return value && OverrideTVVendor.Value;
141 }
142
143 private void OnSettingChanged(CECSetting setting, object oldValue, object newValue)
144 {
145 if (SettingChanged != null)
146 SettingChanged(setting, oldValue, newValue);
147 }
148
149 #region Global settings
150 public CECSettingByte HDMIPort
151 {
152 get
153 {
154 if (!_settings.ContainsKey(KeyHDMIPort))
155 {
156 CECSettingByte setting = new CECSettingByte(KeyHDMIPort, "HDMI port", 1, _changedHandler) { LowerLimit = 1, UpperLimit = 15, EnableSetting = EnableHDMIPortSetting };
157 setting.Format += delegate(object sender, ListControlConvertEventArgs args)
158 {
159 ushort tmp;
160 if (ushort.TryParse((string)args.Value, out tmp))
161 args.Value = "HDMI " + args.Value;
162 };
163
164 Load(setting);
165 _settings[KeyHDMIPort] = setting;
166 }
167 return _settings[KeyHDMIPort].AsSettingByte;
168 }
169 }
170
171 public CECSettingLogicalAddress ConnectedDevice
172 {
173 get
174 {
175 if (!_settings.ContainsKey(KeyConnectedToHDMIDevice))
176 {
177 CecLogicalAddresses allowedMask = new CecLogicalAddresses();
178 allowedMask.Set(CecLogicalAddress.Tv); allowedMask.Set(CecLogicalAddress.AudioSystem);
179 CECSettingLogicalAddress setting = new CECSettingLogicalAddress(KeyConnectedToHDMIDevice,
180 Resources.global_connected_to_hdmi_device,
181 CecLogicalAddress.Tv, _changedHandler)
182 {
183 AllowedAddressMask = allowedMask,
184 Enabled = false,
185 EnableSetting = EnableHDMIPortSetting
186 };
187 Load(setting);
188 _settings[KeyConnectedToHDMIDevice] = setting;
189 }
190 return _settings[KeyConnectedToHDMIDevice].AsSettingLogicalAddress;
191 }
192 }
193
194 public CECSettingBool ActivateSource
195 {
196 get
197 {
198 if (!_settings.ContainsKey(KeyActivateSource))
199 {
200 CECSettingBool setting = new CECSettingBool(KeyActivateSource, Resources.global_activate_source, true,
201 _changedHandler) {Enabled = false};
202 Load(setting);
203 _settings[KeyActivateSource] = setting;
204 }
205 return _settings[KeyActivateSource].AsSettingBool;
206 }
207 }
208
209 public CECSettingBool AdvancedMode
210 {
211 get
212 {
213 if (!_settings.ContainsKey(KeyAdvancedMode))
214 {
215 CECSettingBool setting = new CECSettingBool(KeyAdvancedMode, Resources.global_advanced_mode, false,
216 _changedHandler) {Enabled = false};
217 Load(setting);
218 _settings[KeyAdvancedMode] = setting;
219 }
220 return _settings[KeyAdvancedMode].AsSettingBool;
221 }
222 }
223
224 public CECSettingUShort PhysicalAddress
225 {
226 get
227 {
228 if (!_settings.ContainsKey(KeyPhysicalAddress))
229 {
230 CECSettingUShort setting = new CECSettingUShort(KeyPhysicalAddress, Resources.global_physical_address, 0xFFFF, _changedHandler) { Enabled = false, EnableSetting = EnablePhysicalAddressSetting };
231 Load(setting);
232 _settings[KeyPhysicalAddress] = setting;
233 }
234 return _settings[KeyPhysicalAddress].AsSettingUShort;
235 }
236 }
237
238 public CECSettingBool OverridePhysicalAddress
239 {
240 get
241 {
242 if (!_settings.ContainsKey(KeyAdvancedMode))
243 {
244 CECSettingBool setting = new CECSettingBool(KeyOverridePhysicalAddress,
245 Resources.global_override_physical_address, false, _changedHandler);
246 Load(setting);
247 _settings[KeyOverridePhysicalAddress] = setting;
248 }
249 return _settings[KeyOverridePhysicalAddress].AsSettingBool;
250 }
251 }
252
253 public CECSettingDeviceType DeviceType
254 {
255 get
256 {
257 if (!_settings.ContainsKey(KeyDeviceType))
258 {
259 CecDeviceTypeList allowedTypes = new CecDeviceTypeList();
260 allowedTypes.Types[(int)CecDeviceType.RecordingDevice] = CecDeviceType.RecordingDevice;
261 allowedTypes.Types[(int)CecDeviceType.PlaybackDevice] = CecDeviceType.PlaybackDevice;
262
263 CECSettingDeviceType setting = new CECSettingDeviceType(KeyDeviceType, Resources.global_device_type,
264 CecDeviceType.RecordingDevice, _changedHandler) { Enabled = false, AllowedTypeMask = allowedTypes };
265 Load(setting);
266 _settings[KeyDeviceType] = setting;
267 }
268 return _settings[KeyDeviceType].AsSettingDeviceType;
269 }
270 }
271
272 public CECSettingVendorId TVVendor
273 {
274 get
275 {
276 if (!_settings.ContainsKey(KeyTVVendor))
277 {
278 CECSettingVendorId setting = new CECSettingVendorId(KeyTVVendor, Resources.global_tv_vendor,
279 CecVendorId.Unknown, _changedHandler)
280 {Enabled = false, EnableSetting = EnableSettingTVVendor};
281 Load(setting);
282 _settings[KeyTVVendor] = setting;
283 }
284 return _settings[KeyTVVendor].AsSettingVendorId;
285 }
286 }
287
288 public CECSettingBool OverrideTVVendor
289 {
290 get
291 {
292 if (!_settings.ContainsKey(KeyOverrideTVVendor))
293 {
294 CECSettingBool setting = new CECSettingBool(KeyOverrideTVVendor, Resources.global_override_tv_vendor, false,
295 _changedHandler) {Enabled = false};
296 Load(setting);
297 _settings[KeyOverrideTVVendor] = setting;
298 }
299 return _settings[KeyOverrideTVVendor].AsSettingBool;
300 }
301 }
302
303 public CECSettingLogicalAddresses WakeDevices
304 {
305 get
306 {
307 if (!_settings.ContainsKey(KeyWakeDevices))
308 {
309 CecLogicalAddresses defaultDeviceList = new CecLogicalAddresses();
310 defaultDeviceList.Set(CecLogicalAddress.Tv);
311 CECSettingLogicalAddresses setting = new CECSettingLogicalAddresses(KeyWakeDevices,
312 Resources.global_wake_devices,
313 defaultDeviceList, _changedHandler)
314 {Enabled = false};
315 Load(setting);
316 _settings[KeyWakeDevices] = setting;
317 }
318 return _settings[KeyWakeDevices].AsSettingLogicalAddresses;
319 }
320 }
321
322 public CECSettingLogicalAddresses PowerOffDevices
323 {
324 get
325 {
326 if (!_settings.ContainsKey(KeyPowerOffDevices))
327 {
328 CecLogicalAddresses defaultDeviceList = new CecLogicalAddresses();
329 defaultDeviceList.Set(CecLogicalAddress.Tv);
330 CECSettingLogicalAddresses setting = new CECSettingLogicalAddresses(KeyPowerOffDevices,
331 Resources.global_standby_devices,
332 defaultDeviceList,
333 _changedHandler) {Enabled = false};
334 Load(setting);
335 _settings[KeyPowerOffDevices] = setting;
336 }
337 return _settings[KeyPowerOffDevices].AsSettingLogicalAddresses;
338 }
339 }
340
341 public CECSettingBool StartHidden
342 {
343 get
344 {
345 if (!_settings.ContainsKey(KeyStartHidden))
346 {
347 CECSettingBool setting = new CECSettingBool(KeyStartHidden, Resources.global_start_hidden, false, _changedHandler);
348 Load(setting);
349 _settings[KeyStartHidden] = setting;
350 }
351 return _settings[KeyStartHidden].AsSettingBool;
352 }
353 }
354 #endregion
355
356 public bool ContainsKey(string key)
357 {
358 return _settings.ContainsKey(key);
359 }
360
361 public void SetVendorName(CecLogicalAddress address, CecVendorId vendorId, string vendorName)
362 {
363 VendorNames[(int)address] = vendorName;
364
365 if (address == CecLogicalAddress.Tv && vendorId == CecVendorId.Panasonic)
366 {
367 DeviceType.AllowedTypeMask = new CecDeviceTypeList {Types = new[] {CecDeviceType.PlaybackDevice}};
368 }
369
370 foreach (var setting in _settings)
371 {
372 if (setting.Value.SettingType == CECSettingType.LogicalAddress)
373 setting.Value.AsSettingLogicalAddress.ResetItems(true);
374 }
375 }
376
377 public bool Enabled
378 {
379 set
380 {
381 CECSetting[] settings = new CECSetting[_settings.Count + 10];
382 _settings.Values.CopyTo(settings, 0);
383 foreach (var setting in settings)
384 if (setting != null)
385 setting.Enabled = value;
386 }
387 get
388 {
389 var enabled = true;
390 foreach (var setting in _settings)
391 enabled &= setting.Value.Enabled;
392 return enabled;
393 }
394 }
395
396 /// <summary>
397 /// Read or write one of the settings, given it's key
398 /// </summary>
399 /// <param name="key">The key of the setting</param>
400 /// <returns>The setting</returns>
401 public CECSetting this[string key]
402 {
403 get { return _settings.ContainsKey(key) ? _settings[key] : null; }
404 set {_settings[key] = value; }
405 }
406
407 /// <summary>
408 /// Create the registry key that holds all settings.
409 /// </summary>
410 /// <returns>True when created (or already existing), false otherwise</returns>
411 private static bool CreateRegistryKey()
412 {
413 using (var regKey = Registry.CurrentUser.OpenSubKey("Software", true))
414 {
415 if (regKey != null)
416 {
417 regKey.CreateSubKey(RegistryCompanyName);
418 regKey.Close();
419 }
420 else
421 {
422 return false;
423 }
424 }
425 using (var regKey = Registry.CurrentUser.OpenSubKey("Software\\" + RegistryCompanyName, true))
426 {
427 if (regKey != null)
428 {
429 regKey.CreateSubKey(RegistryApplicationName);
430 regKey.Close();
431 }
432 else
433 {
434 return false;
435 }
436 }
437 return true;
438 }
439
440 private readonly Dictionary<string, CECSetting> _settings = new Dictionary<string, CECSetting>();
441 private static string RegistryKeyName
442 {
443 get { return string.Format("Software\\{0}\\{1}", RegistryCompanyName, RegistryApplicationName); }
444 }
445
446 private readonly CECSetting.SettingChangedHandler _changedHandler;
447 public event CECSetting.SettingChangedHandler SettingChanged;
448
449 public static readonly string[] VendorNames = new string[15];
450 }
451}