cec: added RescanDevices()/cec_rescan_devices() to the interface, to let libCEC force...
[deb_libcec.git] / src / cec-config-gui / CecConfigGUI.cs
index b1731cfa2c8dfdcae7bb92ece32b03fab0c9a482..e3decec7fe03ef9907b602182cc21f214f52136b 100644 (file)
@@ -14,6 +14,14 @@ using System.Xml;
 
 namespace CecConfigGui
 {
+  internal enum ConfigTab
+  {
+    Configuration,
+    KeyConfiguration,
+    Tester,
+    Log
+  }
+
   public partial class CecConfigGUI : AsyncForm
   {
     public CecConfigGUI()
@@ -31,14 +39,6 @@ namespace CecConfigGui
       InitializeComponent();
       LoadButtonConfiguration();
 
-      //TODO read the com port setting from the configuration
-      CecAdapter[] adapters = Lib.FindAdapters(string.Empty);
-      if (adapters.Length == 0 || !Lib.Open(adapters[0].ComPort, 10000))
-      {
-        MessageBox.Show("Could not connect to any CEC adapter. Please check your configuration and try again.", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK);
-        Application.Exit();
-      }
-
       ActiveProcess = new ConnectToDevice(ref Lib, Config);
       ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
       (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
@@ -271,6 +271,7 @@ namespace CecConfigGui
           SetControlText(tbPhysicalAddress, string.Format("{0,4:X}", updateEvent.IntValue));
           break;
         case UpdateEventType.ProgressBar:
+          SetControlVisible(pProgress, true);
           SetProgressValue(pProgress, updateEvent.IntValue);
           break;
         case UpdateEventType.TVVendorId:
@@ -305,13 +306,111 @@ namespace CecConfigGui
           ConfigurationChanged(updateEvent.ConfigValue);
           SuppressUpdates = false;
           break;
+        case UpdateEventType.PollDevices:
+          CheckActiveDevices();
+          break;
         case UpdateEventType.ProcessCompleted:
           ActiveProcess = null;
           SetControlsEnabled(true);
+          if (UpdatingInfoPanel != null)
+          {
+            UpdatingInfoPanel.SetControlEnabled(UpdatingInfoPanel.bUpdate, true);
+            UpdatingInfoPanel = null;
+          }
+          SetControlVisible(pProgress, false);
           break;
       }
     }
 
+    private void SetControlsEnabled(bool val)
+    {
+      SetControlEnabled(cbPortNumber, val && !Config.AutodetectAddress);
+      SetControlEnabled(cbConnectedDevice, cbConnectedDevice.Items.Count > 1 && !Config.AutodetectAddress ? val : false);
+      SetControlEnabled(tbPhysicalAddress, val && !Config.AutodetectAddress);
+      SetControlEnabled(cbDeviceType, val);
+      SetControlEnabled(cbUseTVMenuLanguage, val);
+      SetControlEnabled(cbActivateSource, val);
+      SetControlEnabled(cbPowerOffScreensaver, val);
+      SetControlEnabled(cbPowerOffOnStandby, val);
+      SetControlEnabled(cbWakeDevices, val);
+      SetControlEnabled(cbPowerOffDevices, val);
+      SetControlEnabled(cbVendorOverride, val);
+      SetControlEnabled(cbVendorId, val && cbVendorOverride.Checked);
+      SetControlEnabled(bClose, val);
+      SetControlEnabled(bSaveConfig, val);
+      SetControlEnabled(bReloadConfig, val);
+      SetControlEnabled(bRescanDevices, val);
+
+      SetControlEnabled(bSendImageViewOn, val);
+      SetControlEnabled(bStandby, val);
+      SetControlEnabled(bActivateSource, val);
+      SetControlEnabled(bScan, val);
+
+      bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem) && val;
+      SetControlEnabled(bVolUp, enableVolumeButtons);
+      SetControlEnabled(bVolDown, enableVolumeButtons);
+      SetControlEnabled(bMute, enableVolumeButtons);
+    }
+
+    private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
+    {
+      switch (tabControl1.SelectedIndex)
+      {
+        case 0:
+          SelectedTab = ConfigTab.Configuration;
+          break;
+        case 1:
+          SelectedTab = ConfigTab.KeyConfiguration;
+          break;
+        case 2:
+          SelectedTab = ConfigTab.Tester;
+          break;
+        case 3:
+          SelectedTab = ConfigTab.Log;
+          UpdateLog();
+          break;
+        default:
+          SelectedTab = ConfigTab.Configuration;
+          break;
+      }
+    }
+
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing)
+      {
+        Lib.DisableCallbacks();
+        Lib.StandbyDevices(CecLogicalAddress.Broadcast);
+        Lib.Close();
+      }
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Actions
+    public void ReloadXMLConfiguration()
+    {
+      LoadXMLConfiguration(ref Config);
+      Lib.SetConfiguration(Config);
+      ConfigurationChanged(Config);
+    }
+
+    public void UpdateInfoPanel(DeviceInformation panel)
+    {
+      if (!SuppressUpdates && ActiveProcess == null)
+      {
+        SetControlsEnabled(false);
+        UpdatingInfoPanel = panel;
+        panel.SetControlEnabled(panel.bUpdate, false);
+        ActiveProcess = new UpdateDeviceInfo(this, ref Lib, panel);
+        ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
+        (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
+      }
+    }
+
     public void SetPhysicalAddress(ushort physicalAddress)
     {
       if (!SuppressUpdates && ActiveProcess == null)
@@ -325,6 +424,17 @@ namespace CecConfigGui
       }
     }
 
