7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-03-30 06:26:55 +00:00

Move layer arg parsing up so we can handle user-defined layer names.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18773
This commit is contained in:
Jeff Young 2025-03-16 17:26:45 +00:00
parent 77747aa41e
commit 1333c4c305
16 changed files with 166 additions and 303 deletions

View File

@ -42,6 +42,10 @@ public:
JOB_EXPORT_PCB_PLOT( PLOT_FORMAT aFormat, const std::string& aType, bool aOutputIsDirectory );
public:
wxString m_argLayers;
wxString m_argCommonLayers;
PLOT_FORMAT m_plotFormat;
wxString m_filename;

View File

@ -22,13 +22,11 @@
#include <cli/exit_codes.h>
#include "jobs/job_fp_export_svg.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <wx/crt.h>
#include <wx/dir.h>
#include <macros.h>
#include <wx/tokenzr.h>
#define ARG_FOOTPRINT "--footprint"
@ -38,7 +36,7 @@ CLI::FP_EXPORT_SVG_COMMAND::FP_EXPORT_SVG_COMMAND() :
m_argParser.add_description( UTF8STDSTR( _( "Exports the footprint or entire footprint "
"library to SVG" ) ) );
addLayerArg( false );
addLayerArg();
addDefineArg();
m_argParser.add_argument( "-t", ARG_THEME )
@ -75,10 +73,6 @@ CLI::FP_EXPORT_SVG_COMMAND::FP_EXPORT_SVG_COMMAND() :
int CLI::FP_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_FP_EXPORT_SVG> svgJob = std::make_unique<JOB_FP_EXPORT_SVG>();
svgJob->m_libraryPath = m_argInput;
@ -99,12 +93,7 @@ int CLI::FP_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
svgJob->m_colorTheme = From_UTF8( m_argParser.get<std::string>( ARG_THEME ).c_str() );
if( !m_selectedLayers.empty() )
svgJob->m_plotLayerSequence = m_selectedLayers;
else
svgJob->m_plotLayerSequence = LSET::AllLayersMask().SeqStackupForPlotting();
svgJob->m_argLayers = From_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, svgJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, svgJob.get() );
}

View File

