Simulation: add export current plot to clipboard and current schematic

These exports are in file menu.
This commit is contained in:
jean-pierre charras 2024-03-19 17:04:42 +01:00
parent 63dd4aed93
commit f3966371be
9 changed files with 127 additions and 17 deletions

View File

@ -2329,20 +2329,19 @@ void mpWindow::GetBoundingBox( double* bbox ) const
} }
bool mpWindow::SaveScreenshot( const wxString& filename, wxBitmapType type, wxSize imageSize, bool mpWindow::SaveScreenshot( wxImage& aImage, wxSize aImageSize, bool aFit )
bool fit )
{ {
int sizeX, sizeY; int sizeX, sizeY;
if( imageSize == wxDefaultSize ) if( aImageSize == wxDefaultSize )
{ {
sizeX = m_scrX; sizeX = m_scrX;
sizeY = m_scrY; sizeY = m_scrY;
} }
else else
{ {
sizeX = imageSize.x; sizeX = aImageSize.x;
sizeY = imageSize.y; sizeY = aImageSize.y;
SetScr( sizeX, sizeY ); SetScr( sizeX, sizeY );
} }
@ -2355,7 +2354,7 @@ bool mpWindow::SaveScreenshot( const wxString& filename, wxBitmapType type, wxSi
screenDC.SetBrush( brush ); screenDC.SetBrush( brush );
screenDC.DrawRectangle( 0, 0, sizeX, sizeY ); screenDC.DrawRectangle( 0, 0, sizeX, sizeY );
if( fit ) if( aFit )
Fit( m_minX, m_maxX, m_minY, m_maxY, &sizeX, &sizeY ); Fit( m_minX, m_maxX, m_minY, m_maxY, &sizeX, &sizeY );
else else
Fit( m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax, &sizeX, &sizeY ); 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 ) for( mpLayer* layer : m_layers )
layer->Plot( screenDC, *this ); layer->Plot( screenDC, *this );
if( imageSize != wxDefaultSize ) if( aImageSize != wxDefaultSize )
{ {
// Restore dimensions // Restore dimensions
int bk_scrX = m_scrX; 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 // Once drawing is complete, actually save screen shot
wxImage screenImage = screenBuffer.ConvertToImage(); aImage = screenBuffer.ConvertToImage();
return screenImage.SaveFile( filename, type );
return true;
} }

View File

@ -442,7 +442,6 @@ SIM_PLOT_TAB::SIM_PLOT_TAB( const wxString& aSimCommand, wxWindow* parent ) :
m_plotWin->LimitView( true ); m_plotWin->LimitView( true );
m_plotWin->SetMargins( 30, 70, 45, 70 ); m_plotWin->SetMargins( 30, 70, 45, 70 );
UpdatePlotColors(); UpdatePlotColors();
updateAxes(); updateAxes();

View File

@ -709,6 +709,8 @@ void SIMULATOR_FRAME::setupUIConditions()
mgr->SetConditions( EE_ACTIONS::exportPlotAsPNG, ENABLE( havePlot ) ); mgr->SetConditions( EE_ACTIONS::exportPlotAsPNG, ENABLE( havePlot ) );
mgr->SetConditions( EE_ACTIONS::exportPlotAsCSV, 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::zoomUndo, ENABLE( haveZoomUndo ) );
mgr->SetConditions( ACTIONS::zoomRedo, ENABLE( haveZoomRedo ) ); mgr->SetConditions( ACTIONS::zoomRedo, ENABLE( haveZoomRedo ) );

View File

@ -106,6 +106,9 @@ void SIMULATOR_FRAME::doReCreateMenuBar()
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
fileMenu->Add( EE_ACTIONS::exportPlotAsPNG ); fileMenu->Add( EE_ACTIONS::exportPlotAsPNG );
fileMenu->Add( EE_ACTIONS::exportPlotAsCSV ); fileMenu->Add( EE_ACTIONS::exportPlotAsCSV );
fileMenu->AppendSeparator();
fileMenu->Add( EE_ACTIONS::exportPlotToClipboard );
fileMenu->Add( EE_ACTIONS::exportPlotToSchematic );
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
fileMenu->AddClose( _( "Simulator" ) ); fileMenu->AddClose( _( "Simulator" ) );

View File

@ -1462,6 +1462,18 @@ TOOL_ACTION EE_ACTIONS::exportPlotAsCSV( TOOL_ACTION_ARGS()
.FriendlyName( _( "Export Current Plot as CSV..." ) ) .FriendlyName( _( "Export Current Plot as CSV..." ) )
.Icon( BITMAPS::export_file ) ); .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() TOOL_ACTION EE_ACTIONS::toggleLegend( TOOL_ACTION_ARGS()
.Name( "eeschema.Simulator.toggleLegend" ) .Name( "eeschema.Simulator.toggleLegend" )
.Scope( AS_GLOBAL ) .Scope( AS_GLOBAL )

View File

@ -271,6 +271,8 @@ public:
static TOOL_ACTION saveWorkbookAs; static TOOL_ACTION saveWorkbookAs;
static TOOL_ACTION exportPlotAsPNG; static TOOL_ACTION exportPlotAsPNG;
static TOOL_ACTION exportPlotAsCSV; static TOOL_ACTION exportPlotAsCSV;
static TOOL_ACTION exportPlotToClipboard;
static TOOL_ACTION exportPlotToSchematic;
static TOOL_ACTION showSimulator; static TOOL_ACTION showSimulator;
static TOOL_ACTION simProbe; static TOOL_ACTION simProbe;
static TOOL_ACTION simTune; static TOOL_ACTION simTune;

View File

@ -20,6 +20,8 @@
* or you may write to the Free Software Foundation, Inc., * or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#define wxUSE_BASE64 1
#include <wx/base64.h>
#include <wx/ffile.h> #include <wx/ffile.h>
#include <wx/filedlg.h> #include <wx/filedlg.h>
@ -40,6 +42,10 @@
#include <scintilla_tricks.h> #include <scintilla_tricks.h>
#include <sim/spice_circuit_model.h> #include <sim/spice_circuit_model.h>
#include <dialogs/dialog_user_defined_signals.h> #include <dialogs/dialog_user_defined_signals.h>
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#include <wx/mstream.h>
#include <string_utils.h>
bool SIMULATOR_CONTROL::Init() bool SIMULATOR_CONTROL::Init()
@ -169,7 +175,88 @@ int SIMULATOR_CONTROL::ExportPlotAsPNG( const TOOL_EVENT& aEvent )
if( saveDlg.ShowModal() == wxID_CANCEL ) if( saveDlg.ShowModal() == wxID_CANCEL )
return -1; 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<SIM_PLOT_TAB*>( 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<SIM_PLOT_TAB*>( 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; return 0;
@ -533,6 +620,9 @@ void SIMULATOR_CONTROL::setTransitions()
Go( &SIMULATOR_CONTROL::SaveWorkbook, EE_ACTIONS::saveWorkbookAs.MakeEvent() ); Go( &SIMULATOR_CONTROL::SaveWorkbook, EE_ACTIONS::saveWorkbookAs.MakeEvent() );
Go( &SIMULATOR_CONTROL::ExportPlotAsPNG, EE_ACTIONS::exportPlotAsPNG.MakeEvent() ); Go( &SIMULATOR_CONTROL::ExportPlotAsPNG, EE_ACTIONS::exportPlotAsPNG.MakeEvent() );
Go( &SIMULATOR_CONTROL::ExportPlotAsCSV, EE_ACTIONS::exportPlotAsCSV.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::Close, ACTIONS::quit.MakeEvent() );
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInCenter.MakeEvent() ); Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInCenter.MakeEvent() );

View File

@ -59,6 +59,8 @@ public:
int SaveWorkbook( const TOOL_EVENT& aEvent ); int SaveWorkbook( const TOOL_EVENT& aEvent );
int ExportPlotAsPNG( const TOOL_EVENT& aEvent ); int ExportPlotAsPNG( const TOOL_EVENT& aEvent );
int ExportPlotAsCSV( 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 Close( const TOOL_EVENT& aEvent );
int Zoom( const TOOL_EVENT& aEvent ); int Zoom( const TOOL_EVENT& aEvent );

View File

@ -1177,12 +1177,12 @@ public:
void GetBoundingBox( double* bbox ) const; void GetBoundingBox( double* bbox ) const;
/** Draw the window on a wxBitmap, then save it to a file. /** Draw the window on a wxBitmap, then save it to a file.
* @param filename File name where to save the screenshot * @param aImage a wxImage where to save the screenshot
* @param type image type to be saved: see wxImage output file types for flags * @param aImageSize Set a size for the output image. Default is the same as the screen size
* @param imageSize 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
* @param fit Decide whether to fit the plot into the size*/ */
bool SaveScreenshot( const wxString& filename, wxBitmapType type = wxBITMAP_TYPE_BMP, bool SaveScreenshot( wxImage& aImage,
wxSize imageSize = wxDefaultSize, bool fit = false ); 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. /** 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. * It must be a number above unity. This number is used for zoom in, and its inverse for zoom out.