//-----------------------------------------------------------------------
//
// Copyright © 2012 Nils Hammar. All rights reserved.
//
//-----------------------------------------------------------------------
/*
* Software to access vehicle information via the OBD-II connector.
*
* Copyright © 2012 Nils Hammar
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Alternative licensing is possible, see the licensing document.
*
* The above text may not be removed or modified.
*/
namespace UserInterface.GUI.OBD
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
using global::SharedObjects;
using global::SharedObjects.GUI;
using global::SharedObjects.Misc;
using global::UserInterface.GUI.Objects;
///
/// Common class for some controls, should have been abstract
/// but can't be due to shortcomings in Visual Studio Designer.
///
public class AbstractUserControl : UserControl, IDataEventCallback
{
///
/// Gets application Tree instance.
///
protected IApplicationTree applicationTree { get; private set; }
///
/// Gets node in tree that "owns" this control.
///
protected PanelTreeNode owningNode { get; private set; }
///
/// Gets or sets logging instance.
///
protected ILogging iLogging { get; set; }
///
/// Gets current vehicle instance.
///
protected XmlClass.vehicle vehicle { get; private set; }
///
/// Gets dictionary of ECU:s.
///
protected SortedDictionary ecuData { get; private set; }
///
/// Initializes a new instance of the class.
///
protected AbstractUserControl()
{
this.ecuData = new SortedDictionary();
this.iLogging = null;
this.vehicle = null;
this.applicationTree = null;
}
///
/// Initializes a new instance of the class.
///
/// Event logging instance.
/// Vehicle instance.
/// Application Tree instance.
protected AbstractUserControl(ILogging iLogging, XmlClass.vehicle vehicle, IApplicationTree applicationTree)
{
this.ecuData = new SortedDictionary();
this.iLogging = iLogging;
this.vehicle = vehicle;
this.applicationTree = applicationTree;
}
///
/// Set the owning node for this panel.
///
/// Node in tree that "owns" this panel.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "owningNode", Justification = "Reviewed, intentional.")]
public void setOwningNode(PanelTreeNode owningNode)
{
this.owningNode = owningNode;
}
///
/// Trig a get data event.
///
public virtual void getDataEvent()
{
throw new NotImplementedException("Override this function!");
}
///
/// Set the Application Tree instance.
///
/// Application tree instance.
protected void setApplicationTree(IApplicationTree applicationTree)
{
this.applicationTree = applicationTree;
}
///
/// Get data display panel instance by ECU source address.
///
/// ECU source address.
/// Freeze frame number.
/// ECU data panel instance.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Reviewed.")]
protected EcuDataPanel getDataPanelByAddress(uint sourceAddress, int frameNumber)
{
EcuDataPanel ecuDataPanel = null;
if (this.applicationTree.InvokeRequired)
{
try
{
ecuDataPanel = (EcuDataPanel)this.applicationTree.Invoke(new getDataPanelByAddressFunc(this.getDataPanelByAddress), new object[] { sourceAddress, frameNumber });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
if (!this.ecuData.ContainsKey(sourceAddress))
{
string ecuName = this.getEcuName(sourceAddress);
ecuDataPanel = new EcuDataPanel(this.iLogging, this.applicationTree, ecuName, this);
ecuDataPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right)));
PanelTreeNode dataNode;
if (frameNumber == -1)
{
dataNode = new PanelTreeNode(ecuName, "application_form_magnify.png", "application_form_magnify.png", ecuDataPanel);
}
else
{
EmptyControl emptyControl = new EmptyControl();
dataNode = new PanelTreeNode(ecuName, "application_cascade.png", "application_cascade.png", emptyControl);
PanelTreeNode dataNode1 = new PanelTreeNode("Frame #" + frameNumber, "application_form_magnify.png", "application_form_magnify.png", ecuDataPanel, frameNumber);
dataNode.Nodes.Add(dataNode1);
dataNode.Expand();
}
this.owningNode.Nodes.Add(dataNode);
this.owningNode.Expand();
this.ecuData.Add(sourceAddress, dataNode);
}
else
{
if (frameNumber == -1)
{
ecuDataPanel = (EcuDataPanel)(this.ecuData[sourceAddress].userControl);
}
else
{
ecuDataPanel = null;
foreach (PanelTreeNode panel in this.ecuData[sourceAddress].Nodes)
{
if (panel.frameNumber == frameNumber)
{
ecuDataPanel = (EcuDataPanel)panel.userControl;
}
}
if (ecuDataPanel == null)
{
string ecuName = this.getEcuName(sourceAddress);
ecuDataPanel = new EcuDataPanel(this.iLogging, this.applicationTree, ecuName, this);
ecuDataPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right)));
PanelTreeNode dataNode1 = new PanelTreeNode("Frame #" + frameNumber, "application_form_magnify.png", "application_form_magnify.png", ecuDataPanel, frameNumber);
this.ecuData[sourceAddress].Nodes.Add(dataNode1);
this.ecuData[sourceAddress].Expand();
}
}
}
}
return ecuDataPanel;
}
///
/// Get the name of the ECU for the given address.
///
/// ECU address.
/// ECU name.
private string getEcuName(uint sourceAddress)
{
string ecuName = null;
uint mask;
if (sourceAddress < 0x800 && sourceAddress > 0xff)
{
mask = 0x07;
}
else
{
mask = 0xff;
}
foreach (XmlClass.vehicle.ecuData ecu in this.vehicle.ecus)
{
uint id = Utils.hexParse(ecu.id);
if ((id & mask) == (sourceAddress & mask))
{
ecuName = ecu.name;
break;
}
}
if (ecuName == null)
{
ecuName = "ECU 0x" + sourceAddress.ToString("x2");
}
return ecuName;
}
///
/// Get panel instance by ECU source address.
///
/// ECU source address.
/// Freeze frame number.
/// EcuDataPanel instance.
private delegate EcuDataPanel getDataPanelByAddressFunc(uint sourceAddress, int frameNumber);
}
}