@ -19,126 +19,33 @@
*/
#include "command_pcb_export_base.h"
#include <cli/exit_codes.h>
#include <kiface_base.h>
#include <bitset>
#include <layer_ids.h>
#include <lset.h>
#include <lseq.h>
#include <string_utils.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <wx/crt.h>
CLI::PCB_EXPORT_BASE_COMMAND::PCB_EXPORT_BASE_COMMAND( const std::string& aName,
bool aInputCanBeDir,
bool aOutputIsDir ) :
bool aInputCanBeDir, bool aOutputIsDir ) :
COMMAND( aName )
{
m_selectedLayersSet = false;
m_requireLayers = false;
m_hasLayerArg = false;
addCommonArgs( true, true, aInputCanBeDir, aOutputIsDir );
// Build list of layer names and their layer mask:
for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
{
std::string untranslated = TO_UTF8( wxString( LSET::Name( PCB_LAYER_ID( layer ) ) ) );
//m_layerIndices[untranslated] = PCB_LAYER_ID( layer );
// Add layer name used in pcb files
m_layerMasks[untranslated] = LSET( { PCB_LAYER_ID( layer ) } );
// Add layer name using GUI canonical layer name
m_layerGuiMasks[ TO_UTF8(LayerName( layer ) ) ] = LSET( { PCB_LAYER_ID( layer ) } );
}
// Add list of grouped layer names used in pcb files
m_layerMasks["*"] = LSET::AllLayersMask();
m_layerMasks["*.Cu"] = LSET::AllCuMask();
m_layerMasks["*In.Cu"] = LSET::InternalCuMask();
m_layerMasks["F&B.Cu"] = LSET( { F_Cu, B_Cu } );
m_layerMasks["*.Adhes"] = LSET( { B_Adhes, F_Adhes } );
m_layerMasks["*.Paste"] = LSET( { B_Paste, F_Paste } );
m_layerMasks["*.Mask"] = LSET( { B_Mask, F_Mask } );
m_layerMasks["*.SilkS"] = LSET( { B_SilkS, F_SilkS } );
m_layerMasks["*.Fab"] = LSET( { B_Fab, F_Fab } );
m_layerMasks["*.CrtYd"] = LSET( { B_CrtYd, F_CrtYd } );
// Add list of grouped layer names using GUI canonical layer names
m_layerGuiMasks["*.Adhesive"] = LSET( { B_Adhes, F_Adhes } );
m_layerGuiMasks["*.Silkscreen"] = LSET( { B_SilkS, F_SilkS } );
m_layerGuiMasks["*.Courtyard"] = LSET( { B_CrtYd, F_CrtYd } );
}
LSEQ CLI::PCB_EXPORT_BASE_COMMAND::convertLayerStringList( wxString& aLayerString ) const
{
LSEQ layerMask;
if( !aLayerString.IsEmpty() )
{
wxStringTokenizer layerTokens( aLayerString, "," );
while( layerTokens.HasMoreTokens() )
{
std::string token = TO_UTF8( layerTokens.GetNextToken() );
// Search for a layer name in canonical layer name used in .kicad_pcb files:
if( m_layerMasks.count( token ) )
{
for( PCB_LAYER_ID layer : m_layerMasks.at( token ).Seq() )
layerMask.push_back( layer );
}
// Search for a layer name in canonical layer name used in GUI (not translated):
else if( m_layerGuiMasks.count( token ) )
{
for( PCB_LAYER_ID layer : m_layerGuiMasks.at( token ).Seq() )
layerMask.push_back( layer );
}
else
{
wxFprintf( stderr, _( "Invalid layer name \"%s\"\n" ), token );
}
}
}
return layerMask;
}
void CLI::PCB_EXPORT_BASE_COMMAND::addLayerArg( bool aRequire )
void CLI::PCB_EXPORT_BASE_COMMAND::addLayerArg()
{
m_argParser.add_argument( "-l", ARG_LAYERS )
.default_value( std::string() )
.help( UTF8STDSTR(
_( "Comma separated list of untranslated layer names to include such as "
"F.Cu,B.Cu" ) ) )
.help( UTF8STDSTR( _( "Comma separated list of untranslated layer names to include "
"such as F.Cu,B.Cu" ) ) )
.metavar( "LAYER_LIST" );
m_hasLayerArg = true;
m_requireLayers = aRequire;
}
int CLI::PCB_EXPORT_BASE_COMMAND::doPerform( KIWAY& aKiway )
void CLI::PCB_EXPORT_BASE_COMMAND::addCommonLayersArg()
{
if( m_hasLayerArg )
{
wxString layers = From_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
LSEQ layerMask = convertLayerStringList( layers );
if( m_requireLayers && layerMask.size() < 1 )
{
wxFprintf( stderr, _( "At least one layer must be specified\n" ) );
return EXIT_CODES::ERR_ARGS;
}
m_selectedLayers = layerMask;
}
return EXIT_CODES::OK;
}
m_argParser.add_argument( "--cl", ARG_COMMON_LAYERS )
.default_value( std::string() )
.help( UTF8STDSTR( _( "Layers to include on each plot, comma separated list of "
"untranslated layer names to include such as F.Cu,B.Cu" ) ) )
.metavar( "COMMON_LAYER_LIST" );
}

View File

@ -22,9 +22,6 @@
#define COMMAND_EXPORT_PCB_BASE_H
#include "command.h"
#include <layer_ids.h>
#include <lset.h>
#include <lseq.h>
namespace CLI
{
@ -74,21 +71,8 @@ struct PCB_EXPORT_BASE_COMMAND : public COMMAND
bool aOutputIsDir = false );
protected:
int doPerform( KIWAY& aKiway ) override;
LSEQ convertLayerStringList( wxString& aLayerString ) const;
void addLayerArg( bool aRequire );
// The list of canonical layer names used in .kicad_pcb files:
std::map<std::string, LSET> m_layerMasks;
// The list of canonical layer names used in GUI (not translated):
std::map<std::string, LSET> m_layerGuiMasks;
LSEQ m_selectedLayers;
bool m_selectedLayersSet;
bool m_hasLayerArg;
bool m_requireLayers;
void addLayerArg();
void addCommonLayersArg();
};
} // namespace CLI

View File

