From f3966371be85131050121c4fca45542094f86e8a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 19 Mar 2024 17:04:42 +0100 Subject: [PATCH] Simulation: add export current plot to clipboard and current schematic These exports are in file menu. --- common/widgets/mathplot.cpp | 18 ++--- eeschema/sim/sim_plot_tab.cpp | 1 - eeschema/sim/simulator_frame.cpp | 2 + eeschema/sim/toolbars_simulator_frame.cpp | 3 + eeschema/tools/ee_actions.cpp | 12 +++ eeschema/tools/ee_actions.h | 2 + eeschema/tools/simulator_control.cpp | 92 ++++++++++++++++++++++- eeschema/tools/simulator_control.h | 2 + include/widgets/mathplot.h | 12 +-- 9 files changed, 127 insertions(+), 17 deletions(-) diff --git a/common/widgets/mathplot.cpp b/common/widgets/mathplot.cpp index 2a9b2b1469..0f15997c08 100644 --- a/common/widgets/mathplot.cpp +++ b/common/widgets/mathplot.cpp @@ -2329,20 +2329,19 @@ void mpWindow::GetBoundingBox( double* bbox ) const } -bool mpWindow::SaveScreenshot( const wxString& filename, wxBitmapType type, wxSize imageSize, - bool fit ) +bool mpWindow::SaveScreenshot( wxImage& aImage, wxSize aImageSize, bool aFit ) { int sizeX, sizeY; - if( imageSize == wxDefaultSize ) + if( aImageSize == wxDefaultSize ) { sizeX = m_scrX; sizeY = m_scrY; } else { - sizeX = imageSize.x; - sizeY = imageSize.y; + sizeX = aImageSize.x; + sizeY = aImageSize.y; SetScr( sizeX, sizeY ); } @@ -2355,7 +2354,7 @@ bool mpWindow::SaveScreenshot( const wxString& filename, wxBitmapType type, wxSi screenDC.SetBrush( brush ); screenDC.DrawRectangle( 0, 0, sizeX, sizeY ); - if( fit ) + if( aFit ) Fit( m_minX, m_maxX, m_minY, m_maxY, &sizeX, &sizeY ); else Fit( m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax, &sizeX, &sizeY ); @@ -2364,7 +2363,7 @@ bool mpWindow::SaveScreenshot( const wxString& filename, wxBitmapType type, wxSi for( mpLayer* layer : m_layers ) layer->Plot( screenDC, *this ); - if( imageSize != wxDefaultSize ) + if( aImageSize != wxDefaultSize ) { // Restore dimensions int bk_scrX = m_scrX; @@ -2375,8 +2374,9 @@ bool mpWindow::SaveScreenshot( const wxString& filename, wxBitmapType type, wxSi } // Once drawing is complete, actually save screen shot - wxImage screenImage = screenBuffer.ConvertToImage(); - return screenImage.SaveFile( filename, type ); + aImage = screenBuffer.ConvertToImage(); + + return true; } diff --git a/eeschema/sim/sim_plot_tab.cpp b/eeschema/sim/sim_plot_tab.cpp index a0a475d4a9..782e75de4f 100644 --- a/eeschema/sim/sim_plot_tab.cpp +++ b/eeschema/sim/sim_plot_tab.cpp @@ -442,7 +442,6 @@ SIM_PLOT_TAB::SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent ) : m_plotWin->LimitView( true ); m_plotWin->SetMargins( 30, 70, 45, 70 ); - UpdatePlotColors(); updateAxes(); diff --git a/eeschema/sim/simulator_frame.cpp b/eeschema/sim/simulator_frame.cpp index 8871517303..02ab3727bb 100644 --- a/eeschema/sim/simulator_frame.cpp +++ b/eeschema/sim/simulator_frame.cpp @@ -709,6 +709,8 @@ void SIMULATOR_FRAME::setupUIConditions() mgr->SetConditions( EE_ACTIONS::exportPlotAsPNG, ENABLE( havePlot ) ); mgr->SetConditions( EE_ACTIONS::exportPlotAsCSV, ENABLE( havePlot ) ); + mgr->SetConditions( EE_ACTIONS::exportPlotToClipboard, ENABLE( havePlot ) ); + mgr->SetConditions( EE_ACTIONS::exportPlotToSchematic, ENABLE( havePlot ) ); mgr->SetConditions( ACTIONS::zoomUndo, ENABLE( haveZoomUndo ) ); mgr->SetConditions( ACTIONS::zoomRedo, ENABLE( haveZoomRedo ) ); diff --git a/eeschema/sim/toolbars_simulator_frame.cpp b/eeschema/sim/toolbars_simulator_frame.cpp index d8c2ad5dcd..2f266af772 100644 --- a/eeschema/sim/toolbars_simulator_frame.cpp +++ b/eeschema/sim/toolbars_simulator_frame.cpp @@ -106,6 +106,9 @@ void SIMULATOR_FRAME::doReCreateMenuBar() fileMenu->AppendSeparator(); fileMenu->Add( EE_ACTIONS::exportPlotAsPNG ); fileMenu->Add( EE_ACTIONS::exportPlotAsCSV ); + fileMenu->AppendSeparator(); + fileMenu->Add( EE_ACTIONS::exportPlotToClipboard ); + fileMenu->Add( EE_ACTIONS::exportPlotToSchematic ); fileMenu->AppendSeparator(); fileMenu->AddClose( _( "Simulator" ) ); diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index 36fae008dc..e9a51b08dc 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -1462,6 +1462,18 @@ TOOL_ACTION EE_ACTIONS::exportPlotAsCSV( TOOL_ACTION_ARGS() .FriendlyName( _( "Export Current Plot as CSV..." ) ) .Icon( BITMAPS::export_file ) ); +TOOL_ACTION EE_ACTIONS::exportPlotToClipboard( TOOL_ACTION_ARGS() + .Name( "eeschema.Simulator.exportToClipboard" ) + .Scope( AS_GLOBAL ) + .FriendlyName( _( "Export Current Plot to Clipboard" ) ) + .Icon( BITMAPS::export_png ) ); + +TOOL_ACTION EE_ACTIONS::exportPlotToSchematic( TOOL_ACTION_ARGS() + .Name( "eeschema.Simulator.exportPlotToSchematic" ) + .Scope( AS_GLOBAL ) + .FriendlyName( _( "Export Current Plot to Schematic" ) ) + .Icon( BITMAPS::export_png ) ); + TOOL_ACTION EE_ACTIONS::toggleLegend( TOOL_ACTION_ARGS() .Name( "eeschema.Simulator.toggleLegend" ) .Scope( AS_GLOBAL ) diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index 1b24279bd3..467f7cb17d 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -271,6 +271,8 @@ public: static TOOL_ACTION saveWorkbookAs; static TOOL_ACTION exportPlotAsPNG; static TOOL_ACTION exportPlotAsCSV; + static TOOL_ACTION exportPlotToClipboard; + static TOOL_ACTION exportPlotToSchematic; static TOOL_ACTION showSimulator; static TOOL_ACTION simProbe; static TOOL_ACTION simTune; diff --git a/eeschema/tools/simulator_control.cpp b/eeschema/tools/simulator_control.cpp index 2caf3a1087..e54871eeb5 100644 --- a/eeschema/tools/simulator_control.cpp +++ b/eeschema/tools/simulator_control.cpp @@ -20,6 +20,8 @@ * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#define wxUSE_BASE64 1 +#include #include #include @@ -40,6 +42,10 @@ #include #include #include +#include +#include +#include +#include bool SIMULATOR_CONTROL::Init() @@ -169,7 +175,88 @@ int SIMULATOR_CONTROL::ExportPlotAsPNG( const TOOL_EVENT& aEvent ) if( saveDlg.ShowModal() == wxID_CANCEL ) return -1; - plotTab->GetPlotWin()->SaveScreenshot( saveDlg.GetPath(), wxBITMAP_TYPE_PNG ); + wxImage screenImage; + plotTab->GetPlotWin()->SaveScreenshot( screenImage ); + screenImage.SaveFile( saveDlg.GetPath(), wxBITMAP_TYPE_PNG ); + } + + return 0; +} + + +int SIMULATOR_CONTROL::ExportPlotToClipboard( const TOOL_EVENT& aEvent ) +{ + if( SIM_PLOT_TAB* plotTab = dynamic_cast( getCurrentSimTab() ) ) + { + wxImage screenImage; + plotTab->GetPlotWin()->SaveScreenshot( screenImage ); + + if( wxTheClipboard->Open() ) + { + wxBitmap bm( screenImage ); + + wxTheClipboard->SetData( new wxBitmapDataObject( bm ) ); + wxTheClipboard->Flush(); // Allow data to be available after closing KiCad + wxTheClipboard->Close(); + } + } + + return 0; +} + + +int SIMULATOR_CONTROL::ExportPlotToSchematic( const TOOL_EVENT& aEvent ) +{ + if( m_schematicFrame == nullptr ) + return -1; + + if( SIM_PLOT_TAB* plotTab = dynamic_cast( getCurrentSimTab() ) ) + { + wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog(); + + if( blocking_dialog ) + blocking_dialog->Close( true ); + + wxImage screenImage; + plotTab->GetPlotWin()->SaveScreenshot( screenImage ); + + if( wxTheClipboard->Open() ) + { + // Build a PNG bitmap: + wxMemoryOutputStream stream; + screenImage.SaveFile( stream, wxBITMAP_TYPE_PNG ); + stream.Close(); + + // Create a SCH_BITMAP data string + wxString string; + string << "(image (at 0 0)\n"; + string << " (data\n"; + + wxMemoryBuffer buff; + buff.GetWriteBuf( stream.GetLength() ); + stream.CopyTo( buff.GetData(), stream.GetLength() ); + buff.SetDataLen( stream.GetLength() ); + + wxString out; + out << wxBase64Encode( buff ); + + #define MIME_BASE64_LENGTH 76 + size_t first = 0; + + while( first < out.Length() ) + { + string << " \"" << TO_UTF8( out( first, MIME_BASE64_LENGTH ) ); + string << "\"\n"; + first += MIME_BASE64_LENGTH; + } + string << " )\n)\n"; + + wxTheClipboard->SetData( new wxTextDataObject( string ) ); + wxTheClipboard->Close(); + + m_schematicFrame->GetToolManager()->PostAction( ACTIONS::paste ); + m_schematicFrame->Raise(); + } } return 0; @@ -533,6 +620,9 @@ void SIMULATOR_CONTROL::setTransitions() Go( &SIMULATOR_CONTROL::SaveWorkbook, EE_ACTIONS::saveWorkbookAs.MakeEvent() ); Go( &SIMULATOR_CONTROL::ExportPlotAsPNG, EE_ACTIONS::exportPlotAsPNG.MakeEvent() ); Go( &SIMULATOR_CONTROL::ExportPlotAsCSV, EE_ACTIONS::exportPlotAsCSV.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ExportPlotToClipboard, EE_ACTIONS::exportPlotToClipboard.MakeEvent() ); + Go( &SIMULATOR_CONTROL::ExportPlotToSchematic, EE_ACTIONS::exportPlotToSchematic.MakeEvent() ); + Go( &SIMULATOR_CONTROL::Close, ACTIONS::quit.MakeEvent() ); Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInCenter.MakeEvent() ); diff --git a/eeschema/tools/simulator_control.h b/eeschema/tools/simulator_control.h index b02a877896..bf32fe7640 100644 --- a/eeschema/tools/simulator_control.h +++ b/eeschema/tools/simulator_control.h @@ -59,6 +59,8 @@ public: int SaveWorkbook( const TOOL_EVENT& aEvent ); int ExportPlotAsPNG( const TOOL_EVENT& aEvent ); int ExportPlotAsCSV( const TOOL_EVENT& aEvent ); + int ExportPlotToClipboard( const TOOL_EVENT& aEvent ); + int ExportPlotToSchematic( const TOOL_EVENT& aEvent ); int Close( const TOOL_EVENT& aEvent ); int Zoom( const TOOL_EVENT& aEvent ); diff --git a/include/widgets/mathplot.h b/include/widgets/mathplot.h index 90c47f9b29..9c1fea0443 100644 --- a/include/widgets/mathplot.h +++ b/include/widgets/mathplot.h @@ -1177,12 +1177,12 @@ public: void GetBoundingBox( double* bbox ) const; /** Draw the window on a wxBitmap, then save it to a file. - * @param filename File name where to save the screenshot - * @param type image type to be saved: see wxImage output file types for flags - * @param imageSize Set a size for the output image. Default is the same as the screen size - * @param fit Decide whether to fit the plot into the size*/ - bool SaveScreenshot( const wxString& filename, wxBitmapType type = wxBITMAP_TYPE_BMP, - wxSize imageSize = wxDefaultSize, bool fit = false ); + * @param aImage a wxImage where to save the screenshot + * @param aImageSize Set a size for the output image. Default is the same as the screen size + * @param aFit Decide whether to fit the plot into the size + */ + bool SaveScreenshot( wxImage& aImage, + wxSize aImageSize = wxDefaultSize, bool aFit = false ); /** This value sets the zoom steps whenever the user clicks "Zoom in/out" or performs zoom with the mouse wheel. * It must be a number above unity. This number is used for zoom in, and its inverse for zoom out.