2 * This file is part of the libCEC(R) library.
4 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
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.
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.
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.
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
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/
34 using System.Windows.Forms;
37 using LibCECTray.Properties;
38 using LibCECTray.controller;
39 using LibCECTray.controller.applications;
40 using LibCECTray.settings;
41 using Microsoft.Win32;
42 using System.Security.Permissions;
44 namespace LibCECTray.ui
47 /// The tab pages in this application
49 internal enum ConfigTab
60 /// Main LibCecTray GUI
62 partial class CECTray : AsyncForm
66 Text = Resources.app_name;
67 InitializeComponent();
68 VisibleChanged += delegate
75 SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(OnPowerModeChanged);
76 SystemEvents.SessionEnding += new SessionEndingEventHandler(OnSessionEnding);
79 public void OnSessionEnding(object sender, SessionEndingEventArgs e)
84 public void OnPowerModeChanged(Object sender, PowerModeChangedEventArgs e)
88 case PowerModes.Resume:
89 Controller.Initialise();
91 case PowerModes.Suspend:
94 case PowerModes.StatusChange:
99 public override sealed string Text
101 get { return base.Text; }
102 set { base.Text = value; }
105 public void Initialise()
107 Controller.Initialise();
110 protected override void Dispose(bool disposing)
117 if (disposing && (components != null))
119 components.Dispose();
121 base.Dispose(disposing);
124 #region Configuration tab
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
129 public void InitialiseSettingsComponent(CECSettings settings)
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);
144 private void BSaveClick(object sender, EventArgs e)
146 Controller.PersistSettings();
149 private void BReloadConfigClick(object sender, EventArgs e)
151 Controller.ResetDefaultSettings();
155 #region CEC Tester tab
156 delegate void SetActiveDevicesCallback(string[] activeDevices);
157 public void SetActiveDevices(string[] activeDevices)
159 if (cbCommandDestination.InvokeRequired)
161 SetActiveDevicesCallback d = SetActiveDevices;
164 Invoke(d, new object[] { activeDevices });
166 catch (Exception) { }
170 cbCommandDestination.Items.Clear();
171 foreach (string item in activeDevices)
172 cbCommandDestination.Items.Add(item);
176 delegate CecLogicalAddress GetTargetDeviceCallback();
177 private CecLogicalAddress GetTargetDevice()
179 if (cbCommandDestination.InvokeRequired)
181 GetTargetDeviceCallback d = GetTargetDevice;
182 CecLogicalAddress retval = CecLogicalAddress.Unknown;
185 retval = (CecLogicalAddress)Invoke(d, new object[] { });
187 catch (Exception) { }
191 return CECSettingLogicalAddresses.GetLogicalAddressFromString(cbCommandDestination.Text);
194 private void BSendImageViewOnClick(object sender, EventArgs e)
196 Controller.CECActions.SendImageViewOn(GetTargetDevice());
199 private void BStandbyClick(object sender, EventArgs e)
201 Controller.CECActions.SendStandby(GetTargetDevice());
204 private void BScanClick(object sender, EventArgs e)
206 Controller.CECActions.ShowDeviceInfo(GetTargetDevice());
209 private void BActivateSourceClick(object sender, EventArgs e)
211 Controller.CECActions.ActivateSource(GetTargetDevice());
214 private void CbCommandDestinationSelectedIndexChanged(object sender, EventArgs e)
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);
224 private void BVolUpClick(object sender, EventArgs e)
226 Controller.Lib.VolumeUp(true);
229 private void BVolDownClick(object sender, EventArgs e)
231 Controller.Lib.VolumeDown(true);
234 private void BMuteClick(object sender, EventArgs e)
236 Controller.Lib.MuteAudio(true);
239 private void BRescanDevicesClick(object sender, EventArgs e)
241 Controller.CECActions.RescanDevices();
246 delegate void UpdateLogCallback();
247 private void UpdateLog()
249 if (tbLog.InvokeRequired)
251 UpdateLogCallback d = UpdateLog;
254 Invoke(d, new object[] { });
256 catch (Exception) { }
261 tbLog.Select(tbLog.Text.Length, 0);
262 tbLog.ScrollToCaret();
266 public void AddLogMessage(CecLogMessage message)
268 string strLevel = "";
269 bool display = false;
270 switch (message.Level)
272 case CecLogLevel.Error:
273 strLevel = "ERROR: ";
274 display = cbLogError.Checked;
276 case CecLogLevel.Warning:
277 strLevel = "WARNING: ";
278 display = cbLogWarning.Checked;
280 case CecLogLevel.Notice:
281 strLevel = "NOTICE: ";
282 display = cbLogNotice.Checked;
284 case CecLogLevel.Traffic:
285 strLevel = "TRAFFIC: ";
286 display = cbLogTraffic.Checked;
288 case CecLogLevel.Debug:
289 strLevel = "DEBUG: ";
290 display = cbLogDebug.Checked;
296 string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message) + Environment.NewLine;
297 AddLogMessage(strLog);
301 public void AddLogMessage(string message)
305 if (_selectedTab == ConfigTab.Log)
309 private void BClearLogClick(object sender, EventArgs e)
315 private void BSaveLogClick(object sender, EventArgs e)
317 SaveFileDialog dialog = new SaveFileDialog
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,
326 if (dialog.ShowDialog() == DialogResult.OK)
328 FileStream fs = (FileStream)dialog.OpenFile();
331 MessageBox.Show(string.Format(Resources.cannot_open_for_writing, dialog.FileName), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Error);
335 StreamWriter writer = new StreamWriter(fs);
340 MessageBox.Show(string.Format(Resources.log_stored_as, dialog.FileName), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Information);
346 #region Tray icon and window controls
347 private void HideToolStripMenuItemClick(object sender, EventArgs e)
352 private void CloseToolStripMenuItemClick(object sender, EventArgs e)
357 private void AboutToolStripMenuItemClick(object sender, EventArgs e)
359 (new About(Controller.LibServerVersion, Controller.LibClientVersion, Controller.LibInfo)).ShowDialog();
362 private void AdvancedModeToolStripMenuItemClick(object sender, EventArgs e)
364 Controller.Settings.AdvancedMode.Value = !advancedModeToolStripMenuItem.Checked;
365 ShowHideAdvanced(!advancedModeToolStripMenuItem.Checked);
368 private void BCancelClick(object sender, EventArgs e)
373 private void TrayIconClick(object sender, EventArgs e)
375 if (e is MouseEventArgs && (e as MouseEventArgs).Button == MouseButtons.Left)
381 ShowInTaskbar = false;
383 tsMenuShowHide.Text = Resources.show;
388 ShowInTaskbar = true;
389 WindowState = FormWindowState.Normal;
391 tsMenuShowHide.Text = Resources.hide;
394 private void ShowHideToggle()
396 if (Visible && WindowState != FormWindowState.Minimized)
398 Controller.Settings.StartHidden.Value = true;
403 Controller.Settings.StartHidden.Value = false;
408 private void TsMenuCloseClick(object sender, EventArgs e)
413 private void CECTrayResize(object sender, EventArgs e)
415 if (WindowState == FormWindowState.Minimized)
421 private void TsMenuShowHideClick(object sender, EventArgs e)
426 public void ShowHideAdvanced(bool setTo)
430 tsAdvanced.Checked = true;
431 advancedModeToolStripMenuItem.Checked = true;
433 if (!tabPanel.Controls.Contains(tbTestCommands))
434 TabControls.Add(tbTestCommands);
435 if (!tabPanel.Controls.Contains(LogOutput))
436 TabControls.Add(LogOutput);
441 tsAdvanced.Checked = false;
442 advancedModeToolStripMenuItem.Checked = false;
444 tabPanel.Controls.Remove(tbTestCommands);
445 tabPanel.Controls.Remove(LogOutput);
450 private void TsAdvancedClick(object sender, EventArgs e)
452 Controller.Settings.AdvancedMode.Value = !tsAdvanced.Checked;
453 ShowHideAdvanced(!tsAdvanced.Checked);
456 public void SetStatusText(string status)
458 SetControlText(lStatus, status);
461 public void SetProgressBar(int progress, bool visible)
463 SetControlVisible(pProgress, visible);
464 SetProgressValue(pProgress, progress);
467 public void SetControlsEnabled(bool val)
470 SetControlEnabled(bClose, val);
471 SetControlEnabled(bSaveConfig, val);
472 SetControlEnabled(bReloadConfig, val);
475 SetControlEnabled(bRescanDevices, val);
476 SetControlEnabled(bSendImageViewOn, val);
477 SetControlEnabled(bStandby, val);
478 SetControlEnabled(bActivateSource, val);
479 SetControlEnabled(bScan, val);
481 bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem) && val;
482 SetControlEnabled(bVolUp, enableVolumeButtons);
483 SetControlEnabled(bVolDown, enableVolumeButtons);
484 SetControlEnabled(bMute, enableVolumeButtons);
487 private void TabControl1SelectedIndexChanged(object sender, EventArgs e)
489 switch (tabPanel.TabPages[tabPanel.SelectedIndex].Name)
491 case "tbTestCommands":
492 _selectedTab = ConfigTab.Tester;
495 _selectedTab = ConfigTab.Log;
499 _selectedTab = ConfigTab.Configuration;
505 #region Class members
506 private ConfigTab _selectedTab = ConfigTab.Configuration;
507 private string _log = string.Empty;
508 private CECController _controller;
509 public CECController Controller
513 return _controller ?? (_controller = new CECController(this));
516 public Control.ControlCollection TabControls
518 get { return tabPanel.Controls; }
520 public string SelectedTabName
522 get { return GetSelectedTabName(tabPanel, tabPanel.TabPages); }
526 private void AddNewApplicationToolStripMenuItemClick(object sender, EventArgs e)
528 ConfigureApplication appConfig = new ConfigureApplication(Controller.Settings, Controller);
529 Controller.DisplayDialog(appConfig, false);