|
|
/*
* This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016-2023 CERN * Copyright The KiCad Developers, see AUTHORS.txt for contributors. * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch> * * 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, you may find one here: * https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
#include <memory>
#include <wx/debug.h>
#include <project/project_file.h>
#include <confirm.h>
#include <string_utils.h>
#include <sim/simulator_frame_ui.h>
#include <sim/simulator_frame.h>
#include <sim/sim_plot_tab.h>
void SIMULATOR_FRAME_UI::parseTraceParams( SIM_PLOT_TAB* aPlotTab, TRACE* aTrace, const wxString& aSignalName, const wxString& aParams ){ auto addCursor = [&]( int aCursorId, double x ) { CURSOR* cursor = new CURSOR( aTrace, aPlotTab );
cursor->SetName( aSignalName ); cursor->SetCoordX( x );
aTrace->SetCursor( aCursorId, cursor ); aPlotTab->GetPlotWin()->AddLayer( cursor ); };
wxArrayString items = wxSplit( aParams, '|' );
for( const wxString& item : items ) { if( item.StartsWith( wxS( "rgb" ) ) ) { wxColour color; color.Set( item ); aTrace->SetTraceColour( color ); aPlotTab->UpdateTraceStyle( aTrace ); } else if( item.StartsWith( wxS( "cursor1" ) ) ) { wxArrayString parts = wxSplit( item, ':' ); double val;
if( parts.size() == 3 ) { parts[0].AfterFirst( '=' ).ToDouble( &val ); m_cursorFormats[0][0].FromString( parts[1] ); m_cursorFormats[0][1].FromString( parts[2] ); addCursor( 1, val ); } } else if( item.StartsWith( wxS( "cursor2" ) ) ) { wxArrayString parts = wxSplit( item, ':' ); double val;
if( parts.size() == 3 ) { parts[0].AfterFirst( '=' ).ToDouble( &val ); m_cursorFormats[1][0].FromString( parts[1] ); m_cursorFormats[1][1].FromString( parts[2] ); addCursor( 2, val ); } } else if( item.StartsWith( wxS( "cursorD" ) ) ) { wxArrayString parts = wxSplit( item, ':' );
if( parts.size() == 3 ) { m_cursorFormats[2][0].FromString( parts[1] ); m_cursorFormats[2][1].FromString( parts[2] ); } } else if( item == wxS( "dottedSecondary" ) ) { aPlotTab->SetDottedSecondary( true ); } else if( item == wxS( "hideGrid" ) ) { aPlotTab->ShowGrid( false ); } }}
bool SIMULATOR_FRAME_UI::loadLegacyWorkbook( const wxString& aPath ){ wxTextFile file( aPath );
#define EXPECTING( msg ) \
DisplayErrorMessage( this, wxString::Format( _( "Error loading workbook: line %d: %s." ), \ file.GetCurrentLine()+1, \ msg ) )
if( !file.Open() ) return false;
long version = 1; wxString firstLine = file.GetFirstLine(); wxString pageCountLine;
if( firstLine.StartsWith( wxT( "version " ) ) ) { if( !firstLine.substr( 8 ).ToLong( &version ) ) { EXPECTING( _( "expecting version" ) ); file.Close();
return false; }
pageCountLine = file.GetNextLine(); } else { pageCountLine = firstLine; }
long tabCount;
if( !pageCountLine.ToLong( &tabCount ) ) { EXPECTING( _( "expecting simulation tab count" ) ); file.Close();
return false; }
std::map<SIM_PLOT_TAB*, std::vector<std::tuple<long, wxString, wxString>>> traceInfo;
for( long i = 0; i < tabCount; ++i ) { long simType, tracesCount;
if( !file.GetNextLine().ToLong( &simType ) ) { EXPECTING( _( "expecting simulation tab type" ) ); file.Close();
return false; }
wxString command = UnescapeString( file.GetNextLine() ); wxString simCommand; int simOptions = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS; wxStringTokenizer tokenizer( command, "\r\n", wxTOKEN_STRTOK );
if( version >= 2 ) { simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS; simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES; simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS; }
if( version >= 3 ) { simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_DISSIPATIONS; }
while( tokenizer.HasMoreTokens() ) { wxString line = tokenizer.GetNextToken();
if( line.StartsWith( wxT( ".kicad adjustpaths" ) ) ) simOptions |= NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS; else if( line.StartsWith( wxT( ".save all" ) ) ) simOptions |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES; else if( line.StartsWith( wxT( ".probe alli" ) ) ) simOptions |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS; else if( line.StartsWith( wxT( ".probe allp" ) ) ) simOptions |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_DISSIPATIONS; else simCommand += line + wxT( "\n" ); }
SIM_TAB* simTab = NewSimTab( simCommand ); SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( simTab );
simTab->SetSimOptions( simOptions );
if( !file.GetNextLine().ToLong( &tracesCount ) ) { EXPECTING( _( "expecting trace count" ) ); file.Close();
return false; }
if( plotTab ) traceInfo[plotTab] = {};
for( long j = 0; j < tracesCount; ++j ) { long traceType; wxString name, param;
if( !file.GetNextLine().ToLong( &traceType ) ) { EXPECTING( _( "expecting trace type" ) ); file.Close();
return false; }
name = file.GetNextLine();
if( name.IsEmpty() ) { EXPECTING( _( "expecting trace name" ) ); file.Close();
return false; }
param = file.GetNextLine();
if( param.IsEmpty() ) { EXPECTING( _( "expecting trace color" ) ); file.Close();
return false; }
if( plotTab ) traceInfo[plotTab].emplace_back( std::make_tuple( traceType, name, param ) ); }
if( version > 4 ) { long measurementCount;
if( !file.GetNextLine().ToLong( &measurementCount ) ) { EXPECTING( _( "expecting measurement count" ) ); file.Close();
return false; }
for( int ii = 0; ii < (int) measurementCount; ++ ii ) { wxString measurement = file.GetNextLine();
if( measurement.IsEmpty() ) { EXPECTING( _( "expecting measurement definition" ) ); file.Close();
return false; }
wxString format = file.GetNextLine();
if( format.IsEmpty() ) { EXPECTING( _( "expecting measurement format definition" ) ); file.Close();
return false; }
if( plotTab ) plotTab->Measurements().emplace_back( measurement, format ); } } }
long userDefinedSignalCount;
if( file.GetNextLine().ToLong( &userDefinedSignalCount ) ) { for( int ii = 0; ii < (int) userDefinedSignalCount; ++ii ) m_userDefinedSignals[ ii ] = file.GetNextLine(); }
for( const auto& [ plotTab, traceInfoVector ] : traceInfo ) { for( const auto& [ traceType, signalName, param ] : traceInfoVector ) { if( traceType == SPT_UNKNOWN && signalName == wxS( "$LEGEND" ) ) { wxArrayString coords = wxSplit( param, ' ' );
if( coords.size() >= 2 ) { long x = 0; long y = 0;
coords[0].ToLong( &x ); coords[1].ToLong( &y ); plotTab->SetLegendPosition( wxPoint( (int) x, (int) y ) ); }
plotTab->ShowLegend( true ); } else { wxString vectorName = vectorNameFromSignalName( plotTab, signalName, nullptr ); TRACE* trace = plotTab->GetOrAddTrace( vectorName, (int) traceType );
if( version >= 4 && trace ) parseTraceParams( plotTab, trace, signalName, param ); } }
plotTab->UpdatePlotColors(); }
if( SIM_TAB* simTab = GetCurrentSimTab() ) { m_simulatorFrame->LoadSimulator( simTab->GetSimCommand(), simTab->GetSimOptions() );
if( version >= 5 ) { simTab = dynamic_cast<SIM_TAB*>( m_plotNotebook->GetPage( 0 ) );
if( simTab ) simTab->SetLastSchTextSimCommand( file.GetNextLine() ); } }
file.Close(); return true;}
|