@ -22,13 +22,10 @@
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_dxf.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <locale_io.h>
#define ARG_USE_CONTOURS "--use-contours"
@ -42,7 +39,8 @@ CLI::PCB_EXPORT_DXF_COMMAND::PCB_EXPORT_DXF_COMMAND() :
{
m_argParser.add_description( UTF8STDSTR( _( "Generate a DXF from a list of layers" ) ) );
addLayerArg( true );
addLayerArg();
addCommonLayersArg();
addDrawingSheetArg();
addDefineArg();
@ -96,13 +94,6 @@ CLI::PCB_EXPORT_DXF_COMMAND::PCB_EXPORT_DXF_COMMAND() :
.scan<'i', int>()
.default_value( 2 );
m_argParser.add_argument( "--cl", ARG_COMMON_LAYERS )
.default_value( std::string() )
.help( UTF8STDSTR(
_( "Layers to include on each plot, comma separated list of untranslated "
"layer names to include such as F.Cu,B.Cu" ) ) )
.metavar( "COMMON_LAYER_LIST" );
m_argParser.add_argument( ARG_MODE_SINGLE )
.help( UTF8STDSTR(
_( "Generates a single file with the output arg path acting as the complete "
@ -124,10 +115,6 @@ CLI::PCB_EXPORT_DXF_COMMAND::PCB_EXPORT_DXF_COMMAND() :
int CLI::PCB_EXPORT_DXF_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_EXPORT_PCB_DXF> dxfJob( new JOB_EXPORT_PCB_DXF() );
dxfJob->m_filename = m_argInput;
@ -175,10 +162,8 @@ int CLI::PCB_EXPORT_DXF_COMMAND::doPerform( KIWAY& aKiway )
return EXIT_CODES::ERR_ARGS;
}
dxfJob->m_plotLayerSequence = m_selectedLayers;
wxString layers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
dxfJob->m_plotOnAllLayersSequence = convertLayerStringList( layers );
dxfJob->m_argLayers = From_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
dxfJob->m_argCommonLayers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
if( m_argParser.get<bool>( ARG_MODE_MULTI ) )
dxfJob->m_genMode = JOB_EXPORT_PCB_DXF::GEN_MODE::MULTI;
@ -196,7 +181,5 @@ int CLI::PCB_EXPORT_DXF_COMMAND::doPerform( KIWAY& aKiway )
LOCALE_IO dummy; // Switch to "C" locale
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, dxfJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, dxfJob.get() );
}

View File

@ -22,21 +22,16 @@
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_gencad.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <locale_io.h>
CLI::PCB_EXPORT_GENCAD_COMMAND::PCB_EXPORT_GENCAD_COMMAND() :
PCB_EXPORT_BASE_COMMAND( "gencad", false, true )
{
// TODO: Update string to remove reference to layers
m_argParser.add_description( UTF8STDSTR( _( "Generate Gencad from a list of layers" ) ) );
m_argParser.add_description( UTF8STDSTR( _( "Export the PCB in Gencad format" ) ) );
addDefineArg();
@ -70,11 +65,6 @@ CLI::PCB_EXPORT_GENCAD_COMMAND::PCB_EXPORT_GENCAD_COMMAND() :
int CLI::PCB_EXPORT_GENCAD_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_EXPORT_PCB_GENCAD> gencadJob( new JOB_EXPORT_PCB_GENCAD() );
gencadJob->m_filename = m_argInput;
@ -94,7 +84,5 @@ int CLI::PCB_EXPORT_GENCAD_COMMAND::doPerform( KIWAY& aKiway )
}
LOCALE_IO dummy; // Switch to "C" locale
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gencadJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, gencadJob.get() );
}

View File

