diff --git a/common/common.cpp b/common/common.cpp index 88881fa386..475fc906b3 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2008-2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -344,6 +345,61 @@ wxString GetKicadConfigPath() return cfgpath.GetPath(); } + + +bool EnsureFileDirectoryExists( wxFileName* aTargetFullFileName, + const wxString& aBaseFilename, + REPORTER* aReporter ) +{ + wxString msg; + wxString baseFilePath = wxFileName( aBaseFilename ).GetPath(); + + // make aTargetFullFileName path, which is relative to aBaseFilename path (if it is not + // already an absolute path) absolute: + if( !aTargetFullFileName->MakeAbsolute( baseFilePath ) ) + { + if( aReporter ) + { + msg.Printf( _( "*** Error: cannot make path '%s' absolute with respect to '%s'! ***" ), + GetChars( aTargetFullFileName->GetPath() ), + GetChars( baseFilePath ) ); + aReporter->Report( msg ); + } + + return false; + } + + // Ensure the path of aTargetFullFileName exists, and create it if needed: + wxString outputPath( aTargetFullFileName->GetPath() ); + + if( !wxFileName::DirExists( outputPath ) ) + { + if( wxMkdir( outputPath ) ) + { + if( aReporter ) + { + msg.Printf( _( "Output directory '%s' created.\n" ), GetChars( outputPath ) ); + aReporter->Report( msg ); + return true; + } + } + else + { + if( aReporter ) + { + msg.Printf( _( "*** Error: cannot create output directory '%s'! ***\n" ), + GetChars( outputPath ) ); + aReporter->Report( msg ); + } + + return false; + } + } + + return true; +} + + #ifdef __WXMAC__ wxString GetOSXKicadUserDataDir() { diff --git a/eeschema/dialogs/dialog_plot_schematic.cpp b/eeschema/dialogs/dialog_plot_schematic.cpp index 9390e6d6e1..8dbdd51f51 100644 --- a/eeschema/dialogs/dialog_plot_schematic.cpp +++ b/eeschema/dialogs/dialog_plot_schematic.cpp @@ -57,6 +57,10 @@ void SCH_EDIT_FRAME::PlotSchematic( wxCommandEvent& event ) DIALOG_PLOT_SCHEMATIC dlg( this ); dlg.ShowModal(); + + // save project config if the prj config has changed: + if( dlg.PrjConfigChanged() ) + SaveProjectSettings( true ); } @@ -64,6 +68,7 @@ DIALOG_PLOT_SCHEMATIC::DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* parent ) : DIALOG_PLOT_SCHEMATIC_BASE( parent ) { m_parent = parent; + m_configChanged = false; m_config = Kiface().KifaceSettings(); initDlg(); @@ -139,11 +144,58 @@ void DIALOG_PLOT_SCHEMATIC::initDlg() PutValueInLocalUnits( *m_penHPGLWidthCtrl, m_HPGLPenSize ); m_HPGLPaperSizeOption->SetSelection( m_HPGLPaperSizeSelect ); + // Plot directory + wxString path = m_parent->GetPlotDirectoryName(); +#ifdef __WINDOWS__ + path.Replace( '/', '\\' ); +#endif + m_outputDirectoryName->SetValue( path ); + // Hide/show widgets that are not always displayed: wxCommandEvent cmd_event; OnPlotFormatSelection( cmd_event ); } +/* + * TODO: Copy of DIALOG_PLOT::OnOutputDirectoryBrowseClicked in dialog_plot.cpp, maybe merge to a common method. + */ +void DIALOG_PLOT_SCHEMATIC::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) +{ + // Build the absolute path of current output plot directory + // to preselect it when opening the dialog. + wxFileName fn( m_outputDirectoryName->GetValue() ); + wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() ); + + wxDirDialog dirDialog( this, _( "Select Output Directory" ), path ); + + if( dirDialog.ShowModal() == wxID_CANCEL ) + { + return; + } + + wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() ); + + wxMessageDialog dialog( this, _( "Use a relative path? " ), + _( "Plot Output Directory" ), + wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT ); + + // relative directory selected + if( dialog.ShowModal() == wxID_YES ) + { + + wxString plotFilePath = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) + + PS_PLOTTER::GetDefaultFileExtension(); + + plotFilePath = Prj().AbsolutePath(plotFilePath); + plotFilePath = wxPathOnly( plotFilePath ); + + if( !dirName.MakeRelativeTo( plotFilePath ) ) + wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ), + _( "Plot Output Directory" ), wxOK | wxICON_ERROR ); + } + + m_outputDirectoryName->SetValue( dirName.GetFullPath() ); +} PlotFormat DIALOG_PLOT_SCHEMATIC::GetPlotFileFormat() { @@ -161,7 +213,6 @@ PlotFormat DIALOG_PLOT_SCHEMATIC::GetPlotFileFormat() void DIALOG_PLOT_SCHEMATIC::OnButtonCancelClick( wxCommandEvent& event ) { - getPlotOptions(); EndModal( wxID_CANCEL ); } @@ -179,6 +230,16 @@ void DIALOG_PLOT_SCHEMATIC::getPlotOptions() m_pageSizeSelect = m_PaperSizeOption->GetSelection(); SetDefaultLineThickness( ValueFromTextCtrl( *m_DefaultLineSizeCtrl ) ); + + // Plot directory + wxString path = m_outputDirectoryName->GetValue(); + path.Replace( '\\', '/' ); + + if( m_parent->GetPlotDirectoryName() != path ) + m_configChanged = true; + + m_parent->SetPlotDirectoryName( path ); + } @@ -250,12 +311,6 @@ void DIALOG_PLOT_SCHEMATIC::PlotSchematic( bool aPlotAll ) createHPGLFile( aPlotAll, getPlotFrameRef() ); break; - default: - // Fall through. Default to Postscript. - case PLOT_FORMAT_POST: - createPSFile( aPlotAll, getPlotFrameRef() ); - break; - case PLOT_FORMAT_DXF: CreateDXFFile( aPlotAll, getPlotFrameRef() ); break; @@ -267,7 +322,31 @@ void DIALOG_PLOT_SCHEMATIC::PlotSchematic( bool aPlotAll ) case PLOT_FORMAT_SVG: createSVGFile( aPlotAll, getPlotFrameRef() ); break; + + case PLOT_FORMAT_POST: + // Fall through. Default to Postscript. + default: + createPSFile( aPlotAll, getPlotFrameRef() ); + break; + } m_MessagesBox->AppendText( wxT( "****\n" ) ); } + +wxFileName DIALOG_PLOT_SCHEMATIC::createPlotFileName( wxTextCtrl* aOutputDirectoryName, + wxString& aPlotFileName, + wxString& aExtension, + REPORTER* aReporter ) +{ + wxString outputDirName = aOutputDirectoryName->GetValue(); + wxFileName outputDir = wxFileName::DirName( outputDirName ); + + wxString plotFileName = Prj().AbsolutePath( aPlotFileName + wxT(".") + aExtension); + + EnsureFileDirectoryExists( &outputDir, plotFileName, aReporter ); + wxFileName fn( plotFileName ); + fn.SetPath( outputDir.GetFullPath() ); + return fn; + +} diff --git a/eeschema/dialogs/dialog_plot_schematic.h b/eeschema/dialogs/dialog_plot_schematic.h index df547ffbe6..c2aca65cd4 100644 --- a/eeschema/dialogs/dialog_plot_schematic.h +++ b/eeschema/dialogs/dialog_plot_schematic.h @@ -4,7 +4,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2012 Jean-Pierre Charras * @@ -33,6 +33,7 @@ #include #include #include +#include enum PageFormatReq { @@ -46,7 +47,8 @@ class DIALOG_PLOT_SCHEMATIC : public DIALOG_PLOT_SCHEMATIC_BASE { private: SCH_EDIT_FRAME* m_parent; - wxConfigBase* m_config; + wxConfigBase* m_config; + bool m_configChanged; // true if a project config param has changed static int m_pageSizeSelect; // Static to keep last option for some format: // Static to keep last option: // use default size or force A or A4 size @@ -57,6 +59,9 @@ public: // / Constructors DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* parent ); + bool PrjConfigChanged() { return m_configChanged; } // return true if the prj config was modified + // and therefore should be saved + private: void OnPlotFormatSelection( wxCommandEvent& event ); void OnButtonPlotCurrentClick( wxCommandEvent& event ); @@ -74,6 +79,11 @@ private: void setModeColor( bool aColor ) { m_ModeColorOption->SetSelection( aColor ? 0 : 1 ); } + /** + * Set the m_outputDirectoryName variable to the selected directory from directory dialog. + */ + void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ); + PlotFormat GetPlotFileFormat(); bool getPlotFrameRef() { return m_PlotFrameRefOpt->GetValue(); } @@ -86,6 +96,15 @@ private: void plotOneSheetPDF( PLOTTER* aPlotter, SCH_SCREEN* aScreen, bool aPlotFrameRef); void setupPlotPagePDF( PLOTTER* aPlotter, SCH_SCREEN* aScreen ); + /** + * Everything done, close the plot and restore the environment + * @param aPlotter the plotter to close and destroy + * @param aOldsheetpath the stored old sheet path for the current sheet before the plot started + * @param aMsg the message which is print to the message box + */ + void restoreEnvironment( PDF_PLOTTER* aPlotter, SCH_SHEET_PATH aOldsheetpath, + const wxString& aMsg ); + // DXF void CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ); bool PlotOneSheetDXF( const wxString& aFileName, SCH_SCREEN* aScreen, @@ -96,10 +115,12 @@ private: { return m_plotOriginOpt->GetSelection() == 1; } + void SetPlotOriginCenter( bool aCenter ) { m_plotOriginOpt->SetSelection( aCenter ? 1 : 0 ); } + void createHPGLFile( bool aPlotAll, bool aPlotFrameRef ); void SetHPGLPenWidth(); bool Plot_1_Page_HPGL( const wxString& aFileName, SCH_SCREEN* aScreen, @@ -115,6 +136,20 @@ private: // SVG void createSVGFile( bool aPlotAll, bool aPlotFrameRef ); + /** + * Create a file name with an absolute path name + * @param aOutputDirectoryName the diretory name to plot, + * this can be a relative name of the current project diretory or an absolute directory name. + * @param aPlotFileName the name for the file to plot without a path + * @param aExtension the extension for the file to plot + * @param aReporter a point to a REPORTER object use to show messages (can be NULL) + * @return the created file name + * @throw IO_ERROR on file I/O errors + */ + wxFileName createPlotFileName( wxTextCtrl* aOutputDirectoryName, + wxString& aPlotFileName, + wxString& aExtension, REPORTER* aReporter = NULL ); + public: // This function is static because it is called by libedit // outside a dialog. This is the reason we need aFrame as parameter diff --git a/eeschema/dialogs/dialog_plot_schematic_base.cpp b/eeschema/dialogs/dialog_plot_schematic_base.cpp index a7047281b5..cef11dbc12 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.cpp +++ b/eeschema/dialogs/dialog_plot_schematic_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Sep 11 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -16,6 +16,31 @@ DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWind wxBoxSizer* bMainSizer; bMainSizer = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer* bSizer6; + bSizer6 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextOutputDirectory = new wxStaticText( this, wxID_ANY, _("Output directory:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextOutputDirectory->Wrap( -1 ); + bSizer6->Add( m_staticTextOutputDirectory, 0, wxALL, 5 ); + + wxBoxSizer* bSizer5; + bSizer5 = new wxBoxSizer( wxHORIZONTAL ); + + m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_outputDirectoryName->SetMaxLength( 0 ); + m_outputDirectoryName->SetToolTip( _("Target directory for plot files. Can be absolute or relative to the schematic file location.") ); + + bSizer5->Add( m_outputDirectoryName, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 5 ); + + m_browseButton = new wxButton( this, wxID_ANY, _("Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer5->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); + + + bSizer6->Add( bSizer5, 1, wxEXPAND, 5 ); + + + bMainSizer->Add( bSizer6, 0, wxEXPAND|wxLEFT|wxTOP, 5 ); + m_optionsSizer = new wxBoxSizer( wxHORIZONTAL ); m_paperOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Paper Options") ), wxVERTICAL ); @@ -136,6 +161,7 @@ DIALOG_PLOT_SCHEMATIC_BASE::DIALOG_PLOT_SCHEMATIC_BASE( wxWindow* parent, wxWind // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnCloseWindow ) ); + m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnOutputDirectoryBrowseClicked ), NULL, this ); m_HPGLPaperSizeOption->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnHPGLPageSelected ), NULL, this ); m_plotFormatOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnPlotFormatSelection ), NULL, this ); m_buttonPlotCurrent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonPlotCurrentClick ), NULL, this ); @@ -147,6 +173,7 @@ DIALOG_PLOT_SCHEMATIC_BASE::~DIALOG_PLOT_SCHEMATIC_BASE() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnCloseWindow ) ); + m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnOutputDirectoryBrowseClicked ), NULL, this ); m_HPGLPaperSizeOption->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnHPGLPageSelected ), NULL, this ); m_plotFormatOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnPlotFormatSelection ), NULL, this ); m_buttonPlotCurrent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PLOT_SCHEMATIC_BASE::OnButtonPlotCurrentClick ), NULL, this ); diff --git a/eeschema/dialogs/dialog_plot_schematic_base.fbp b/eeschema/dialogs/dialog_plot_schematic_base.fbp index 87cc308064..86771a8252 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.fbp +++ b/eeschema/dialogs/dialog_plot_schematic_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -20,8 +20,10 @@ . 1 + 1 1 1 + UI 1 0 @@ -91,6 +93,290 @@ bMainSizer wxVERTICAL none + + 5 + wxEXPAND|wxLEFT|wxTOP + 0 + + + bSizer6 + wxVERTICAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Output directory: + + 0 + + + 0 + + 1 + m_staticTextOutputDirectory + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer5 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_outputDirectoryName + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Target directory for plot files. Can be absolute or relative to the schematic file location. + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Browse... + + 0 + + + 0 + + 1 + m_browseButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnOutputDirectoryBrowseClicked + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 wxEXPAND|wxLEFT|wxRIGHT|wxTOP diff --git a/eeschema/dialogs/dialog_plot_schematic_base.h b/eeschema/dialogs/dialog_plot_schematic_base.h index aa828ba6b6..9c9da7cecb 100644 --- a/eeschema/dialogs/dialog_plot_schematic_base.h +++ b/eeschema/dialogs/dialog_plot_schematic_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Sep 11 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -15,18 +15,18 @@ class DIALOG_SHIM; #include "dialog_shim.h" #include -#include +#include #include #include #include #include -#include -#include #include +#include #include +#include +#include #include #include -#include #include /////////////////////////////////////////////////////////////////////////// @@ -45,6 +45,9 @@ class DIALOG_PLOT_SCHEMATIC_BASE : public DIALOG_SHIM wxID_PRINT_ALL }; + wxStaticText* m_staticTextOutputDirectory; + wxTextCtrl* m_outputDirectoryName; + wxButton* m_browseButton; wxBoxSizer* m_optionsSizer; wxStaticBoxSizer* m_paperOptionsSizer; wxRadioBox* m_PaperSizeOption; @@ -68,6 +71,7 @@ class DIALOG_PLOT_SCHEMATIC_BASE : public DIALOG_SHIM // Virtual event handlers, overide them in your derived class virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); } + virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); } virtual void OnHPGLPageSelected( wxCommandEvent& event ) { event.Skip(); } virtual void OnPlotFormatSelection( wxCommandEvent& event ) { event.Skip(); } virtual void OnButtonPlotCurrentClick( wxCommandEvent& event ) { event.Skip(); } diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index a9dbf74966..a81b996953 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -415,6 +415,9 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList() m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "PageLayoutDescrFile" ), &BASE_SCREEN::m_PageLayoutDescrFileName ) ); + m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "PlotDirectoryName" ), + &m_plotDirectoryName ) ); + m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "SubpartIdSeparator" ), LIB_PART::SubpartIdSeparatorPtr(), 0, 0, 126 ) ); diff --git a/eeschema/plot_schematic_DXF.cpp b/eeschema/plot_schematic_DXF.cpp index c42b54fcb3..17c25a309f 100644 --- a/eeschema/plot_schematic_DXF.cpp +++ b/eeschema/plot_schematic_DXF.cpp @@ -40,7 +40,6 @@ void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ) SCH_SCREEN* screen = schframe->GetScreen(); SCH_SHEET_PATH* sheetpath; SCH_SHEET_PATH oldsheetpath = schframe->GetCurrentSheet(); - wxString plotFileName; /* When printing all pages, the printed page is not the current page. * In complex hierarchies, we must setup references and others parameters @@ -52,6 +51,7 @@ void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ) sheetpath = SheetList.GetFirst(); SCH_SHEET_PATH list; + WX_TEXT_CTRL_REPORTER reporter(m_MessagesBox); while( true ) { @@ -78,23 +78,39 @@ void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ) } wxPoint plot_offset; - plotFileName = schframe->GetUniqueFilenameForCurrentSheet() + wxT(".") - + DXF_PLOTTER::GetDefaultFileExtension(); - - plotFileName = Prj().AbsolutePath( plotFileName ); - wxString msg; - if( PlotOneSheetDXF( plotFileName, screen, plot_offset, 1.0, aPlotFrameRef ) ) - msg.Printf( _( "Plot: <%s> OK\n" ), GetChars( plotFileName ) ); - else // Error - msg.Printf( _( "Unable to create <%s>\n" ), GetChars( plotFileName ) ); - - m_MessagesBox->AppendText( msg ); + try + { + wxString fname = schframe->GetUniqueFilenameForCurrentSheet(); + wxString ext = DXF_PLOTTER::GetDefaultFileExtension(); + wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, fname, + ext, &reporter ); + if( PlotOneSheetDXF( plotFileName.GetFullPath(), screen, plot_offset, 1.0, aPlotFrameRef ) ) + { + msg.Printf( _( "Plot: '%s' OK\n" ), GetChars( plotFileName.GetFullPath() ) ); + } + else // Error + { + msg.Printf( _( "Unable to create '%s'\n" ), GetChars( plotFileName.GetFullPath() ) ); + } + m_MessagesBox->AppendText( msg ); + } + catch (IO_ERROR& e) + { + msg.Printf( _( "DXF Plotter Exception : '%s'"), wxString(e.errorText ) ); + m_MessagesBox->AppendText( msg ); + schframe->SetCurrentSheet( oldsheetpath ); + schframe->GetCurrentSheet().UpdateAllScreenReferences(); + schframe->SetSheetNumberAndCount(); + return; + } if( !aPlotAll ) + { break; + } } schframe->SetCurrentSheet( oldsheetpath ); diff --git a/eeschema/plot_schematic_HPGL.cpp b/eeschema/plot_schematic_HPGL.cpp index 6c40eb6759..89c6bea205 100644 --- a/eeschema/plot_schematic_HPGL.cpp +++ b/eeschema/plot_schematic_HPGL.cpp @@ -110,7 +110,6 @@ void DIALOG_PLOT_SCHEMATIC::SetHPGLPenWidth() void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef ) { - wxString plotFileName; SCH_SCREEN* screen = m_parent->GetScreen(); SCH_SHEET_PATH* sheetpath; SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet(); @@ -125,6 +124,7 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef ) sheetpath = SheetList.GetFirst(); SCH_SHEET_PATH list; + WX_TEXT_CTRL_REPORTER reporter(m_MessagesBox); SetHPGLPenWidth(); @@ -167,6 +167,7 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef ) // Calculate offsets wxPoint plotOffset; + wxString msg; if( GetPlotOriginCenter() ) { @@ -174,24 +175,32 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef ) plotOffset.y = -plotPage.GetHeightIU() / 2; } - plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) - + HPGL_PLOTTER::GetDefaultFileExtension(); + try + { + wxString fname = m_parent->GetUniqueFilenameForCurrentSheet(); + wxString ext = HPGL_PLOTTER::GetDefaultFileExtension(); + wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, fname, + ext, &reporter ); - plotFileName = Prj().AbsolutePath( plotFileName ); + LOCALE_IO toggle; - LOCALE_IO toggle; + if( Plot_1_Page_HPGL( plotFileName.GetFullPath(), screen, plotPage, plotOffset, + plot_scale, aPlotFrameRef ) ) + msg.Printf( _( "Plot: '%s' OK\n" ), GetChars( plotFileName.GetFullPath() ) ); + else // Error + msg.Printf( _( "Unable to create '%s'\n" ), GetChars( plotFileName.GetFullPath() ) ); - wxString msg; - if( Plot_1_Page_HPGL( plotFileName, screen, plotPage, plotOffset, - plot_scale, aPlotFrameRef ) ) - msg.Printf( _( "Plot: <%s> OK\n" ), GetChars( plotFileName ) ); - else // Error - msg.Printf( _( "Unable to create <%s>\n" ), GetChars( plotFileName ) ); + m_MessagesBox->AppendText( msg ); - m_MessagesBox->AppendText( msg ); + if( !aPlotAll ) + break; + } + catch (IO_ERROR& e) + { + msg.Printf( _( "HPGL Plotter Exception : '%s'"), wxString(e.errorText ) ); + m_MessagesBox->AppendText( msg ); + } - if( !aPlotAll ) - break; } m_parent->SetCurrentSheet( oldsheetpath ); diff --git a/eeschema/plot_schematic_PDF.cpp b/eeschema/plot_schematic_PDF.cpp index ecab45a1c7..f8fa9cc4c8 100644 --- a/eeschema/plot_schematic_PDF.cpp +++ b/eeschema/plot_schematic_PDF.cpp @@ -60,7 +60,8 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) plotter->SetCreator( wxT( "Eeschema-PDF" ) ); wxString msg; - wxString plotFileName; + wxFileName plotFileName; + WX_TEXT_CTRL_REPORTER reporter(m_MessagesBox); // First page handling is different bool first_page = true; @@ -86,24 +87,37 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) if( first_page ) { - plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) - + PDF_PLOTTER::GetDefaultFileExtension(); - plotFileName = Prj().AbsolutePath( plotFileName ); - - if( !plotter->OpenFile( plotFileName ) ) + try { - msg.Printf( _( "Unable to create <%s>\n" ), GetChars( plotFileName ) ); - m_MessagesBox->AppendText( msg ); - delete plotter; + wxString fname = m_parent->GetUniqueFilenameForCurrentSheet(); + wxString ext = PDF_PLOTTER::GetDefaultFileExtension(); + plotFileName = createPlotFileName( m_outputDirectoryName, + fname, ext, &reporter ); + + if( !plotter->OpenFile( plotFileName.GetFullPath() ) ) + { + msg.Printf( _( "Unable to create '%s'\n" ), GetChars( plotFileName.GetFullPath() ) ); + m_MessagesBox->AppendText( msg ); + delete plotter; + return; + } + + // Open the plotter and do the first page + SetLocaleTo_C_standard(); + setupPlotPagePDF( plotter, screen ); + plotter->StartPlot(); + first_page = false; + + } + catch (const IO_ERROR& e) + { + // Cannot plot PDF file + msg.Printf( _( "PDF Plotter Exception : <%s>"), wxString(e.errorText ) ); + restoreEnvironment(plotter, oldsheetpath, msg); return; } - // Open the plotter and do the first page - SetLocaleTo_C_standard(); - setupPlotPagePDF( plotter, screen ); - plotter->StartPlot(); - first_page = false; } else { @@ -118,17 +132,25 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) } while( aPlotAll && sheetpath ); // Everything done, close the plot and restore the environment - plotter->EndPlot(); - delete plotter; + msg.Printf( _( "Plot: <%s> OK\n" ), GetChars( plotFileName.GetFullPath() ) ); + restoreEnvironment(plotter, oldsheetpath, msg); + +} + + +void DIALOG_PLOT_SCHEMATIC::restoreEnvironment( PDF_PLOTTER* aPlotter, + SCH_SHEET_PATH aOldsheetpath, const wxString& aMsg ) +{ + aPlotter->EndPlot(); + delete aPlotter; SetLocaleTo_Default(); // Restore the previous sheet - m_parent->SetCurrentSheet( oldsheetpath ); + m_parent->SetCurrentSheet( aOldsheetpath ); m_parent->GetCurrentSheet().UpdateAllScreenReferences(); m_parent->SetSheetNumberAndCount(); - msg.Printf( _( "Plot: <%s> OK\n" ), GetChars( plotFileName ) ); - m_MessagesBox->AppendText( msg ); + m_MessagesBox->AppendText( aMsg ); } diff --git a/eeschema/plot_schematic_PS.cpp b/eeschema/plot_schematic_PS.cpp index 3ded1578a0..6e97f31f08 100644 --- a/eeschema/plot_schematic_PS.cpp +++ b/eeschema/plot_schematic_PS.cpp @@ -32,6 +32,7 @@ #include #include #include +#include void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef ) @@ -39,7 +40,6 @@ void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef ) SCH_SCREEN* screen = m_parent->GetScreen(); SCH_SHEET_PATH* sheetpath; SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet(); // sheetpath is saved here - wxString plotFileName; PAGE_INFO actualPage; // page size selected in schematic PAGE_INFO plotPage; // page size selected to plot @@ -102,21 +102,38 @@ void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef ) double scale = std::min( scalex, scaley ); wxPoint plot_offset; - plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) - + PS_PLOTTER::GetDefaultFileExtension(); - plotFileName = Prj().AbsolutePath( plotFileName ); + wxString outputDirName = m_outputDirectoryName->GetValue(); + wxFileName outputDir = wxFileName::DirName( outputDirName ); wxString msg; + WX_TEXT_CTRL_REPORTER reporter(m_MessagesBox); - if( plotOneSheetPS( plotFileName, screen, plotPage, plot_offset, - scale, aPlotFrameRef ) ) - msg.Printf( _( "Plot: <%s> OK\n" ), GetChars( plotFileName ) ); - else // Error - msg.Printf( _( "Unable to create <%s>\n" ), GetChars( plotFileName ) ); + try + { + wxString fname = m_parent->GetUniqueFilenameForCurrentSheet(); + wxString ext = PS_PLOTTER::GetDefaultFileExtension(); + wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, + fname, ext, &reporter ); - m_MessagesBox->AppendText( msg ); + if( plotOneSheetPS( plotFileName.GetFullPath(), screen, plotPage, plot_offset, + scale, aPlotFrameRef ) ) + { + msg.Printf( _( "Plot: '%s' OK\n" ), GetChars( plotFileName.GetFullPath() ) ); + } + else + { + // Error + msg.Printf( _( "Unable to create '%s'\n" ), GetChars( plotFileName.GetFullPath() ) ); + } + m_MessagesBox->AppendText( msg ); + } + catch (IO_ERROR& e) + { + msg.Printf( _( "PS Plotter Exception : '%s'"), wxString(e.errorText ) ); + m_MessagesBox->AppendText( msg ); + } if( !aPlotAll ) break; diff --git a/eeschema/plot_schematic_SVG.cpp b/eeschema/plot_schematic_SVG.cpp index 2badb2c968..a929b0271b 100644 --- a/eeschema/plot_schematic_SVG.cpp +++ b/eeschema/plot_schematic_SVG.cpp @@ -43,7 +43,6 @@ void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef ) { wxString msg; - wxFileName fn; if( aPrintAll ) { @@ -52,11 +51,14 @@ void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef ) SCH_SHEET_LIST SheetList( NULL ); sheetpath = SheetList.GetFirst(); SCH_SHEET_PATH list; + WX_TEXT_CTRL_REPORTER reporter(m_MessagesBox); for( ; ; ) { if( sheetpath == NULL ) + { break; + } SCH_SCREEN* screen; list.Clear(); @@ -69,30 +71,47 @@ void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef ) screen = m_parent->GetCurrentSheet().LastScreen(); } else // Should not happen + { return; + } sheetpath = SheetList.GetNext(); - wxString fileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( ".svg" ); - - fn = Prj().AbsolutePath( fileName ); - - bool success = plotOneSheetSVG( m_parent, fn.GetFullPath(), screen, - getModeColor() ? false : true, - aPrintFrameRef ); - - if( !success ) + try { - msg.Printf( _( "Error creating file <%s>\n" ), - GetChars( fn.GetFullPath() ) ); - } - else - { - msg.Printf( _( "File <%s> OK\n" ), - GetChars( fn.GetFullPath() ) ); - } + wxString fname = m_parent->GetUniqueFilenameForCurrentSheet(); + wxString ext = SVG_PLOTTER::GetDefaultFileExtension(); + wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, + fname, ext, &reporter ); - m_MessagesBox->AppendText( msg ); + bool success = plotOneSheetSVG( m_parent, plotFileName.GetFullPath(), screen, + getModeColor() ? false : true, + aPrintFrameRef ); + + if( !success ) + { + msg.Printf( _( "Error creating file '%s'\n" ), + GetChars( plotFileName.GetFullPath() ) ); + } + else + { + msg.Printf( _( "File '%s' OK\n" ), + GetChars( plotFileName.GetFullPath() ) ); + } + + m_MessagesBox->AppendText( msg ); + } + catch (const IO_ERROR& e) + { + // Cannot plot SVG file + msg.Printf( _( "SVG Plotter Exception : '%s'" ), wxString( e.errorText ) ); + m_MessagesBox->AppendText( msg ); + + m_parent->SetCurrentSheet( oldsheetpath ); + m_parent->GetCurrentSheet().UpdateAllScreenReferences(); + m_parent->SetSheetNumberAndCount(); + return; + } } m_parent->SetCurrentSheet( oldsheetpath ); @@ -103,21 +122,34 @@ void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef ) { SCH_SCREEN* screen = (SCH_SCREEN*) m_parent->GetScreen(); - fn = screen->GetFileName(); - fn.SetExt( wxT( "svg" ) ); - fn.MakeAbsolute(); + try + { + wxString fname = screen->GetFileName(); + wxString ext = SVG_PLOTTER::GetDefaultFileExtension(); + wxFileName fn = createPlotFileName( m_outputDirectoryName, fname, ext ); - bool success = plotOneSheetSVG( m_parent, fn.GetFullPath(), screen, - getModeColor() ? false : true, - aPrintFrameRef ); - if( success ) - msg.Printf( _( "Plot: <%s> OK\n" ), - GetChars( fn.GetFullPath() ) ); - else // Error - msg.Printf( _( "Unable to create <%s>\n" ), - GetChars( fn.GetFullPath() ) ); - - m_MessagesBox->AppendText( msg ); + bool success = plotOneSheetSVG( m_parent, fn.GetFullPath(), screen, + getModeColor() ? false : true, + aPrintFrameRef ); + if( success ) + { + msg.Printf( _( "Plot: <%s> OK\n" ), + GetChars( fn.GetFullPath() ) ); + } + else // Error + { + msg.Printf( _( "Unable to create <%s>\n" ), + GetChars( fn.GetFullPath() ) ); + } + m_MessagesBox->AppendText( msg ); + } + catch (const IO_ERROR& e) + { + // Cannot plot SVG file + msg.Printf( _( "SVG Plotter Exception : <%s>"), wxString(e.errorText ) ); + m_MessagesBox->AppendText( msg ); + return; + } } } diff --git a/include/common.h b/include/common.h index 1c1cb3a4f1..db96185273 100644 --- a/include/common.h +++ b/include/common.h @@ -46,6 +46,7 @@ class wxAboutDialogInfo; class SEARCH_STACK; class wxSingleInstanceChecker; +class REPORTER; // Flag for special keys @@ -599,6 +600,19 @@ void SystemDirsAppend( SEARCH_STACK* aSearchStack ); */ wxString SearchHelpFileFullPath( const SEARCH_STACK& aSearchStack, const wxString& aBaseName ); +/** + * Helper function EnsureFileDirectoryExists + * make \a aTargetFullFileName absolute and creates the path of this file if it doesn't yet exist. + * @param aTargetFullFileName the wxFileName containing the full path and file name to modify. The path + * may be absolute or relative to \a aBaseFilename . + * @param aBaseFilename a full filename. Only its path is used to set the aTargetFullFileName path. + * @param aReporter a point to a REPORTER object use to show messages (can be NULL) + * @return true if \a aOutputDir already exists or was successfully created. + */ +bool EnsureFileDirectoryExists( wxFileName* aTargetFullFileName, + const wxString& aBaseFilename, + REPORTER* aReporter = NULL ); + /** * Function LockFile * tests to see if aFileName can be locked (is not already locked) and only then diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index 2319c79f43..860d6e25bb 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -152,6 +152,9 @@ private: /// Flag to indicate show hidden pins. bool m_showAllPins; + /// The name of the destination directory to use when generating plot files. + wxString m_plotDirectoryName; + /// The name of the format to use when generating a net list. wxString m_netListFormat; @@ -239,6 +242,10 @@ public: void SetComponentLibraries( const wxArrayString& aList ) { m_componentLibFiles = aList; } */ + /// accessor to the destination directory to use when generating plot files. + const wxString& GetPlotDirectoryName() const { return m_plotDirectoryName; } + void SetPlotDirectoryName( const wxString& aDirName ) { m_plotDirectoryName = aDirName; } + void Process_Special_Functions( wxCommandEvent& event ); void OnColorConfig( wxCommandEvent& aEvent ); void Process_Config( wxCommandEvent& event ); diff --git a/pcbnew/dialogs/dialog_SVG_print.cpp b/pcbnew/dialogs/dialog_SVG_print.cpp index f7573e04f2..4317bbbfb0 100644 --- a/pcbnew/dialogs/dialog_SVG_print.cpp +++ b/pcbnew/dialogs/dialog_SVG_print.cpp @@ -268,7 +268,7 @@ void DIALOG_SVG_PRINT::ExportSVGFile( bool aOnlyOneFile ) WX_TEXT_CTRL_REPORTER reporter( m_messagesBox ); - if( !EnsureOutputDirectory( &outputDir, boardFilename, &reporter ) ) + if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) ) { wxString msg = wxString::Format( _( "Could not write plot files to folder '%s'." ), diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index 68a26bd4ad..2c85290887 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -711,7 +711,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event ) wxString boardFilename = m_parent->GetBoard()->GetFileName(); WX_TEXT_CTRL_REPORTER reporter( m_messagesBox ); - if( !EnsureOutputDirectory( &outputDir, boardFilename, &reporter ) ) + if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) ) { wxString msg; msg.Printf( _( "Could not write plot files to folder \"%s\"." ), diff --git a/pcbnew/exporters/gen_modules_placefile.cpp b/pcbnew/exporters/gen_modules_placefile.cpp index 9764c24c68..fe90791e30 100644 --- a/pcbnew/exporters/gen_modules_placefile.cpp +++ b/pcbnew/exporters/gen_modules_placefile.cpp @@ -212,7 +212,7 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles() wxString boardFilename = m_parent->GetBoard()->GetFileName(); WX_TEXT_CTRL_REPORTER reporter( m_messagesBox ); - if( !EnsureOutputDirectory( &outputDir, boardFilename, &reporter ) ) + if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) ) { msg.Printf( _( "Could not write plot files to folder \"%s\"." ), GetChars( outputDir.GetPath() ) ); diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp index 7913fab939..b252c882db 100644 --- a/pcbnew/pcbplot.cpp +++ b/pcbnew/pcbplot.cpp @@ -214,56 +214,6 @@ void BuildPlotFileName( wxFileName* aFilename, } -bool EnsureOutputDirectory( wxFileName* aOutputDir, - const wxString& aBoardFilename, - REPORTER* aReporter ) -{ - wxString msg; - wxString boardFilePath = wxFileName( aBoardFilename ).GetPath(); - - if( !aOutputDir->MakeAbsolute( boardFilePath ) ) - { - if( aReporter ) - { - msg.Printf( _( "*** Error: cannot make path '%s' absolute with respect to '%s'! ***" ), - GetChars( aOutputDir->GetPath() ), - GetChars( boardFilePath ) ); - aReporter->Report( msg ); - } - - return false; - } - - wxString outputPath( aOutputDir->GetPath() ); - - if( !wxFileName::DirExists( outputPath ) ) - { - if( wxMkdir( outputPath ) ) - { - if( aReporter ) - { - msg.Printf( _( "Output directory '%s' created.\n" ), GetChars( outputPath ) ); - aReporter->Report( msg ); - return true; - } - } - else - { - if( aReporter ) - { - msg.Printf( _( "*** Error: cannot create output directory '%s'! ***\n" ), - GetChars( outputPath ) ); - aReporter->Report( msg ); - } - - return false; - } - } - - return true; -} - - PLOT_CONTROLLER::PLOT_CONTROLLER( BOARD *aBoard ) : m_plotter( NULL ), m_board( aBoard ) { @@ -313,7 +263,7 @@ bool PLOT_CONTROLLER::OpenPlotfile( const wxString &aSuffix, wxFileName outputDir = wxFileName::DirName( outputDirName ); wxString boardFilename = m_board->GetFileName(); - if( EnsureOutputDirectory( &outputDir, boardFilename ) ) + if( EnsureFileDirectoryExists( &outputDir, boardFilename ) ) { wxFileName fn( boardFilename ); BuildPlotFileName( &fn, outputDirName, aSuffix, GetDefaultPlotExtension( aFormat ) ); diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index d74ca0cd60..3ac861bbfa 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -227,19 +227,6 @@ void PlotSilkScreen( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt ); -/** - * Function EnsureOutputDirectory (helper function) - * make \a OutputDir absolute and creates the path if it doesn't exist. - * @param aOutputDir the wxFileName containing the full path and file name to modify. The path - * may be absolute or relative to \a aBoardFilename . - * @param aBoardFilename the board full path and filename. - * @param aReporter a point to a REPORTER object use to show messages (can be NULL) - * @return true if \a aOutputDir already exists or was successfully created. - */ -bool EnsureOutputDirectory( wxFileName* aOutputDir, - const wxString& aBoardFilename, - REPORTER* aReporter = NULL ); - /** * Function BuildPlotFileName (helper function) * Complete a plot filename: forces the output directory,