//-----------------------------------------------------------------------
//
// 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 CanApp
{
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Windows.Forms;
using global::CanApp.SystemEvents;
using global::DataMgmt;
using global::DataSource;
using global::DeviceApi.J2534;
using global::DynamicApiLoading.Api.Dynamic;
using global::LoggingLibrary;
using global::SharedObjects;
using global::SharedObjects.Api;
using global::SharedObjects.DataMgmt;
using global::SharedObjects.GUI;
using global::SharedObjects.Misc;
using global::UserInterface.GUI;
using global::UserInterface.GUI.Popup;
///
/// Program to connect to CAN bus via OBD-II connector and log information.
///
public partial class CanMain : Form, IMiscFunc, ISerialPortMonitorCallback
{
///
/// Gets Actual data file directory.
///
public string dataFileDir { get; private set; }
///
/// PID group manager instance.
///
private PidGroupManager pidGrpManager = null;
///
/// Unit manager instance.
///
private UnitManager unitManager = null;
///
/// Mode Manager instance.
///
private ModeManager modeManager = null;
///
/// Mode Manager instance.
///
private IconsManager iconsManager = null;
///
/// Vehicles manager instance.
///
private VehiclesManager vehiclesManager = null;
///
/// Communication speed manager instance.
///
private CommSpeedManager commSpeedManager = null;
///
/// Parameter manager instance.
///
private ParametersManager parametersManager = null;
///
/// OBD code manager instance.
///
private ObdCodeManager obdCodeManager = null;
///
/// Available interfaces to use.
///
private IPassThru[] passthruInterfaces = null;
///
/// Logging form instance.
///
private ILogging iLogging;
///
/// Logging form instance.
///
private LoggingForm loggingForm;
///
/// List of interface panels.
///
private List interfacePanels = new List();
///
/// Preferences instance.
///
private IPreferences iPreferences;
///
/// Class for monitoring serial port changes.
///
private SerialPortMonitor serialPortMonitor;
///
/// Data source implementation instance.
///
private IDataSource iDataSource;
///
/// Dynamically located J2534 DLLs.
///
private DynamicLocater dynamicLocater;
///
/// The rude helper.
///
private Herman herman = null;
///
/// Hint engine instance.
///
private HintEngine hintEngine;
///
/// Vector Passthru instance.
///
private VectorPassthru vectorPassthru;
///
/// Initializes a new instance of the class.
///
/// Start Class for application.
///
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Reviewed, single instance only.")]
public CanMain()
{
this.InitializeComponent();
this.loggingForm = new LoggingForm();
this.iLogging = this.loggingForm;
this.dataFileDir = DataSourceImplementation.locateDataFiles();
this.iLogging.appendText("Data Directory: " + this.dataFileDir + "\r\n");
PreferencesPanel preferencesPanel = new PreferencesPanel(this.iLogging, this.dataFileDir);
this.iPreferences = preferencesPanel;
this.iDataSource = new DataSourceImplementation(this.iLogging, this.iPreferences, this.dataFileDir);
this.iDataSource.load();
preferencesPanel.setDataSource(this.iDataSource);
this.dynamicLocater = new DynamicLocater();
this.iLogging.appendText(this.dynamicLocater.ToString() + "\r\n");
try
{
this.vectorPassthru = new VectorPassthru(this.iLogging, this.iPreferences);
PassThruDevice.addDynamicInterface(this.vectorPassthru);
}
catch (Exception ex)
{
this.iLogging.appendText(ex.GetType().ToString() + ": " + ex.Message + "\r\n" + ex.StackTrace + "\r\n");
}
foreach (DynamicAdapter adapter in this.dynamicLocater.adapters)
{
try
{
DynPassthru dynPassthru = new DynPassthru(adapter);
PassThruDevice.addDynamicInterface(dynPassthru);
}
catch (DynamicLoaderException ex)
{
this.iLogging.appendText("DynamicLoaderException: " + adapter.Name + ": " + ex.Message + "\r\n");
}
}
this.hintEngine = new HintEngine(this.Location, preferencesPanel);
this.applicationTree1.init(this.contentPanel, this.hintEngine, this.dataFileDir);
this.applicationTree1.setPreferencesNode(preferencesPanel);
this.serialPortMonitor = new SerialPortMonitor(this);
this.updateInterfaces();
this.loggingForm.Show();
this.applicationTree1.Focus();
}
///
/// Get seconds string.
///
/// The number of seconds is relative to a saved timestamp.
///
///
/// Timestamp to relate to.
/// Seconds string.
public string getSecondsStr(long t1)
{
return this.loggingForm.getSecondsStr(t1);
}
///
/// Reload the vehicles drop-down with fresh data.
///
public void reloadVehicles()
{
foreach (InterfacePanel interfacePanel in this.interfacePanels)
{
interfacePanel.reloadVehicles();
}
}
///
/// Reload the serial port list.
///
/// Name of port that triggered the change, 'null' value permitted.
public void refreshSerialPortInfo(string newPort)
{
foreach (InterfacePanel interfacePanel in this.interfacePanels)
{
interfacePanel.refreshSerialPortInfo(newPort);
}
}
///
/// Update interfaces drop-down.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Reviewed, intentional.")]
private void updateInterfaces()
{
string[] portNames = SerialPort.GetPortNames();
this.passthruInterfaces = PassThruDevice.getInterfaces(this.iLogging);
for (int i = 0; i < this.passthruInterfaces.Length; i++)
{
if (!this.passthruInterfaces[i].isSerial() || portNames.Length > 0)
{
InterfacePanel interfacePanel = new InterfacePanel(
this,
this.iDataSource,
this.iLogging,
this.passthruInterfaces[i],
this.iPreferences,
this.applicationTree1,
this.hintEngine,
this.dataFileDir);
this.applicationTree1.addInterfaceNode(this.passthruInterfaces[i].name, interfacePanel);
this.interfacePanels.Add(interfacePanel);
}
}
this.serialPortMonitor.startThread();
}
///
/// Handling event of form being closed.
///
/// Sending object.
/// Event data.
private void CanMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.vectorPassthru != null)
{
this.vectorPassthru.Dispose();
}
this.serialPortMonitor.Close();
PassThruDevice.close();
if (this.pidGrpManager != null && this.pidGrpManager.CanFocus)
{
this.pidGrpManager.Close();
}
if (this.unitManager != null && this.unitManager.CanFocus)
{
this.unitManager.Close();
}
foreach (InterfacePanel interfacePanel in this.interfacePanels)
{
interfacePanel.closeDevice();
}
this.loggingForm.closeCanDataLog();
this.loggingForm.closeEventLog();
this.loggingForm.closeDataLog();
this.loggingForm.Close(true);
}
///
/// Open CAN data log menu event.
///
/// Sending object.
/// Event data.
private void openCanLogfileToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.loggingForm.openCanDataLog())
{
this.openCanLogfileToolStripMenuItem.Enabled = false;
this.closeCanLogfileToolStripMenuItem.Enabled = true;
}
}
///
/// Close CAN data log menu event.
///
/// Sending object.
/// Event data.
private void closeCanLogfileToolStripMenuItem_Click(object sender, EventArgs e)
{
this.loggingForm.closeCanDataLog();
this.openCanLogfileToolStripMenuItem.Enabled = true;
this.closeCanLogfileToolStripMenuItem.Enabled = false;
}
///
/// Exit application menu event.
///
/// Sending object.
/// Event data.
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
///
/// Open event log menu event.
///
/// Sending object.
/// Event data.
private void openEventLogfileToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.loggingForm.openEventLog())
{
this.openEventLogfileToolStripMenuItem.Enabled = false;
this.closeEventLogfileToolStripMenuItem.Enabled = true;
}
}
///
/// Close event log menu event.
///
/// Sending object.
/// Event data.
private void closeEventLogfileToolStripMenuItem_Click(object sender, EventArgs e)
{
this.loggingForm.closeEventLog();
this.openEventLogfileToolStripMenuItem.Enabled = true;
this.closeEventLogfileToolStripMenuItem.Enabled = false;
}
///
/// About menu event.
///
/// Sending object.
/// Event data.
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutBox1 ab = null;
try
{
ab = new AboutBox1();
ab.ShowDialog(this);
}
finally
{
if (ab != null)
{
ab.Dispose();
}
}
}
///
/// Save event window menu event.
///
/// Sending object.
/// Event data.
private void saveEventWindowMenuItem_Click(object sender, EventArgs e)
{
this.loggingForm.saveEventWindow();
}
///
/// Configure sensors menu event.
///
/// Sending object.
/// Event data.
private void sensorsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.pidGrpManager == null || !this.pidGrpManager.CanFocus)
{
this.pidGrpManager = new PidGroupManager(this.iLogging, this.iPreferences, this.iDataSource);
}
this.pidGrpManager.Visible = true;
this.pidGrpManager.Focus();
}
///
/// Configure units menu event.
///
/// Sending object.
/// Event data.
private void unitsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.unitManager == null || !this.unitManager.CanFocus)
{
this.unitManager = new UnitManager(this.iDataSource);
}
this.unitManager.Visible = true;
this.unitManager.Focus();
}
///
/// Configure Modes menu event.
///
/// Sending object.
/// Event data.
private void modesToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.modeManager == null || !this.modeManager.CanFocus)
{
this.modeManager = new ModeManager(this.iDataSource);
}
this.modeManager.Visible = true;
this.modeManager.Focus();
}
///
/// Configure vehicles menu event.
///
/// Sending object.
/// Event data.
private void vehiclesToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.vehiclesManager == null || !this.vehiclesManager.CanFocus)
{
this.vehiclesManager = new VehiclesManager(this.iLogging, this.iDataSource, this.dataFileDir);
}
this.vehiclesManager.Visible = true;
this.vehiclesManager.Focus();
}
///
/// Configure communication speeds menu event.
///
/// Sending object.
/// Event data.
private void communicationSpeedsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.commSpeedManager == null || !this.commSpeedManager.CanFocus)
{
this.commSpeedManager = new CommSpeedManager(this.iDataSource);
}
this.commSpeedManager.Visible = true;
this.commSpeedManager.Focus();
}
///
/// Configure parameters menu event.
///
/// Sending object.
/// Event data.
private void configParametersToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.parametersManager == null || !this.parametersManager.CanFocus)
{
this.parametersManager = new ParametersManager(this.iDataSource);
}
this.parametersManager.Visible = true;
this.parametersManager.Focus();
}
///
/// Configure OBD codes menu event.
///
/// Sending object.
/// Event data.
private void oBDCodesToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.obdCodeManager == null || !this.obdCodeManager.CanFocus)
{
this.obdCodeManager = new ObdCodeManager(this.iLogging, this.iDataSource, this.dataFileDir);
}
this.obdCodeManager.Visible = true;
this.obdCodeManager.Focus();
}
///
/// Open measurement data log file menu event.
///
/// Sending object.
/// Event data.
private void openMeasurementDataLogFileToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.loggingForm.openDataLog())
{
this.openMeasurementDataLogFileToolStripMenuItem.Enabled = false;
this.closeMeasurementDataLogFileToolStripMenuItem.Enabled = true;
}
}
///
/// Close measurement data log file menu event.
///
/// Sending object.
/// Event data.
private void closeMeasurementDataLogFileToolStripMenuItem_Click(object sender, EventArgs e)
{
this.loggingForm.closeDataLog();
this.openMeasurementDataLogFileToolStripMenuItem.Enabled = true;
this.closeMeasurementDataLogFileToolStripMenuItem.Enabled = false;
}
///
/// Icons menu clicked.
///
/// Sending object.
/// Event data.
private void iconsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.iconsManager == null || !this.iconsManager.CanFocus)
{
this.iconsManager = new IconsManager(this.iDataSource, this.dataFileDir);
}
this.iconsManager.Visible = true;
this.iconsManager.Focus();
}
///
/// Show the event log.
///
/// Sending object.
/// Event data.
private void eventLogToolStripMenuItem_Click(object sender, EventArgs e)
{
// this.loggingForm.Visible = true;
this.loggingForm.WindowState = FormWindowState.Normal;
this.loggingForm.Show();
this.loggingForm.Focus();
}
///
/// The rude helper strikes again!
///
/// Sending object.
/// Event data.
private void helpPopupToolStripMenuItem_Click(object sender, EventArgs e)
{
if (this.herman == null || !this.herman.CanFocus)
{
this.herman = new Herman(0);
}
this.herman.Show();
}
///
/// Refresh the balloon locations when the main window is moved.
///
/// Sending object.
/// Event data.
private void CanMain_LocationChanged(object sender, EventArgs e)
{
Control currentControl = this.ActiveControl;
this.hintEngine.setOrigin(this.Location);
if (currentControl == null)
{
this.applicationTree1.Focus();
}
else
{
currentControl.Focus();
}
this.Show();
this.Focus();
}
///
/// Open the raw data log file.
///
/// Sending object.
/// Event data.
private void openRawLogFileToolStripMenuItem_Click(object sender, EventArgs e)
{
this.openRawLogFileToolStripMenuItem.Enabled = false;
this.loggingForm.openRawLog();
this.closeRawLogFileToolStripMenuItem.Enabled = true;
}
///
/// Close the raw data log file.
///
/// Sending object.
/// Event data.
private void closeRawLogFileToolStripMenuItem_Click(object sender, EventArgs e)
{
this.closeRawLogFileToolStripMenuItem.Enabled = false;
this.loggingForm.closeRawLog();
this.openRawLogFileToolStripMenuItem.Enabled = true;
}
}
}