KiCad PCB EDA Suite
Loading...
Searching...
No Matches
simulator_frame.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 (C) 2016-2024 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, you may find one here:
21 * https://www.gnu.org/licenses/gpl-3.0.html
22 * or you may search the http://www.gnu.org website for the version 3 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <wx/debug.h>
28
29// For some obscure reason, needed on msys2 with some wxWidgets versions (3.0) to avoid
30// undefined symbol at link stage (due to use of #include <pegtl.hpp>)
31// Should not create issues on other platforms
32#include <wx/menu.h>
33
35#include <sch_edit_frame.h>
36#include <kiway.h>
37#include <confirm.h>
38#include <bitmaps.h>
42#include <widgets/wx_grid.h>
43#include <tool/tool_manager.h>
45#include <tool/action_manager.h>
46#include <tool/action_toolbar.h>
47#include <tool/common_control.h>
49#include <tools/ee_actions.h>
50#include <string_utils.h>
51#include <pgm_base.h>
52#include "ngspice.h"
53#include <sim/simulator_frame.h>
55#include <sim/sim_plot_tab.h>
56#include <sim/spice_simulator.h>
58#include <eeschema_settings.h>
59#include <advanced_config.h>
60
61#include <memory>
62
63
65{
66public:
68 m_parent( aParent )
69 {
70 }
71
72 REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override
73 {
74 wxCommandEvent* event = new wxCommandEvent( EVT_SIM_REPORT );
75 event->SetString( aText );
76 wxQueueEvent( m_parent, event );
77 return *this;
78 }
79
80 bool HasMessage() const override
81 {
82 return false; // Technically "indeterminate" rather than false.
83 }
84
85 void OnSimStateChange( SIMULATOR* aObject, SIM_STATE aNewState ) override
86 {
87 wxCommandEvent* event = nullptr;
88
89 switch( aNewState )
90 {
91 case SIM_IDLE: event = new wxCommandEvent( EVT_SIM_FINISHED ); break;
92 case SIM_RUNNING: event = new wxCommandEvent( EVT_SIM_STARTED ); break;
93 default: wxFAIL; return;
94 }
95
96 wxQueueEvent( m_parent, event );
97 }
98
99private:
101};
102
103
104BEGIN_EVENT_TABLE( SIMULATOR_FRAME, KIWAY_PLAYER )
105 EVT_MENU( wxID_EXIT, SIMULATOR_FRAME::onExit )
106 EVT_MENU( wxID_CLOSE, SIMULATOR_FRAME::onExit )
107END_EVENT_TABLE()
108
109
110SIMULATOR_FRAME::SIMULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
111 KIWAY_PLAYER( aKiway, aParent, FRAME_SIMULATOR, _( "Simulator" ), wxDefaultPosition,
112 wxDefaultSize, wxDEFAULT_FRAME_STYLE, wxT( "simulator" ), unityScale ),
113 m_schematicFrame( nullptr ),
114 m_toolBar( nullptr ),
115 m_ui( nullptr ),
116 m_simFinished( false ),
117 m_workbookModified( false )
118{
119 m_schematicFrame = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false );
120 wxASSERT( m_schematicFrame );
121
122 // Give an icon
123 wxIcon icon;
124 icon.CopyFromBitmap( KiBitmap( BITMAPS::simulator ) );
125 SetIcon( icon );
126
127 wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
128 SetSizer( mainSizer );
129
130 m_infoBar = new WX_INFOBAR( this );
131 mainSizer->Add( m_infoBar, 0, wxEXPAND, 0 );
132
133 m_toolBar = new ACTION_TOOLBAR( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
134 wxAUI_TB_DEFAULT_STYLE|wxAUI_TB_HORZ_LAYOUT|wxAUI_TB_PLAIN_BACKGROUND );
135 m_toolBar->Realize();
136 mainSizer->Add( m_toolBar, 0, wxEXPAND, 5 );
137
138 m_ui = new SIMULATOR_FRAME_UI( this, m_schematicFrame );
139 mainSizer->Add( m_ui, 1, wxEXPAND, 5 );
140
141 m_simulator = SIMULATOR::CreateInstance( "ngspice" );
142 wxASSERT( m_simulator );
143
144 LoadSettings( config() );
145
146 NGSPICE_SETTINGS* settings = dynamic_cast<NGSPICE_SETTINGS*>( m_simulator->Settings().get() );
147
148 wxCHECK2( settings, /* do nothing in release builds*/ );
149
150 if( settings && settings->GetWorkbookFilename().IsEmpty() )
152
153 m_simulator->Init();
154
155 m_reporter = new SIM_THREAD_REPORTER( this );
156 m_simulator->SetReporter( m_reporter );
157
158 m_circuitModel = std::make_shared<SPICE_CIRCUIT_MODEL>( &m_schematicFrame->Schematic(), this );
159
160 setupTools();
161 setupUIConditions();
162
163 ReCreateHToolbar();
164 ReCreateMenuBar();
165
166 Bind( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIMULATOR_FRAME::onExit ), this,
167 wxID_EXIT );
168
169 Bind( EVT_SIM_UPDATE, &SIMULATOR_FRAME::onUpdateSim, this );
170 Bind( EVT_SIM_REPORT, &SIMULATOR_FRAME::onSimReport, this );
171 Bind( EVT_SIM_STARTED, &SIMULATOR_FRAME::onSimStarted, this );
172 Bind( EVT_SIM_FINISHED, &SIMULATOR_FRAME::onSimFinished, this );
173
174 // Ensure new items are taken in account by sizers:
175 Layout();
176
177 // resize the subwindows size. At least on Windows, calling wxSafeYield before
178 // resizing the subwindows forces the wxSplitWindows size events automatically generated
179 // by wxWidgets to be executed before our resize code.
180 // Otherwise, the changes made by setSubWindowsSashSize are overwritten by one these
181 // events
182 wxSafeYield();
183 m_ui->SetSubWindowsSashSize();
184
185 // Ensure the window is on top
186 Raise();
187
188 m_ui->InitWorkbook();
189 UpdateTitle();
190}
191
192
194{
195 NULL_REPORTER devnull;
196
197 m_simulator->Attach( nullptr, wxEmptyString, 0, wxEmptyString, devnull );
198 m_simulator->SetReporter( nullptr );
199 delete m_reporter;
200}
201
202
204{
205 // Create the manager
207 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
208
210
211 // Attach the events to the tool dispatcher
213 Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
214
215 // Register tools
219}
220
221
223{
225
226 UpdateTitle();
227
229}
230
231
233{
234 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg );
235 wxASSERT( cfg );
236
237 if( cfg )
238 {
240 m_ui->LoadSettings( cfg );
241 }
242
244
245 NGSPICE* currentSim = dynamic_cast<NGSPICE*>( m_simulator.get() );
246
247 if( currentSim )
248 m_simulator->Settings() = project.m_SchematicSettings->m_NgspiceSettings;
249}
250
251
253{
254 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg );
255 wxASSERT( cfg );
256
257 if( cfg )
258 {
260 m_ui->SaveSettings( cfg );
261 }
262
264
265 if( project.m_SchematicSettings )
266 {
267 bool modified = project.m_SchematicSettings->m_NgspiceSettings->SaveToFile();
268
269 if( m_schematicFrame && modified )
271 }
272}
273
274
275void SIMULATOR_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
276{
277 KIWAY_PLAYER::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
278
279 auto* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( m_toolManager->GetSettings() );
280 wxASSERT( cfg != nullptr );
281 m_ui->ApplyPreferences( cfg->m_Simulator.preferences );
282}
283
284
286{
287 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg );
288 wxASSERT( cfg );
289
290 return cfg ? &cfg->m_Simulator.window : nullptr;
291}
292
293
295{
296 if( m_ui->GetCurrentSimTab() )
298 else
299 return m_circuitModel->GetSchTextSimCommand();
300}
301
302
304{
306}
307
308
310{
311 if( SIM_TAB* simTab = m_ui->GetCurrentSimTab() )
312 return simTab->GetSimOptions();
313 else
315}
316
317
319{
320 bool unsaved = true;
321 bool readOnly = false;
322 wxString title;
323 wxFileName filename = Prj().AbsolutePath( m_simulator->Settings()->GetWorkbookFilename() );
324
325 if( filename.IsOk() && filename.FileExists() )
326 {
327 unsaved = false;
328 readOnly = !filename.IsFileWritable();
329 }
330
332 title = wxT( "*" ) + filename.GetName();
333 else
334 title = filename.GetName();
335
336 if( readOnly )
337 title += wxS( " " ) + _( "[Read Only]" );
338
339 if( unsaved )
340 title += wxS( " " ) + _( "[Unsaved]" );
341
342 title += wxT( " \u2014 " ) + _( "Spice Simulator" );
343
344 SetTitle( title );
345}
346
347
348
349bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimOptions )
350{
351 wxString errors;
352 WX_STRING_REPORTER reporter( &errors );
353
354 if( !m_schematicFrame->ReadyToNetlist( _( "Simulator requires a fully annotated schematic." ) ) )
355 return false;
356
357 // If we are using the new connectivity, make sure that we do a full-rebuild
358 if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
360
361 if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(),
362 reporter ) )
363 {
364 DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors );
365 return false;
366 }
367
368 return true;
369}
370
371
372void SIMULATOR_FRAME::ReloadSimulator( const wxString& aSimCommand, unsigned aSimOptions )
373{
374 wxString errors;
375 WX_STRING_REPORTER reporter( &errors );
376
377 if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(),
378 reporter ) )
379 {
380 DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors );
381 }
382}
383
384
386{
387 SIM_TAB* simTab = m_ui->GetCurrentSimTab();
388
389 if( !simTab )
390 return;
391
392 if( simTab->GetSimCommand().Upper().StartsWith( wxT( "FFT" ) )
393 || simTab->GetSimCommand().Upper().Contains( wxT( "\nFFT" ) ) )
394 {
395 wxString tranSpicePlot;
396
397 if( SIM_TAB* tranPlotTab = m_ui->GetSimTab( ST_TRAN ) )
398 tranSpicePlot = tranPlotTab->GetSpicePlotName();
399
400 if( tranSpicePlot.IsEmpty() )
401 {
402 DisplayErrorMessage( this, _( "You must run a TRAN simulation first; its results"
403 "will be used for the fast Fourier transform." ) );
404 }
405 else
406 {
407 m_simulator->Command( "setplot " + tranSpicePlot.ToStdString() );
408
409 wxArrayString commands = wxSplit( simTab->GetSimCommand(), '\n' );
410
411 for( const wxString& command : commands )
412 {
413 wxBusyCursor wait;
414 m_simulator->Command( command.ToStdString() );
415 }
416
417 simTab->SetSpicePlotName( m_simulator->CurrentPlotName() );
418 m_ui->OnSimRefresh( true );
419
420#if 0
421 m_simulator->Command( "setplot" ); // Print available plots to console
422 m_simulator->Command( "display" ); // Print vectors in current plot to console
423#endif
424 }
425
426 return;
427 }
428 else
429 {
430 if( m_ui->GetSimTabIndex( simTab ) == 0
431 && m_circuitModel->GetSchTextSimCommand() != simTab->GetLastSchTextSimCommand() )
432 {
433 if( simTab->GetLastSchTextSimCommand().IsEmpty()
434 || IsOK( this, _( "Schematic sheet simulation command directive has changed. "
435 "Do you wish to update the Simulation Command?" ) ) )
436 {
437 simTab->SetSimCommand( m_circuitModel->GetSchTextSimCommand() );
438 simTab->SetLastSchTextSimCommand( simTab->GetSimCommand() );
439 OnModify();
440 }
441 }
442 }
443
444 if( !LoadSimulator( simTab->GetSimCommand(), simTab->GetSimOptions() ) )
445 return;
446
447 std::unique_lock<std::mutex> simulatorLock( m_simulator->GetMutex(), std::try_to_lock );
448
449 if( simulatorLock.owns_lock() )
450 {
451 m_ui->OnSimUpdate();
452 m_simulator->Run();
453
454 // Netlist from schematic may have changed; update signals list, measurements list,
455 // etc.
457 }
458 else
459 {
460 DisplayErrorMessage( this, _( "Another simulation is already running." ) );
461 }
462}
463
464
465SIM_TAB* SIMULATOR_FRAME::NewSimTab( const wxString& aSimCommand )
466{
467 return m_ui->NewSimTab( aSimCommand );
468}
469
470
471const std::vector<wxString> SIMULATOR_FRAME::SimPlotVectors()
472{
473 return m_ui->SimPlotVectors();
474}
475
476
477const std::vector<wxString> SIMULATOR_FRAME::Signals()
478{
479 return m_ui->Signals();
480}
481
482
483const std::map<int, wxString>& SIMULATOR_FRAME::UserDefinedSignals()
484{
485 return m_ui->UserDefinedSignals();
486}
487
488
489void SIMULATOR_FRAME::SetUserDefinedSignals( const std::map<int, wxString>& aSignals )
490{
491 m_ui->SetUserDefinedSignals( aSignals );
492}
493
494
495void SIMULATOR_FRAME::AddVoltageTrace( const wxString& aNetName )
496{
497 m_ui->AddTrace( aNetName, SPT_VOLTAGE );
498}
499
500
501void SIMULATOR_FRAME::AddCurrentTrace( const wxString& aDeviceName )
502{
503 m_ui->AddTrace( aDeviceName, SPT_CURRENT );
504}
505
506
507void SIMULATOR_FRAME::AddTuner( const SCH_SHEET_PATH& aSheetPath, SCH_SYMBOL* aSymbol )
508{
509 m_ui->AddTuner( aSheetPath, aSymbol );
510}
511
512
514{
515 return m_ui->GetCurrentSimTab();
516}
517
518
519bool SIMULATOR_FRAME::LoadWorkbook( const wxString& aPath )
520{
521 if( m_ui->LoadWorkbook( aPath ) )
522 {
523 UpdateTitle();
524
525 // Successfully loading a workbook does not count as modifying it. Clear the modified
526 // flag after all the EVT_WORKBOOK_MODIFIED events have been processed.
527 CallAfter( [this]()
528 {
529 m_workbookModified = false;
530 } );
531
532 return true;
533 }
534
535 return false;
536}
537
538
539bool SIMULATOR_FRAME::SaveWorkbook( const wxString& aPath )
540{
541 if( m_ui->SaveWorkbook( aPath ) )
542 {
543 m_workbookModified = false;
544 UpdateTitle();
545
546 return true;
547 }
548
549 return false;
550}
551
552
554{
556}
557
558
560{
561 SIM_TAB* simTab = m_ui->GetCurrentSimTab();
562 DIALOG_SIM_COMMAND dlg( this, m_circuitModel, m_simulator->Settings() );
563 wxString errors;
564 WX_STRING_REPORTER reporter( &errors );
565
566 if( !simTab )
567 return false;
568
569 if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS,
570 reporter ) )
571 {
572 DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" )
573 + errors );
574 }
575
576 dlg.SetSimCommand( simTab->GetSimCommand() );
577 dlg.SetSimOptions( simTab->GetSimOptions() );
578 dlg.SetPlotSettings( simTab );
579
580 if( dlg.ShowModal() == wxID_OK )
581 {
582 simTab->SetSimCommand( dlg.GetSimCommand() );
583 dlg.ApplySettings( simTab );
585 OnModify();
586 return true;
587 }
588
589 return false;
590}
591
592
593bool SIMULATOR_FRAME::canCloseWindow( wxCloseEvent& aEvent )
594{
596 {
597 wxFileName filename = m_simulator->Settings()->GetWorkbookFilename();
598
599 if( filename.GetName().IsEmpty() )
600 {
601 if( Prj().GetProjectName().IsEmpty() )
602 filename.SetFullName( wxT( "noname.wbk" ) );
603 else
604 filename.SetFullName( Prj().GetProjectName() + wxT( ".wbk" ) );
605 }
606
607 return HandleUnsavedChanges( this, _( "Save changes to workbook?" ),
608 [&]() -> bool
609 {
610 return SaveWorkbook( Prj().AbsolutePath( filename.GetFullName() ) );
611 } );
612 }
613
614 return true;
615}
616
617
619{
620 if( m_simulator->IsRunning() )
621 m_simulator->Stop();
622
623 // Prevent memory leak on exit by deleting all simulation vectors
624 m_simulator->Clean();
625
626 // Cancel a running simProbe or simTune tool
628
629 SaveSettings( config() );
630
631 m_simulator->Settings() = nullptr;
632
633 Destroy();
634}
635
636
638{
640
642 wxASSERT( mgr );
643
644 auto showGridCondition =
645 [this]( const SELECTION& aSel )
646 {
647 SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
648 return plotTab && plotTab->IsGridShown();
649 };
650
651 auto showLegendCondition =
652 [this]( const SELECTION& aSel )
653 {
654 SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
655 return plotTab && plotTab->IsLegendShown();
656 };
657
658 auto showDottedCondition =
659 [this]( const SELECTION& aSel )
660 {
661 SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
662 return plotTab && plotTab->GetDottedSecondary();
663 };
664
665 auto darkModePlotCondition =
666 [this]( const SELECTION& aSel )
667 {
668 return m_ui->DarkModePlots();
669 };
670
671 auto simRunning =
672 [this]( const SELECTION& aSel )
673 {
674 return m_simulator && m_simulator->IsRunning();
675 };
676
677 auto simFinished =
678 [this]( const SELECTION& aSel )
679 {
680 return m_simFinished;
681 };
682
683 auto haveSim =
684 [this]( const SELECTION& aSel )
685 {
686 return GetCurrentSimTab() != nullptr;
687 };
688
689 auto havePlot =
690 [this]( const SELECTION& aSel )
691 {
692 return dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() ) != nullptr;
693 };
694
695 auto haveZoomUndo =
696 [this]( const SELECTION& aSel )
697 {
698 SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
699 return plotTab && plotTab->GetPlotWin()->UndoZoomStackSize() > 0;
700 };
701
702 auto haveZoomRedo =
703 [this]( const SELECTION& aSel )
704 {
705 SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( GetCurrentSimTab() );
706 return plotTab && plotTab->GetPlotWin()->RedoZoomStackSize() > 0;
707 };
708
709#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
710#define CHECK( x ) ACTION_CONDITIONS().Check( x )
711
715
720
721 mgr->SetConditions( ACTIONS::zoomUndo, ENABLE( haveZoomUndo ) );
722 mgr->SetConditions( ACTIONS::zoomRedo, ENABLE( haveZoomRedo ) );
723 mgr->SetConditions( EE_ACTIONS::toggleGrid, CHECK( showGridCondition ) );
724 mgr->SetConditions( EE_ACTIONS::toggleLegend, CHECK( showLegendCondition ) );
725 mgr->SetConditions( EE_ACTIONS::toggleDottedSecondary, CHECK( showDottedCondition ) );
726 mgr->SetConditions( EE_ACTIONS::toggleDarkModePlots, CHECK( darkModePlotCondition ) );
727
730 mgr->SetConditions( EE_ACTIONS::runSimulation, ENABLE( !simRunning ) );
731 mgr->SetConditions( EE_ACTIONS::stopSimulation, ENABLE( simRunning ) );
732 mgr->SetConditions( EE_ACTIONS::simProbe, ENABLE( simFinished ) );
733 mgr->SetConditions( EE_ACTIONS::simTune, ENABLE( simFinished ) );
735
736#undef CHECK
737#undef ENABLE
738}
739
740
741void SIMULATOR_FRAME::onSimStarted( wxCommandEvent& aEvent )
742{
743 SetCursor( wxCURSOR_ARROWWAIT );
744}
745
746
747void SIMULATOR_FRAME::onSimFinished( wxCommandEvent& aEvent )
748{
749 // Sometimes (for instance with a directive like wrdata my_file.csv "my_signal")
750 // the simulator is in idle state (simulation is finished), but still running, during
751 // the time the file is written. So gives a slice of time to fully finish the work:
752 if( m_simulator->IsRunning() )
753 {
754 int max_time = 40; // For a max timeout = 2s
755
756 do
757 {
758 wxMilliSleep( 50 );
759 wxYield();
760
761 if( max_time )
762 max_time--;
763
764 } while( max_time && m_simulator->IsRunning() );
765 }
766
767 // ensure the shown cursor is the default cursor, not the wxCURSOR_ARROWWAIT set when
768 // staring the simulator in onSimStarted:
769 SetCursor( wxNullCursor );
770
771 // Is a warning message useful if the simulatior is still running?
772 SCHEMATIC& schematic = m_schematicFrame->Schematic();
773 schematic.ClearOperatingPoints();
774
775 m_simFinished = true;
776
777 m_ui->OnSimRefresh( true );
778
781}
782
783
784void SIMULATOR_FRAME::onUpdateSim( wxCommandEvent& aEvent )
785{
786 static bool updateInProgress = false;
787
788 // skip update when events are triggered too often and previous call didn't end yet
789 if( updateInProgress )
790 return;
791
792 updateInProgress = true;
793
794 if( m_simulator->IsRunning() )
795 m_simulator->Stop();
796
797 std::unique_lock<std::mutex> simulatorLock( m_simulator->GetMutex(), std::try_to_lock );
798
799 if( simulatorLock.owns_lock() )
800 {
801 m_ui->OnSimUpdate();
802 m_simulator->Run();
803 }
804 else
805 {
806 DisplayErrorMessage( this, _( "Another simulation is already running." ) );
807 }
808
809 updateInProgress = false;
810}
811
812
813void SIMULATOR_FRAME::onSimReport( wxCommandEvent& aEvent )
814{
815 m_ui->OnSimReport( aEvent.GetString() );
816}
817
818
819void SIMULATOR_FRAME::onExit( wxCommandEvent& aEvent )
820{
821 if( aEvent.GetId() == wxID_EXIT )
822 Kiway().OnKiCadExit();
823
824 if( aEvent.GetId() == wxID_CLOSE )
825 Close( false );
826}
827
828
830{
832 m_workbookModified = true;
833 UpdateTitle();
834}
835
836
837wxDEFINE_EVENT( EVT_SIM_UPDATE, wxCommandEvent );
838wxDEFINE_EVENT( EVT_SIM_REPORT, wxCommandEvent );
839
840wxDEFINE_EVENT( EVT_SIM_STARTED, wxCommandEvent );
841wxDEFINE_EVENT( EVT_SIM_FINISHED, wxCommandEvent );
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:111
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
static TOOL_ACTION toggleGrid
Definition: actions.h:172
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
static TOOL_ACTION zoomRedo
Definition: actions.h:129
static TOOL_ACTION zoomUndo
Definition: actions.h:128
Manage TOOL_ACTION objects.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
Define the structure of a toolbar with buttons that invoke ACTIONs.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:92
Handle actions that are shared between different applications.
void SetPlotSettings(const SIM_TAB *aSimTab)
void SetSimCommand(const wxString &aCommand)
void ApplySettings(SIM_TAB *aTab)
void SetSimOptions(int aOptions)
const wxString & GetSimCommand() const
virtual APP_SETTINGS_BASE * config() const
Returns the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
virtual void OnModify()
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
static TOOL_ACTION simAnalysisProperties
Definition: ee_actions.h:286
static TOOL_ACTION openWorkbook
Definition: ee_actions.h:273
static TOOL_ACTION stopSimulation
Definition: ee_actions.h:288
static TOOL_ACTION toggleLegend
Definition: ee_actions.h:283
static TOOL_ACTION saveWorkbook
Definition: ee_actions.h:274
static TOOL_ACTION saveWorkbookAs
Definition: ee_actions.h:275
static TOOL_ACTION exportPlotAsCSV
Definition: ee_actions.h:277
static TOOL_ACTION simTune
Definition: ee_actions.h:282
static TOOL_ACTION toggleDarkModePlots
Definition: ee_actions.h:285
static TOOL_ACTION exportPlotAsPNG
Definition: ee_actions.h:276
static TOOL_ACTION showNetlist
Definition: ee_actions.h:290
static TOOL_ACTION simProbe
Definition: ee_actions.h:281
static TOOL_ACTION toggleDottedSecondary
Definition: ee_actions.h:284
static TOOL_ACTION exportPlotToSchematic
Definition: ee_actions.h:279
static TOOL_ACTION runSimulation
Definition: ee_actions.h:287
static TOOL_ACTION newAnalysisTab
Definition: ee_actions.h:272
static TOOL_ACTION exportPlotToClipboard
Definition: ee_actions.h:278
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:55
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:65
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
void OnKiCadExit()
Definition: kiway.cpp:717
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:406
Container for Ngspice simulator settings.
void SetCompatibilityMode(NGSPICE_COMPATIBILITY_MODE aMode)
A singleton reporter that reports to nowhere.
Definition: reporter.h:223
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:70
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
Definition: project.cpp:320
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
Holds all the data relating to one schematic.
Definition: schematic.h:75
void ClearOperatingPoints()
Clear operating points from a .op simulation.
Definition: schematic.h:224
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Schematic editor (Eeschema) main window.
void RefreshOperatingPointDisplay()
Refresh the display of any operaintg points.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
bool ReadyToNetlist(const wxString &aAnnotateMessage)
Check if we are ready to write a netlist file for the current schematic.
SCHEMATIC & Schematic() const
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition: sch_symbol.h:105
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
Handle actions for the various symbol editor and viewers.
The SIMULATOR_FRAME_UI holds the main user-interface for running simulations.
SIM_TAB * NewSimTab(const wxString &aSimCommand)
Create a new simulation tab for a given simulation type.
void SetUserDefinedSignals(const std::map< int, wxString > &aSignals)
void OnSimRefresh(bool aFinal)
SIM_TAB * GetSimTab(SIM_TYPE aType) const
std::vector< wxString > SimPlotVectors() const
std::vector< wxString > Signals() const
bool SaveWorkbook(const wxString &aPath)
Save plot, signal, cursor, measurement, etc.
SIM_TAB * GetCurrentSimTab() const
Return the currently opened plot panel (or NULL if there is none).
bool LoadWorkbook(const wxString &aPath)
Load plot, signal, cursor, measurement, etc.
bool DarkModePlots() const
const std::map< int, wxString > & UserDefinedSignals()
void AddTrace(const wxString &aName, SIM_TRACE_TYPE aType)
Add a new trace to the current plot.
void SaveSettings(EESCHEMA_SETTINGS *aCfg)
int GetSimTabIndex(SIM_TAB *aPlot) const
void OnSimReport(const wxString &aMsg)
void ApplyPreferences(const SIM_PREFERENCES &aPrefs)
Called when settings are changed via the common Preferences dialog.
void AddTuner(const SCH_SHEET_PATH &aSheetPath, SCH_SYMBOL *aSymbol)
Add a tuner for a symbol.
void LoadSettings(EESCHEMA_SETTINGS *aCfg)
The SIMULATOR_FRAME holds the main user-interface for running simulations.
SIM_TAB * GetCurrentSimTab() const
Return the current tab (or NULL if there is none).
void ShowChangedLanguage() override
bool canCloseWindow(wxCloseEvent &aEvent) override
void onSimFinished(wxCommandEvent &aEvent)
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
bool LoadSimulator(const wxString &aSimCommand, unsigned aSimOptions)
Check and load the current netlist into the simulator.
void onSimReport(wxCommandEvent &aEvent)
wxString GetCurrentSimCommand() const
void onExit(wxCommandEvent &event)
std::shared_ptr< SPICE_SIMULATOR > m_simulator
SIM_TYPE GetCurrentSimType() const
void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
void AddCurrentTrace(const wxString &aDeviceName)
Add a current trace for a given device to the current plot.
void OnModify() override
Must be called after a model change in order to set the "modify" flag and do other frame-specific pro...
bool SaveWorkbook(const wxString &aPath)
Save plot, signal, cursor, measurement, etc.
const std::vector< wxString > Signals()
void doCloseWindow() override
const std::vector< wxString > SimPlotVectors()
void AddVoltageTrace(const wxString &aNetName)
Add a voltage trace for a given net to the current plot.
void ToggleDarkModePlots()
Toggle dark-mode of the plot tabs.
SIM_THREAD_REPORTER * m_reporter
void AddTuner(const SCH_SHEET_PATH &aSheetPath, SCH_SYMBOL *aSymbol)
Add a tuner for a symbol.
void onSimStarted(wxCommandEvent &aEvent)
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
std::shared_ptr< SPICE_CIRCUIT_MODEL > m_circuitModel
SIM_TAB * NewSimTab(const wxString &aSimCommand)
Create a new plot tab for a given simulation type.
bool EditAnalysis()
Shows a dialog for editing the current tab's simulation command, or creating a new tab with a differe...
int GetCurrentOptions() const
bool LoadWorkbook(const wxString &aPath)
Load plot, signal, cursor, measurement, etc.
WINDOW_SETTINGS * GetWindowSettings(APP_SETTINGS_BASE *aCfg) override
Return a pointer to the window settings for this frame.
void onUpdateSim(wxCommandEvent &aEvent)
void UpdateTitle()
Set the main window title bar text.
const std::map< int, wxString > & UserDefinedSignals()
void SetUserDefinedSignals(const std::map< int, wxString > &aSignals)
void ReloadSimulator(const wxString &aSimCommand, unsigned aSimOptions)
Re-send the current command and settings to the simulator.
SCH_EDIT_FRAME * m_schematicFrame
SIMULATOR_FRAME_UI * m_ui
Interface to receive simulation updates from SPICE_SIMULATOR class.
static std::shared_ptr< SPICE_SIMULATOR > CreateInstance(const std::string &aName)
mpWindow * GetPlotWin() const
Definition: sim_plot_tab.h:350
bool IsGridShown() const
Definition: sim_plot_tab.h:285
bool GetDottedSecondary() const
Toggle cursor for a particular trace.
Definition: sim_plot_tab.h:329
bool IsLegendShown() const
Definition: sim_plot_tab.h:299
int GetSimOptions() const
Definition: sim_tab.h:55
const wxString & GetSpicePlotName() const
Definition: sim_tab.h:61
void SetLastSchTextSimCommand(const wxString &aCmd)
Definition: sim_tab.h:59
void SetSimCommand(const wxString &aSimCommand)
Definition: sim_tab.h:53
const wxString & GetSimCommand() const
Definition: sim_tab.h:52
wxString GetLastSchTextSimCommand() const
Definition: sim_tab.h:58
void SetSpicePlotName(const wxString &aPlotName)
Definition: sim_tab.h:62
SIMULATOR_FRAME * m_parent
SIM_THREAD_REPORTER(SIMULATOR_FRAME *aParent)
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
void OnSimStateChange(SIMULATOR *aObject, SIM_STATE aNewState) override
static SIM_TYPE CommandToSimType(const wxString &aCmd)
Return simulation type basing on a simulation command directive.
wxString GetWorkbookFilename() const
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:167
TOOL_DISPATCHER * m_toolDispatcher
Definition: tools_holder.h:169
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
virtual void DispatchWxEvent(wxEvent &aEvent)
Process wxEvents (mostly UI events), translate them to TOOL_EVENTs, and make tools handle those.
Master controller class:
Definition: tool_manager.h:62
ACTION_MANAGER * GetActionManager() const
Definition: tool_manager.h:302
APP_SETTINGS_BASE * GetSettings() const
Definition: tool_manager.h:400
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
Definition: tool_manager.h:235
void RegisterTool(TOOL_BASE *aTool)
Add a tool to the manager set and sets it up.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
void InitTools()
Initializes all registered tools.
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:75
A wrapper for reporting to a wxString object.
Definition: reporter.h:164
int RedoZoomStackSize() const
Definition: mathplot.h:1267
int UndoZoomStackSize() const
Definition: mathplot.h:1266
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:241
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:121
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:186
This file is part of the common library.
#define CHECK(x)
#define ENABLE(x)
#define _(s)
@ FRAME_SCH
Definition: frame_type.h:34
@ FRAME_SIMULATOR
Definition: frame_type.h:38
see class PGM_BASE
SEVERITY
@ RPT_SEVERITY_UNDEFINED
@ GLOBAL_CLEANUP
@ SPT_VOLTAGE
Definition: sim_types.h:52
@ SPT_CURRENT
Definition: sim_types.h:53
SIM_TYPE
< Possible simulation types
Definition: sim_types.h:32
@ ST_TRAN
Definition: sim_types.h:42
wxDEFINE_EVENT(EVT_SIM_UPDATE, wxCommandEvent)
@ SIM_IDLE
@ SIM_RUNNING
KIWAY Kiway(KFCTL_STANDALONE)
Stores the common settings that are saved and loaded for each window / frame.
Definition: app_settings.h:74
Definition of file extensions used in Kicad.