//************************************************************************************************** // NbkNgSpice.cpp * // ---------------- * // Started : 2004-05-08 * // Last Update : 2016-11-09 * // Copyright : (C) 2004-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. * // * //************************************************************************************************** #include "NbkNgSpice.hpp" //************************************************************************************************** // Implement an event table. wxBEGIN_EVENT_TABLE( NbkNgSpice, NbkSimEngBase ) EVT_NOTEBOOK_PAGE_CHANGED( -1, NbkNgSpice::OnPageChangd ) EVT_BUTTON( PnlAnaBase::ID_BTN_OPTIONS, NbkNgSpice::OnBtnOptions ) wxEND_EVENT_TABLE( ) //************************************************************************************************** // Constructor. // // Arguments : // poParent - The parent window // oWinID - The display object ID // roPosn - The notebook position // roSize - The notebook size NbkNgSpice::NbkNgSpice( wxWindow * poParent, wxWindowID oWinID ) : NbkSimEngBase( poParent, oWinID ), m_oDlgCfgOPT( poParent ) { // Set the simulator engine type specifier m_eSimEng = eSIMR_NGSPICE; // Create the various display objects m_poPnlNgSpiceDC = new PnlNgSpiceDC( this ); m_poPnlNgSpiceAC = new PnlNgSpiceAC( this ); m_poPnlNgSpiceTR = new PnlNgSpiceTR( this ); m_poPnlNgSpiceOP = new PnlNgSpiceOP( this ); // Add the display objects to the note book AddPage( m_poPnlNgSpiceOP, wxT( " Quiescent " ) ); AddPage( m_poPnlNgSpiceDC, wxT( " DC " ) ); AddPage( m_poPnlNgSpiceAC, wxT( " AC " ) ); AddPage( m_poPnlNgSpiceTR, wxT( " Transient " ) ); // Specify the default page to be displayed SetSelection( 0 ); } //************************************************************************************************** // Destructor. NbkNgSpice::~NbkNgSpice( ) { } //************************************************************************************************** // Clear the object attributes. // // Return Values : // true - Success // false - Failure bool NbkNgSpice::bClear( void ) { bool bRtn=true; // Clear the base class if( ! NbkSimEngBase ::bClear( ) ) bRtn = false; if( ! m_poPnlNgSpiceOP->bClear( ) ) bRtn = false; if( ! m_poPnlNgSpiceDC->bClear( ) ) bRtn = false; if( ! m_poPnlNgSpiceAC->bClear( ) ) bRtn = false; if( ! m_poPnlNgSpiceTR->bClear( ) ) bRtn = false; if( ! m_oDlgCfgOPT .bClear( ) ) bRtn = false; return( bRtn ); } //************************************************************************************************** // Load information from a simulation object. // // Argument List : // roSimn - The simulation object // // Return Values : // true - Success // false - Failure bool NbkNgSpice::bLoad( const SimnBase & roSimn ) { bool bRtn=true; size_t sz1; if( roSimn.eGetSimEng( ) != eSIMR_NGSPICE ) return( false ); PnlAnaBase::m_oCpntSwpSrc = roSimn.m_oCpntSwpSrc; SimnNgSpice & roSimnNgs = (SimnNgSpice &) roSimn; if( ! bSetPage( roSimnNgs.eGetAnaType( ) ) ) bRtn = false; sz1 = 0; if( m_poPnlNgSpiceOP->bLoad( roSimnNgs ) ) sz1++; if( m_poPnlNgSpiceDC->bLoad( roSimnNgs ) ) sz1++; if( m_poPnlNgSpiceAC->bLoad( roSimnNgs ) ) sz1++; if( m_poPnlNgSpiceTR->bLoad( roSimnNgs ) ) sz1++; if( sz1 == 0 ) bRtn = false; if( ! m_oDlgCfgOPT.bSetValues( roSimnNgs.m_oCmdOPT ) ) bRtn = false; return( bRtn ); } //************************************************************************************************** // Save information to a simulation object. // // Argument List : // roSimultn - The simulation object // // Return Values : // true - Success // false - Failure bool NbkNgSpice::bSave( SimnBase & roSimn ) { wxString os1; int i1; // Only proceed if this is an NG-Spice simulation object if( roSimn.eGetSimEng( ) != eSIMR_NGSPICE ) return( false ); SimnNgSpice & roSimnNgs = (SimnNgSpice &) roSimn; // Clear the error string NbkSimEngBase::m_osErrMsg.Empty( ); // Create the analysis command/s switch( GetSelection( ) ) { case 0 : // OP analysis if( ! m_poPnlNgSpiceOP->bSave( roSimnNgs ) ) SetErrMsg( m_poPnlNgSpiceOP->rosGetErrMsg( ) ); break; case 1 : // DC analysis if( ! m_poPnlNgSpiceDC->bSave( roSimnNgs ) ) SetErrMsg( m_poPnlNgSpiceDC->rosGetErrMsg( ) ); break; case 2 : // AC analysis if( ! m_poPnlNgSpiceAC->bSave( roSimnNgs ) ) SetErrMsg( m_poPnlNgSpiceAC->rosGetErrMsg( ) ); break; case 3 : // TR analysis if( ! m_poPnlNgSpiceTR->bSave( roSimnNgs ) ) SetErrMsg( m_poPnlNgSpiceTR->rosGetErrMsg( ) ); break; default : return( false ); } if( ! bIsOk( ) ) return( false ); // Transfer the values in OPTIONS config. dialogue to OPTIONS command object m_oDlgCfgOPT.bGetValues( roSimnNgs.m_oCmdOPT ); // Set the results output page width : 40 chars. for the index and the // independent variable plus 16 chars. multiplied by the number of dependent // variables. i1 = 40 + 16 * roSimnNgs.m_oCmdPR.iGetParamCnt( ); CnvtType::bIntToStr( i1, os1 ); os1.Trim( false ); roSimnNgs.m_oCmdOPT.m_osWIDTH = os1; // Create the OPTIONS command roSimnNgs.m_oCmdOPT.bFormat( ); if( ! roSimnNgs.m_oCmdOPT.bIsValid( ) ) { os1 = wxT("OPTIONS command fault :\n\n "); SetErrMsg( os1 + roSimnNgs.m_oCmdOPT.rosGetErrMsg( ) ); return( false ); } return( true ); } //************************************************************************************************** // Set the page to be displayed. // // Argument List : // eAnalysis - The enumerated analysis type specifier // // Return Values : // true - Success // false - Failure bool NbkNgSpice::bSetPage( eTypeCmd eAnalysis ) { int iPage; switch( eAnalysis ) { case eCMD_OP : iPage = 0; break; case eCMD_DC : iPage = 1; break; case eCMD_AC : iPage = 2; break; case eCMD_TR : iPage = 3; break; default : return( false ); } SetSelection( iPage ); // Specify the page to be displayed return( true ); } //************************************************************************************************** // Set the page to be displayed. // // Argument List : // rosAnalysis - The two letter analysis type specifier (case ignored) // // Return Values : // true - Success // false - Failure bool NbkNgSpice::bSetPage( const wxString & rosAnalysis ) { eTypeCmd eAnalysis=eCMD_NONE; wxString os1; os1 = rosAnalysis.Upper( ); if( os1.Length( ) == 2 ) { if( os1 == wxT("OP") ) eAnalysis = eCMD_OP; else if( os1 == wxT("DC") ) eAnalysis = eCMD_DC; else if( os1 == wxT("AC") ) eAnalysis = eCMD_AC; else if( os1 == wxT("TR") ) eAnalysis = eCMD_TR; } return( bSetPage( eAnalysis ) ); } //************************************************************************************************** // Get the two letter page specifier. // // Return Values : // Success - The two letter analysis type specifier (lower case) // Failure - An empty string const wxString & NbkNgSpice::rosGetPage( void ) { static wxString osAnalysis; switch( eGetPage( ) ) { case eCMD_OP : osAnalysis = wxT("op"); break; case eCMD_DC : osAnalysis = wxT("dc"); break; case eCMD_AC : osAnalysis = wxT("ac"); break; case eCMD_TR : osAnalysis = wxT("tr"); break; default : osAnalysis.Empty( ); } return( osAnalysis ); } //************************************************************************************************** // Get the enumerated page specifier. // // Return Values : // Success - The enumerated analysis specifier // Failure - eCMD_NONE eTypeCmd NbkNgSpice::eGetPage( void ) { eTypeCmd eAnalysis; switch( GetSelection( ) ) { case 0 : eAnalysis = eCMD_OP; break; case 1 : eAnalysis = eCMD_DC; break; case 2 : eAnalysis = eCMD_AC; break; case 3 : eAnalysis = eCMD_TR; break; default : eAnalysis = eCMD_NONE; } return( eAnalysis ); } //************************************************************************************************** // Event Handlers * //************************************************************************************************** // This event is generated when a notebook page has just changed. // // Argument List: // roEvtNbk - An object holding information about the event void NbkNgSpice::OnPageChangd( wxNotebookEvent & roEvtNbk ) { PnlAnaBase * poPnlAna; wxString os1; int i1; // Synchronize the ambient temperature values between the different analysis pages if( g_oConfig.bGetSyncTemps( ) ) { // Transfer the ambient temperature from the previous page to the OPTIONS dialog i1 = roEvtNbk.GetOldSelection( ); if( i1 != wxNOT_FOUND ) { poPnlAna = (PnlAnaBase *) GetPage( (size_t) i1 ); if( poPnlAna->m_oPnlTemp.GetParent( ) != NULL ) { os1 = poPnlAna->m_oPnlTemp.rosGetValue( ); m_oDlgCfgOPT.bSetValue( DlgNgsCfgOPT::ID_PNL_TEMP, os1 ); } } // Transfer the ambient temperature from the OPTIONS dialog to current page poPnlAna = (PnlAnaBase *) GetCurrentPage( ); if( poPnlAna->m_oPnlTemp.GetParent( ) != NULL ) { os1 = m_oDlgCfgOPT.rosGetValue( DlgNgsCfgOPT::ID_PNL_TEMP ); poPnlAna->m_oPnlTemp.bSetValue( os1 ); } } // Synchronize the sweep sources between the different analysis pages if( g_oConfig.bGetSyncSwpSrcs( ) ) { os1 = poPnlAna->m_oCpntSwpSrc.rosGetName( ); if( poPnlAna->m_oChoSrcName.SetStringSelection( os1 ) ) { // Set the sweep source value if it's been defined if( poPnlAna->m_oPnlSrcLvl.GetParent( ) != NULL ) { poPnlAna->m_oPnlSrcLvl.bSetUnitsType( poPnlAna->m_oCpntSwpSrc.eGetUnitsType( ) ); poPnlAna->m_oPnlSrcLvl.bSetValue( poPnlAna->m_oCpntSwpSrc.rosGetValue( ) ); } } else { // Couldn't set the sweep source name so clear it poPnlAna->m_oChoSrcName.SetSelection( 0 ); if( poPnlAna->m_oPnlSrcLvl.GetParent( ) != NULL ) { poPnlAna->m_oPnlSrcLvl.bSetUnitsType( eUNITS_NONE ); poPnlAna->m_oPnlSrcLvl.bSetValue( 0.0 ); } } // Update the sweep parameter units if( poPnlAna->eGetAnalysType( ) == eCMD_DC ) m_poPnlNgSpiceDC->OnSrcName( (wxCommandEvent &) roEvtNbk ); } // Allow additional event handlers to be called roEvtNbk.Skip( ); } //************************************************************************************************** // Setup .OPTIONS command button event handler. // // Argument List : // roEvtCmd - An object holding information about the event void NbkNgSpice::OnBtnOptions( wxCommandEvent & roEvtCmd ) { PnlAnaBase * poPnlAna; wxString os1; int i1; // Get a pointer to the currently displayed analysis page poPnlAna = (PnlAnaBase *) GetCurrentPage( ); if( poPnlAna == NULL ) return; // Set the temperature in the OPTIONS dialog if( poPnlAna->m_oPnlTemp.GetParent( ) != NULL ) { os1 = poPnlAna->m_oPnlTemp.rosGetValue( ); m_oDlgCfgOPT.bSetValue( DlgNgsCfgOPT::ID_PNL_TEMP, os1 ); } // Display the OPTIONS dialog m_oDlgCfgOPT.CenterOnParent( ); i1 = m_oDlgCfgOPT.ShowModal( ); if( i1 != wxID_OK ) return; // Set the temperature in the current analysis panel if( poPnlAna->m_oPnlTemp.GetParent( ) != NULL ) { os1 = m_oDlgCfgOPT.rosGetValue( DlgNgsCfgOPT::ID_PNL_TEMP ); poPnlAna->m_oPnlTemp.bSetValue( os1 ); } } //**************************************************************************************************