LibCecTray: power management
[deb_libcec.git] / src / LibCecTray / ui / CECTray.cs
CommitLineData
f017f3c4
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
16f47961 4 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
f017f3c4
LOK
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;
34using System.Windows.Forms;
35using CecSharp;
36using System.IO;
37using LibCECTray.Properties;
38using LibCECTray.controller;
39using LibCECTray.controller.applications;
40using LibCECTray.settings;
fec04a82
LOK
41using Microsoft.Win32;
42using System.Security.Permissions;
f017f3c4
LOK
43
44namespace LibCECTray.ui
45{
46 /// <summary>
47 /// The tab pages in this application
48 /// </summary>
49 internal enum ConfigTab
50 {
51 Configuration,
52 KeyConfiguration,
53 Tester,
54 Log,
55 WMC,
56 XBMC
57 }
58
59 /// <summary>
60 /// Main LibCecTray GUI
61 /// </summary>
62 partial class CECTray : AsyncForm
63 {
64 public CECTray()
65 {
66 Text = Resources.app_name;
67 InitializeComponent();
f017f3c4
LOK
68 VisibleChanged += delegate
69 {
70 if (!Visible)
71 OnHide();
72 else
73 OnShow();
74 };
fec04a82
LOK
75 SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(OnPowerModeChanged);
76 SystemEvents.SessionEnding += new SessionEndingEventHandler(OnSessionEnding);
77 }
78
79 public void OnSessionEnding(object sender, SessionEndingEventArgs e)
80 {
81 Controller.Close();
82 }
83
84 public void OnPowerModeChanged(Object sender, PowerModeChangedEventArgs e)
85 {
86 switch (e.Mode)
87 {
88 case PowerModes.Resume:
89 Controller.Initialise();
90 break;
91 case PowerModes.Suspend:
92 Controller.Close();
93 break;
94 case PowerModes.StatusChange:
95 break;
96 }
f017f3c4
LOK
97 }
98
99 public override sealed string Text
100 {
101 get { return base.Text; }
102 set { base.Text = value; }
103 }
104
97401db1 105 public void Initialise()
f017f3c4 106 {
c4bc8944 107 Controller.Initialise();
f017f3c4
LOK
108 }
109
110 protected override void Dispose(bool disposing)
111 {
112 Hide();
113 if (disposing)
114 {
c4bc8944 115 Controller.Close();
f017f3c4
LOK
116 }
117 if (disposing && (components != null))
118 {
119 components.Dispose();
120 }
121 base.Dispose(disposing);
122 }
123
124 #region Configuration tab
125 /// <summary>
126 /// Replaces the gui controls by the ones that are bound to the settings.
127 /// this is a fugly way to do it, but the gui designer doesn't allow us to ref CECSettings, since it uses symbols from LibCecSharp
128 /// </summary>
129 public void InitialiseSettingsComponent(CECSettings settings)
130 {
131 settings.WakeDevices.ReplaceControls(this, Configuration.Controls, lWakeDevices, cbWakeDevices);
132 settings.PowerOffDevices.ReplaceControls(this, Configuration.Controls, lPowerOff, cbPowerOffDevices);
133 settings.OverridePhysicalAddress.ReplaceControls(this, Configuration.Controls, cbOverrideAddress);
134 settings.OverrideTVVendor.ReplaceControls(this, Configuration.Controls, cbVendorOverride);
135 settings.PhysicalAddress.ReplaceControls(this, Configuration.Controls, tbPhysicalAddress);
136 settings.HDMIPort.ReplaceControls(this, Configuration.Controls, lPortNumber, cbPortNumber);
137 settings.ConnectedDevice.ReplaceControls(this, Configuration.Controls, lConnectedDevice, cbConnectedDevice);
138 settings.ActivateSource.ReplaceControls(this, Configuration.Controls, cbActivateSource);
139 settings.DeviceType.ReplaceControls(this, Configuration.Controls, lDeviceType, cbDeviceType);
140 settings.TVVendor.ReplaceControls(this, Configuration.Controls, cbVendorId);
141 settings.StartHidden.ReplaceControls(this, Configuration.Controls, cbStartMinimised);
142 }
143
144 private void BSaveClick(object sender, EventArgs e)
145 {
c4bc8944 146 Controller.PersistSettings();
f017f3c4
LOK
147 }
148
149 private void BReloadConfigClick(object sender, EventArgs e)
150 {
c4bc8944 151 Controller.ResetDefaultSettings();
f017f3c4
LOK
152 }
153 #endregion
154
155 #region CEC Tester tab
156 delegate void SetActiveDevicesCallback(string[] activeDevices);
157 public void SetActiveDevices(string[] activeDevices)
158 {
159 if (cbCommandDestination.InvokeRequired)
160 {
161 SetActiveDevicesCallback d = SetActiveDevices;
162 try
163 {
164 Invoke(d, new object[] { activeDevices });
165 }
166 catch (Exception) { }
167 }
168 else
169 {
170 cbCommandDestination.Items.Clear();
171 foreach (string item in activeDevices)
172 cbCommandDestination.Items.Add(item);
173 }
174 }
175
176 delegate CecLogicalAddress GetTargetDeviceCallback();
177 private CecLogicalAddress GetTargetDevice()
178 {
179 if (cbCommandDestination.InvokeRequired)
180 {
181 GetTargetDeviceCallback d = GetTargetDevice;
182 CecLogicalAddress retval = CecLogicalAddress.Unknown;
183 try
184 {
185 retval = (CecLogicalAddress)Invoke(d, new object[] { });
186 }
187 catch (Exception) { }
188 return retval;
189 }
190
191 return CECSettingLogicalAddresses.GetLogicalAddressFromString(cbCommandDestination.Text);
192 }
193
194 private void BSendImageViewOnClick(object sender, EventArgs e)
195 {
c4bc8944 196 Controller.CECActions.SendImageViewOn(GetTargetDevice());
f017f3c4
LOK
197 }
198
199 private void BStandbyClick(object sender, EventArgs e)
200 {
c4bc8944 201 Controller.CECActions.SendStandby(GetTargetDevice());
f017f3c4
LOK
202 }
203
204 private void BScanClick(object sender, EventArgs e)
205 {
c4bc8944 206 Controller.CECActions.ShowDeviceInfo(GetTargetDevice());
f017f3c4
LOK
207 }
208
209 private void BActivateSourceClick(object sender, EventArgs e)
210 {
c4bc8944 211 Controller.CECActions.ActivateSource(GetTargetDevice());
f017f3c4
LOK
212 }
213
214 private void CbCommandDestinationSelectedIndexChanged(object sender, EventArgs e)
215 {
216 bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem);
217 bVolUp.Enabled = enableVolumeButtons;
218 bVolDown.Enabled = enableVolumeButtons;
219 bMute.Enabled = enableVolumeButtons;
220 bActivateSource.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
221 bScan.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
222 }
223
224 private void BVolUpClick(object sender, EventArgs e)
225 {
c4bc8944 226 Controller.Lib.VolumeUp(true);
f017f3c4
LOK
227 }
228
229 private void BVolDownClick(object sender, EventArgs e)
230 {
c4bc8944 231 Controller.Lib.VolumeDown(true);
f017f3c4
LOK
232 }
233
234 private void BMuteClick(object sender, EventArgs e)
235 {
c4bc8944 236 Controller.Lib.MuteAudio(true);
f017f3c4
LOK
237 }
238
239 private void BRescanDevicesClick(object sender, EventArgs e)
240 {
c4bc8944 241 Controller.CECActions.RescanDevices();
f017f3c4
LOK
242 }
243 #endregion
244
245 #region Log tab
246 delegate void UpdateLogCallback();
247 private void UpdateLog()
248 {
249 if (tbLog.InvokeRequired)
250 {
251 UpdateLogCallback d = UpdateLog;
252 try
253 {
254 Invoke(d, new object[] { });
255 }
256 catch (Exception) { }
257 }
258 else
259 {
260 tbLog.Text = _log;
261 tbLog.Select(tbLog.Text.Length, 0);
262 tbLog.ScrollToCaret();
263 }
264 }
265
266 public void AddLogMessage(CecLogMessage message)
267 {
268 string strLevel = "";
269 bool display = false;
270 switch (message.Level)
271 {
272 case CecLogLevel.Error:
273 strLevel = "ERROR: ";
274 display = cbLogError.Checked;
275 break;
276 case CecLogLevel.Warning:
277 strLevel = "WARNING: ";
278 display = cbLogWarning.Checked;
279 break;
280 case CecLogLevel.Notice:
281 strLevel = "NOTICE: ";
282 display = cbLogNotice.Checked;
283 break;
284 case CecLogLevel.Traffic:
285 strLevel = "TRAFFIC: ";
286 display = cbLogTraffic.Checked;
287 break;
288 case CecLogLevel.Debug:
289 strLevel = "DEBUG: ";
290 display = cbLogDebug.Checked;
291 break;
292 }
293
294 if (display)
295 {
296 string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message) + Environment.NewLine;
297 AddLogMessage(strLog);
298 }
299 }
300
301 public void AddLogMessage(string message)
302 {
303 _log += message;
304
305 if (_selectedTab == ConfigTab.Log)
306 UpdateLog();
307 }
308
309 private void BClearLogClick(object sender, EventArgs e)
310 {
311 _log = string.Empty;
312 UpdateLog();
313 }
314
315 private void BSaveLogClick(object sender, EventArgs e)
316 {
317 SaveFileDialog dialog = new SaveFileDialog
318 {
319 Title = Resources.where_do_you_want_to_store_the_log,
320 InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
321 FileName = Resources.cec_log_filename,
322 Filter = Resources.cec_log_filter,
323 FilterIndex = 1
324 };
325
326 if (dialog.ShowDialog() == DialogResult.OK)
327 {
328 FileStream fs = (FileStream)dialog.OpenFile();
329 if (!fs.CanWrite)
330 {
331 MessageBox.Show(string.Format(Resources.cannot_open_for_writing, dialog.FileName), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Error);
332 }
333 else
334 {
335 StreamWriter writer = new StreamWriter(fs);
336 writer.Write(_log);
337 writer.Close();
338 fs.Close();
339 fs.Dispose();
340 MessageBox.Show(string.Format(Resources.log_stored_as, dialog.FileName), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Information);
341 }
342 }
343 }
344 #endregion
345
346 #region Tray icon and window controls
347 private void HideToolStripMenuItemClick(object sender, EventArgs e)
348 {
349 ShowHideToggle();
350 }
351
352 private void CloseToolStripMenuItemClick(object sender, EventArgs e)
353 {
354 Dispose();
355 }
356
357 private void AboutToolStripMenuItemClick(object sender, EventArgs e)
358 {
c4bc8944 359 (new About(Controller.LibServerVersion, Controller.LibClientVersion, Controller.LibInfo)).ShowDialog();
f017f3c4
LOK
360 }
361
362 private void AdvancedModeToolStripMenuItemClick(object sender, EventArgs e)
363 {
c4bc8944 364 Controller.Settings.AdvancedMode.Value = !advancedModeToolStripMenuItem.Checked;
f017f3c4
LOK
365 ShowHideAdvanced(!advancedModeToolStripMenuItem.Checked);
366 }
367
368 private void BCancelClick(object sender, EventArgs e)
369 {
370 Dispose();
371 }
372
373 private void TrayIconClick(object sender, EventArgs e)
374 {
375 if (e is MouseEventArgs && (e as MouseEventArgs).Button == MouseButtons.Left)
376 ShowHideToggle();
377 }
378
379 public void OnHide()
380 {
381 ShowInTaskbar = false;
382 Visible = false;
383 tsMenuShowHide.Text = Resources.show;
384 }
385
386 public void OnShow()
387 {
388 ShowInTaskbar = true;
389 WindowState = FormWindowState.Normal;
390 Activate();
391 tsMenuShowHide.Text = Resources.hide;
392 }
393
394 private void ShowHideToggle()
395 {
396 if (Visible && WindowState != FormWindowState.Minimized)
397 {
c4bc8944 398 Controller.Settings.StartHidden.Value = true;
f017f3c4
LOK
399 Hide();
400 }
401 else
402 {
c4bc8944 403 Controller.Settings.StartHidden.Value = false;
f017f3c4
LOK
404 Show();
405 }
406 }
407
408 private void TsMenuCloseClick(object sender, EventArgs e)
409 {
410 Dispose();
411 }
412
413 private void CECTrayResize(object sender, EventArgs e)
414 {
415 if (WindowState == FormWindowState.Minimized)
177e3a7b 416 Hide();
f017f3c4 417 else
177e3a7b 418 Show();
f017f3c4
LOK
419 }
420
421 private void TsMenuShowHideClick(object sender, EventArgs e)
422 {
423 ShowHideToggle();
424 }
425
426 public void ShowHideAdvanced(bool setTo)
427 {
428 if (setTo)
429 {
430 tsAdvanced.Checked = true;
431 advancedModeToolStripMenuItem.Checked = true;
432 SuspendLayout();
433 if (!tabPanel.Controls.Contains(tbTestCommands))
434 TabControls.Add(tbTestCommands);
435 if (!tabPanel.Controls.Contains(LogOutput))
436 TabControls.Add(LogOutput);
437 ResumeLayout();
438 }
439 else
440 {
441 tsAdvanced.Checked = false;
442 advancedModeToolStripMenuItem.Checked = false;
443 SuspendLayout();
444 tabPanel.Controls.Remove(tbTestCommands);
445 tabPanel.Controls.Remove(LogOutput);
446 ResumeLayout();
447 }
448 }
449
450 private void TsAdvancedClick(object sender, EventArgs e)
451 {
c4bc8944 452 Controller.Settings.AdvancedMode.Value = !tsAdvanced.Checked;
f017f3c4
LOK
453 ShowHideAdvanced(!tsAdvanced.Checked);
454 }
455
456 public void SetStatusText(string status)
457 {
458 SetControlText(lStatus, status);
459 }
460
461 public void SetProgressBar(int progress, bool visible)
462 {
463 SetControlVisible(pProgress, visible);
464 SetProgressValue(pProgress, progress);
465 }
466
467 public void SetControlsEnabled(bool val)
468 {
469 //main tab
470 SetControlEnabled(bClose, val);
471 SetControlEnabled(bSaveConfig, val);
472 SetControlEnabled(bReloadConfig, val);
473
474 //tester tab
475 SetControlEnabled(bRescanDevices, val);
476 SetControlEnabled(bSendImageViewOn, val);
477 SetControlEnabled(bStandby, val);
478 SetControlEnabled(bActivateSource, val);
479 SetControlEnabled(bScan, val);
480
481 bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem) && val;
482 SetControlEnabled(bVolUp, enableVolumeButtons);
483 SetControlEnabled(bVolDown, enableVolumeButtons);
484 SetControlEnabled(bMute, enableVolumeButtons);
485 }
486
487 private void TabControl1SelectedIndexChanged(object sender, EventArgs e)
488 {
489 switch (tabPanel.TabPages[tabPanel.SelectedIndex].Name)
490 {
491 case "tbTestCommands":
492 _selectedTab = ConfigTab.Tester;
493 break;
494 case "LogOutput":
495 _selectedTab = ConfigTab.Log;
496 UpdateLog();
497 break;
498 default:
499 _selectedTab = ConfigTab.Configuration;
500 break;
501 }
502 }
503 #endregion
504
505 #region Class members
506 private ConfigTab _selectedTab = ConfigTab.Configuration;
507 private string _log = string.Empty;
c4bc8944 508 private CECController _controller;
49689754
LOK
509 public CECController Controller
510 {
97401db1
LOK
511 get
512 {
513 return _controller ?? (_controller = new CECController(this));
514 }
49689754 515 }
f017f3c4
LOK
516 public Control.ControlCollection TabControls
517 {
518 get { return tabPanel.Controls; }
519 }
520 public string SelectedTabName
521 {
522 get { return GetSelectedTabName(tabPanel, tabPanel.TabPages); }
523 }
524 #endregion
525
526 private void AddNewApplicationToolStripMenuItemClick(object sender, EventArgs e)
527 {
c4bc8944
LOK
528 ConfigureApplication appConfig = new ConfigureApplication(Controller.Settings, Controller);
529 Controller.DisplayDialog(appConfig, false);
f017f3c4
LOK
530 }
531 }
532}