@ -22,12 +22,9 @@
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_gerber.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <locale_io.h>
#include <string_utils.h>
@ -35,7 +32,8 @@
CLI::PCB_EXPORT_GERBER_COMMAND::PCB_EXPORT_GERBER_COMMAND( const std::string& aName ) :
PCB_EXPORT_BASE_COMMAND( aName )
{
addLayerArg( true );
addLayerArg();
addCommonLayersArg();
addDrawingSheetArg();
addDefineArg();
@ -90,13 +88,6 @@ CLI::PCB_EXPORT_GERBER_COMMAND::PCB_EXPORT_GERBER_COMMAND( const std::string& aN
.help( UTF8STDSTR( _( "Use drill/place file origin" ) ) )
.flag();
m_argParser.add_argument( "--cl", ARG_COMMON_LAYERS )
.default_value( std::string() )
.help( UTF8STDSTR(
_( "Layers to include on each plot, comma separated list of untranslated "
"layer names to include such as F.Cu,B.Cu" ) ) )
.metavar( "COMMON_LAYER_LIST" );
m_argParser.add_argument( ARG_PRECISION )
.help( UTF8STDSTR( _( "Precision of Gerber coordinates, valid options: 5 or 6" ) ) )
.scan<'i', int>()
@ -140,10 +131,9 @@ int CLI::PCB_EXPORT_GERBER_COMMAND::populateJob( JOB_EXPORT_PCB_GERBER* aJob )
aJob->m_useDrillOrigin = m_argParser.get<bool>( ARG_USE_DRILL_FILE_ORIGIN );
aJob->m_useProtelFileExtension = !m_argParser.get<bool>( ARG_NO_PROTEL_EXTENSION );
aJob->m_precision = m_argParser.get<int>( ARG_PRECISION );
aJob->m_plotLayerSequence = m_selectedLayers;
wxString layers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
aJob->m_plotOnAllLayersSequence = convertLayerStringList( layers );
aJob->m_argLayers = From_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
aJob->m_argCommonLayers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
if( m_argParser.get<bool>( DEPRECATED_ARG_PLOT_INVISIBLE_TEXT ) )
wxFprintf( stdout, DEPRECATED_ARD_PLOT_INVISIBLE_TEXT_WARNING );
@ -169,20 +159,13 @@ int CLI::PCB_EXPORT_GERBER_COMMAND::doPerform( KIWAY& aKiway )
wxFprintf( stdout, wxT( "\033[33;1m%s\033[0m\n" ),
_( "This command is deprecated as of KiCad 9.0, please use \"gerbers\" instead\n" ) );
int exitCode = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( exitCode != EXIT_CODES::OK )
return exitCode;
std::unique_ptr<JOB_EXPORT_PCB_GERBER> gerberJob( new JOB_EXPORT_PCB_GERBER() );
exitCode = populateJob( gerberJob.get() );
int exitCode = populateJob( gerberJob.get() );
if( exitCode != EXIT_CODES::OK )
return exitCode;
LOCALE_IO dummy;
exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() );
}

View File

@ -22,12 +22,7 @@
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_gerbers.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <locale_io.h>
@ -37,19 +32,11 @@
CLI::PCB_EXPORT_GERBERS_COMMAND::PCB_EXPORT_GERBERS_COMMAND() :
PCB_EXPORT_GERBER_COMMAND( "gerbers" )
{
m_requireLayers = false;
addCommonLayersArg();
m_argParser.add_description( UTF8STDSTR( _( "Plot multiple Gerbers for a PCB, including the "
"ability to use stored board plot settings" ) ) );
m_argParser.add_argument( "--cl", ARG_COMMON_LAYERS )
.default_value( std::string() )
.help( UTF8STDSTR(
_( "Layers to include on each plot, comma separated list of untranslated "
"layer names to include such as "
"F.Cu,B.Cu" ) ) )
.metavar( "COMMON_LAYER_LIST" );
m_argParser.add_argument( ARG_USE_BOARD_PLOT_PARAMS )
.help( UTF8STDSTR( _( "Use the Gerber plot settings already configured in the "
"board file" ) ) )
@ -59,24 +46,17 @@ CLI::PCB_EXPORT_GERBERS_COMMAND::PCB_EXPORT_GERBERS_COMMAND() :
int CLI::PCB_EXPORT_GERBERS_COMMAND::doPerform( KIWAY& aKiway )
{
int exitCode = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( exitCode != EXIT_CODES::OK )
return exitCode;
std::unique_ptr<JOB_EXPORT_PCB_GERBERS> gerberJob( new JOB_EXPORT_PCB_GERBERS() );
exitCode = populateJob( gerberJob.get() );
int exitCode = populateJob( gerberJob.get() );
if( exitCode != EXIT_CODES::OK )
return exitCode;
wxString layers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
gerberJob->m_plotOnAllLayersSequence = convertLayerStringList( layers );
gerberJob->m_argLayers = From_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
gerberJob->m_argCommonLayers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
gerberJob->m_useBoardPlotParams = m_argParser.get<bool>( ARG_USE_BOARD_PLOT_PARAMS );
LOCALE_IO dummy;
exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() );
}

View File

