From b3259a1c42a1cd2667d1e284690d786d90adff8f Mon Sep 17 00:00:00 2001 From: Eric Zhuang <840064358@qq.com> Date: Sun, 29 Dec 2024 17:01:27 +0000 Subject: [PATCH] ODB++:Support choice compress format and specify output filename. --- common/jobs/job_export_pcb_odb.cpp | 1 + common/jobs/job_export_pcb_odb.h | 1 + kicad/cli/command_pcb_export_odb.cpp | 8 +- pcbnew/dialogs/dialog_export_odbpp.cpp | 301 +++++++++++++++----- pcbnew/dialogs/dialog_export_odbpp.fbp | 130 ++++++--- pcbnew/dialogs/dialog_export_odbpp.h | 7 +- pcbnew/dialogs/dialog_export_odbpp_base.cpp | 50 ++-- pcbnew/dialogs/dialog_export_odbpp_base.h | 8 +- pcbnew/files.cpp | 4 +- pcbnew/pcb_io/odbpp/pcb_io_odbpp.cpp | 2 +- pcbnew/pcbnew_jobs_handler.cpp | 36 ++- pcbnew/pcbnew_settings.h | 2 +- 12 files changed, 393 insertions(+), 157 deletions(-) diff --git a/common/jobs/job_export_pcb_odb.cpp b/common/jobs/job_export_pcb_odb.cpp index 99fb89d892..ec2db7d80f 100644 --- a/common/jobs/job_export_pcb_odb.cpp +++ b/common/jobs/job_export_pcb_odb.cpp @@ -32,6 +32,7 @@ NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_ODB::ODB_COMPRESSION, { { JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE, "none" }, { JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP, "zip" }, + { JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::TGZ, "tgz" }, } ) diff --git a/common/jobs/job_export_pcb_odb.h b/common/jobs/job_export_pcb_odb.h index de216d0c51..b469495475 100644 --- a/common/jobs/job_export_pcb_odb.h +++ b/common/jobs/job_export_pcb_odb.h @@ -42,6 +42,7 @@ public: { NONE, ZIP, + TGZ, }; wxString m_filename; diff --git a/kicad/cli/command_pcb_export_odb.cpp b/kicad/cli/command_pcb_export_odb.cpp index 41d85c21c0..c1709da44f 100644 --- a/kicad/cli/command_pcb_export_odb.cpp +++ b/kicad/cli/command_pcb_export_odb.cpp @@ -49,7 +49,7 @@ CLI::PCB_EXPORT_ODB_COMMAND::PCB_EXPORT_ODB_COMMAND() : m_argParser.add_argument( ARG_COMPRESS ) .default_value( std::string( "zip" ) ) .help( std::string( "Compression mode" ) ) - .choices( "none", "zip" ); + .choices( "none", "zip", "tgz" ); m_argParser.add_argument( ARG_UNITS ) .default_value( std::string( "mm" ) ) @@ -87,11 +87,13 @@ int CLI::PCB_EXPORT_ODB_COMMAND::doPerform( KIWAY& aKiway ) else if( units == "in" ) job->m_units = JOB_EXPORT_PCB_ODB::ODB_UNITS::INCHES; - wxString compression = From_UTF8( m_argParser.get<std::string>( ARG_COMPRESS ).c_str() ); + wxString compression = From_UTF8( m_argParser.get<std::string>( ARG_COMPRESS ).c_str() ).Lower(); if( compression == "zip" ) job->m_compressionMode = JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP; - else + else if( compression == "tgz" ) + job->m_compressionMode = JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::TGZ; + else if( compression == "none" ) job->m_compressionMode = JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE; LOCALE_IO dummy; diff --git a/pcbnew/dialogs/dialog_export_odbpp.cpp b/pcbnew/dialogs/dialog_export_odbpp.cpp index ec952d9bcb..3f3ddcd44f 100644 --- a/pcbnew/dialogs/dialog_export_odbpp.cpp +++ b/pcbnew/dialogs/dialog_export_odbpp.cpp @@ -42,16 +42,16 @@ #include <jobs/job_export_pcb_odb.h> #include <pcb_io/pcb_io_mgr.h> #include <wx/dir.h> -#include <wx/dirdlg.h> +#include <wx/filedlg.h> #include <wx/wfstream.h> #include <wx/zipstrm.h> +#include <wx/tarstrm.h> +#include <wx/zstream.h> static wxString s_oemColumn = wxEmptyString; DIALOG_EXPORT_ODBPP::DIALOG_EXPORT_ODBPP( PCB_EDIT_FRAME* aParent ) : - DIALOG_EXPORT_ODBPP_BASE( aParent ), - m_parent( aParent ), - m_job( nullptr ) + DIALOG_EXPORT_ODBPP_BASE( aParent ), m_parent( aParent ), m_job( nullptr ) { m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); @@ -62,7 +62,10 @@ DIALOG_EXPORT_ODBPP::DIALOG_EXPORT_ODBPP( PCB_EDIT_FRAME* aParent ) : if( path.IsEmpty() ) { wxFileName brdFile( m_parent->GetBoard()->GetFileName() ); - path = brdFile.GetPath(); + wxFileName odbFile( brdFile.GetPath(), + wxString::Format( wxS( "%s-odb" ), brdFile.GetName() ), + FILEEXT::ArchiveFileExtension ); + path = odbFile.GetFullPath(); } m_outputFileName->SetValue( path ); @@ -78,9 +81,7 @@ DIALOG_EXPORT_ODBPP::DIALOG_EXPORT_ODBPP( PCB_EDIT_FRAME* aParent ) : DIALOG_EXPORT_ODBPP::DIALOG_EXPORT_ODBPP( JOB_EXPORT_PCB_ODB* aJob, PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent ) : - DIALOG_EXPORT_ODBPP_BASE( aParent ), - m_parent( aEditFrame ), - m_job( aJob ) + DIALOG_EXPORT_ODBPP_BASE( aParent ), m_parent( aEditFrame ), m_job( aJob ) { m_browseButton->Hide(); @@ -99,23 +100,128 @@ DIALOG_EXPORT_ODBPP::DIALOG_EXPORT_ODBPP( JOB_EXPORT_PCB_ODB* aJob, PCB_EDIT_FRA void DIALOG_EXPORT_ODBPP::onBrowseClicked( wxCommandEvent& event ) { + // clang-format off + wxString filter = _( "zip files" ) + + AddFileExtListToFilter( { FILEEXT::ArchiveFileExtension } ) + "|" + + _( "tgz files" ) + + AddFileExtListToFilter( { "tgz" } ); + // clang-format on + // Build the absolute path of current output directory to preselect it in the file browser. wxString path = ExpandEnvVarSubstitutions( m_outputFileName->GetValue(), &Prj() ); wxFileName fn( Prj().AbsolutePath( path ) ); - wxDirDialog dlg( this, _( "Export ODB++ File" ), fn.GetPath() ); + wxFileName brdFile( m_parent->GetBoard()->GetFileName() ); + + wxString fileDialogName( wxString::Format( wxS( "%s-odb" ), brdFile.GetName() ) ); + + wxFileDialog dlg( this, _( "Export ODB++ File" ), fn.GetPath(), fileDialogName, filter, + wxFD_SAVE ); if( dlg.ShowModal() == wxID_CANCEL ) return; - m_outputFileName->SetValue( dlg.GetPath() ); + path = dlg.GetPath(); + + fn = wxFileName( path ); + + if( fn.GetExt().Lower() == "zip" ) + { + m_choiceCompress->SetSelection( + static_cast<int>( JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP ) ); + } + else if( fn.GetExt().Lower() == "tgz" ) + { + m_choiceCompress->SetSelection( + static_cast<int>( JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::TGZ ) ); + } + else if( path.EndsWith( "/" ) || path.EndsWith( "\\" ) ) + { + m_choiceCompress->SetSelection( + static_cast<int>( JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE ) ); + } + else + { + wxString msg; + msg.Printf( _( "The selected output file name is not a supported archive format." ) ); + DisplayErrorMessage( this, msg ); + return; + } + + m_outputFileName->SetValue( path ); } +void DIALOG_EXPORT_ODBPP::onFormatChoice( wxCommandEvent& event ) +{ + OnFmtChoiceOptionChanged(); +} + + +void DIALOG_EXPORT_ODBPP::OnFmtChoiceOptionChanged() +{ + wxString fn = m_outputFileName->GetValue(); + + wxFileName fileName( fn ); + + auto compressionMode = + static_cast<JOB_EXPORT_PCB_ODB::ODB_COMPRESSION>( m_choiceCompress->GetSelection() ); + + int sepIdx = std::max( fn.Find( '/', true ), fn.Find( '\\', true ) ); + int dotIdx = fn.Find( '.', true ); + + if( fileName.IsDir() ) + fn = fn.Mid( 0, sepIdx ); + else if( sepIdx < dotIdx ) + fn = fn.Mid( 0, dotIdx ); + + switch( compressionMode ) + { + case JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP: + fn = fn + '.' + FILEEXT::ArchiveFileExtension; + break; + case JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::TGZ: fn += ".tgz"; break; + case JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE: fn = wxFileName( fn, "" ).GetFullPath(); break; + default: break; + }; + + m_outputFileName->SetValue( fn ); +} void DIALOG_EXPORT_ODBPP::onOKClick( wxCommandEvent& event ) { if( !m_job ) + { + wxString fn = m_outputFileName->GetValue(); + + if( fn.IsEmpty() ) + { + wxString msg; + msg.Printf( _( "Output file name cannot be empty." ) ); + DisplayErrorMessage( this, msg ); + return; + } + + auto compressionMode = static_cast<JOB_EXPORT_PCB_ODB::ODB_COMPRESSION>( + m_choiceCompress->GetSelection() ); + + wxFileName fileName( fn ); + bool isDirectory = fileName.IsDir(); + wxString extension = fileName.GetExt(); + + if( ( compressionMode == JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE && !isDirectory ) + || ( compressionMode == JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP && extension != "zip" ) + || ( compressionMode == JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::TGZ + && extension != "tgz" ) ) + { + wxString msg; + msg.Printf( + _( "The output file name conflicts with the selected compression format." ) ); + DisplayErrorMessage( this, msg ); + return; + } + m_parent->SetLastPath( LAST_PATH_ODBPP, m_outputFileName->GetValue() ); + } event.Skip(); } @@ -130,13 +236,13 @@ bool DIALOG_EXPORT_ODBPP::Init() { m_choiceUnits->SetSelection( cfg->m_ExportODBPP.units ); m_precision->SetValue( cfg->m_ExportODBPP.precision ); - m_cbCompress->SetValue( cfg->m_ExportODBPP.compress ); + m_choiceCompress->SetSelection( cfg->m_ExportODBPP.compressFormat ); } else { m_choiceUnits->SetSelection( static_cast<int>( m_job->m_units ) ); m_precision->SetValue( m_job->m_precision ); - m_cbCompress->SetValue( m_job->m_compressionMode == JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP ); + m_choiceCompress->SetSelection( static_cast<int>( m_job->m_compressionMode ) ); } return true; @@ -152,17 +258,17 @@ bool DIALOG_EXPORT_ODBPP::TransferDataFromWindow() cfg->m_ExportODBPP.units = m_choiceUnits->GetSelection(); cfg->m_ExportODBPP.precision = m_precision->GetValue(); - cfg->m_ExportODBPP.compress = m_cbCompress->GetValue(); + cfg->m_ExportODBPP.compressFormat = m_choiceCompress->GetSelection(); } else { m_job->SetOutputPath( m_outputFileName->GetValue() ); m_job->m_precision = m_precision->GetValue(); - m_job->m_units = static_cast<JOB_EXPORT_PCB_ODB::ODB_UNITS>( m_choiceUnits->GetSelection() ); - m_job->m_compressionMode = m_cbCompress->GetValue() - ? JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP - : JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE; + m_job->m_units = + static_cast<JOB_EXPORT_PCB_ODB::ODB_UNITS>( m_choiceUnits->GetSelection() ); + m_job->m_compressionMode = static_cast<JOB_EXPORT_PCB_ODB::ODB_COMPRESSION>( + m_choiceCompress->GetSelection() ); } return true; @@ -170,9 +276,9 @@ bool DIALOG_EXPORT_ODBPP::TransferDataFromWindow() void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BOARD* aBoard, - PCB_EDIT_FRAME* aParentFrame, + PCB_EDIT_FRAME* aParentFrame, PROGRESS_REPORTER* aProgressReporter, - REPORTER* aReporter ) + REPORTER* aReporter ) { wxCHECK( aBoard, /* void */ ); wxString outputPath = aJob.GetOutputPath(); @@ -190,6 +296,20 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO wxString msg; + if( !wxFileName::DirExists( pcbFileName.GetPath() ) ) + { + // Make every directory provided when the provided path doesn't exist + if( !wxFileName::Mkdir( pcbFileName.GetPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) ) + { + msg.Printf( _( "Cannot create output directory '%s'." ), pcbFileName.GetFullPath() ); + + if( aReporter ) + aReporter->Report( msg, RPT_SEVERITY_ERROR ); + + return; + } + } + if( pcbFileName.IsDir() && !pcbFileName.IsDirWritable() ) { msg.Printf( _( "Insufficient permissions to folder '%s'." ), pcbFileName.GetPath() ); @@ -211,35 +331,17 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO return; } - if( !wxFileName::DirExists( pcbFileName.GetFullPath() ) ) - { - // Make every directory provided when the provided path doesn't exist - if( !wxFileName::Mkdir( pcbFileName.GetFullPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) ) - { - msg.Printf( _( "Cannot create output directory '%s'." ), pcbFileName.GetFullPath() ); - - if( aReporter ) - aReporter->Report( msg, RPT_SEVERITY_ERROR ); - - return; - } - } - - wxFileName zipFileName( pcbFileName.GetFullPath(), - wxString::Format( wxS( "%s-odb.zip" ), - aBoard->GetProject()->GetProjectName() ) ); - - wxFileName tempFile( pcbFileName.GetFullPath(), "" ); + wxFileName tempFile( pcbFileName.GetFullPath() ); if( aJob.m_compressionMode != JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE ) { - if( zipFileName.Exists() ) + if( pcbFileName.Exists() ) { if( aParentFrame ) { msg = wxString::Format( _( "Output files '%s' already exists. " "Do you want to overwrite it?" ), - zipFileName.GetFullPath() ); + pcbFileName.GetFullPath() ); KIDIALOG errorDlg( aParentFrame, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); @@ -248,10 +350,10 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO if( errorDlg.ShowModal() != wxID_OK ) return; - if( !wxRemoveFile( zipFileName.GetFullPath() ) ) + if( !wxRemoveFile( pcbFileName.GetFullPath() ) ) { msg.Printf( _( "Cannot remove existing output file '%s'." ), - zipFileName.GetFullPath() ); + pcbFileName.GetFullPath() ); DisplayErrorMessage( aParentFrame, msg ); return; } @@ -259,7 +361,7 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO else { msg = wxString::Format( _( "Output file '%s' already exists." ), - zipFileName.GetFullPath() ); + pcbFileName.GetFullPath() ); if( aReporter ) aReporter->Report( msg, RPT_SEVERITY_ERROR ); @@ -284,10 +386,8 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO } else { - // Plugin will create the 'odb' subdirectory for us, so test for it here - wxFileName odbDir( tempFile ); - odbDir.AppendDir( "odb" ); - wxDir testDir( odbDir.GetFullPath() ); + // Test for the output directory of tempFile + wxDir testDir( tempFile.GetFullPath() ); if( testDir.IsOpened() && ( testDir.HasFiles() || testDir.HasSubDirs() ) ) { @@ -295,7 +395,7 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO { msg = wxString::Format( _( "Output directory '%s' already exists and is not empty. " "Do you want to overwrite it?" ), - odbDir.GetFullPath() ); + tempFile.GetFullPath() ); KIDIALOG errorDlg( aParentFrame, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); @@ -304,10 +404,10 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO if( errorDlg.ShowModal() != wxID_OK ) return; - if( !odbDir.Rmdir( wxPATH_RMDIR_RECURSIVE ) ) + if( !tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE ) ) { msg.Printf( _( "Cannot remove existing output directory '%s'." ), - odbDir.GetFullPath() ); + tempFile.GetFullPath() ); DisplayErrorMessage( aParentFrame, msg ); return; } @@ -315,7 +415,7 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO else { msg = wxString::Format( _( "Output directory '%s' already exists." ), - odbDir.GetFullPath() ); + tempFile.GetFullPath() ); if( aReporter ) aReporter->Report( msg, RPT_SEVERITY_ERROR ); @@ -332,31 +432,30 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO props["units"] = aJob.m_units == JOB_EXPORT_PCB_ODB::ODB_UNITS::MILLIMETERS ? "mm" : "inch"; props["sigfig"] = wxString::Format( "%d", aJob.m_precision ); - auto saveFile = - [&]() -> bool + auto saveFile = [&]() -> bool + { + try + { + IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::ODBPP ) ); + pi->SetReporter( aReporter ); + pi->SetProgressReporter( aProgressReporter ); + pi->SaveBoard( tempFile.GetFullPath(), aBoard, &props ); + return true; + } + catch( const IO_ERROR& ioe ) + { + if( aReporter ) { - try - { - IO_RELEASER<PCB_IO> pi( PCB_IO_MGR::PluginFind( PCB_IO_MGR::ODBPP ) ); - pi->SetReporter( aReporter ); - pi->SetProgressReporter( aProgressReporter ); - pi->SaveBoard( tempFile.GetFullPath(), aBoard, &props ); - return true; - } - catch( const IO_ERROR& ioe ) - { - if( aReporter ) - { - msg = wxString::Format( _( "Error generating ODBPP files '%s'.\n%s" ), - tempFile.GetFullPath(), ioe.What() ); - aReporter->Report( msg, RPT_SEVERITY_ERROR ); - } + msg = wxString::Format( _( "Error generating ODBPP files '%s'.\n%s" ), + tempFile.GetFullPath(), ioe.What() ); + aReporter->Report( msg, RPT_SEVERITY_ERROR ); + } - // In case we started a file but didn't fully write it, clean up - wxFileName::Rmdir( tempFile.GetFullPath() ); - return false; - } - }; + // In case we started a file but didn't fully write it, clean up + wxFileName::Rmdir( tempFile.GetFullPath() ); + return false; + } + }; thread_pool& tp = GetKiCadThreadPool(); auto ret = tp.submit( saveFile ); @@ -365,7 +464,7 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO while( status != std::future_status::ready ) { - if( aProgressReporter) + if( aProgressReporter ) aProgressReporter->KeepRefreshing(); status = ret.wait_for( std::chrono::milliseconds( 250 ) ); @@ -387,12 +486,12 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO return; } - if( aJob.m_compressionMode != JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE ) + if( aJob.m_compressionMode == JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP ) { if( aProgressReporter ) aProgressReporter->AdvancePhase( _( "Compressing output" ) ); - wxFFileOutputStream fnout( zipFileName.GetFullPath() ); + wxFFileOutputStream fnout( pcbFileName.GetFullPath() ); wxZipOutputStream zipStream( fnout ); std::function<void( const wxString&, const wxString& )> addDirToZip = @@ -434,6 +533,54 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE ); } + else if( aJob.m_compressionMode == JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::TGZ ) + { + wxFFileOutputStream fnout( pcbFileName.GetFullPath() ); + wxZlibOutputStream zlibStream( fnout, -1, wxZLIB_GZIP ); + wxTarOutputStream tarStream( zlibStream ); + + std::function<void( const wxString&, const wxString& )> addDirToTar = + [&]( const wxString& dirPath, const wxString& parentPath ) + { + wxDir dir( dirPath ); + wxString fileName; + + bool cont = dir.GetFirst( &fileName, wxEmptyString, wxDIR_DEFAULT ); + while( cont ) + { + wxFileName fileInTar( dirPath, fileName ); + wxString relativePath = + parentPath.IsEmpty() + ? fileName + : parentPath + wxString( wxFileName::GetPathSeparator() ) + + fileName; + + if( wxFileName::DirExists( fileInTar.GetFullPath() ) ) + { + tarStream.PutNextDirEntry( relativePath ); + addDirToTar( fileInTar.GetFullPath(), relativePath ); + } + else + { + wxFFileInputStream fileStream( fileInTar.GetFullPath() ); + tarStream.PutNextEntry( relativePath, wxDateTime::Now(), + fileStream.GetLength() ); + fileStream.Read( tarStream ); + } + cont = dir.GetNext( &fileName ); + } + }; + + addDirToTar( + tempFile.GetFullPath(), + tempFile.GetPath( wxPATH_NO_SEPARATOR ).AfterLast( tempFile.GetPathSeparator() ) ); + + tarStream.Close(); + zlibStream.Close(); + fnout.Close(); + + tempFile.Rmdir( wxPATH_RMDIR_RECURSIVE ); + } if( aProgressReporter ) aProgressReporter->SetCurrentProgress( 1 ); diff --git a/pcbnew/dialogs/dialog_export_odbpp.fbp b/pcbnew/dialogs/dialog_export_odbpp.fbp index 55715e666b..4e1dfb513f 100644 --- a/pcbnew/dialogs/dialog_export_odbpp.fbp +++ b/pcbnew/dialogs/dialog_export_odbpp.fbp @@ -47,10 +47,10 @@ <property name="hidden">0</property> <property name="id">wxID_ANY</property> <property name="maximum_size"></property> - <property name="minimum_size"></property> + <property name="minimum_size">380,265</property> <property name="name">DIALOG_EXPORT_ODBPP_BASE</property> <property name="pos"></property> - <property name="size">380,300</property> + <property name="size">-1,-1</property> <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> <property name="subclass">DIALOG_SHIM; dialog_shim.h</property> <property name="title">Export ODB++</property> @@ -58,15 +58,15 @@ <property name="two_step_creation">0</property> <property name="window_extra_style"></property> <property name="window_name"></property> - <property name="window_style"></property> + <property name="window_style">wxBORDER_DEFAULT</property> <object class="wxBoxSizer" expanded="true"> <property name="minimum_size"></property> <property name="name">bMainSizer</property> <property name="orient">wxVERTICAL</property> <property name="permission">none</property> <object class="sizeritem" expanded="true"> - <property name="border">15</property> - <property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> <property name="proportion">0</property> <object class="wxBoxSizer" expanded="true"> <property name="minimum_size"></property> @@ -75,7 +75,7 @@ <property name="permission">protected</property> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> <property name="proportion">0</property> <object class="wxStaticText" expanded="false"> <property name="BottomDockable">1</property> @@ -106,7 +106,7 @@ <property name="gripper">0</property> <property name="hidden">0</property> <property name="id">wxID_ANY</property> - <property name="label">Folder:</property> + <property name="label">Output File:</property> <property name="markup">0</property> <property name="max_size"></property> <property name="maximize_button">0</property> @@ -137,7 +137,7 @@ </object> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxALIGN_CENTER_VERTICAL</property> + <property name="flag">wxALL|wxEXPAND</property> <property name="proportion">1</property> <object class="wxTextCtrl" expanded="false"> <property name="BottomDockable">1</property> @@ -278,7 +278,7 @@ </object> </object> <object class="sizeritem" expanded="true"> - <property name="border">5</property> + <property name="border">10</property> <property name="flag">wxEXPAND</property> <property name="proportion">0</property> <object class="wxBoxSizer" expanded="true"> @@ -286,11 +286,11 @@ <property name="name">bSizer3</property> <property name="orient">wxHORIZONTAL</property> <property name="permission">none</property> - <object class="sizeritem" expanded="true"> + <object class="sizeritem" expanded="false"> <property name="border">10</property> - <property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property> + <property name="flag">wxEXPAND|wxALL</property> <property name="proportion">1</property> - <object class="wxStaticBoxSizer" expanded="true"> + <object class="wxStaticBoxSizer" expanded="false"> <property name="id">wxID_ANY</property> <property name="label">File Format</property> <property name="minimum_size"></property> @@ -300,12 +300,12 @@ <property name="permission">none</property> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxEXPAND|wxALL</property> + <property name="flag">wxEXPAND|wxLEFT</property> <property name="proportion">3</property> <object class="wxFlexGridSizer" expanded="false"> <property name="cols">2</property> <property name="flexible_direction">wxBOTH</property> - <property name="growablecols">1</property> + <property name="growablecols">0,1</property> <property name="growablerows"></property> <property name="hgap">0</property> <property name="minimum_size"></property> @@ -316,7 +316,7 @@ <property name="vgap">0</property> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> <property name="proportion">0</property> <object class="wxStaticText" expanded="false"> <property name="BottomDockable">1</property> @@ -378,7 +378,7 @@ </object> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxALIGN_RIGHT|wxALL</property> + <property name="flag">wxEXPAND|wxALL</property> <property name="proportion">0</property> <object class="wxChoice" expanded="false"> <property name="BottomDockable">1</property> @@ -415,7 +415,7 @@ <property name="maximum_size"></property> <property name="min_size"></property> <property name="minimize_button">0</property> - <property name="minimum_size"></property> + <property name="minimum_size">-1,-1</property> <property name="moveable">1</property> <property name="name">m_choiceUnits</property> <property name="pane_border">1</property> @@ -427,7 +427,7 @@ <property name="resize">Resizable</property> <property name="selection">0</property> <property name="show">1</property> - <property name="size">130,30</property> + <property name="size">-1,-1</property> <property name="style"></property> <property name="subclass">; ; forward_declare</property> <property name="toolbar_pane">0</property> @@ -443,7 +443,7 @@ </object> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> <property name="proportion">0</property> <object class="wxStaticText" expanded="false"> <property name="BottomDockable">1</property> @@ -505,7 +505,7 @@ </object> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxALIGN_RIGHT|wxALL</property> + <property name="flag">wxALL|wxEXPAND</property> <property name="proportion">0</property> <object class="wxSpinCtrl" expanded="false"> <property name="BottomDockable">1</property> @@ -536,7 +536,7 @@ <property name="gripper">0</property> <property name="hidden">0</property> <property name="id">wxID_ANY</property> - <property name="initial">7</property> + <property name="initial">6</property> <property name="max">16</property> <property name="max_size"></property> <property name="maximize_button">0</property> @@ -555,7 +555,7 @@ <property name="pos"></property> <property name="resize">Resizable</property> <property name="show">1</property> - <property name="size">130,30</property> + <property name="size">-1,-1</property> <property name="style">wxSP_ARROW_KEYS</property> <property name="subclass"></property> <property name="toolbar_pane">0</property> @@ -568,9 +568,9 @@ </object> <object class="sizeritem" expanded="false"> <property name="border">5</property> - <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> <property name="proportion">0</property> - <object class="wxCheckBox" expanded="false"> + <object class="wxStaticText" expanded="false"> <property name="BottomDockable">1</property> <property name="LeftDockable">1</property> <property name="RightDockable">1</property> @@ -584,7 +584,6 @@ <property name="caption"></property> <property name="caption_visible">1</property> <property name="center_pane">0</property> - <property name="checked">0</property> <property name="close_button">1</property> <property name="context_help"></property> <property name="context_menu">1</property> @@ -600,7 +599,8 @@ <property name="gripper">0</property> <property name="hidden">0</property> <property name="id">wxID_ANY</property> - <property name="label">Compress output</property> + <property name="label">Compression Format:</property> + <property name="markup">0</property> <property name="max_size"></property> <property name="maximize_button">0</property> <property name="maximum_size"></property> @@ -608,7 +608,7 @@ <property name="minimize_button">0</property> <property name="minimum_size"></property> <property name="moveable">1</property> - <property name="name">m_cbCompress</property> + <property name="name">m_lblCompress</property> <property name="pane_border">1</property> <property name="pane_position"></property> <property name="pane_size"></property> @@ -619,9 +619,71 @@ <property name="show">1</property> <property name="size"></property> <property name="style"></property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Select the format to compress the output ODB++ files</property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <property name="wrap">-1</property> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxChoice" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="choices">"None" "ZIP" "TGZ"</property> + <property name="close_button">1</property> + <property name="context_help"></property> + <property name="context_menu">1</property> + <property name="default_pane">0</property> + <property name="dock">Dock</property> + <property name="dock_fixed">0</property> + <property name="docking">Left</property> + <property name="drag_accept_files">0</property> + <property name="enabled">1</property> + <property name="fg"></property> + <property name="floatable">1</property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="max_size"></property> + <property name="maximize_button">0</property> + <property name="maximum_size"></property> + <property name="min_size"></property> + <property name="minimize_button">0</property> + <property name="minimum_size">-1,-1</property> + <property name="moveable">1</property> + <property name="name">m_choiceCompress</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="selection">1</property> + <property name="show">1</property> + <property name="size">-1,-1</property> + <property name="style"></property> <property name="subclass">; ; forward_declare</property> <property name="toolbar_pane">0</property> - <property name="tooltip">Compress output into 'zip' file</property> + <property name="tooltip"></property> <property name="validator_data_type"></property> <property name="validator_style">wxFILTER_NONE</property> <property name="validator_type">wxDefaultValidator</property> @@ -629,7 +691,7 @@ <property name="window_extra_style"></property> <property name="window_name"></property> <property name="window_style"></property> - <event name="OnCheckBox">onCompressCheck</event> + <event name="OnChoice">onFormatChoice</event> </object> </object> </object> @@ -638,16 +700,6 @@ </object> </object> </object> - <object class="sizeritem" expanded="false"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">1</property> - <object class="spacer" expanded="false"> - <property name="height">0</property> - <property name="permission">protected</property> - <property name="width">0</property> - </object> - </object> <object class="sizeritem" expanded="false"> <property name="border">5</property> <property name="flag">wxALL|wxEXPAND</property> diff --git a/pcbnew/dialogs/dialog_export_odbpp.h b/pcbnew/dialogs/dialog_export_odbpp.h index 1e2cc76c5b..c76d2abc66 100644 --- a/pcbnew/dialogs/dialog_export_odbpp.h +++ b/pcbnew/dialogs/dialog_export_odbpp.h @@ -45,8 +45,7 @@ public: int GetPrecision() const { return m_precision->GetValue(); } - - bool GetCompress() const { return m_cbCompress->GetValue(); } + int GetCompressFormat() const { return m_choiceCompress->GetSelection(); } // Runs the actual generation process; shared between GUI and CLI system static void GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BOARD* aBoard, @@ -56,8 +55,12 @@ public: private: void onBrowseClicked( wxCommandEvent& event ) override; + void onFormatChoice( wxCommandEvent& event ) override; void onOKClick( wxCommandEvent& event ) override; + void OnFmtChoiceOptionChanged(); + + bool Init(); bool TransferDataFromWindow() override; diff --git a/pcbnew/dialogs/dialog_export_odbpp_base.cpp b/pcbnew/dialogs/dialog_export_odbpp_base.cpp index fc924e30c6..38edd881e2 100644 --- a/pcbnew/dialogs/dialog_export_odbpp_base.cpp +++ b/pcbnew/dialogs/dialog_export_odbpp_base.cpp @@ -13,28 +13,28 @@ DIALOG_EXPORT_ODBPP_BASE::DIALOG_EXPORT_ODBPP_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetSizeHints( wxSize( 380,265 ), wxDefaultSize ); wxBoxSizer* bMainSizer; bMainSizer = new wxBoxSizer( wxVERTICAL ); bSizerTop = new wxBoxSizer( wxHORIZONTAL ); - m_lblBrdFile = new wxStaticText( this, wxID_ANY, _("Folder:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_lblBrdFile = new wxStaticText( this, wxID_ANY, _("Output File:"), wxDefaultPosition, wxDefaultSize, 0 ); m_lblBrdFile->Wrap( -1 ); - bSizerTop->Add( m_lblBrdFile, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + bSizerTop->Add( m_lblBrdFile, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_outputFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_outputFileName->SetToolTip( _("Enter a filename if you do not want to use default file names\nCan be used only when printing the current sheet") ); m_outputFileName->SetMinSize( wxSize( 350,-1 ) ); - bSizerTop->Add( m_outputFileName, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizerTop->Add( m_outputFileName, 1, wxALL|wxEXPAND, 5 ); m_browseButton = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 ); bSizerTop->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - bMainSizer->Add( bSizerTop, 0, wxBOTTOM|wxEXPAND|wxTOP, 15 ); + bMainSizer->Add( bSizerTop, 0, wxALL|wxEXPAND, 5 ); wxBoxSizer* bSizer3; bSizer3 = new wxBoxSizer( wxHORIZONTAL ); @@ -44,47 +44,52 @@ DIALOG_EXPORT_ODBPP_BASE::DIALOG_EXPORT_ODBPP_BASE( wxWindow* parent, wxWindowID wxFlexGridSizer* fgSizer; fgSizer = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer->AddGrowableCol( 0 ); fgSizer->AddGrowableCol( 1 ); fgSizer->SetFlexibleDirection( wxBOTH ); fgSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); m_lblUnits = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 ); m_lblUnits->Wrap( -1 ); - fgSizer->Add( m_lblUnits, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + fgSizer->Add( m_lblUnits, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxString m_choiceUnitsChoices[] = { _("Millimeters"), _("Inches") }; int m_choiceUnitsNChoices = sizeof( m_choiceUnitsChoices ) / sizeof( wxString ); - m_choiceUnits = new wxChoice( sbSizer1->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( 130,30 ), m_choiceUnitsNChoices, m_choiceUnitsChoices, 0 ); + m_choiceUnits = new wxChoice( sbSizer1->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), m_choiceUnitsNChoices, m_choiceUnitsChoices, 0 ); m_choiceUnits->SetSelection( 0 ); - fgSizer->Add( m_choiceUnits, 0, wxALIGN_RIGHT|wxALL, 5 ); + fgSizer->Add( m_choiceUnits, 0, wxEXPAND|wxALL, 5 ); m_lblPrecision = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("Precision:"), wxDefaultPosition, wxDefaultSize, 0 ); m_lblPrecision->Wrap( -1 ); m_lblPrecision->SetToolTip( _("The number of values following the decimal separator") ); - fgSizer->Add( m_lblPrecision, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + fgSizer->Add( m_lblPrecision, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_precision = new wxSpinCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 130,30 ), wxSP_ARROW_KEYS, 2, 16, 7 ); + m_precision = new wxSpinCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxSP_ARROW_KEYS, 2, 16, 6 ); m_precision->SetToolTip( _("The number of values following the decimal separator") ); - fgSizer->Add( m_precision, 0, wxALIGN_RIGHT|wxALL, 5 ); + fgSizer->Add( m_precision, 0, wxALL|wxEXPAND, 5 ); - m_cbCompress = new wxCheckBox( sbSizer1->GetStaticBox(), wxID_ANY, _("Compress output"), wxDefaultPosition, wxDefaultSize, 0 ); - m_cbCompress->SetToolTip( _("Compress output into 'zip' file") ); + m_lblCompress = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("Compression Format:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_lblCompress->Wrap( -1 ); + m_lblCompress->SetToolTip( _("Select the format to compress the output ODB++ files") ); - fgSizer->Add( m_cbCompress, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); + fgSizer->Add( m_lblCompress, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + wxString m_choiceCompressChoices[] = { _("None"), _("ZIP"), _("TGZ") }; + int m_choiceCompressNChoices = sizeof( m_choiceCompressChoices ) / sizeof( wxString ); + m_choiceCompress = new wxChoice( sbSizer1->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), m_choiceCompressNChoices, m_choiceCompressChoices, 0 ); + m_choiceCompress->SetSelection( 1 ); + fgSizer->Add( m_choiceCompress, 0, wxALL|wxEXPAND, 5 ); - sbSizer1->Add( fgSizer, 3, wxEXPAND|wxALL, 5 ); + sbSizer1->Add( fgSizer, 3, wxEXPAND|wxLEFT, 5 ); - bSizer3->Add( sbSizer1, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 10 ); + bSizer3->Add( sbSizer1, 1, wxEXPAND|wxALL, 10 ); - bMainSizer->Add( bSizer3, 0, wxEXPAND, 5 ); - - - bMainSizer->Add( 0, 0, 1, wxEXPAND, 5 ); + bMainSizer->Add( bSizer3, 0, wxEXPAND, 10 ); m_stdButtons = new wxStdDialogButtonSizer(); m_stdButtonsOK = new wxButton( this, wxID_OK ); @@ -98,12 +103,13 @@ DIALOG_EXPORT_ODBPP_BASE::DIALOG_EXPORT_ODBPP_BASE( wxWindow* parent, wxWindowID this->SetSizer( bMainSizer ); this->Layout(); + bMainSizer->Fit( this ); this->Centre( wxBOTH ); // Connect Events m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onBrowseClicked ), NULL, this ); - m_cbCompress->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onCompressCheck ), NULL, this ); + m_choiceCompress->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onFormatChoice ), NULL, this ); m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onOKClick ), NULL, this ); } @@ -111,7 +117,7 @@ DIALOG_EXPORT_ODBPP_BASE::~DIALOG_EXPORT_ODBPP_BASE() { // Disconnect Events m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onBrowseClicked ), NULL, this ); - m_cbCompress->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onCompressCheck ), NULL, this ); + m_choiceCompress->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onFormatChoice ), NULL, this ); m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EXPORT_ODBPP_BASE::onOKClick ), NULL, this ); } diff --git a/pcbnew/dialogs/dialog_export_odbpp_base.h b/pcbnew/dialogs/dialog_export_odbpp_base.h index 0d6a044203..ff40c3bf3a 100644 --- a/pcbnew/dialogs/dialog_export_odbpp_base.h +++ b/pcbnew/dialogs/dialog_export_odbpp_base.h @@ -28,7 +28,6 @@ class STD_BITMAP_BUTTON; #include <wx/sizer.h> #include <wx/choice.h> #include <wx/spinctrl.h> -#include <wx/checkbox.h> #include <wx/statbox.h> #include <wx/dialog.h> @@ -50,20 +49,21 @@ class DIALOG_EXPORT_ODBPP_BASE : public DIALOG_SHIM wxChoice* m_choiceUnits; wxStaticText* m_lblPrecision; wxSpinCtrl* m_precision; - wxCheckBox* m_cbCompress; + wxStaticText* m_lblCompress; + wxChoice* m_choiceCompress; wxStdDialogButtonSizer* m_stdButtons; wxButton* m_stdButtonsOK; wxButton* m_stdButtonsCancel; // Virtual event handlers, override them in your derived class virtual void onBrowseClicked( wxCommandEvent& event ) { event.Skip(); } - virtual void onCompressCheck( wxCommandEvent& event ) { event.Skip(); } + virtual void onFormatChoice( wxCommandEvent& event ) { event.Skip(); } virtual void onOKClick( wxCommandEvent& event ) { event.Skip(); } public: - DIALOG_EXPORT_ODBPP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export ODB++"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 380,300 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_EXPORT_ODBPP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export ODB++"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxBORDER_DEFAULT ); ~DIALOG_EXPORT_ODBPP_BASE(); diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index ad4fb46301..8cf674d5c1 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -1420,8 +1420,8 @@ void PCB_EDIT_FRAME::GenODBPPFiles( wxCommandEvent& event ) job.SetOutputPath( dlg.GetOutputPath() ); job.m_filename = GetBoard()->GetFileName(); - job.m_compressionMode = dlg.GetCompress() ? JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP - : JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE; + job.m_compressionMode = static_cast<JOB_EXPORT_PCB_ODB::ODB_COMPRESSION>( dlg.GetCompressFormat() ); + job.m_precision = dlg.GetPrecision(); job.m_units = dlg.GetUnitsString() == "mm" ? JOB_EXPORT_PCB_ODB::ODB_UNITS::MILLIMETERS : JOB_EXPORT_PCB_ODB::ODB_UNITS::INCHES; diff --git a/pcbnew/pcb_io/odbpp/pcb_io_odbpp.cpp b/pcbnew/pcb_io/odbpp/pcb_io_odbpp.cpp index ee9129df24..a49747c0b6 100644 --- a/pcbnew/pcb_io/odbpp/pcb_io_odbpp.cpp +++ b/pcbnew/pcb_io/odbpp/pcb_io_odbpp.cpp @@ -90,7 +90,7 @@ bool PCB_IO_ODBPP::ExportODB( const wxString& aFileName ) try { std::shared_ptr<ODB_TREE_WRITER> writer = - std::make_shared<ODB_TREE_WRITER>( aFileName, "odb" ); + std::make_shared<ODB_TREE_WRITER>( aFileName ); writer->SetRootPath( writer->GetCurrentPath() ); if( m_progressReporter ) diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index c89a663842..60c6c89fb0 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -1842,15 +1842,39 @@ int PCBNEW_JOBS_HANDLER::JobExportOdb( JOB* aJob ) if( !brd ) return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - if( job->OutputPathFullSpecified() ) - { - wxFileName fn = brd->GetFileName(); - fn.SetName( fn.GetName() ); - fn.SetExt( "zip" ); + wxFileName fn( brd->GetFileName() ); + wxString path = job->GetOutputPath(); - job->SetOutputPath( fn.GetName() ); + if( path.IsEmpty() ) + { + wxFileName outputfn( fn.GetPath(), wxString::Format( wxS( "%s-odb" ), fn.GetName() ) ); + path = outputfn.GetFullPath(); } + wxFileName fileName( path ); + + int sepIdx = std::max( path.Find( '/', true ), path.Find( '\\', true ) ); + int dotIdx = path.Find( '.', true ); + + if( fileName.IsDir() && path.EndsWith( wxFileName::GetPathSeparator() ) ) + path = path.Mid( 0, sepIdx ); + else if( sepIdx < dotIdx ) + path = path.Mid( 0, dotIdx ); + + switch( job->m_compressionMode ) + { + case JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::ZIP: + path = path + '.' + FILEEXT::ArchiveFileExtension; + break; + case JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::TGZ: path += ".tgz"; break; + case JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE: + path = wxFileName( path, "" ).GetFullPath(); + break; + default: break; + }; + + job->SetOutputPath( path ); + DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( *job, brd, nullptr, m_progressReporter, m_reporter ); return CLI::EXIT_CODES::SUCCESS; diff --git a/pcbnew/pcbnew_settings.h b/pcbnew/pcbnew_settings.h index 345ae1aa29..0319844c02 100644 --- a/pcbnew/pcbnew_settings.h +++ b/pcbnew/pcbnew_settings.h @@ -206,7 +206,7 @@ public: { int precision; int units; - bool compress; + int compressFormat; }; struct DIALOG_EXPORT_SVG