+    public void UpdateConfigurationAsync()
+    {
+      if (!SuppressUpdates && ActiveProcess == null)
+      {
+        SetControlsEnabled(false);
+        ActiveProcess = new UpdateConfiguration(ref Lib, Config);
+        ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
+        (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
+      }
+    }
+
     public void SendImageViewOn(CecLogicalAddress address)
     {
       if (!SuppressUpdates && ActiveProcess == null)
@@ -368,34 +478,7 @@ namespace CecConfigGui
         (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
       }
     }
-
-    private void SetControlsEnabled(bool val)
-    {
-      SetControlEnabled(cbPortNumber, val);
-      SetControlEnabled(cbConnectedDevice, cbConnectedDevice.Items.Count > 1 ? val : false);
-      SetControlEnabled(tbPhysicalAddress, val);
-      SetControlEnabled(cbDeviceType, false); // TODO not implemented yet
-      SetControlEnabled(cbUseTVMenuLanguage, val);
-      SetControlEnabled(cbActivateSource, val);
-      SetControlEnabled(cbPowerOffScreensaver, val);
-      SetControlEnabled(cbPowerOffOnStandby, val);
-      SetControlEnabled(cbWakeDevices, false); // TODO not implemented yet
-      SetControlEnabled(cbPowerOffDevices, false); // TODO not implemented yet
-      SetControlEnabled(cbVendorOverride, false); // TODO not implemented yet
-      SetControlEnabled(cbVendorId, false); // TODO not implemented yet
-      SetControlEnabled(bClose, val);
-      SetControlEnabled(bSave, val);
-
-      SetControlEnabled(bSendImageViewOn, val);
-      SetControlEnabled(bStandby, val);
-      SetControlEnabled(bActivateSource, val);
-      SetControlEnabled(bScan, val);
-
-      bool enableVolumeButtons = (GetTargetDevice() == CecLogicalAddress.AudioSystem) && val;
-      SetControlEnabled(bVolUp, enableVolumeButtons);
-      SetControlEnabled(bVolDown, enableVolumeButtons);
-      SetControlEnabled(bMute, enableVolumeButtons);
-    }
+    #endregion
 
     #region Configuration tab
     private void tbPhysicalAddress_TextChanged(object sender, EventArgs e)
@@ -446,6 +529,8 @@ namespace CecConfigGui
       Config.ActivateSource = cbActivateSource.Checked;
       Config.PowerOffScreensaver = cbPowerOffScreensaver.Checked;
       Config.PowerOffOnStandby = cbPowerOffOnStandby.Checked;
+      Config.WakeDevices = WakeDevices;
+      Config.PowerOffDevices = PowerOffDevices;
 
       if (!Lib.CanPersistConfiguration())
       {
@@ -466,10 +551,19 @@ namespace CecConfigGui
 
           if (dialog.ShowDialog() == DialogResult.OK)
           {
-            FileStream fs = (FileStream)dialog.OpenFile();
+            FileStream fs = null;
+            string error = string.Empty;
+            try
+            {
+              fs = (FileStream)dialog.OpenFile();
+            }
+            catch (Exception ex)
+            {
+              error = ex.Message;
+            }
             if (fs == null)
             {
-              MessageBox.Show("Cannot open '" + dialog.FileName + "' for writing", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Error);
+              MessageBox.Show("Cannot open '" + dialog.FileName + "' for writing" + (error.Length > 0 ? ": " + error : string.Empty ), "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Error);
             }
             else
             {
@@ -487,20 +581,21 @@ namespace CecConfigGui
               output.AppendLine("<setting id=\"port\" value=\"\" />");
 
               // only supported by 1.5.0+ clients
+              output.AppendLine("<!-- the following lines are only supported by v1.5.0+ clients -->");
               output.AppendLine("<setting id=\"physical_address\" value=\"" + string.Format("{0,4:X}", Config.PhysicalAddress) + "\" />");
               output.AppendLine("<setting id=\"device_type\" value=\"" + (int)Config.DeviceTypes.Types[0] + "\" />");
-              output.AppendLine("<setting id=\"tv_vendor\" value=\"" + string.Format("{0,6:X}", (int)Config.TvVendor) + "\" />");
+              output.AppendLine("<setting id=\"tv_vendor\" value=\"" + string.Format("{0,6:X}", (int)Config.TvVendor).Trim() + "\" />");
 
               output.Append("<setting id=\"wake_devices\" value=\"");
               foreach (CecLogicalAddress addr in Config.WakeDevices.Addresses)
-                if (addr != CecLogicalAddress.Unregistered)
-                  output.Append(" " + addr);
+                if (addr != CecLogicalAddress.Unknown)
+                  output.Append(" " + (int)addr);
               output.AppendLine("\" />");
 
               output.Append("<setting id=\"standby_devices\" value=\"");
               foreach (CecLogicalAddress addr in Config.PowerOffDevices.Addresses)
-                if (addr != CecLogicalAddress.Unregistered)
-                  output.Append(" " + addr);
+                if (addr != CecLogicalAddress.Unknown)
+                  output.Append(" " + (int)addr);
               output.AppendLine("\" />");
 
               output.AppendLine("</settings>");
@@ -523,6 +618,76 @@ namespace CecConfigGui
       }
       SetControlsEnabled(true);
     }
+
+    private void bReloadConfig_Click(object sender, EventArgs e)
+    {
+      if (Lib.CanPersistConfiguration())
+      {
+        Lib.GetCurrentConfiguration(Config);
+        ConfigurationChanged(Config);
+      }
+      else
+      {
+        ReloadXMLConfiguration();
+      }
+    }
+
+    private void cbVendorOverride_CheckedChanged(object sender, EventArgs e)
+    {
+      if (cbVendorOverride.Checked)
+      {
+        cbVendorId.Enabled = true;
+        switch (cbVendorId.Text)
+        {
+          case "LG":
+            Config.TvVendor = CecVendorId.LG;
+            break;
+          case "Onkyo":
+            Config.TvVendor = CecVendorId.Onkyo;
+            break;
+          case "Panasonic":
+            Config.TvVendor = CecVendorId.Panasonic;
+            break;
+          case "Philips":
+            Config.TvVendor = CecVendorId.Philips;
+            break;
+          case "Pioneer":
+            Config.TvVendor = CecVendorId.Pioneer;
+            break;
+          case "Samsung":
+            Config.TvVendor = CecVendorId.Samsung;
+            break;
+          case "Sony":
+            Config.TvVendor = CecVendorId.Sony;
+            break;
+          case "Yamaha":
+            Config.TvVendor = CecVendorId.Yamaha;
+            break;
+          default:
+            Config.TvVendor = CecVendorId.Unknown;
+            break;
+        }
+      }
+      else
+      {
+        cbVendorId.Enabled = false;
+        Config.TvVendor = CecVendorId.Unknown;
+      }
+    }
+
+    private void cbDeviceType_SelectedIndexChanged(object sender, EventArgs e)
+    {
+      CecDeviceType type = SelectedDeviceType;
+      if (type != Config.DeviceTypes.Types[0])
+      {
+        Config.DeviceTypes.Types[0] = type;
+        if (!DeviceChangeWarningDisplayed)
+        {
+          DeviceChangeWarningDisplayed = true;
+          MessageBox.Show("You have changed the device type. Save the configuration, and restart the application to use the new setting.", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+        }
+      }
+    }
     #endregion
 
     #region Key configuration tab
@@ -570,6 +735,40 @@ namespace CecConfigGui
     #endregion
 
     #region CEC Tester tab
+    public void CheckActiveDevices()
+    {
+      CecLogicalAddresses activeDevices = Lib.GetActiveDevices();
+      List<string> deviceList = new List<string>();
+      foreach (CecLogicalAddress activeDevice in activeDevices.Addresses)
+      {
+        if (activeDevice != CecLogicalAddress.Unknown)
+          deviceList.Add(string.Format("{0,1:X} : {1}", (int)activeDevice, Lib.ToString(activeDevice)));
+      }
+      deviceList.Add(string.Format("{0,1:X} : {1}", (int)CecLogicalAddress.Broadcast, Lib.ToString(CecLogicalAddress.Broadcast)));
+
+      SetActiveDevices(deviceList.ToArray());
+    }
+
+    delegate void SetActiveDevicesCallback(string[] activeDevices);
+    private void SetActiveDevices(string[] activeDevices)
+    {
+      if (this.cbCommandDestination.InvokeRequired)
+      {
+        SetActiveDevicesCallback d = new SetActiveDevicesCallback(SetActiveDevices);
+        try
+        {
+          this.Invoke(d, new object[] { activeDevices });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        this.cbCommandDestination.Items.Clear();
+        foreach (string item in activeDevices)
+          this.cbCommandDestination.Items.Add(item);
+      }
+    }
+
     delegate CecLogicalAddress GetTargetDeviceCallback();
     private CecLogicalAddress GetTargetDevice()
     {
@@ -585,7 +784,12 @@ namespace CecConfigGui
         return retval;
       }
 
-      switch (this.cbCommandDestination.Text.Substring(0, 1).ToLower())
+      return GetLogicalAddressFromString(this.cbCommandDestination.Text);
+    }
+
+    private CecLogicalAddress GetLogicalAddressFromString(string name)
+    {
+      switch (name.Substring(0, 1).ToLower())
       {
         case "0":
           return CecLogicalAddress.Tv;
@@ -650,6 +854,8 @@ namespace CecConfigGui
       this.bVolUp.Enabled = enableVolumeButtons;
       this.bVolDown.Enabled = enableVolumeButtons;
       this.bMute.Enabled = enableVolumeButtons;
+      this.bActivateSource.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
+      this.bScan.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
     }
 
     private void bVolUp_Click(object sender, EventArgs e)
@@ -672,64 +878,84 @@ namespace CecConfigGui
       Lib.MuteAudio(true);
       SetControlsEnabled(true);
     }
+
+    private void bRescanDevices_Click(object sender, EventArgs e)
+    {
+      if (!SuppressUpdates && ActiveProcess == null)
+      {
+        SetControlsEnabled(false);
+        ActiveProcess = new RescanDevices(ref Lib);
+        ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
+        (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
+      }
+    }
     #endregion
 
     #region Log tab
-    delegate void AddLogMessageCallback(CecLogMessage message);
-    private void AddLogMessage(CecLogMessage message)
+    delegate void UpdateLogCallback();
+    private void UpdateLog()
     {
       if (tbLog.InvokeRequired)
       {
-        AddLogMessageCallback d = new AddLogMessageCallback(AddLogMessage);
+        UpdateLogCallback d = new UpdateLogCallback(UpdateLog);
         try
         {
-          this.Invoke(d, new object[] { message });
+          this.Invoke(d, new object[] { });
         }
         catch (Exception) { }
       }
       else
       {
-        string strLevel = "";
-        bool display = false;
-        switch (message.Level)
-        {
-          case CecLogLevel.Error:
-            strLevel = "ERROR:   ";
-            display = cbLogError.Checked;
-            break;
-          case CecLogLevel.Warning:
-            strLevel = "WARNING: ";
-            display = cbLogWarning.Checked;
-            break;
-          case CecLogLevel.Notice:
-            strLevel = "NOTICE:  ";
-            display = cbLogNotice.Checked;
-            break;
-          case CecLogLevel.Traffic:
-            strLevel = "TRAFFIC: ";
-            display = cbLogTraffic.Checked;
-            break;
-          case CecLogLevel.Debug:
-            strLevel = "DEBUG:   ";
-            display = cbLogDebug.Checked;
-            break;
-          default:
-            break;
-        }
+        tbLog.Text = Log;
+        tbLog.Select(tbLog.Text.Length, 0);
+        tbLog.ScrollToCaret();
+      }
+    }
 
-        if (display)
-        {
-          string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message) + System.Environment.NewLine;
-          tbLog.Text += strLog;
-          tbLog.Select(tbLog.Text.Length, 0);
-          tbLog.ScrollToCaret();
-        }
+    private void AddLogMessage(CecLogMessage message)
+    {
+      string strLevel = "";
+      bool display = false;
+      switch (message.Level)
+      {
+        case CecLogLevel.Error:
+          strLevel = "ERROR:   ";
+          display = cbLogError.Checked;
+          break;
+        case CecLogLevel.Warning:
+          strLevel = "WARNING: ";
+          display = cbLogWarning.Checked;
+          break;
+        case CecLogLevel.Notice:
+          strLevel = "NOTICE:  ";
+          display = cbLogNotice.Checked;
+          break;
+        case CecLogLevel.Traffic:
+          strLevel = "TRAFFIC: ";
+          display = cbLogTraffic.Checked;
+          break;
+        case CecLogLevel.Debug:
+          strLevel = "DEBUG:   ";
+          display = cbLogDebug.Checked;
+          break;
+        default:
+          break;
+      }
+
+      if (display)
+      {
+        string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message) + System.Environment.NewLine;
+        Log += strLog;
       }
+
+      if (SelectedTab == ConfigTab.Log)
+        UpdateLog();
     }
 
     private void bClearLog_Click(object sender, EventArgs e)
     {
-      tbLog.Text = string.Empty;
+      Log = string.Empty;
+      UpdateLog();
     }
 
     private void bSaveLog_Click(object sender, EventArgs e)
@@ -753,7 +979,7 @@ namespace CecConfigGui
         else
         {
           StreamWriter writer = new StreamWriter(fs);
-          writer.Write(tbLog.Text);
+          writer.Write(Log);
           writer.Close();
           fs.Close();
           fs.Dispose();
@@ -770,11 +996,44 @@ namespace CecConfigGui
       SetControlText(tbPhysicalAddress, string.Format("{0,4:X}", Config.PhysicalAddress));
       SetControlText(cbConnectedDevice, Config.BaseDevice == CecLogicalAddress.AudioSystem ? AVRVendorString : TVVendorString);
       SetControlText(cbPortNumber, Config.HDMIPort.ToString());
+      switch (config.DeviceTypes.Types[0])
+      {
+        case CecDeviceType.RecordingDevice:
+          SetControlText(cbDeviceType, "Recorder");
+          break;
+        case CecDeviceType.PlaybackDevice:
+          SetControlText(cbDeviceType, "Player");
+          break;
+        case CecDeviceType.Tuner:
+          SetControlText(cbDeviceType, "Tuner");
+          break;
+        default:
+          SetControlText(cbDeviceType, "Recorder");
+          break;
+      }
+      if (config.TvVendor != CecVendorId.Unknown)
+      {
+        SetCheckboxChecked(cbVendorOverride, true);
+        SetControlText(cbVendorId, Lib.ToString(config.TvVendor));
+      }
+      else
+      {
+        SetCheckboxChecked(cbVendorOverride, false);
+        SetControlText(cbVendorId, Lib.ToString(TVVendor));
+      }
+
       SetCheckboxChecked(cbUseTVMenuLanguage, Config.UseTVMenuLanguage);
       SetCheckboxChecked(cbActivateSource, Config.ActivateSource);
       SetCheckboxChecked(cbPowerOffScreensaver, Config.PowerOffScreensaver);
       SetCheckboxChecked(cbPowerOffOnStandby, Config.PowerOffOnStandby);
       UpdateSelectedDevice();
+
+      for (int iPtr = 0; iPtr < 15; iPtr++)
+        SetCheckboxItemChecked(cbWakeDevices, iPtr, Config.WakeDevices.IsSet((CecLogicalAddress)iPtr));
+      for (int iPtr = 0; iPtr < 15; iPtr++)
+        SetCheckboxItemChecked(cbPowerOffDevices, iPtr, Config.PowerOffDevices.IsSet((CecLogicalAddress)iPtr));
+
+      SetControlText(this, "Pulse-Eight USB-CEC Adapter - libCEC " + Lib.ToString(Config.ServerVersion));
       return 1;
     }
 
@@ -791,7 +1050,11 @@ namespace CecConfigGui
 
     public int ReceiveLogMessage(CecLogMessage message)
     {
-      AddLogMessage(message);
+      try
+      {
+        AddLogMessage(message);
+      }
+      catch (Exception) { }
       return 1;
     }
     #endregion
@@ -839,6 +1102,21 @@ namespace CecConfigGui
         return (cbConnectedDevice.Text.Equals(AVRVendorString)) ? CecLogicalAddress.AudioSystem : CecLogicalAddress.Tv;
       }
     }
+    public CecDeviceType SelectedDeviceType
+    {
+      get
+      {
+        switch (cbDeviceType.Text.ToLower())
+        {
+          case "player":
+            return CecDeviceType.PlaybackDevice;
+          case "tuner":
+            return CecDeviceType.Tuner;
+          default:
+            return CecDeviceType.RecordingDevice;
+        }
+      }
+    }
     public int SelectedPortNumber
     {
       get
@@ -853,7 +1131,37 @@ namespace CecConfigGui
     protected LibCecSharp Lib;
     private CecCallbackWrapper Callbacks;
     private UpdateProcess ActiveProcess = null;
-    private bool SuppressUpdates = false;
+    private bool SuppressUpdates = true;
+    private ConfigTab SelectedTab = ConfigTab.Configuration;
+    private string Log = string.Empty;
+    private DeviceInformation UpdatingInfoPanel = null;
+    private bool DeviceChangeWarningDisplayed = false;
+    public CecLogicalAddresses WakeDevices
+    {
+      get
+      {
+        CecLogicalAddresses addr = new CecLogicalAddresses();
+        foreach (object item in this.cbWakeDevices.CheckedItems)
+        {
+          string c = item as string;
+          addr.Set(GetLogicalAddressFromString(c));
+        }
+        return addr;
+      }
+    }
+    public CecLogicalAddresses PowerOffDevices
+    {
+      get
+      {
+        CecLogicalAddresses addr = new CecLogicalAddresses();
+        foreach (object item in this.cbPowerOffDevices.CheckedItems)
+        {
+          string c = item as string;
+          addr.Set(GetLogicalAddressFromString(c));
+        }
+        return addr;
+      }
+    }
     #endregion
   }