@ -102,11 +102,6 @@ CLI::PCB_EXPORT_IPC2581_COMMAND::PCB_EXPORT_IPC2581_COMMAND() :
int CLI::PCB_EXPORT_IPC2581_COMMAND::doPerform( KIWAY& aKiway )
{
int exitCode = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( exitCode != EXIT_CODES::OK )
return exitCode;
std::unique_ptr<JOB_EXPORT_PCB_IPC2581> ipc2581Job( new JOB_EXPORT_PCB_IPC2581() );
ipc2581Job->m_filename = m_argInput;
@ -146,7 +141,5 @@ int CLI::PCB_EXPORT_IPC2581_COMMAND::doPerform( KIWAY& aKiway )
From_UTF8( m_argParser.get<std::string>( ARG_BOM_COL_DIST ).c_str() );
LOCALE_IO dummy;
exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, ipc2581Job.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, ipc2581Job.get() );
}

View File

@ -25,9 +25,6 @@
#include <string_utils.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <locale_io.h>
CLI::PCB_EXPORT_IPCD356_COMMAND::PCB_EXPORT_IPCD356_COMMAND() :
@ -39,11 +36,6 @@ CLI::PCB_EXPORT_IPCD356_COMMAND::PCB_EXPORT_IPCD356_COMMAND() :
int CLI::PCB_EXPORT_IPCD356_COMMAND::doPerform( KIWAY& aKiway )
{
int exitCode = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( exitCode != EXIT_CODES::OK )
return exitCode;
std::unique_ptr<JOB_EXPORT_PCB_IPCD356> ipcd356Job( new JOB_EXPORT_PCB_IPCD356() );
ipcd356Job->m_filename = m_argInput;
@ -55,7 +47,5 @@ int CLI::PCB_EXPORT_IPCD356_COMMAND::doPerform( KIWAY& aKiway )
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, ipcd356Job.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, ipcd356Job.get() );
}

View File

@ -25,8 +25,6 @@
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <locale_io.h>
#define ARG_COMPRESS "--compression"
@ -60,11 +58,6 @@ CLI::PCB_EXPORT_ODB_COMMAND::PCB_EXPORT_ODB_COMMAND() :
int CLI::PCB_EXPORT_ODB_COMMAND::doPerform( KIWAY& aKiway )
{
int exitCode = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( exitCode != EXIT_CODES::OK )
return exitCode;
std::unique_ptr<JOB_EXPORT_PCB_ODB> job( new JOB_EXPORT_PCB_ODB() );
job->m_filename = m_argInput;
@ -97,7 +90,5 @@ int CLI::PCB_EXPORT_ODB_COMMAND::doPerform( KIWAY& aKiway )
job->m_compressionMode = JOB_EXPORT_PCB_ODB::ODB_COMPRESSION::NONE;
LOCALE_IO dummy;
exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, job.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, job.get() );
}

View File

@ -22,7 +22,6 @@
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_pdf.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <wx/crt.h>
@ -37,7 +36,8 @@ CLI::PCB_EXPORT_PDF_COMMAND::PCB_EXPORT_PDF_COMMAND() :
{
m_argParser.add_description( UTF8STDSTR( _( "Generate PDF from a list of layers" ) ) );
addLayerArg( true );
addLayerArg();
addCommonLayersArg();
addDrawingSheetArg();
addDefineArg();
@ -95,14 +95,6 @@ CLI::PCB_EXPORT_PDF_COMMAND::PCB_EXPORT_PDF_COMMAND() :
.scan<'i', int>()
.default_value( 2 );
m_argParser.add_argument( "--cl", ARG_COMMON_LAYERS )
.default_value( std::string() )
.help( UTF8STDSTR(
_( "Layers to include on each plot, comma separated list of untranslated "
"layer names to include such as "
"F.Cu,B.Cu" ) ) )
.metavar( "COMMON_LAYER_LIST" );
m_argParser.add_argument( DEPRECATED_ARG_PLOT_INVISIBLE_TEXT )
.help( UTF8STDSTR( _( DEPRECATED_ARG_PLOT_INVISIBLE_TEXT_DESC ) ) )
.flag();
@ -126,11 +118,6 @@ CLI::PCB_EXPORT_PDF_COMMAND::PCB_EXPORT_PDF_COMMAND() :
int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_EXPORT_PCB_PDF> pdfJob( new JOB_EXPORT_PCB_PDF() );
pdfJob->m_filename = m_argInput;
@ -166,8 +153,6 @@ int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway )
int drillShape = m_argParser.get<int>( ARG_DRILL_SHAPE_OPTION );
pdfJob->m_drillShapeOption = static_cast<JOB_EXPORT_PCB_PDF::DRILL_MARKS>( drillShape );
pdfJob->m_plotLayerSequence = m_selectedLayers;
bool argModeMulti = m_argParser.get<bool>( ARG_MODE_MULTIPAGE );
bool argModeSeparate = m_argParser.get<bool>( ARG_MODE_SEPARATE );
bool argModeSingle = m_argParser.get<bool>( ARG_MODE_SINGLE );
@ -178,8 +163,8 @@ int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway )
return EXIT_CODES::ERR_ARGS;
}
wxString layers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
pdfJob->m_plotOnAllLayersSequence = convertLayerStringList( layers );
pdfJob->m_argLayers = From_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
pdfJob->m_argCommonLayers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
if( argModeMulti )
pdfJob->m_pdfGenMode = JOB_EXPORT_PCB_PDF::GEN_MODE::ONE_PAGE_PER_LAYER_ONE_FILE;
@ -189,7 +174,5 @@ int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway )
pdfJob->m_pdfGenMode = JOB_EXPORT_PCB_PDF::GEN_MODE::ALL_LAYERS_ONE_FILE;
LOCALE_IO dummy; // Switch to "C" locale
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, pdfJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, pdfJob.get() );
}

