KiCad PCB EDA Suite
Loading...
Searching...
No Matches
legacy_workbook.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016-2023 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Wlostowski <[email protected]>
7 * @author Maciej Suminski <[email protected]>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 3
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#include <memory>
24#include <wx/debug.h>
25#include <wx/tokenzr.h>
26
28#include <confirm.h>
29#include <string_utils.h>
31#include <sim/simulator_frame.h>
32#include <sim/sim_plot_tab.h>
33
34
36 const wxString& aSignalName, const wxString& aParams )
37{
38 auto addCursor =
39 [&]( int aCursorId, double x )
40 {
41 CURSOR* cursor = new CURSOR( aTrace, aPlotTab );
42
43 cursor->SetName( aSignalName );
44 cursor->SetCoordX( x );
45
46 aTrace->SetCursor( aCursorId, cursor );
47
48 if( SIM_VIEW* view = aTrace->GetView() )
49 view->AddLayer( cursor );
50 };
51
52 wxArrayString items = wxSplit( aParams, '|' );
53
54 for( const wxString& item : items )
55 {
56 if( item.StartsWith( wxS( "rgb" ) ) )
57 {
58 wxColour color;
59 color.Set( item );
60 aTrace->SetTraceColour( color );
61 aPlotTab->UpdateTraceStyle( aTrace );
62 }
63 else if( item.StartsWith( wxS( "cursor1" ) ) )
64 {
65 wxArrayString parts = wxSplit( item, ':' );
66 double val;
67
68 if( parts.size() == 3 )
69 {
70 parts[0].AfterFirst( '=' ).ToDouble( &val );
71 m_cursorFormats[0][0].FromString( parts[1] );
72 m_cursorFormats[0][1].FromString( parts[2] );
73 addCursor( 1, val );
74 }
75 }
76 else if( item.StartsWith( wxS( "cursor2" ) ) )
77 {
78 wxArrayString parts = wxSplit( item, ':' );
79 double val;
80
81 if( parts.size() == 3 )
82 {
83 parts[0].AfterFirst( '=' ).ToDouble( &val );
84 m_cursorFormats[1][0].FromString( parts[1] );
85 m_cursorFormats[1][1].FromString( parts[2] );
86 addCursor( 2, val );
87 }
88 }
89 else if( item.StartsWith( wxS( "cursorD" ) ) )
90 {
91 wxArrayString parts = wxSplit( item, ':' );
92
93 if( parts.size() == 3 )
94 {
95 m_cursorFormats[2][0].FromString( parts[1] );
96 m_cursorFormats[2][1].FromString( parts[2] );
97 }
98 }
99 else if( item == wxS( "dottedSecondary" ) )
100 {
101 aPlotTab->SetDottedSecondary( true );
102 }
103 else if( item == wxS( "hideGrid" ) )
104 {
105 aPlotTab->ShowGrid( false );
106 }
107 }
108}
109
110
111bool SIMULATOR_FRAME_UI::loadLegacyWorkbook( const wxString& aPath )
112{
113 wxTextFile file( aPath );
114
115#define EXPECTING( msg ) \
116 DisplayErrorMessage( this, wxString::Format( _( "Error loading workbook: line %d: %s." ), \
117 file.GetCurrentLine()+1, \
118 msg ) )
119
120 if( !file.Open() )
121 return false;
122
123 long version = 1;
124 wxString firstLine = file.GetFirstLine();
125 wxString pageCountLine;
126
127 if( firstLine.StartsWith( wxT( "version " ) ) )
128 {
129 if( !firstLine.substr( 8 ).ToLong( &version ) )
130 {
131 EXPECTING( _( "expecting version" ) );
132 file.Close();
133
134 return false;
135 }
136
137 pageCountLine = file.GetNextLine();
138 }
139 else
140 {
141 pageCountLine = firstLine;
142 }
143
144 long tabCount;
145
146 if( !pageCountLine.ToLong( &tabCount ) )
147 {
148 EXPECTING( _( "expecting simulation tab count" ) );
149 file.Close();
150
151 return false;
152 }
153
154 std::map<SIM_PLOT_TAB*, std::vector<std::tuple<long, wxString, wxString>>> traceInfo;
155
156 for( long i = 0; i < tabCount; ++i )
157 {
158 long simType, tracesCount;
159
160 if( !file.GetNextLine().ToLong( &simType ) )
161 {
162 EXPECTING( _( "expecting simulation tab type" ) );
163 file.Close();
164
165 return false;
166 }
167
168 wxString command = UnescapeString( file.GetNextLine() );
169 wxString simCommand;
171 wxStringTokenizer tokenizer( command, "\r\n", wxTOKEN_STRTOK );
172
173 if( version >= 2 )
174 {
175 simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS;
176 simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
177 simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
178 }
179
180 if( version >= 3 )
181 {
182 simOptions &= ~NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_DISSIPATIONS;
183 }
184
185 while( tokenizer.HasMoreTokens() )
186 {
187 wxString line = tokenizer.GetNextToken();
188
189 if( line.StartsWith( wxT( ".kicad adjustpaths" ) ) )
191 else if( line.StartsWith( wxT( ".save all" ) ) )
193 else if( line.StartsWith( wxT( ".probe alli" ) ) )
195 else if( line.StartsWith( wxT( ".probe allp" ) ) )
197 else
198 simCommand += line + wxT( "\n" );
199 }
200
201 SIM_TAB* simTab = NewSimTab( simCommand );
202 SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( simTab );
203
204 simTab->SetSimOptions( simOptions );
205
206 if( !file.GetNextLine().ToLong( &tracesCount ) )
207 {
208 EXPECTING( _( "expecting trace count" ) );
209 file.Close();
210
211 return false;
212 }
213
214 if( plotTab )
215 traceInfo[plotTab] = {};
216
217 for( long j = 0; j < tracesCount; ++j )
218 {
219 long traceType;
220 wxString name, param;
221
222 if( !file.GetNextLine().ToLong( &traceType ) )
223 {
224 EXPECTING( _( "expecting trace type" ) );
225 file.Close();
226
227 return false;
228 }
229
230 name = file.GetNextLine();
231
232 if( name.IsEmpty() )
233 {
234 EXPECTING( _( "expecting trace name" ) );
235 file.Close();
236
237 return false;
238 }
239
240 param = file.GetNextLine();
241
242 if( param.IsEmpty() )
243 {
244 EXPECTING( _( "expecting trace color" ) );
245 file.Close();
246
247 return false;
248 }
249
250 if( plotTab )
251 traceInfo[plotTab].emplace_back( std::make_tuple( traceType, name, param ) );
252 }
253
254 if( version > 4 )
255 {
256 long measurementCount;
257
258 if( !file.GetNextLine().ToLong( &measurementCount ) )
259 {
260 EXPECTING( _( "expecting measurement count" ) );
261 file.Close();
262
263 return false;
264 }
265
266 for( int ii = 0; ii < (int) measurementCount; ++ ii )
267 {
268 wxString measurement = file.GetNextLine();
269
270 if( measurement.IsEmpty() )
271 {
272 EXPECTING( _( "expecting measurement definition" ) );
273 file.Close();
274
275 return false;
276 }
277
278 wxString format = file.GetNextLine();
279
280 if( format.IsEmpty() )
281 {
282 EXPECTING( _( "expecting measurement format definition" ) );
283 file.Close();
284
285 return false;
286 }
287
288 if( plotTab )
289 plotTab->Measurements().emplace_back( measurement, format );
290 }
291 }
292 }
293
294 long userDefinedSignalCount;
295
296 if( file.GetNextLine().ToLong( &userDefinedSignalCount ) )
297 {
298 for( int ii = 0; ii < (int) userDefinedSignalCount; ++ii )
299 m_userDefinedSignals[ ii ] = file.GetNextLine();
300 }
301
302 for( const auto& [ plotTab, traceInfoVector ] : traceInfo )
303 {
304 for( const auto& [ traceType, signalName, param ] : traceInfoVector )
305 {
306 if( traceType == SPT_UNKNOWN && signalName == wxS( "$LEGEND" ) )
307 {
308 wxArrayString coords = wxSplit( param, ' ' );
309
310 if( coords.size() >= 2 )
311 {
312 long x = 0;
313 long y = 0;
314
315 coords[0].ToLong( &x );
316 coords[1].ToLong( &y );
317 plotTab->SetLegendPosition( wxPoint( (int) x, (int) y ) );
318 }
319
320 plotTab->ShowLegend( true );
321 }
322 else
323 {
324 wxString vectorName = vectorNameFromSignalName( plotTab, signalName, nullptr );
325 TRACE* trace = plotTab->GetOrAddTrace( vectorName, (int) traceType, plotTab->GetDefaultView() );
326
327 if( version >= 4 && trace )
328 parseTraceParams( plotTab, trace, signalName, param );
329 }
330 }
331
332 plotTab->UpdatePlotColors();
333 }
334
335 if( SIM_TAB* simTab = GetCurrentSimTab() )
336 {
337 m_simulatorFrame->LoadSimulator( simTab->GetSimCommand(), simTab->GetSimOptions() );
338
339 if( version >= 5 )
340 {
341 simTab = dynamic_cast<SIM_TAB*>( m_plotNotebook->GetPage( 0 ) );
342
343 if( simTab )
344 simTab->SetLastSchTextSimCommand( file.GetNextLine() );
345 }
346 }
347
348 file.Close();
349 return true;
350}
351
352
const char * name
The SIMULATOR_FRAME holds the main user-interface for running simulations.
SIM_TAB * NewSimTab(const wxString &aSimCommand)
Create a new simulation tab for a given simulation type.
bool loadLegacyWorkbook(const wxString &aPath)
wxString vectorNameFromSignalName(SIM_PLOT_TAB *aPlotTab, const wxString &aSignalName, int *aTraceType)
Get the simulator output vector name for a given signal name and type.
SIM_TAB * GetCurrentSimTab() const
Return the currently opened plot panel (or NULL if there is none).
std::map< int, wxString > m_userDefinedSignals
SIMULATOR_FRAME * m_simulatorFrame
void parseTraceParams(SIM_PLOT_TAB *aPlotTab, TRACE *aTrace, const wxString &aSignalName, const wxString &aParams)
SPICE_VALUE_FORMAT m_cursorFormats[3][2]
void ShowGrid(bool aEnable)
std::vector< std::pair< wxString, wxString > > & Measurements()
void UpdateTraceStyle(TRACE *trace)
Update plot colors.
void SetDottedSecondary(bool aEnable)
Draw secondary signal traces (current or phase) with dotted lines.
void SetLastSchTextSimCommand(const wxString &aCmd)
Definition sim_tab.h:55
void SetSimOptions(int aOptions)
Definition sim_tab.h:52
A single stacked plot area within a SIM_PLOT_TAB.
Overlay layer drawing the Smith chart grid (constant resistance and reactance circles)
void SetTraceColour(const wxColour &aColour)
SIM_VIEW * GetView() const
void SetCursor(int aCursorId, CURSOR *aCursor)
This file is part of the common library.
#define _(s)
#define EXPECTING(msg)
@ SPT_UNKNOWN
Definition sim_types.h:68
wxString UnescapeString(const wxString &aSource)