//----------------------------------------------------------------------- // // 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; } } }