View File

@ -22,7 +22,6 @@
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_pos.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <wx/crt.h>
@ -92,11 +91,6 @@ CLI::PCB_EXPORT_POS_COMMAND::PCB_EXPORT_POS_COMMAND() :
int CLI::PCB_EXPORT_POS_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_EXPORT_PCB_POS> aPosJob( new JOB_EXPORT_PCB_POS() );
aPosJob->m_filename = m_argInput;
@ -179,9 +173,6 @@ int CLI::PCB_EXPORT_POS_COMMAND::doPerform( KIWAY& aKiway )
return EXIT_CODES::ERR_ARGS;
}
LOCALE_IO dummy;
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, aPosJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, aPosJob.get() );
}

View File

@ -24,7 +24,6 @@
#include "command_pcb_export_base.h"
#include "jobs/job_export_pcb_svg.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <regex>
#include <wx/crt.h>
@ -41,7 +40,8 @@ CLI::PCB_EXPORT_SVG_COMMAND::PCB_EXPORT_SVG_COMMAND() :
{
m_argParser.add_description( UTF8STDSTR( _( "Generate SVG outputs of a given layer list" ) ) );
addLayerArg( true );
addLayerArg();
addCommonLayersArg();
addDrawingSheetArg();
addDefineArg();
@ -103,15 +103,6 @@ CLI::PCB_EXPORT_SVG_COMMAND::PCB_EXPORT_SVG_COMMAND() :
.default_value( 2 )
.metavar( "SHAPE_OPTION" );
m_argParser.add_argument( "--cl", ARG_COMMON_LAYERS )
.default_value( std::string() )
.help( UTF8STDSTR(
_( "Layers to include on each plot, comma separated list of untranslated "
"layer names to include such as "
"F.Cu,B.Cu" ) ) )
.metavar( "COMMON_LAYER_LIST" );
m_argParser.add_argument( ARG_MODE_SINGLE )
.help( UTF8STDSTR(
_( "Generates a single file with the output arg path acting as the complete "
@ -133,10 +124,6 @@ CLI::PCB_EXPORT_SVG_COMMAND::PCB_EXPORT_SVG_COMMAND() :
int CLI::PCB_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
{
int baseExit = PCB_EXPORT_BASE_COMMAND::doPerform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_EXPORT_PCB_SVG> svgJob( new JOB_EXPORT_PCB_SVG() );
svgJob->m_mirror = m_argParser.get<bool>( ARG_MIRROR );
@ -179,8 +166,8 @@ int CLI::PCB_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
svgJob->m_plotDrawingSheet = !m_argParser.get<bool>( ARG_EXCLUDE_DRAWING_SHEET );
svgJob->SetVarOverrides( m_argDefineVars );
wxString layers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
svgJob->m_plotOnAllLayersSequence = convertLayerStringList( layers );
svgJob->m_argLayers = From_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
svgJob->m_argCommonLayers = From_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
if( !wxFile::Exists( svgJob->m_filename ) )
{
@ -188,8 +175,6 @@ int CLI::PCB_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
svgJob->m_plotLayerSequence = m_selectedLayers;
if( m_argParser.get<bool>( ARG_MODE_MULTI ) )
svgJob->m_genMode = JOB_EXPORT_PCB_SVG::GEN_MODE::MULTI;
else if( m_argParser.get<bool>( ARG_MODE_SINGLE ) )
@ -205,7 +190,5 @@ int CLI::PCB_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
_( "The new behavior will match --mode-multi" ) );
}
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, svgJob.get() );
return exitCode;
return aKiway.ProcessJob( KIWAY::FACE_PCB, svgJob.get() );
}

View File

@ -330,6 +330,75 @@ BOARD* PCBNEW_JOBS_HANDLER::getBoard( const wxString& aPath )
}
LSEQ PCBNEW_JOBS_HANDLER::convertLayerArg( wxString& aLayerString, BOARD* aBoard ) const
{
std::map<wxString, LSET> layerMasks;
std::map<wxString, LSET> layerGuiMasks;
// Build list of layer names and their layer mask:
for( PCB_LAYER_ID layer : LSET::AllLayersMask().Seq() )
{
// Add layer name used in pcb files
layerMasks[ LSET::Name( layer ) ] = LSET( { layer } );
// Add layer name using GUI canonical layer name
layerGuiMasks[ LayerName( layer ) ] = LSET( { layer } );
// Add user layer name
if( aBoard )
layerGuiMasks[ aBoard->GetLayerName( layer ) ] = LSET( { layer } );
}
// Add list of grouped layer names used in pcb files
layerMasks[ wxT( "*" ) ] = LSET::AllLayersMask();
layerMasks[ wxT( "*.Cu" ) ] = LSET::AllCuMask();
layerMasks[ wxT( "*In.Cu" ) ] = LSET::InternalCuMask();
layerMasks[ wxT( "F&B.Cu" ) ] = LSET( { F_Cu, B_Cu } );
layerMasks[ wxT( "*.Adhes" ) ] = LSET( { B_Adhes, F_Adhes } );
layerMasks[ wxT( "*.Paste" ) ] = LSET( { B_Paste, F_Paste } );
layerMasks[ wxT( "*.Mask" ) ] = LSET( { B_Mask, F_Mask } );
layerMasks[ wxT( "*.SilkS" ) ] = LSET( { B_SilkS, F_SilkS } );
layerMasks[ wxT( "*.Fab" ) ] = LSET( { B_Fab, F_Fab } );
layerMasks[ wxT( "*.CrtYd" ) ] = LSET( { B_CrtYd, F_CrtYd } );
// Add list of grouped layer names using GUI canonical layer names
layerGuiMasks[ wxT( "*.Adhesive" ) ] = LSET( { B_Adhes, F_Adhes } );
layerGuiMasks[ wxT( "*.Silkscreen" ) ] = LSET( { B_SilkS, F_SilkS } );
layerGuiMasks[ wxT( "*.Courtyard" ) ] = LSET( { B_CrtYd, F_CrtYd } );
LSEQ layerMask;
if( !aLayerString.IsEmpty() )
{
wxStringTokenizer layerTokens( aLayerString, "," );
while( layerTokens.HasMoreTokens() )
{
std::string token = TO_UTF8( layerTokens.GetNextToken() );
// Search for a layer name in canonical layer name used in .kicad_pcb files:
if( layerMasks.count( token ) )
{
for( PCB_LAYER_ID layer : layerMasks.at( token ).Seq() )
layerMask.push_back( layer );
}
// Search for a layer name in canonical layer name used in GUI (not translated):
else if( layerGuiMasks.count( token ) )
{
for( PCB_LAYER_ID layer : layerGuiMasks.at( token ).Seq() )
layerMask.push_back( layer );
}
else
{
m_reporter->Report( wxString::Format( _( "Invalid layer name \"%s\"\n" ),
token ) );
}
}
}
return layerMask;
}
int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob )
{
JOB_EXPORT_PCB_3D* aStepJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( aJob );
@ -753,6 +822,14 @@ int PCBNEW_JOBS_HANDLER::JobExportSvg( JOB* aJob )
loadOverrideDrawingSheet( brd, aSvgJob->m_drawingSheet );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
brd->SynchronizeProperties();
aSvgJob->m_plotLayerSequence = convertLayerArg( aSvgJob->m_argLayers, brd );
aSvgJob->m_plotOnAllLayersSequence = convertLayerArg( aSvgJob->m_argCommonLayers, brd );
if( aSvgJob->m_plotLayerSequence.size() < 1 )
{
m_reporter->Report( _( "At least one layer must be specified\n" ), RPT_SEVERITY_ERROR );
return CLI::EXIT_CODES::ERR_ARGS;
}
PCB_PLOT_PARAMS plotOpts;
PCB_PLOTTER::PlotJobToPlotOpts( plotOpts, aSvgJob, *m_reporter );
@ -802,7 +879,14 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob )
loadOverrideDrawingSheet( brd, aDxfJob->m_drawingSheet );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
brd->SynchronizeProperties();
aDxfJob->m_plotLayerSequence = convertLayerArg( aDxfJob->m_argLayers, brd );
aDxfJob->m_plotOnAllLayersSequence = convertLayerArg( aDxfJob->m_argCommonLayers, brd );
if( aDxfJob->m_plotLayerSequence.size() < 1 )
{
m_reporter->Report( _( "At least one layer must be specified\n" ), RPT_SEVERITY_ERROR );
return CLI::EXIT_CODES::ERR_ARGS;
}
if( aDxfJob->m_genMode == JOB_EXPORT_PCB_DXF::GEN_MODE::SINGLE )
{
@ -872,6 +956,14 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob )
loadOverrideDrawingSheet( brd, aPdfJob->m_drawingSheet );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
brd->SynchronizeProperties();
aPdfJob->m_plotLayerSequence = convertLayerArg( aPdfJob->m_argLayers, brd );
aPdfJob->m_plotOnAllLayersSequence = convertLayerArg( aPdfJob->m_argCommonLayers, brd );
if( aPdfJob->m_plotLayerSequence.size() < 1 )
{
m_reporter->Report( _( "At least one layer must be specified\n" ), RPT_SEVERITY_ERROR );
return CLI::EXIT_CODES::ERR_ARGS;
}
if( aPdfJob->m_pdfGenMode == JOB_EXPORT_PCB_PDF::GEN_MODE::ALL_LAYERS_ONE_FILE
&& aPdfJob->GetConfiguredOutputPath().IsEmpty() )
@ -960,6 +1052,13 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob )
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
brd->SynchronizeProperties();
if( !aGerberJob->m_argLayers.empty() )
aGerberJob->m_plotLayerSequence = convertLayerArg( aGerberJob->m_argLayers, nullptr );
else
aGerberJob->m_plotLayerSequence = LSET::AllLayersMask().SeqStackupForPlotting();
aGerberJob->m_plotOnAllLayersSequence = convertLayerArg( aGerberJob->m_argCommonLayers, brd );
PCB_PLOT_PARAMS boardPlotOptions = brd->GetPlotOptions();
GERBER_JOBFILE_WRITER jobfile_writer( brd );
@ -1177,6 +1276,14 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob )
aJob->SetTitleBlock( brd->GetTitleBlock() );
brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
brd->SynchronizeProperties();
aGerberJob->m_plotLayerSequence = convertLayerArg( aGerberJob->m_argLayers, brd );
aGerberJob->m_plotOnAllLayersSequence = convertLayerArg( aGerberJob->m_argCommonLayers, brd );
if( aGerberJob->m_plotLayerSequence.size() < 1 )
{
m_reporter->Report( _( "At least one layer must be specified\n" ), RPT_SEVERITY_ERROR );
return CLI::EXIT_CODES::ERR_ARGS;
}
if( aGerberJob->GetConfiguredOutputPath().IsEmpty() )
{
@ -1654,6 +1761,11 @@ int PCBNEW_JOBS_HANDLER::JobExportFpSvg( JOB* aJob )
PCB_IO_KICAD_SEXPR pcb_io( CTL_FOR_LIBRARY );
FP_CACHE fpLib( &pcb_io, svgJob->m_libraryPath );
if( !svgJob->m_argLayers.empty() )
svgJob->m_plotLayerSequence = convertLayerArg( svgJob->m_argLayers, nullptr );
else
svgJob->m_plotLayerSequence = LSET::AllLayersMask().SeqStackupForPlotting();
try
{
fpLib.Load();

View File

@ -55,6 +55,8 @@ public:
private:
BOARD* getBoard( const wxString& aPath = wxEmptyString );
LSEQ convertLayerArg( wxString& aLayerString, BOARD* aBoard ) const;
void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts,
JOB_EXPORT_PCB_GERBER* aJob );
void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts,