//************************************************************************************************** // This file is part of SACAMOS, cable models for EMI simulations in SPICE. * // It was developed by the University of Nottingham and the Netherlands Aerospace * // Centre (NLR) for ESA under contract number 4000112765/14/NL/HK. * // Copyright (C) 2015-2017 University of Nottingham * // * // SACAMOS 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. * // * // SACAMOS 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. * // * // A copy of the GNU General Public License version 3 can be found in the * // file GNU_GPL_v3 in the root or at . * // * // The University of Nottingham can be contacted at ggiemr@nottingham.ac.uk * // * // This file is a minor modification of gSpiceUI to allow the library of spice cable models (MOD) * // to be accessed via a GUI * //************************************************************************************************** //************************************************************************************************** // FrmMain.cpp * // ------------- * // Started : 2003-08-18 * // Last Update : 2016-11-05 * // Copyright : (C) 2003-2016 MSWaters * //************************************************************************************************** //************************************************************************************************** // * // 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. * // * //************************************************************************************************** //#define DEBUG 0 #include "FrmMain.hpp" // The application icons #include "icons/gspiceui-32x32.xpm" #include "icons/file-open.xpm" #include "icons/file-import.xpm" #include "icons/file-reload.xpm" #include "icons/file-close.xpm" #include "icons/sim-create.xpm" #include "icons/sim-run.xpm" #include "icons/sim-stop.xpm" #include "icons/sim-edit.xpm" #include "icons/sim-plot.xpm" #include "icons/help.xpm" //************************************************************************************************** // Implement an event table in which the events are routed to their respective handler functions in // the class. If -1 is given as the ID, the given handler will be invoked for any event of the // specified type. wxBEGIN_EVENT_TABLE( FrmMain, wxFrame ) EVT_MENU( FrmMain::ID_MNU_OPEN , FrmMain::OnOpen ) EVT_MENU( FrmMain::ID_MNU_IMPORT , FrmMain::OnImport ) EVT_MENU( FrmMain::ID_MNU_RELOAD , FrmMain::OnReload ) EVT_MENU( FrmMain::ID_MNU_CLOSE , FrmMain::OnClose ) EVT_MENU( FrmMain::ID_MNU_QUIT , FrmMain::OnQuit ) EVT_MENU( FrmMain::ID_MNU_CREATE , FrmMain::OnSimCreate ) EVT_MENU( FrmMain::ID_MNU_RUN , FrmMain::OnSimRun ) EVT_MENU( FrmMain::ID_MNU_STOP , FrmMain::OnSimStop ) EVT_MENU( FrmMain::ID_MNU_SCHEM , FrmMain::OnSchematic ) EVT_MENU( FrmMain::ID_MNU_VIEWER , FrmMain::OnViewData ) // BEGIN: EVENT_TABLE addition for vSACAMOS EVT_MENU( FrmMain::ID_MNU_GUPSYM , FrmMain::OngUpSym ) EVT_MENU( FrmMain::ID_MNU_GSCHEM , FrmMain::Ongschem ) EVT_MENU( FrmMain::ID_MNU_GNETLIST, FrmMain::Ongnetlist ) EVT_MENU( FrmMain::ID_MNU_SRESULTS, FrmMain::OnSResults ) // END: EVENT_TABLE addition for vSACAMOS EVT_MENU( FrmMain::ID_MNU_NGSPICE , FrmMain::OnSelSimEng ) EVT_MENU( FrmMain::ID_MNU_GNUCAP , FrmMain::OnSelSimEng ) EVT_MENU( FrmMain::ID_MNU_PREFS , FrmMain::OnPrefs ) EVT_MENU( FrmMain::ID_MNU_MAN_USER, FrmMain::OnManualUser ) EVT_MENU( FrmMain::ID_MNU_MAN_NGSP, FrmMain::OnManualNGSP ) EVT_MENU( FrmMain::ID_MNU_MAN_GCAP, FrmMain::OnManualGCAP ) EVT_MENU( FrmMain::ID_MNU_ABOUT , FrmMain::OnAbout ) EVT_TOOL( FrmMain::ID_TBR_OPEN , FrmMain::OnOpen ) EVT_TOOL( FrmMain::ID_TBR_IMPORT , FrmMain::OnImport ) EVT_TOOL( FrmMain::ID_TBR_RELOAD , FrmMain::OnReload ) EVT_TOOL( FrmMain::ID_TBR_CLOSE , FrmMain::OnClose ) EVT_TOOL( FrmMain::ID_TBR_CREATE , FrmMain::OnSimCreate ) EVT_TOOL( FrmMain::ID_TBR_RUN , FrmMain::OnSimRun ) EVT_TOOL( FrmMain::ID_TBR_STOP , FrmMain::OnSimStop ) EVT_TOOL( FrmMain::ID_TBR_SCHEM , FrmMain::OnSchematic ) EVT_TOOL( FrmMain::ID_TBR_VIEWER , FrmMain::OnViewData ) // BEGIN: EVENT_TABLE addition for vSACAMOS EVT_TOOL( FrmMain::ID_TBR_GUPSYM , FrmMain::OngUpSym ) EVT_TOOL( FrmMain::ID_TBR_GSCHEM , FrmMain::Ongschem ) EVT_TOOL( FrmMain::ID_TBR_GNETLIST, FrmMain::Ongnetlist ) EVT_TOOL( FrmMain::ID_TBR_SRESULTS ,FrmMain::OnSResults ) // END: EVENT_TABLE addition for vSACAMOS EVT_TOOL( FrmMain::ID_TBR_HELP , FrmMain::OnManualUser ) EVT_TOOL_ENTER( -1 , FrmMain::OnToolEnter ) EVT_CLOSE( FrmMain::OnSysExit ) wxEND_EVENT_TABLE( ) //************************************************************************************************** // Constructor. // // Argument List : // poApp - A pointer to the class that created this object FrmMain::FrmMain( const wxApp * poApp ) : wxFrame( (wxFrame *) NULL, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX ), m_oFileTasks( this ), m_oHelpTasks( this ), m_oSimnNgSp( ), m_oSimnGCap( ), m_oPrc_gschem( ), m_oPrc_gaw( ), m_oPrc_gwave( ) { wxString os1; // Indicate that the main frame is open m_bIsOpen = true; // Initialize pointers m_poSimn = NULL; m_poPrcSimEng = NULL; m_poNbkSimEng = NULL; // Create everything Initialize( ); // Set status bar text os1 << APP_NAME << wxT(" version ") << APP_VERSION << wxT(" (") << APP_DATE << wxT(")"); SetStatusText( wxT(" Welcome to ") + os1, ePANE_MESAGE ); } //************************************************************************************************** // Destructor. FrmMain::~FrmMain( ) { if( m_poNbkSimEng != NULL ) { delete m_poNbkSimEng; m_poNbkSimEng = NULL; } if( m_poPrcSimEng != NULL ) { delete m_poPrcSimEng; m_poPrcSimEng = NULL; } } //************************************************************************************************** // Initialize the main frame. void FrmMain::Initialize( void ) { // Set the frame icon, font and title SetIcon( wxICON( gspiceui32x32 ) ); SetFont( FONT_NORM ); m_oFileTasks.bSetTitle( ); // Automatically update the frame layout when it is resized SetAutoLayout( true ); // Set the main frame layout m_uiFrmLayout = g_oConfig.uiGetFrmLayout( ); // Call the initialization functions InitMenuBar ( ); InitToolBar ( ); InitLstBoxs ( ); InitNbkTCtls( ); InitStatBar ( ); InitToolTips( ); InitSimEng ( ); DoLayout( ); InitPosnSize( ); // Display desired analysis page m_poNbkSimEng->bSetPage( g_oConfig.eGetAnalysis( ) ); // Initialize the FileTasks object (eg. load schematic or netlist file/s) and set log file name m_oFileTasks.Initialize( ); InitLogFiles( ); // The log files can't be configured until m_oFileTsks.Initialize( ) is called // If necessary load the simulation or netlist if( ! m_oNetLst.bIsEmpty( ) ) bSimnLoad( ); // Display the appropriate text control page if( ! m_oNbkTxtCtls.poGetPage( NbkTxtCtls::ePAGE_SIMULTN )->bIsEmpty( ) ) m_oNbkTxtCtls.bSetPage( NbkTxtCtls::ePAGE_SIMULTN ); else if( ! m_oNbkTxtCtls.poGetPage( NbkTxtCtls::ePAGE_NETLIST )->bIsEmpty( ) ) m_oNbkTxtCtls.bSetPage( NbkTxtCtls::ePAGE_NETLIST ); else m_oNbkTxtCtls.bSetPage( NbkTxtCtls::ePAGE_CONSOLE ); } //************************************************************************************************** // Initialize the menu bar. void FrmMain::InitMenuBar( void ) { // Create the menu bar and menus wxMenuBar * poMenuBar = new wxMenuBar; wxMenu * poMenuFile = new wxMenu; wxMenu * poMenuSimu = new wxMenu; wxMenu * poMenuSACAMOS = new wxMenu; // Menu for vSACAMOS wxMenu * poMenuSets = new wxMenu; wxMenu * poMenuHelp = new wxMenu; // Set the tool bar font poMenuBar->SetFont( FONT_NORM ); // Load the menus with items poMenuFile->Append( ID_MNU_OPEN , wxT(" &Open ... ") ); poMenuFile->Append( ID_MNU_IMPORT, wxT(" &Import ... ") ); poMenuFile->Append( ID_MNU_RELOAD, wxT(" &Reload ") ); poMenuFile->Append( ID_MNU_CLOSE , wxT(" &Close ") ); poMenuFile->AppendSeparator( ); poMenuFile->Append( ID_MNU_QUIT , wxT(" &Quit ") ); poMenuSimu->Append( ID_MNU_CREATE, wxT(" &Create ") ); poMenuSimu->Append( ID_MNU_RUN , wxT(" &Run ") ); poMenuSimu->Append( ID_MNU_STOP , wxT(" &Stop ") ); poMenuSimu->AppendSeparator( ); poMenuSimu->Append( ID_MNU_SCHEM , wxT(" Sc&hematic ... ") ); poMenuSimu->Append( ID_MNU_VIEWER, wxT(" R&esults ... ") ); // BEGIN: Menu additions for vSACAMOS poMenuSACAMOS->Append( ID_MNU_GUPSYM , wxT(" &Import MOD ") ); poMenuSACAMOS->AppendSeparator( ); poMenuSACAMOS->Append( ID_MNU_GSCHEM , wxT(" &gschem ") ); poMenuSACAMOS->Append( ID_MNU_GNETLIST , wxT(" &gnetlist ") ); poMenuSACAMOS->AppendSeparator( ); poMenuSACAMOS->Append( ID_MNU_SRESULTS, wxT(" View Results") ); // END: Menu additions for vSACAMOS poMenuSets->Append( ID_MNU_PREFS, wxT(" &Preferences ... ") ); poMenuSets->AppendSeparator( ); poMenuSets->AppendRadioItem( ID_MNU_NGSPICE, wxT(" &NG-Spice ") ); poMenuSets->AppendRadioItem( ID_MNU_GNUCAP , wxT(" &GNU-Cap ") ); poMenuHelp->Append( ID_MNU_MAN_USER, wxT(" &User Manual ... ") ); // poMenuHelp->Append( ID_MNU_MAN_NGSP, wxT(" &NG-Spice Manual ... ") ); // poMenuHelp->Append( ID_MNU_MAN_GCAP, wxT(" &GNU-Cap Manual ... ") ); // poMenuHelp->AppendSeparator( ); poMenuHelp->Append( ID_MNU_ABOUT , wxT(" &About ... ") ); // Load the menubar with menus poMenuBar->Append( poMenuFile, wxT(" &File ") ); poMenuBar->Append( poMenuSimu, wxT(" &Simulate ") ); poMenuBar->Append( poMenuSACAMOS, wxT(" SACAMOS ") ); // vSACAMOS poMenuBar->Append( poMenuSets, wxT(" S&ettings ") ); poMenuBar->Append( poMenuHelp, wxT(" &Help ") ); // Check the appropriate simulation engine menu item if( g_oConfig.eGetSimEng( ) == eSIMR_NGSPICE ) poMenuSets->Check( ID_MNU_NGSPICE, true ); else poMenuSets->Check( ID_MNU_GNUCAP , true ); // Attach the menu bar to the frame SetMenuBar( poMenuBar ); } //************************************************************************************************** // Initialize the tool bar. void FrmMain::InitToolBar( void ) { wxToolBar * poToolBar; wxBitmap * poPixMap[ 10 ]; // Create the tool bar poToolBar = CreateToolBar( wxHORIZONTAL | wxTB_FLAT ); poToolBar->SetToolSeparation( 10 ); // Create the bitmaps for the tools poPixMap[ 0 ] = new wxBitmap( file_open_xpm ); poPixMap[ 1 ] = new wxBitmap( file_import_xpm ); poPixMap[ 2 ] = new wxBitmap( file_reload_xpm ); poPixMap[ 3 ] = new wxBitmap( file_close_xpm ); poPixMap[ 4 ] = new wxBitmap( sim_create_xpm ); poPixMap[ 5 ] = new wxBitmap( sim_run_xpm ); poPixMap[ 6 ] = new wxBitmap( sim_stop_xpm ); poPixMap[ 7 ] = new wxBitmap( sim_edit_xpm ); poPixMap[ 8 ] = new wxBitmap( sim_plot_xpm ); poPixMap[ 9 ] = new wxBitmap( help_xpm ); // Add the tools to the toolbar poToolBar->AddTool( ID_TBR_OPEN, wxT(""), *(poPixMap[ 0 ]), wxT("Open a netlist file") ); poToolBar->AddTool( ID_TBR_IMPORT, wxT(""), *(poPixMap[ 1 ]), wxT("Import a schematic file") ); poToolBar->AddTool( ID_TBR_RELOAD, wxT(""), *(poPixMap[ 2 ]), wxT("Reload a netlist / schematic file") ); poToolBar->AddTool( ID_TBR_CLOSE, wxT(""), *(poPixMap[ 3 ]), wxT("Close a netlist / schematic file") ); poToolBar->AddSeparator( ); poToolBar->AddTool( ID_TBR_CREATE, wxT(""), *(poPixMap[ 4 ]), wxT("Create a netlist file including simulation instructions") ); poToolBar->AddTool( ID_TBR_RUN, wxT(""), *(poPixMap[ 5 ]), wxT("Run the simulation") ); poToolBar->AddTool( ID_TBR_STOP, wxT(""), *(poPixMap[ 6 ]), wxT("Stop the simulation") ); poToolBar->AddSeparator( ); poToolBar->AddTool( ID_TBR_SCHEM, wxT(""), *(poPixMap[ 7 ]), wxT("Edit / view a schematic") ); poToolBar->AddTool( ID_TBR_VIEWER, wxT(""), *(poPixMap[ 8 ]), wxT("View simulation results") ); poToolBar->AddSeparator( ); poToolBar->AddTool( ID_TBR_HELP, wxT(""), *(poPixMap[ 9 ]), wxT("View the user manual") ); // Realize the toolbar poToolBar->Realize( ); // Delete the bitmaps for( int i1=0; i1<10; i1++ ) delete poPixMap[ i1 ]; } //************************************************************************************************** // Initialize the test node and component list boxes. void FrmMain::InitLstBoxs( void ) { long lStyle; // Create the node and component list labels lStyle = wxALIGN_CENTER; m_oLblNodes.Create( this, ID_UNUSED, wxT("Nodes"), wxDefaultPosition, wxDefaultSize, lStyle ); m_oLblCpnts.Create( this, ID_UNUSED, wxT("Components"), wxDefaultPosition, wxDefaultSize, lStyle ); // Create the node and component list boxes lStyle = wxLB_EXTENDED | wxLB_NEEDED_SB; m_oLbxNodes.Create( this, ID_LBX_NODES, wxDefaultPosition, wxSize( 100, -1 ), 0, NULL, lStyle ); m_oLbxCpnts.Create( this, ID_LBX_CPNTS, wxDefaultPosition, wxSize( 100, -1 ), 0, NULL, lStyle ); } //************************************************************************************************** // Initialize the console notebook. void FrmMain::InitNbkTCtls( void ) { uint ui1; // Create the text control notebook m_oNbkTxtCtls.bCreate( this, ID_NBK_TXTCTRLS ); // Set the text control maximum lines ui1 = g_oConfig.uiGetNbkMaxLns( ); m_oNbkTxtCtls.bSetLinesMax( ui1 ); // Set the precision of the results data ui1 = g_oConfig.uiGetPrecision( ); CnvtType::bSetFltRes( ui1 ); } //************************************************************************************************** // Initialize the status bar. // // Note : The first field in the status bar has benn effectively disable by setting it's width to // near zero. It is not used since the frame insists on writing text into this field as the // user moves the mouse over display controls. void FrmMain::InitStatBar( void ) { wxStatusBar * poStatusBar = new wxStatusBar; long liStyle; int iaPaneWidths[ ePANE_LAST+1 ]; #if wxCHECK_VERSION( 3,0,0 ) int iaPaneStyles[ ePANE_LAST+1 ]; #endif wxString os1; // Set the style bits #if wxCHECK_VERSION( 3,0,0 ) liStyle = wxSTB_SHOW_TIPS | wxSTB_ELLIPSIZE_END | wxFULL_REPAINT_ON_RESIZE; #else liStyle = wxFULL_REPAINT_ON_RESIZE; #endif // Create the status bar poStatusBar->Create( this, wxID_ANY, liStyle ); poStatusBar->SetFieldsCount( ePANE_LAST+1 ); poStatusBar->SetMinHeight( 25 ); // Set the status bar pane widths iaPaneWidths[ ePANE_MESAGE ] = -1; // Variable width iaPaneWidths[ ePANE_SIMENG ] = 144; // Fixed width iaPaneWidths[ ePANE_VIEWER ] = 110; // Fixed width poStatusBar->SetStatusWidths( ePANE_LAST+1, iaPaneWidths ); // Set the status bar pane styles #if wxCHECK_VERSION( 3,0,0 ) iaPaneStyles[ ePANE_MESAGE ] = wxSB_SUNKEN; iaPaneStyles[ ePANE_SIMENG ] = wxSB_SUNKEN; iaPaneStyles[ ePANE_VIEWER ] = wxSB_SUNKEN; poStatusBar->SetStatusStyles( ePANE_LAST+1, iaPaneStyles ); #endif // Get the viewer application name from the configuration object os1 = g_oConfig.rosGetDataViewer( ); // Set status bar text poStatusBar->SetStatusText( wxT(" Welcome message") , ePANE_MESAGE ); poStatusBar->SetStatusText( wxT(" Simulator : None"), ePANE_SIMENG ); poStatusBar->SetStatusText( wxT(" Viewer : ") + os1 , ePANE_VIEWER ); // Set the main frame status bar SetStatusBar( poStatusBar ); // Disable the status bar pane used to display menu and toolbar help SetStatusBarPane( -1 ); } //************************************************************************************************** // Initialize the tool tips. void FrmMain::InitToolTips( void ) { // Define tool tips for each control m_oLbxNodes.SetToolTip( wxT(" Test Nodes ") ); m_oLbxCpnts.SetToolTip( wxT(" Test Components ") ); // Set global tool tip attributes wxToolTip::Enable( g_oConfig.bGetToolTips( ) ); wxToolTip::SetDelay( g_oConfig.uiGetToolTipDly( ) ); } //************************************************************************************************** // Set the electronic circuit simulator engine to use. void FrmMain::InitSimEng( void ) { // Delete any existing simulation engine notebook object if( m_poNbkSimEng != NULL ) { GetSizer( )->Detach( m_poNbkSimEng ); delete m_poNbkSimEng; m_poNbkSimEng = NULL; } // Delete any existing simulation engine process object if( m_poPrcSimEng != NULL ) { delete m_poPrcSimEng; m_poPrcSimEng = NULL; } // Create the new simulation engine objects and update the status text if( GetMenuBar( )->IsChecked( ID_MNU_NGSPICE ) ) { m_poNbkSimEng = new NbkNgSpice( this, ID_NBK_ANALYSIS ); m_poPrcSimEng = new PrcNgSpice( ); m_poSimn = &m_oSimnNgSp; SetStatusText( wxT(" Simulator : NG-Spice"), ePANE_SIMENG ); } else { m_poNbkSimEng = new NbkGnuCap( this, ID_NBK_ANALYSIS ); m_poPrcSimEng = new PrcGnuCap( ); m_poSimn = &m_oSimnGCap; SetStatusText( wxT(" Simulator : GNU-Cap"), ePANE_SIMENG ); } } //************************************************************************************************** // Initialize the log file names in the process objects. void FrmMain::InitLogFiles( void ) { wxFileName ofn1; wxString os1; // Check that a netlist file has been defined ofn1 = m_oFileTasks.rosGetNetLstFile( ); if( ! ofn1.IsOk( ) ) return; if( ! ofn1.FileExists( ) ) return; // Get the path to the schematic or netlist file os1 = ofn1.GetPath( ) + wxT("/gspiceui.log"); // Set the log file path for the gNetList process object m_oFileTasks.bSetLogFile( os1 ); // Set the log file path for the simulation process object if( m_poPrcSimEng != NULL ) m_poPrcSimEng->bSetLogFile( os1 ); } //************************************************************************************************** // Initialize the frames position amd size. void FrmMain::InitPosnSize( void ) { int iPosnX, iPosnY, iSizeW, iSizeH; // Get the position and size from the configuration object iPosnX = g_oConfig.iGetMainPosnX( ); iPosnY = g_oConfig.iGetMainPosnY( ); iSizeW = g_oConfig.iGetMainSizeW( ); iSizeH = g_oConfig.iGetMainSizeH( ); // Set the position and size if( iPosnX>=0 && iPosnY>=0 ) Move( iPosnX, iPosnY ); if( iSizeW> 0 && iSizeH> 0 ) SetClientSize( iSizeW, iSizeH ); } //************************************************************************************************** // Layout the main frame display objects. void FrmMain::DoLayout( void ) { wxGridBagSizer * poSzr; wxGBPosition oGBPosn; wxGBSpan oGBSpan; int iFlags; int iBorder; size_t sz1; if( GetSizer( ) == NULL ) { // Create and set the frame's sizer (at startup) poSzr = new wxGridBagSizer( 1, 1 ); SetSizer( poSzr ); // Specify how the sizer will grow when resized poSzr->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); poSzr->SetCols( 3 ); poSzr->AddGrowableCol( 0 ); poSzr->AddGrowableCol( 1 ); for( sz1=13; sz1<20; sz1++ ) poSzr->AddGrowableRow( sz1 ); } else { // Detach the display objects from the sizer poSzr = (wxGridBagSizer *) GetSizer( ); poSzr->Detach( &m_oLblNodes ); poSzr->Detach( &m_oLbxNodes ); poSzr->Detach( &m_oLblCpnts ); poSzr->Detach( &m_oLbxCpnts ); poSzr->Detach( m_poNbkSimEng ); poSzr->Detach( &m_oNbkTxtCtls ); poSzr->Clear( ); } iFlags = wxTOP | wxALIGN_CENTER_HORIZONTAL | wxALIGN_TOP; iBorder = 11; // Add the nodes list box label oGBPosn.SetCol( 0 ); oGBPosn.SetRow( 0 ); oGBSpan.SetColspan( 1 ); oGBSpan.SetRowspan( 1 ); poSzr->Add( &m_oLblNodes, oGBPosn, oGBSpan, iFlags, iBorder ); // Add the components list box label oGBPosn.SetCol( 1 ); oGBPosn.SetRow( 0 ); oGBSpan.SetColspan( 1 ); oGBSpan.SetRowspan( 1 ); poSzr->Add( &m_oLblCpnts, oGBPosn, oGBSpan, iFlags, iBorder ); iFlags = (wxALL & ~wxRIGHT) | wxALIGN_CENTER | wxEXPAND; iBorder = 5; // Add the nodes list box oGBPosn.SetCol( 0 ); oGBPosn.SetRow( 1 ); oGBSpan.SetColspan( 1 ); if( m_uiFrmLayout == 0 ) oGBSpan.SetRowspan( 19 ); else oGBSpan.SetRowspan( 12 ); poSzr->Add( &m_oLbxNodes, oGBPosn, oGBSpan, iFlags, iBorder ); // Add the components list box oGBPosn.SetCol( 1 ); oGBPosn.SetRow( 1 ); oGBSpan.SetColspan( 1 ); if( m_uiFrmLayout == 0 ) oGBSpan.SetRowspan( 19 ); else oGBSpan.SetRowspan( 12 ); poSzr->Add( &m_oLbxCpnts, oGBPosn, oGBSpan, iFlags, iBorder ); iFlags = wxALL | wxALIGN_CENTER | wxEXPAND; iBorder = 5; // Add the simulator notebook oGBPosn.SetCol( 2 ); oGBPosn.SetRow( 0 ); oGBSpan.SetColspan( 1 ); oGBSpan.SetRowspan( 13 ); poSzr->Add( m_poNbkSimEng, oGBPosn, oGBSpan, iFlags, iBorder ); #ifndef LAYOUT_MNGR poSzr->SetItemMinSize( m_poNbkSimEng, NBKSIMENG_WIDTH, NBKSIMENG_HEIGHT ); #endif // LAYOUT_MNGR iFlags = (wxALL & ~wxTOP) | wxALIGN_CENTER | wxEXPAND; iBorder = 5; // Add the console notebook oGBPosn.SetRow( 13 ); oGBSpan.SetRowspan( 7 ); if( m_uiFrmLayout == 0 ) { oGBPosn.SetCol( 2 ); oGBSpan.SetColspan( 1 ); } else { oGBPosn.SetCol( 0 ); oGBSpan.SetColspan( 3 ); } poSzr->Add( &m_oNbkTxtCtls, oGBPosn, oGBSpan, iFlags, iBorder ); #ifndef LAYOUT_MNGR poSzr->SetItemMinSize( &m_oNbkTxtCtls, NBKTXTCTLS_WIDTH, NBKTXTCTLS_HEIGHT ); #endif // LAYOUT_MNGR // Set minimum and initial sizes as calculated by the frame's sizer poSzr->SetSizeHints( this ); } //************************************************************************************************** // Load information from the Simulation object (FrmMain::m_poSimn) into the various display // controls. // // Return Values : // true - Success // false - Failure bool FrmMain::bSimnLoad( void ) { TextCtrl * poTxtCtl; wxArrayString osa1; size_t sz1; // Load all the nodes (except ground) into the "Nodes" list box for( sz1=0; sz1m_osaNodeLbls.GetCount( ); sz1++ ) m_oLbxNodes.Append( m_poSimn->m_osaNodeLbls.Item( sz1 ) ); // Select the test nodes (if any have been specified) for( sz1=0; sz1rosaGetTstNodes( ).GetCount( ); sz1++ ) m_oLbxNodes.SetStringSelection( m_poSimn->rosaGetTstNodes( ).Item( sz1 ) ); // Load all 2-port components into the "Components" list box for( sz1=0; sz1m_oaCpnts.GetCount( ); sz1++ ) { Component & roCpnt = m_poSimn->m_oaCpnts.Item( sz1 ); switch( roCpnt.eGetType( ) ) // Only collect two terminal components { case eCPNT_CAP : // Capacitor case eCPNT_RES : // Resistor case eCPNT_IND : // Inductor case eCPNT_CIND : // Coupled (Mutual) Inductors case eCPNT_DIODE : // Diode case eCPNT_VCVS : // Voltage Controlled Voltage Source case eCPNT_CCCS : // Current Controlled Current Source case eCPNT_VCCS : // Voltage Controlled Current Source case eCPNT_CCVS : // Current Controlled Voltage Source case eCPNT_IVS : // Independent Voltage Source case eCPNT_ICS : // Independent Current Source case eCPNT_NLDS : // Non-Linear Dependent Source case eCPNT_NLDCS : // Non-Linear Dependent Current Source case eCPNT_NLDVS : // Non-Linear Dependent Voltage Source case eCPNT_STJ : // Super-conducting Tunnel Junction osa1.Add( roCpnt.rosGetName( ) ); break; default : // Do nothing break; } } osa1.Sort( &iStrCmpCpnt ); // Function iStrCmpCpnt( ) is defined in utility/StrUtils.hpp if( ! osa1.IsEmpty( ) ) m_oLbxCpnts.InsertItems( osa1, 0 ); // Select the test components (if any have been specified) const wxArrayString & rosa1 = m_poSimn->rosaGetTstCpnts( ); for( sz1=0; sz1bClear( ); for( sz1=0; sz1bAppendLine( m_oNetLst.m_osaNetLst.Item( sz1 ) ); m_oNbkTxtCtls.bSetPosn( 0 ); } // Load the analysis notebook with simulation information if( ! m_poNbkSimEng->bLoad( *m_poSimn ) ) return( false ); // Load the circuit description into the Simulation text control m_oNbkTxtCtls.bSetPage( NbkTxtCtls::ePAGE_SIMULTN ); poTxtCtl = m_oNbkTxtCtls.poGetPage( ); poTxtCtl->bClear( ); for( sz1=0; sz1bAppendLine( m_oNetLst.m_osaNetLst.Item( sz1 ) ); m_oNbkTxtCtls.bSetPosn( 0 ); poTxtCtl->SetEditable( true ); return( true ); } //************************************************************************************************** // Reload information from the Simulation object (FrmMain::m_poSimn) into the various display // controls. // // Return Values : // true - Success // false - Failure bool FrmMain::bSimnReload( void ) { wxArrayString osaTstNodes; wxArrayString osaTstCpnts; size_t sz1; int i1; // Record the nodes that are currently selected #if wxCHECK_VERSION( 2,8,0 ) for( sz1=0; sz1bClrCmds( ); // Get an array of indicies to the currently selected test points m_oLbxNodes.GetSelections( oaiSelNodes ); m_oLbxCpnts.GetSelections( oaiSelCpnts ); // Load the test nodes into the simulation object for( sz1=0; sz1bAddTstNode( osSel ); } // Load the test components into the simulation object for( sz1=0; sz1bAddTstCpnt( osSel ); } // Transfer the simulation parameters into the simulation object if( ! m_poNbkSimEng->bSave( *m_poSimn ) ) return( false ); // Create the simulation information and save it to file if( ! m_poSimn->bSave( ) ) return( false ); if( ! m_poSimn->bSaveFile( ) ) return( false ); return( true ); } //************************************************************************************************** // Check that the electronic circuit simulator engine is present and accounted for, if not display // an error message. // // Argument List : // poPrcSimEng - The utility object to be tested // // Return Values : // true - Success // false - Failure bool FrmMain::bIsOkSimEng( PrcBase * poPrcSimEng ) { wxString os1; // Check that gnetlist exists and is accessible if( ! poPrcSimEng->bBinExists( ) ) { os1 << wxT("Can't find the binary file required to run simulation :\n") << poPrcSimEng->roGetBinFile( ).GetFullName( ) << wxT("\nThere is no path to the binary or it hasn't been installed.") << wxT("\n\n"); DlgErrMsg( wxT("ERROR"), os1 ); return( false ); } return( true ); } //************************************************************************************************** // Check that the waveform viewer utility is present and accounted for, if not display an error // message. // // Argument List : // poPrcViewer - The utility object to be tested // // Return Values : // true - Success // false - Failure bool FrmMain::bIsOkViewer( PrcBase * poPrcViewer ) { wxString os1; // Check that the waveform viewer utility exists and is accessible if( ! poPrcViewer->bBinExists( ) ) { os1 << wxT("Can't find the binary file required to plot the simulation ") << wxT("results :\n") << poPrcViewer->roGetBinFile( ).GetFullName( ) << wxT("\nThere is no path to the binary or it hasn't been installed.") << wxT("\n\n"); DlgErrMsg( wxT("ERROR"), os1 ); return( false ); } return( true ); } //************************************************************************************************** // Check that a required binary file is present and accounted for, if not display an error message. // // Argument List : // poProcess - The process object to test // rosPurpose - What is the binary needed to do? // // Return Values : // true - Success // false - Failure bool FrmMain::bIsOkBinary( PrcBase * poProcess, const wxString & rosPurpose ) { wxString os1; // Check that the waveform viewer utility exists and is accessible if( ! poProcess->bBinExists( ) ) { os1 << wxT("Can't find the binary file required to ") << rosPurpose << wxT(" :\n") << poProcess->roGetBinFile( ).GetFullName( ) << wxT("\nThere is no path to the binary or it hasn't been installed.") << wxT("\n\n"); DlgErrMsg( wxT("ERROR"), os1 ); return( false ); } return( true ); } //************************************************************************************************** // Lock GUI controls. // // Argument List : // bEnable - Enable or disable lock GUI mode void FrmMain::LockGUI( bool bEnable ) { size_t sz1; GetMenuBar( )->Enable( ! bEnable ); // Set the menu bar state m_poNbkSimEng->Enable( ! bEnable ); // Set the simulator notebook state m_oLbxNodes .Enable( ! bEnable ); // Set the node label list box state m_oLbxCpnts .Enable( ! bEnable ); // Set the component label list box state // Set the individual state of each tool in the tool bar for( sz1=ID_TBR_FST; sz1<=ID_TBR_LST; sz1++ ) GetToolBar( )->EnableTool( sz1, ! bEnable ); if( bEnable ) ::wxBeginBusyCursor( ); // Change the cursor to the wait symbol else ::wxEndBusyCursor( ); // Change the cursor to the default } //************************************************************************************************** // Clear the object attributes. bool FrmMain::bClear( void ) { bool bRtn = true; // Clear all previously selected test points m_oLbxNodes.Clear( ); m_oLbxCpnts.Clear( ); // Clear simulation object attributes m_oSimnGCap.bClear( ); m_oSimnNgSp.bClear( ); // Clear the simulation object and the analysis panels if( m_poNbkSimEng != NULL ) if( ! m_poNbkSimEng->bClear( ) ) bRtn = false; // Clear the text controls if( ! m_oNbkTxtCtls.bClear( ) ) bRtn = false; m_oNbkTxtCtls.bInitialize( ); // Terminate any simulation process if( m_poPrcSimEng != NULL ) if( ! m_poPrcSimEng->bKill( ) ) bRtn = false; // Terminate any schematic editor process if( ! m_oPrc_gschem.bKill( ) ) bRtn = false; // Terminate any waveform viewer process if( g_oConfig.eGetDataViewer( ) == eVIEW_GAW ) { if( ! m_oPrc_gaw .bKill( ) ) bRtn = false; } else { if( ! m_oPrc_gwave.bKill( ) ) bRtn = false; } return( bRtn ); } //************************************************************************************************** // Display a dialog box containing an error message. // // Note : At start-up the first error message is held over until the the main GUI is created and // displayed; to display this message call this function with no arguments. // // Argument List : // rosTitle - The dialogue box title // rosMsg - The error message void FrmMain::DlgErrMsg( const wxString & rosTitle, const wxString & rosMsg ) { static wxMessageDialog * poDlgMsg=NULL; wxStringTokenizer ostk1; wxString os1, os2, os3; if( poDlgMsg == NULL ) { if( rosTitle.IsEmpty( ) || rosMsg.IsEmpty( ) ) return; // Tokenize the message into lines ostk1.SetString( rosMsg, wxT(" \n\r"), wxTOKEN_STRTOK ); // Use the first complete sentence as the status bar message os1 << wxT(" ERROR :"); while( ostk1.HasMoreTokens( ) ) { // Get the next line os2 = ostk1.GetNextToken( ).Strip( wxString::both ); // Remove the path from file names if( os2.Freq( wxT('/') ) > 1 ) { os3 << os2.AfterLast( wxT('/') ) << wxT(','); os2 = os3; } // Look for the end of the sentence if( os2==wxT('.') || os2==wxT(':') ) break; // Append the line to the message os1 << wxT(' ') << os2; } // If debug mode is enabled send the error message to the console if( g_bDebug ) std::cerr << "DEBUG : " << rosStrToLine( os1 ).mb_str( ) << "\n\n"; // Set the status line message SetStatusText( os1, ePANE_MESAGE ); // Create the error message dialog os1 = wxT('\n') + rosMsg; poDlgMsg = new wxMessageDialog( this, os1, rosTitle, wxOK | wxICON_ERROR ); } if( ! IsShown( ) ) return; // Display the error message dialog poDlgMsg->ShowModal( ); // Delete the error message dialog delete poDlgMsg; poDlgMsg = NULL; } //************************************************************************************************** // Event Handlers * //************************************************************************************************** // Open a circuit description file. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnOpen( wxCommandEvent & roEvtCmd ) { if( ! m_oFileTasks.bDlgOpen( ) ) return; // Attempt to get a netlist file name from the user LockGUI( true ); // Lock the GUI controls bClear( ); // Clear the main frame object attributes m_oFileTasks.bOpen( ); // Attempt to open and read the netlist file bSimnLoad( ); // Load the simulation information InitLogFiles( ); // Initialize the process log files LockGUI( false ); // Unlock the GUI controls } //************************************************************************************************** // Import a schematic file using gnetlist to convert the schematic to a circuit description. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnImport( wxCommandEvent & roEvtCmd ) { if( ! m_oFileTasks.bDlgImport( ) ) return; // Attempt to get the schematic file name/s from user LockGUI( true ); // Lock the GUI controls bClear( ); // Clear the main frame object attributes m_oFileTasks.bImport( ); // Attempt to import schematic/s and read netlist file bSimnLoad( ); // Load the simulation information InitLogFiles( ); // Initialize the process log files LockGUI( false ); // Unlock the GUI controls } //************************************************************************************************** // Reload the schematic or netlist file. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnReload( wxCommandEvent & roEvtCmd ) { LockGUI( true ); // Lock the GUI controls m_oFileTasks.bReload( ); // Reload schematic file/s and/or the netlist file bSimnReload( ); // Reload the simulation information LockGUI( false ); // Unlock the GUI controls } //************************************************************************************************** // Close the circuit description file. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnClose( wxCommandEvent & roEvtCmd ) { m_oFileTasks.bClose( ); // Delete temporary files bClear( ); // Clear the object attributes m_oFileTasks.bSetTitle( ); // Set the frame title m_poNbkSimEng->bSetPage( (eTypeCmd) 0 ); // Display first analysis panel } //************************************************************************************************** // Exit the application. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnQuit( wxCommandEvent & roEvtCmd ) { Close( true ); // Generates a wxCloseEvent which is handled by OnSysExit( ) } //************************************************************************************************** // Create the simulation. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnSimCreate( wxCommandEvent & roEvtCmd ) { TextCtrl * poTxtCtl; wxString osErrMsg; // If a simulation is currently running do nothing if( m_poPrcSimEng->bIsExec( ) ) return; LockGUI( true ); // Lock the GUI controls if( ! m_oNetLst.m_osaNetLst.IsEmpty( ) ) { // Save the simulation info. in the simulation object if( bSimnSave( ) ) { // Print the simulation to the simulation text control m_oNbkTxtCtls.bSetPage( NbkTxtCtls::ePAGE_SIMULTN ); poTxtCtl = m_oNbkTxtCtls.poGetPage( NbkTxtCtls::ePAGE_SIMULTN ); poTxtCtl->bLoadFile( m_poSimn->roGetSaveFile( ).GetFullPath( ) ); poTxtCtl->SetEditable( true ); } else { if( ! m_poNbkSimEng->bIsOk( ) ) osErrMsg = m_poNbkSimEng->rosGetErrMsg( ); else if( ! m_poSimn->bIsValid( ) ) osErrMsg = m_poSimn ->rosGetErrMsg( ); else osErrMsg = wxT("Unknown error."); } } else osErrMsg = wxT("There's no schematic or netlist file loaded."); // Display exit status message if( ! osErrMsg.IsEmpty( ) ) DlgErrMsg( wxT("Create Simulation Error"), osErrMsg ); else SetStatusText( wxT(" Simulation ran successfully"), ePANE_MESAGE ); LockGUI( false ); // Unlock the GUI controls } //************************************************************************************************** // Run the simulation. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnSimRun( wxCommandEvent & roEvtCmd ) { TextCtrl * poTxtCtl; NbkTxtCtls::ePageType ePage; wxFileName ofn1; wxString osErrMsg, os1; //------------------------------------------------------------------------------------------------ // Prepare to run the simulation LockGUI( true ); // Lock the GUI controls GetToolBar( )->EnableTool( ID_TBR_STOP, true ); SetStatusText( wxT(" Running the simulation ..."), ePANE_MESAGE ); //------------------------------------------------------------------------------------------------ // Check if a schematic or netlist file is currently open ofn1 = m_oFileTasks.rosGetNetLstFile( ); if( ofn1.GetFullPath( ).IsEmpty( ) ) { osErrMsg = wxT("There's no schematic or netlist file loaded."); goto OnSimRun_Exit; } //------------------------------------------------------------------------------------------------ // Prepare to run the simulation (and update the Simulation text page) poTxtCtl = m_oNbkTxtCtls.poGetPage( NbkTxtCtls::ePAGE_SIMULTN ); if( poTxtCtl->IsModified( ) ) { // Save the simulation in the text page to file, the user has modified it poTxtCtl->SaveFile( m_poSimn->roGetSaveFile( ).GetFullPath( ) ); } else if( bSimnSave( ) ) { // Load the simulation on file into the Simulation text page poTxtCtl->bLoadFile( m_poSimn->roGetSaveFile( ).GetFullPath( ) ); poTxtCtl->DiscardEdits( ); // Reset modified flag as if changes had been saved poTxtCtl->SetEditable( true ); // Make the text control editable } else { // There's been an error, report it to the user and return if( ! m_poNbkSimEng->bIsOk( ) ) osErrMsg = m_poNbkSimEng->rosGetErrMsg( ); else if( ! m_poSimn->bIsValid( ) ) osErrMsg = m_poSimn ->rosGetErrMsg( ); else osErrMsg = wxT("Unknown error."); goto OnSimRun_Exit; } m_oNbkTxtCtls.bSetPage( NbkTxtCtls::ePAGE_SIMULTN ); //------------------------------------------------------------------------------------------------ // Run the simulation (and update the Console text page) if( ! m_poPrcSimEng->bMakeArgLst( *m_poSimn ) ) { osErrMsg = m_poPrcSimEng->rosGetErrMsg( ); goto OnSimRun_Exit; } if( ! m_poPrcSimEng->bExec( ) ) { osErrMsg = m_poPrcSimEng->rosGetErrMsg( ); goto OnSimRun_Exit; } m_oNbkTxtCtls.bSetPage( NbkTxtCtls::ePAGE_CONSOLE ); poTxtCtl = m_oNbkTxtCtls.poGetPage( NbkTxtCtls::ePAGE_CONSOLE ); poTxtCtl->bClear( ); // Clear the Console text page m_poPrcSimEng->PrintCmd( *poTxtCtl ); // Print simulator cmd to Console page // Return immediately if the user aborted the simulation if( GetStatusBar( )->GetStatusText( 1 ).Contains( wxT("aborted") ) ) goto OnSimRun_Exit; GetToolBar( )->EnableTool( ID_TBR_STOP, false ); m_poPrcSimEng->PrintRsp( *poTxtCtl ); // Print simulator output to Console page //------------------------------------------------------------------------------------------------ // Format the simulation results (and update the Results text page) SetStatusText( wxT(" Formatting the simulation results ..."), ePANE_MESAGE ); wxTheApp->Yield( true ); // Allow the display to update if( ! m_poPrcSimEng->bFmtResults( ) ) { osErrMsg = m_poPrcSimEng->rosGetErrMsg( ); goto OnSimRun_Exit; } if( m_poNbkSimEng->eGetSimEng( ) == eSIMR_GNUCAP ) ePage = NbkTxtCtls::ePAGE_GNUCAP; else ePage = NbkTxtCtls::ePAGE_NGSPICE; poTxtCtl = m_oNbkTxtCtls.poGetPage( ePage ); os1 = m_poPrcSimEng->roGetResultsFile( ).GetFullPath( ); // Load the simulation output into the results text page if( ! poTxtCtl->bLoadFile( os1 ) ) { osErrMsg = wxT("Couldn't load the results file : \n\n") + os1; goto OnSimRun_Exit; } m_oNbkTxtCtls.bSetPage( ePage ); // Change to the appropriate results page //------------------------------------------------------------------------------------------------ // Display status and any errors messages and return OnSimRun_Exit: // Display exit status message if( ! osErrMsg.IsEmpty( ) ) DlgErrMsg( wxT("Run Simulation Error"), osErrMsg ); else SetStatusText( wxT(" Simulation ran successfully"), ePANE_MESAGE ); LockGUI( false ); // Unlock the GUI controls } //************************************************************************************************** // Stop the simulation. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnSimStop( wxCommandEvent & roEvtCmd ) { if( m_poPrcSimEng->bIsExec( ) ) { // A simulation is currently running, abort it m_poPrcSimEng->bKill( ); SetStatusText( wxT(" Simulation aborted by the user"), ePANE_MESAGE ); } else { // No simulation is currently running, display an error message dialogue DlgErrMsg( wxT("Stop Simulation Error"), wxT("There's no simulation running.") ); } } //************************************************************************************************** // Edit / view the schematic file. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnSchematic( wxCommandEvent & roEvtCmd ) { wxString osErrHdr = wxT("Schematic Editor Error"); wxString osErrMsg; // Check if the schematic editor process is already running if( m_oPrc_gschem.bIsExec( ) ) { osErrMsg = wxT("The schematic editor process is already running."); DlgErrMsg( osErrHdr, osErrMsg ); return; } // Check if a schematic file is currently set m_oPrc_gschem.bSetSchemFiles( m_oFileTasks.rosaGetSchemFiles( ) ); if( m_oPrc_gschem.rosGetSchemFiles( ).IsEmpty( ) ) { osErrMsg = wxT("There's no schematic loaded or the netlist has no associated schematic file."); DlgErrMsg( osErrHdr, osErrMsg ); return; } // Execute the schematic editor process if( ! m_oPrc_gschem.bExec( ) ) { // Something went wrong, display an error message osErrMsg = m_oPrc_gschem.rosGetErrMsg( ); DlgErrMsg( osErrHdr, osErrMsg ); } } //************************************************************************************************** // View the simulation results. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnViewData( wxCommandEvent & roEvtCmd ) { wxFileName ofn1; wxString osErrHdr = wxT("Plot Results Error"); wxString os1; // Check if the waveform viewer process is already running if( m_oPrc_gaw.bIsExec( ) || m_oPrc_gwave.bIsExec( ) ) { DlgErrMsg( osErrHdr, wxT("The waveform viewer process is already running.") ); return; } // Check if a schematic or netlist file is currently open ofn1 = m_oFileTasks.rosGetNetLstFile( ); if( ofn1.GetFullPath( ).IsEmpty( ) ) { DlgErrMsg( osErrHdr, wxT("There's no schematic or netlist file loaded.") ); return; } // Create the appropriate name for the results file os1 = ofn1.GetName( ); switch( m_poNbkSimEng->eGetSimEng( ) ) { case eSIMR_GNUCAP : if( m_oNbkTxtCtls.eGetPage( ) == NbkTxtCtls::ePAGE_NGSPICE ) os1 << wxT(".ngspice"); else os1 << wxT(".gnucap"); break; case eSIMR_NGSPICE : if( m_oNbkTxtCtls.eGetPage( ) == NbkTxtCtls::ePAGE_GNUCAP ) os1 << wxT(".gnucap"); else os1 << wxT(".ngspice"); break; default : return; } ofn1.SetName( os1 ); ofn1.SetExt( m_poNbkSimEng->rosGetPage( ) ); // Set the results file in the waveform viewer process if( ! ofn1.FileExists( ) ) { os1.Empty( ); os1 << wxT("The simulation results file :\n\n") << ofn1.GetFullPath( ) << wxT("\n\nhasn't yet been generated."); DlgErrMsg( osErrHdr, os1 ); return; } m_oPrc_gaw .bSetResultsFile( ofn1.GetFullPath( ) ); m_oPrc_gwave.bSetResultsFile( ofn1.GetFullPath( ) ); // Execute the waveform viewer process if( g_oConfig.eGetDataViewer( ) == eVIEW_GAW ) { if( ! m_oPrc_gaw .bExec( ) ) DlgErrMsg( osErrHdr, m_oPrc_gaw .rosGetErrMsg( ) ); } else { if( ! m_oPrc_gwave.bExec( ) ) DlgErrMsg( osErrHdr, m_oPrc_gwave.rosGetErrMsg( ) ); } } //************************************************************************************************** // Select which simulator to use. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnSelSimEng( wxCommandEvent & roEvtCmd ) { int iw, ih; // Temporarily store the current main frame size GetClientSize( &iw, &ih ); // Change cursor to the wait symbol and hide the GUI while re-constructing it ::wxBeginBusyCursor( ); Show( false ); // Create and display a progress dialog wxProgressDialog oDlgProgress( wxT(" GNU Spice GUI"), wxT("Changing simulation engines ..."), 100, this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_SMOOTH ); oDlgProgress.CenterOnParent( ); oDlgProgress.Update( 5 ); ::wxMilliSleep( 250 ); // Record the simulation engine change in the configuration file if( GetMenuBar( )->IsChecked( ID_MNU_NGSPICE ) ) g_oConfig.bSetSimEng( eSIMR_NGSPICE ); else g_oConfig.bSetSimEng( eSIMR_GNUCAP ); g_oConfig.bFlush( ); // Write changes to the configuration file // Update the progress dialog oDlgProgress.Update( 20 ); // Change the simulator InitSimEng( ); // Update the progress dialog oDlgProgress.Update( 50 ); ::wxMilliSleep( 150 ); // Set the simulator process log file name InitLogFiles( ); // Update the progress dialog oDlgProgress.Update( 60 ); ::wxMilliSleep( 150 ); // Update the GUI components DoLayout( ); // Update the progress dialog oDlgProgress.Update( 70 ); ::wxMilliSleep( 150 ); // Transfer info. from one simulation object to the other if( ! m_oNetLst.bIsEmpty( ) ) { if( GetMenuBar( )->IsChecked( ID_MNU_GNUCAP ) ) m_oSimnGCap = m_oSimnNgSp; else m_oSimnNgSp = m_oSimnGCap; } // Update the progress dialog oDlgProgress.Update( 80 ); ::wxMilliSleep( 150 ); // Load the analysis notebook with the simulation values m_poNbkSimEng->bLoad( *m_poSimn ); // Update the progress dialog oDlgProgress.Update( 90 ); ::wxMilliSleep( 150 ); // Restore the frame's original size SetClientSize( iw, ih ); // Update the progress dialog oDlgProgress.Update( 99 ); ::wxMilliSleep( 150 ); oDlgProgress.Update( 100 ); // Kill the progress dialog // Show the GUI again and change the cursor to the default Show( true ); ::wxEndBusyCursor( ); } //************************************************************************************************** // Show the application preferences dialog. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnPrefs( wxCommandEvent & roEvtCmd ) { uint ui1; DlgPrefs oDlgPrefs( this ); oDlgPrefs.CenterOnParent( ); oDlgPrefs.ShowModal( ); if( oDlgPrefs.GetReturnCode( ) == wxID_OK ) { // Set the schematic capture / editor program binary // m_oPrc_gschem.bSetBinFile( g_oConfig.rosGetSchemEdit( ) ); // Set the waveform viewer SetStatusText( wxString( wxT(" Viewer : ") ) + g_oConfig.rosGetDataViewer( ), ePANE_VIEWER ); // Set the precision of the results values CnvtType::bSetFltRes( g_oConfig.uiGetPrecision( ) ); // Set the gnetlist Guile procedure to use for the backend processing m_oFileTasks.bSetGuileProc( g_oConfig.rosGetGuileProc( ) ); // Set the text control maximum lines m_oNbkTxtCtls.bSetLinesMax( g_oConfig.uiGetNbkMaxLns( ) ); // Set the spin control update rate PnlTxtSpn::bSetSpnPeriod( g_oConfig.uiGetSpnPeriod( ) ); // Set the state of tooltips wxToolTip::Enable( g_oConfig.bGetToolTips( ) ); wxToolTip::SetDelay( g_oConfig.uiGetToolTipDly( ) ); // Set the main frame layout to be used ui1 = g_oConfig.uiGetFrmLayout( ); if( m_uiFrmLayout != ui1 ) { m_uiFrmLayout = ui1; DoLayout( ); InitPosnSize( ); } } } //************************************************************************************************** // Display the gSpiceUI user manual. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnManualUser( wxCommandEvent & roEvtCmd ) { m_oHelpTasks.ManualUser( ); } //************************************************************************************************** // Display about message dialog. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnAbout( wxCommandEvent & roEvtCmd ) { m_oHelpTasks.About( ); } //************************************************************************************************** // Change the cursor when a simulation is running and the mouse is over the stop button. // // Argument List : // roEvtCmd - The event to be processed void FrmMain::OnToolEnter( wxCommandEvent & roEvtCmd ) { if( roEvtCmd.GetSelection( ) == ID_TBR_STOP ) { if( m_poPrcSimEng->bIsExec( ) && ::wxIsBusy( ) ) { ::wxEndBusyCursor( ); // Change the cursor to the default wxTheApp->Yield( true ); // Allow the display to update } } else { if( m_poPrcSimEng->bIsExec( ) && !::wxIsBusy( ) ) { ::wxBeginBusyCursor( ); // Change the cursor to the hour glass wxTheApp->Yield( true ); // Allow the display to update } } } //************************************************************************************************** // Event handler for system close. // // Argument List : // roEvtClose - The event to be processed void FrmMain::OnSysExit( wxCloseEvent & roEvtClose ) { int iPosnX, iPosnY, iSizeW, iSizeH; bClear( ); // Kill any processes currently running m_oFileTasks.bExit( ); // Delete temporary files Hide( ); // Hide the main frame while exiting // Save the frame size and position GetPosition( &iPosnX, &iPosnY ); GetClientSize( &iSizeW, &iSizeH ); g_oConfig.bSetMainPosnX( iPosnX ); g_oConfig.bSetMainPosnY( iPosnY ); g_oConfig.bSetMainSizeW( iSizeW ); g_oConfig.bSetMainSizeH( iSizeH ); // Record the simulation engine currently selected g_oConfig.bSetSimEng( m_poPrcSimEng->eGetSimEng( ) ); // Record the analysis type last used g_oConfig.bSetAnalysis( m_poNbkSimEng->eGetPage( ) ); g_oConfig.bFlush( ); // Write changes to the configuration file m_bIsOpen = false; // Indicate that the main frame has been closed Destroy( ); // Destroys the window safely (used instead of the delete operator) } //************************************************************************************************** //Below Added by SG 05_17 for gSpiceUI vSACAMOS void FrmMain::OngUpSym( wxCommandEvent & roEvtCmd ) { wxString defaultPath = wxT("/"); wxDirDialog dialog(this, wxT("Directory picker"), defaultPath, wxDD_NEW_DIR_BUTTON); if (dialog.ShowModal() == wxID_OK) { wxString path = dialog.GetPath(); wxDir symbolFolder(path); if ( !symbolFolder.IsOpened() ) { // deal with the error here - wxDir would already log an error message // explaining the exact reason of the failure return; } wxString filename; bool cont = symbolFolder.GetFirst(&filename, wxEmptyString, wxDIR_FILES ); while ( cont ) { wxString source = path; source = source + "\\" + filename; // Copy to \geda\local - assumes gEDA is installed to root of C: drive // Windows permissions prevent writing to program file directories wxString dest = "C:\\gEDA\\gEDA\\share\\gEDA\\sym\\local\\" ; dest = dest + filename; if ( wxCopyFile(source , dest)) { wxMessageBox("Import Succesful", source); } else { ///wxMessageBox( wxT("Failed")); } cont = symbolFolder.GetNext(&filename); } } } void FrmMain::Ongschem ( wxCommandEvent & roEvtCmd ) { wxExecute(wxT("gschem"), wxEXEC_SYNC); } void FrmMain::Ongnetlist( wxCommandEvent & roEvtCmd ) { wxString outputFile, filePath, gnetlistCL; wxArrayString output, errors; wxString myString1, myString2; // Open file browser and filter on .sch wxFileDialog* OpenDialog = new wxFileDialog( this, _("Choose a file to open"), wxEmptyString, wxEmptyString, _("Schematic Files (*.sch)|*.sch"), wxFD_OPEN, wxDefaultPosition); if (OpenDialog->ShowModal() == wxID_OK) { filePath = OpenDialog->GetPath(); inputFile = OpenDialog->GetFilename(); filePath.Replace("\\","/",true); // Truncate at file extension outputFile = filePath.BeforeLast('.'); // Construct name of file holding results resultsFile = outputFile + ".ngspice.ac"; outputFile += ".net"; gnetlistCL = "gnetlist -g spice-sdb -o " ; gnetlistCL += outputFile ; gnetlistCL += " " ; gnetlistCL += filePath ; wxExecute(gnetlistCL, output, errors, wxEXEC_SYNC); wxString myString; for(size_t i = 0; i < output.size(); i++) myString += " " + output[i]; wxMessageBox(myString,"gnetlist report"); } OpenDialog->Destroy(); } void FrmMain::OnSResults( wxCommandEvent & roEvtCmd ) { #ifdef DEBUG wxMessageBox(resultsFile,_("File to plot")); #endif wxFileInputStream input(resultsFile); wxTextInputStream text(input, wxT("\x09"), wxConvUTF8 ); wxString plotHeader=text.ReadLine(); //wxString t_plotHeader = plotHeader; // Reduce multiple white spaces to single space while ( plotHeader.Replace(" "," ")); // Replace single SPACE with UNDERSCORE and count occurences, add one = number of columns int Cols = plotHeader.Replace(" ","_") + 1; wxString tmpCols; tmpCols << Cols; #ifdef DEBUG wxMessageBox(tmpCols,_("Number of columns")); #endif // Revert back while ( plotHeader.Replace("_"," ")) ; // NULL #ifdef DEBUG wxMessageBox(plotHeader,_("Plot Header")); #endif std::ofstream plotFile; inputFile = inputFile.BeforeLast('.'); wxString gnuplotFile = inputFile + ".plt"; plotFile.open (gnuplotFile); #ifdef DEBUG wxMessageBox(gnuplotFile,_("Plot Header")); #endif plotFile << "set title '" << inputFile << "'" << "\t# Plot Title\n"; plotFile << "set xlabel 'frequency (Hz)' \n"; plotFile << "plot "; for (int i = 1; i