Initial jobset creation and running within the CLI and GUI.

Incomplete, just pushing this before feature freeze, much fixing left
This commit is contained in:
Marek Roszko 2024-07-15 18:20:13 -04:00
parent 6255586d5b
commit d74caace0a
150 changed files with 9950 additions and 3247 deletions

View File

@ -61,12 +61,16 @@ set( KICOMMON_SRCS
gal/color4d.cpp
# Jobs
jobs/job.cpp
jobs/job_registry.cpp
jobs/jobs_output_archive.cpp
jobs/jobs_output_folder.cpp
jobs/job_export_pcb_drill.cpp
jobs/job_export_pcb_dxf.cpp
jobs/job_export_pcb_gerber.cpp
jobs/job_export_pcb_gerbers.cpp
jobs/job_export_pcb_ipc2581.cpp
jobs/job_export_pcb_pdf.cpp
jobs/job_export_pcb_plot.cpp
jobs/job_export_pcb_pos.cpp
jobs/job_export_pcb_svg.cpp
jobs/job_export_pcb_gencad.cpp
@ -75,6 +79,7 @@ set( KICOMMON_SRCS
jobs/job_export_sch_netlist.cpp
jobs/job_export_sch_plot.cpp
jobs/job_export_sch_pythonbom.cpp
jobs/jobset.cpp
jobs/job_fp_export_svg.cpp
jobs/job_fp_upgrade.cpp
jobs/job_pcb_render.cpp

View File

@ -120,6 +120,7 @@ static const wxChar ResolveTextRecursionDepth[] = wxT( "ResolveTextRecursionDept
static const wxChar EnableExtensionSnaps[] = wxT( "EnableExtensionSnaps" );
static const wxChar EnableSnapAnchorsDebug[] = wxT( "EnableSnapAnchorsDebug" );
static const wxChar EnableODB[] = wxT( "EnableODB" );
static const wxChar EnableJobset[] = wxT( "EnableJobset" );
} // namespace KEYS
@ -248,6 +249,7 @@ ADVANCED_CFG::ADVANCED_CFG()
m_EnableDesignBlocks = false;
m_EnableGenerators = false;
m_EnableGit = false;
m_EnableJobset = false;
m_EnableLibWithText = false;
m_EnableLibDir = false;
@ -479,6 +481,9 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableGit,
&m_EnableGit, m_EnableGit ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableJobset,
&m_EnableJobset, m_EnableJobset ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableLibWithText,
&m_EnableLibWithText, m_EnableLibWithText ) );
@ -528,7 +533,7 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::ResolveTextRecursionDepth,
&m_ResolveTextRecursionDepth,
m_ResolveTextRecursionDepth, 0, 10 ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableODB,
&m_EnableODB, m_EnableODB ) );

View File

@ -274,7 +274,7 @@ EDA_BASE_FRAME::~EDA_BASE_FRAME()
Disconnect( ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
wxTimerEventHandler( EDA_BASE_FRAME::onAutoSaveTimer ) );
Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) );
delete m_autoSaveTimer;
delete m_fileHistory;

View File

@ -39,6 +39,10 @@
#include <launch_ext.h>
#include "wx/tokenzr.h"
#include <wx/wfstream.h>
#include <wx/fs_zip.h>
#include <wx/zipstrm.h>
#include <filesystem>
void QuoteString( wxString& string )
@ -369,3 +373,99 @@ bool RmDirRecursive( const wxString& aFileName, wxString* aErrors )
return true;
}
bool CopyDirectory( const wxString& aSourceDir, const wxString& aDestDir, wxString& aErrors )
{
wxDir dir( aSourceDir );
if( !dir.IsOpened() )
{
aErrors += wxString::Format( _( "Could not open source directory: %s" ), aSourceDir );
aErrors += wxT( "\n" );
return false;
}
if( !wxFileName::Mkdir( aDestDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
{
aErrors += wxString::Format( _( "Could not create destination directory: %s" ), aDestDir );
aErrors += wxT( "\n" );
return false;
}
wxString filename;
bool cont = dir.GetFirst( &filename );
while( cont )
{
wxString sourcePath = aSourceDir + wxFileName::GetPathSeparator() + filename;
wxString destPath = aDestDir + wxFileName::GetPathSeparator() + filename;
if( wxFileName::DirExists( sourcePath ) )
{
// Recursively copy subdirectories
if( !CopyDirectory( sourcePath, destPath, aErrors ) )
{
return false;
}
}
else
{
// Copy files
if( !wxCopyFile( sourcePath, destPath ) )
{
aErrors += wxString::Format( _( "Could not copy file: %s to %s" ), sourcePath, destPath );
return false;
}
}
cont = dir.GetNext( &filename );
}
return true;
}
bool AddDirectoryToZip( wxZipOutputStream& aZip, const wxString& aSourceDir, wxString& aErrors,
const wxString& aParentDir )
{
wxDir dir( aSourceDir );
if( !dir.IsOpened() )
{
aErrors += wxString::Format( _( "Could not open source directory: %s" ), aSourceDir );
aErrors += "\n";
return false;
}
wxString filename;
bool cont = dir.GetFirst( &filename );
while( cont )
{
wxString sourcePath = aSourceDir + wxFileName::GetPathSeparator() + filename;
wxString zipPath = aParentDir + filename;
if( wxFileName::DirExists( sourcePath ) )
{
// Add directory entry to the ZIP file
aZip.PutNextDirEntry( zipPath + "/" );
// Recursively add subdirectories
if( !AddDirectoryToZip( aZip, sourcePath, aErrors, zipPath + "/" ) )
{
return false;
}
}
else
{
// Add file entry to the ZIP file
aZip.PutNextEntry( zipPath );
wxFFileInputStream fileStream( sourcePath );
if( !fileStream.IsOk() )
{
aErrors += wxString::Format( _( "Could not read file: %s" ), sourcePath );
return false;
}
aZip.Write( fileStream );
}
cont = dir.GetNext( &filename );
}
return true;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -19,10 +19,152 @@
*/
#include <jobs/job.h>
#include <wx/filename.h>
JOB::JOB( const std::string& aType, bool aIsCli ) :
JOB::JOB( const std::string& aType, bool aOutputIsDirectory, bool aIsCli ) :
m_type( aType ),
m_isCli( aIsCli ),
m_varOverrides()
m_varOverrides(),
m_tempOutputDirectory(),
m_outputPath(),
m_outputPathIsDirectory( aOutputIsDirectory )
{
if( m_outputPathIsDirectory )
{
m_params.emplace_back(
new JOB_PARAM<wxString>( "output_dir", &m_outputPath, m_outputPath ) );
}
else
{
m_params.emplace_back(
new JOB_PARAM<wxString>( "output_filename", &m_outputPath, m_outputPath ) );
}
}
JOB::~JOB()
{
for( JOB_PARAM_BASE* param : m_params )
delete param;
m_params.clear();
}
void JOB::FromJson( const nlohmann::json& j )
{
for( JOB_PARAM_BASE* param : m_params )
param->FromJson( j );
}
void JOB::ToJson( nlohmann::json& j ) const
{
for( JOB_PARAM_BASE* param : m_params )
param->ToJson( j );
}
wxString JOB::GetDescription()
{
return wxEmptyString;
}
void JOB::SetTempOutputDirectory( const wxString& aBase )
{
m_tempOutputDirectory = aBase;
}
void PrependDirectoryToPath( wxFileName& aFileName, const wxString aDirPath )
{
wxFileName fn( aDirPath + wxFileName::GetPathSeparator() + aFileName.GetFullPath() );
aFileName = fn;
}
wxString JOB::GetFullOutputPath() const
{
if( !m_tempOutputDirectory.IsEmpty() )
{
if( m_outputPathIsDirectory )
{
wxFileName fn( m_outputPath );
if( fn.IsAbsolute() || m_outputPath.IsEmpty() )
{
fn.AssignDir( m_tempOutputDirectory );
}
else
{
PrependDirectoryToPath( fn, m_tempOutputDirectory );
}
return fn.GetFullPath();
}
else
{
wxFileName fn( m_outputPath );
if( fn.IsAbsolute() || m_outputPath.IsEmpty() )
{
// uhhh, do nothing
// either its a full path passed by cli, so we return as-is
// or it's a empty path from either...in which case things will fail but who cares
// the job handlers should have fixed empty paths
}
else
{
PrependDirectoryToPath( fn, m_tempOutputDirectory );
}
return fn.GetFullPath();
}
}
return m_outputPath;
}
void JOB::SetOutputPath( const wxString& aPath )
{
m_outputPath = aPath;
}
bool JOB::OutputPathFullSpecified() const
{
if( m_outputPath.IsEmpty() )
{
return false;
}
wxFileName fn( m_outputPath );
if( m_outputPathIsDirectory )
{
return fn.IsDir();
}
else
{
return !fn.IsDir();
}
}
KICOMMON_API void to_json( nlohmann::json& j, const JOB& f )
{
f.ToJson( j );
}
KICOMMON_API void from_json( const nlohmann::json& j, JOB& f )
{
f.FromJson( j );
}
JOB_PARAM_BASE::JOB_PARAM_BASE( const std::string& aJsonPath ) :
m_jsonPath( aJsonPath )
{
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -18,12 +18,55 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_H
#define JOB_H
#pragma once
#include <kicommon.h>
#include <map>
#include <wx/string.h>
#include <settings/json_settings.h>
class KICOMMON_API JOB_PARAM_BASE
{
public:
JOB_PARAM_BASE( const std::string& aJsonPath );
virtual ~JOB_PARAM_BASE() = default;
virtual void FromJson( const nlohmann::json& j ) const = 0;
virtual void ToJson( nlohmann::json& j ) = 0;
protected:
std::string m_jsonPath;
};
template <typename ValueType>
class JOB_PARAM : public JOB_PARAM_BASE
{
public:
JOB_PARAM( const std::string& aJsonPath, ValueType* aPtr,
ValueType aDefault ) :
JOB_PARAM_BASE( aJsonPath ), m_ptr( aPtr ), m_default( aDefault )
{
}
virtual void FromJson( const nlohmann::json& j ) const override
{
*m_ptr = j.value( m_jsonPath, m_default );
}
virtual void ToJson( nlohmann::json& j ) override { j[m_jsonPath] = *m_ptr; }
protected:
ValueType* m_ptr;
ValueType m_default;
};
struct KICOMMON_API JOB_OUTPUT
{
wxString m_outputPath;
};
/**
* An simple container class that lets us dispatch output jobs to kifaces
@ -31,9 +74,9 @@
class KICOMMON_API JOB
{
public:
JOB( const std::string& aType, bool aIsCli );
JOB( const std::string& aType, bool aOutputIsDirectory, bool aIsCli );
virtual ~JOB() {}
virtual ~JOB();
const std::string& GetType() const { return m_type; };
bool IsCli() const { return m_isCli; };
@ -45,10 +88,51 @@ public:
m_varOverrides = aVarOverrides;
}
virtual void FromJson( const nlohmann::json& j );
virtual void ToJson( nlohmann::json& j ) const;
virtual wxString GetDescription();
const std::vector<JOB_PARAM_BASE*>& GetParams() {
return m_params;
}
void ClearExistingOutputs() {
m_outputs.clear();
}
const std::vector<JOB_OUTPUT>& GetOutputs() {
return m_outputs;
}
void AddOutput( wxString aOutputPath ) {
m_outputs.emplace_back( aOutputPath );
}
void SetTempOutputDirectory( const wxString& aBase );
void SetOutputPath( const wxString& aPath );
wxString GetOutputPath() const { return m_outputPath; }
wxString GetFullOutputPath() const;
bool OutputPathFullSpecified() const;
protected:
std::string m_type;
bool m_isCli;
std::map<wxString, wxString> m_varOverrides;
wxString m_tempOutputDirectory;
wxString m_outputPath;
bool m_outputPathIsDirectory;
std::vector<JOB_PARAM_BASE*> m_params;
std::vector<JOB_OUTPUT> m_outputs;
};
#endif
KICOMMON_API void from_json( const nlohmann::json& j, JOB& f );
KICOMMON_API void to_json( nlohmann::json& j, const JOB& f );

View File

@ -23,6 +23,7 @@
#include <reporter.h>
#include <wx/debug.h>
class wxWindow;
JOB_DISPATCHER::JOB_DISPATCHER( KIWAY* aKiway ) :
m_kiway( aKiway )
@ -33,14 +34,18 @@ JOB_DISPATCHER::JOB_DISPATCHER( KIWAY* aKiway ) :
void JOB_DISPATCHER::Register( const std::string& aJobTypeName,
std::function<int( JOB* job )> aHandler )
std::function<int( JOB* job )> aHandler,
std::function<bool( JOB* aJob, wxWindow* aParent )> aConfigHandler )
{
m_jobHandlers.emplace( aJobTypeName, aHandler );
m_jobConfigHandlers.emplace( aJobTypeName, aConfigHandler );
}
int JOB_DISPATCHER::RunJob( JOB* job )
{
job->ClearExistingOutputs();
if( m_jobHandlers.count( job->GetType() ) )
{
return m_jobHandlers[job->GetType()]( job );
@ -50,6 +55,17 @@ int JOB_DISPATCHER::RunJob( JOB* job )
}
bool JOB_DISPATCHER::HandleJobConfig( JOB* job, wxWindow* aParent )
{
if( m_jobConfigHandlers.count( job->GetType() ) )
{
return m_jobConfigHandlers[job->GetType()]( job, aParent );
}
return false;
}
void JOB_DISPATCHER::SetReporter( REPORTER* aReporter )
{
wxCHECK( aReporter != nullptr, /*void*/ );

View File

@ -30,13 +30,16 @@
class KIWAY;
class REPORTER;
class PROGRESS_REPORTER;
class wxWindow;
class JOB_DISPATCHER
{
public:
JOB_DISPATCHER( KIWAY* aKiway );
void Register( const std::string& aJobTypeName, std::function<int( JOB* job )> aHandler );
int RunJob( JOB* job );
void Register( const std::string& aJobTypeName, std::function<int( JOB* job )> aHandler,
std::function<bool( JOB* job, wxWindow* aParent )> aConfigHandler );
int RunJob( JOB* aJob );
bool HandleJobConfig( JOB* aJob, wxWindow* aParent );
void SetReporter( REPORTER* aReporter );
void SetProgressReporter( PROGRESS_REPORTER* aReporter );
@ -47,6 +50,8 @@ protected:
private:
std::map<std::string, std::function<int( JOB* job )>> m_jobHandlers;
std::map<std::string, std::function<bool( JOB* job, wxWindow* aParent )>>
m_jobConfigHandlers;
};

View File

@ -19,7 +19,27 @@
*/
#include <jobs/job_export_pcb_3d.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_3D::FORMAT,
{
{ JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN, nullptr },
{ JOB_EXPORT_PCB_3D::FORMAT::STEP, "step" },
{ JOB_EXPORT_PCB_3D::FORMAT::BREP, "brep" },
{ JOB_EXPORT_PCB_3D::FORMAT::GLB, "step" },
{ JOB_EXPORT_PCB_3D::FORMAT::VRML, "vrml" },
{ JOB_EXPORT_PCB_3D::FORMAT::XAO, "xao" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_3D::VRML_UNITS,
{
{ JOB_EXPORT_PCB_3D::VRML_UNITS::INCHES, "in" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::METERS, "m" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::MILLIMETERS, "mm" },
{ JOB_EXPORT_PCB_3D::VRML_UNITS::TENTHS, "tenths" },
} )
wxString EXPORTER_STEP_PARAMS::GetDefaultExportExtension() const
{
@ -49,7 +69,7 @@ wxString EXPORTER_STEP_PARAMS::GetFormatName() const
JOB_EXPORT_PCB_3D::JOB_EXPORT_PCB_3D( bool aIsCli ) :
JOB( "3d", aIsCli ),
JOB( "3d", false, aIsCli ),
m_hasUserOrigin( false ),
m_filename(),
m_format( JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN ),
@ -57,4 +77,58 @@ JOB_EXPORT_PCB_3D::JOB_EXPORT_PCB_3D( bool aIsCli ) :
m_vrmlModelDir( wxEmptyString ),
m_vrmlRelativePaths( false )
{
m_params.emplace_back(
new JOB_PARAM<bool>( "overwrite", &m_3dparams.m_Overwrite, m_3dparams.m_Overwrite ) );
m_params.emplace_back( new JOB_PARAM<bool>( "use_grid_origin", &m_3dparams.m_UseGridOrigin,
m_3dparams.m_UseGridOrigin ) );
m_params.emplace_back( new JOB_PARAM<bool>( "use_drill_origin", &m_3dparams.m_UseDrillOrigin,
m_3dparams.m_UseDrillOrigin ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "board_only", &m_3dparams.m_BoardOnly, m_3dparams.m_BoardOnly ) );
m_params.emplace_back( new JOB_PARAM<bool>( "include_unspecified",
&m_3dparams.m_IncludeUnspecified,
m_3dparams.m_IncludeUnspecified ) );
m_params.emplace_back( new JOB_PARAM<bool>( "include_dnp", &m_3dparams.m_IncludeDNP,
m_3dparams.m_IncludeDNP ) );
m_params.emplace_back( new JOB_PARAM<bool>( "subst_models", &m_3dparams.m_SubstModels,
m_3dparams.m_SubstModels ) );
m_params.emplace_back( new JOB_PARAM<bool>( "optimize_step", &m_3dparams.m_OptimizeStep,
m_3dparams.m_OptimizeStep ) );
m_params.emplace_back( new JOB_PARAM<double>( "user_origin.x", &m_3dparams.m_Origin.x,
m_3dparams.m_Origin.x ) );
m_params.emplace_back( new JOB_PARAM<double>( "user_origin.y", &m_3dparams.m_Origin.y,
m_3dparams.m_Origin.y ) );
m_params.emplace_back( new JOB_PARAM<double>( "board_outlines_chaining_epsilon",
&m_3dparams.m_BoardOutlinesChainingEpsilon,
m_3dparams.m_BoardOutlinesChainingEpsilon ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_board_body", &m_3dparams.m_ExportBoardBody,
m_3dparams.m_ExportBoardBody ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_components", &m_3dparams.m_ExportComponents,
m_3dparams.m_ExportComponents ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_tracks", &m_3dparams.m_ExportTracksVias,
m_3dparams.m_ExportTracksVias ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_pads", &m_3dparams.m_ExportPads,
m_3dparams.m_ExportPads ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_zones", &m_3dparams.m_ExportZones,
m_3dparams.m_ExportZones ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_inner_copper",
&m_3dparams.m_ExportInnerCopper,
m_3dparams.m_ExportInnerCopper ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_silkscreen", &m_3dparams.m_ExportSilkscreen,
m_3dparams.m_ExportInnerCopper ) );
m_params.emplace_back( new JOB_PARAM<bool>( "export_soldermask", &m_3dparams.m_ExportSoldermask,
m_3dparams.m_ExportSoldermask ) );
m_params.emplace_back( new JOB_PARAM<bool>( "fuse_shapes", &m_3dparams.m_FuseShapes,
m_3dparams.m_FuseShapes ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "vrml_model_dir", &m_vrmlModelDir, m_vrmlModelDir ) );
m_params.emplace_back( new JOB_PARAM<bool>( "vrml_relative_paths", &m_vrmlRelativePaths,
m_vrmlRelativePaths ) );
}
wxString JOB_EXPORT_PCB_3D::GetDescription()
{
return wxString::Format( _( "3D model export" ) );
}
REGISTER_JOB( pcb_export_3d, _HKI( "PCB: Export 3D Model" ), KIWAY::FACE_PCB, JOB_EXPORT_PCB_3D );

View File

@ -53,7 +53,8 @@ public:
m_ExportSoldermask( false ),
m_FuseShapes( false ),
m_OptimizeStep( true ),
m_Format( FORMAT::STEP )
m_Format( FORMAT::STEP ),
m_OutputFile()
{};
enum class FORMAT
@ -64,7 +65,6 @@ public:
GLB
};
wxString m_OutputFile;
wxString m_NetFilter;
wxString m_ComponentFilter;
@ -89,6 +89,7 @@ public:
bool m_FuseShapes;
bool m_OptimizeStep;
FORMAT m_Format;
wxString m_OutputFile;
wxString GetDefaultExportExtension() const;
wxString GetFormatName() const;
@ -99,6 +100,7 @@ class KICOMMON_API JOB_EXPORT_PCB_3D : public JOB
{
public:
JOB_EXPORT_PCB_3D( bool aIsCli );
wxString GetDescription() override;
enum class FORMAT
{

View File

@ -19,11 +19,47 @@
*/
#include <jobs/job_export_pcb_drill.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::DRILL_FORMAT,
{
{ JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::EXCELLON, "excellon" },
{ JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::GERBER, "gerber" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN,
{
{ JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABS, "abs" },
{ JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::PLOT, "plot" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::DRILL_UNITS,
{
{ JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCHES, "in" },
{ JOB_EXPORT_PCB_DRILL::DRILL_UNITS::MILLIMETERS, "mm" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT,
{
{ JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::DECIMAL, "decimal" },
{ JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::SUPPRESS_LEADING, "surpress_leading" },
{ JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::SUPPRESS_TRAILING, "surpress_trailing" },
{ JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::KEEP_ZEROS, "keep_zeros" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DRILL::MAP_FORMAT,
{
{ JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF, "dxf" },
{ JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2, "gerberx2" },
{ JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF, "pdf" },
{ JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT, "postscript" },
{ JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG, "svg" },
} )
JOB_EXPORT_PCB_DRILL::JOB_EXPORT_PCB_DRILL( bool aIsCli ) :
JOB( "drill", aIsCli ),
JOB( "drill", true, aIsCli ),
m_filename(),
m_outputDir(),
m_excellonMirrorY( false ),
m_excellonMinimalHeader( false ),
m_excellonCombinePTHNPTH( true ),
@ -36,4 +72,56 @@ JOB_EXPORT_PCB_DRILL::JOB_EXPORT_PCB_DRILL( bool aIsCli ) :
m_gerberPrecision( 5 ),
m_generateMap( false )
{
}
m_params.emplace_back( new JOB_PARAM<bool>( "excellon.mirror_y",
&m_excellonMirrorY,
m_excellonMirrorY ) );
m_params.emplace_back( new JOB_PARAM<bool>( "excellon.minimal_header",
&m_excellonMinimalHeader,
m_excellonMinimalHeader ) );
m_params.emplace_back( new JOB_PARAM<bool>( "excellon.combine_pth_npth",
&m_excellonCombinePTHNPTH,
m_excellonCombinePTHNPTH ) );
m_params.emplace_back( new JOB_PARAM<bool>( "excellon.oval_drill_route",
&m_excellonOvalDrillRoute,
m_excellonOvalDrillRoute ) );
m_params.emplace_back( new JOB_PARAM<DRILL_FORMAT>( "format",
&m_format,
m_format ) );
m_params.emplace_back( new JOB_PARAM<DRILL_ORIGIN>( "drill_origin",
&m_drillOrigin,
m_drillOrigin ) );
m_params.emplace_back( new JOB_PARAM<DRILL_UNITS>( "units",
&m_drillUnits,
m_drillUnits ) );
m_params.emplace_back( new JOB_PARAM<ZEROS_FORMAT>( "zero_format",
&m_zeroFormat,
m_zeroFormat ) );
m_params.emplace_back( new JOB_PARAM<bool>( "generate_map",
&m_generateMap,
m_generateMap ) );
m_params.emplace_back( new JOB_PARAM<MAP_FORMAT>( "map_format",
&m_mapFormat,
m_mapFormat ) );
m_params.emplace_back( new JOB_PARAM<int>( "gerber_precision",
&m_gerberPrecision,
m_gerberPrecision ) );
}
wxString JOB_EXPORT_PCB_DRILL::GetDescription()
{
return wxString::Format( _( "Drill data export" ), m_format );
}
REGISTER_JOB( pcb_export_drill, _HKI( "PCB: Export drill data" ), KIWAY::FACE_PCB,
JOB_EXPORT_PCB_DRILL );

View File

@ -31,8 +31,9 @@ class KICOMMON_API JOB_EXPORT_PCB_DRILL : public JOB
public:
JOB_EXPORT_PCB_DRILL( bool aIsCli );
wxString GetDescription() override;
wxString m_filename;
wxString m_outputDir;
bool m_excellonMirrorY;
bool m_excellonMinimalHeader;

View File

@ -19,19 +19,43 @@
*/
#include <jobs/job_export_pcb_dxf.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_DXF::DXF_UNITS,
{
{ JOB_EXPORT_PCB_DXF::DXF_UNITS::INCHES, "in" },
{ JOB_EXPORT_PCB_DXF::DXF_UNITS::MILLIMETERS, "mm" },
} )
JOB_EXPORT_PCB_DXF::JOB_EXPORT_PCB_DXF( bool aIsCli ) :
JOB( "dxf", aIsCli ),
m_filename(),
m_outputFile(),
m_drawingSheet(),
m_plotFootprintValues( true ),
m_plotRefDes( true ),
JOB_EXPORT_PCB_PLOT( JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::DXF, "dxf", false, aIsCli ),
m_plotGraphicItemsUsingContours( true ),
m_useDrillOrigin( false ),
m_plotBorderTitleBlocks( false ),
m_dxfUnits( DXF_UNITS::INCHES ),
m_printMaskLayer()
m_dxfUnits( DXF_UNITS::INCHES )
{
}
m_plotDrawingSheet = false;
m_params.emplace_back(
new JOB_PARAM<wxString>( "drawing_sheet", &m_drawingSheet, m_drawingSheet ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "plot_footprint_values", &m_plotFootprintValues, m_plotFootprintValues ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_ref_des", &m_plotRefDes, m_plotRefDes ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_graphic_items_using_contours", &m_plotGraphicItemsUsingContours,
m_plotGraphicItemsUsingContours ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "use_drill_origin", &m_useDrillOrigin, m_useDrillOrigin ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_border_title_blocks", &m_plotDrawingSheet,
m_plotDrawingSheet ) );
m_params.emplace_back( new JOB_PARAM<DXF_UNITS>( "units", &m_dxfUnits, m_dxfUnits ) );
m_params.emplace_back(
new JOB_PARAM<LSEQ>( "layers", &m_printMaskLayer, m_printMaskLayer ) );
}
wxString JOB_EXPORT_PCB_DXF::GetDescription()
{
return wxString::Format( _( "PCB DXF export" ) );
}
REGISTER_JOB( pcb_export_dxf, _HKI( "PCB: Export DXF" ), KIWAY::FACE_PCB, JOB_EXPORT_PCB_DXF );

View File

@ -25,12 +25,14 @@
#include <layer_ids.h>
#include <lseq.h>
#include <wx/string.h>
#include <jobs/job_export_pcb_plot.h>
#include "job.h"
class KICOMMON_API JOB_EXPORT_PCB_DXF : public JOB
class KICOMMON_API JOB_EXPORT_PCB_DXF : public JOB_EXPORT_PCB_PLOT
{
public:
JOB_EXPORT_PCB_DXF( bool aIsCli );
wxString GetDescription() override;
enum class DXF_UNITS
{
@ -38,18 +40,9 @@ public:
MILLIMETERS
};
wxString m_filename;
wxString m_outputFile;
wxString m_drawingSheet;
bool m_plotFootprintValues;
bool m_plotRefDes;
bool m_plotGraphicItemsUsingContours;
bool m_useDrillOrigin;
bool m_plotBorderTitleBlocks;
DXF_UNITS m_dxfUnits;
LSEQ m_printMaskLayer;
};
#endif

View File

@ -22,7 +22,7 @@
JOB_EXPORT_PCB_GENCAD::JOB_EXPORT_PCB_GENCAD( bool aIsCli ) :
JOB( "gencad", aIsCli ),
JOB( "gencad", false, aIsCli ),
m_flipBottomPads( false ),
m_useIndividualShapes( false ),
m_storeOriginCoords( false ),

View File

@ -31,8 +31,6 @@ class KICOMMON_API JOB_EXPORT_PCB_GENCAD : public JOB
{
public:
JOB_EXPORT_PCB_GENCAD( bool aIsCli );
wxString m_outputFile;
wxString m_filename;
bool m_flipBottomPads;

View File

@ -19,29 +19,65 @@
*/
#include <jobs/job_export_pcb_gerber.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
JOB_EXPORT_PCB_GERBER::JOB_EXPORT_PCB_GERBER( const std::string& aType, bool aIsCli ) :
JOB( aType, aIsCli ),
m_filename(),
m_outputFile(),
m_drawingSheet(),
m_plotFootprintValues( true ),
m_plotRefDes( true ),
m_plotBorderTitleBlocks( false ),
JOB_EXPORT_PCB_PLOT( JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::GERBER, aType, false, aIsCli ),
m_subtractSolderMaskFromSilk( false ),
m_includeNetlistAttributes( true ),
m_useX2Format( true ),
m_disableApertureMacros( false ),
m_useAuxOrigin( false ),
m_useProtelFileExtension( true ),
m_precision( 5 ),
m_printMaskLayer()
m_precision( 5 )
{
m_plotDrawingSheet = false;
m_params.emplace_back( new JOB_PARAM<wxString>( "drawing_sheet",
&m_drawingSheet,
m_drawingSheet ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_footprint_values",
&m_plotFootprintValues,
m_plotFootprintValues ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_ref_des", &m_plotRefDes, m_plotRefDes ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_drawing_sheet",
&m_plotDrawingSheet,
m_plotDrawingSheet ) );
m_params.emplace_back( new JOB_PARAM<bool>( "subtract_solder_mask_from_silk",
&m_subtractSolderMaskFromSilk,
m_subtractSolderMaskFromSilk ) );
m_params.emplace_back( new JOB_PARAM<bool>( "include_netlist_attributes",
&m_includeNetlistAttributes,
m_includeNetlistAttributes ) );
m_params.emplace_back( new JOB_PARAM<bool>( "use_x2_format", &m_useX2Format, m_useX2Format ) );
m_params.emplace_back( new JOB_PARAM<bool>( "disable_aperture_macros", &m_disableApertureMacros,
m_disableApertureMacros ) );
m_params.emplace_back( new JOB_PARAM<bool>( "use_aux_origin",
&m_useAuxOrigin,
m_useAuxOrigin ) );
m_params.emplace_back( new JOB_PARAM<bool>( "use_protel_file_extension",
&m_useProtelFileExtension,
m_useProtelFileExtension ) );
m_params.emplace_back( new JOB_PARAM<int>( "precision", &m_precision, m_precision ) );
m_params.emplace_back( new JOB_PARAM<LSEQ>( "layers", &m_printMaskLayer, m_printMaskLayer ) );
}
JOB_EXPORT_PCB_GERBER::JOB_EXPORT_PCB_GERBER( bool aIsCli ) :
JOB_EXPORT_PCB_GERBER( "gerber", aIsCli )
{
}
wxString JOB_EXPORT_PCB_GERBER::GetDescription()
{
return wxString::Format( _( "Single gerber export" ) );
}

View File

@ -25,21 +25,15 @@
#include <layer_ids.h>
#include <lseq.h>
#include <wx/string.h>
#include "job.h"
#include <jobs/job_export_pcb_plot.h>
class KICOMMON_API JOB_EXPORT_PCB_GERBER : public JOB
class KICOMMON_API JOB_EXPORT_PCB_GERBER : public JOB_EXPORT_PCB_PLOT
{
public:
JOB_EXPORT_PCB_GERBER( const std::string& aType, bool aIsCli );
JOB_EXPORT_PCB_GERBER( bool aIsCli );
wxString GetDescription() override;
wxString m_filename;
wxString m_outputFile;
wxString m_drawingSheet;
bool m_plotFootprintValues;
bool m_plotRefDes;
bool m_plotBorderTitleBlocks;
bool m_subtractSolderMaskFromSilk;
bool m_includeNetlistAttributes;
bool m_useX2Format;
@ -48,9 +42,6 @@ public:
bool m_useProtelFileExtension;
int m_precision;
LSEQ m_printMaskLayer;
};
#endif

View File

@ -19,7 +19,9 @@
*/
#include <jobs/job_export_pcb_gerbers.h>
#include <jobs/lset_json.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
JOB_EXPORT_PCB_GERBERS::JOB_EXPORT_PCB_GERBERS( bool aIsCli ) :
JOB_EXPORT_PCB_GERBER( "gerbers", aIsCli ),
@ -27,4 +29,22 @@ JOB_EXPORT_PCB_GERBERS::JOB_EXPORT_PCB_GERBERS( bool aIsCli ) :
m_layersIncludeOnAllSet( false ),
m_useBoardPlotParams( false )
{
}
m_params.emplace_back( new JOB_PARAM<bool>( "use_board_plot_params", &m_useBoardPlotParams,
m_useBoardPlotParams ) );
m_params.emplace_back( new JOB_PARAM<bool>( "layers_include_on_all_set", &m_layersIncludeOnAllSet,
m_layersIncludeOnAllSet ) );
m_params.emplace_back( new JOB_PARAM<LSET>( "layers_include_on_all", &m_layersIncludeOnAll,
m_layersIncludeOnAll ) );
}
wxString JOB_EXPORT_PCB_GERBERS::GetDescription()
{
return wxString::Format( _( "Multi gerber export" ) );
}
REGISTER_JOB( pcb_export_gerbers, _HKI( "PCB: Export Gerbers" ), KIWAY::FACE_PCB,
JOB_EXPORT_PCB_GERBERS );

View File

@ -32,6 +32,7 @@ class KICOMMON_API JOB_EXPORT_PCB_GERBERS : public JOB_EXPORT_PCB_GERBER
{
public:
JOB_EXPORT_PCB_GERBERS( bool aIsCli );
wxString GetDescription() override;
LSET m_layersIncludeOnAll;

View File

@ -19,11 +19,25 @@
*/
#include <jobs/job_export_pcb_ipc2581.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
#include <wildcards_and_files_ext.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS,
{
{ JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::INCHES, "in" },
{ JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MILLIMETERS, "mm" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION,
{
{ JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::B, "B" },
{ JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::C, "C" },
} )
JOB_EXPORT_PCB_IPC2581::JOB_EXPORT_PCB_IPC2581( bool aIsCli ) :
JOB( "ipc2581", aIsCli ),
JOB( "ipc2581", false, aIsCli ),
m_filename(),
m_outputFile(),
m_drawingSheet(),
m_units( IPC2581_UNITS::MILLIMETERS ),
m_version( IPC2581_VERSION::C ),
@ -35,4 +49,38 @@ JOB_EXPORT_PCB_IPC2581::JOB_EXPORT_PCB_IPC2581( bool aIsCli ) :
m_colDistPn(),
m_colDist()
{
}
m_params.emplace_back( new JOB_PARAM<wxString>( "drawing_sheet", &m_drawingSheet, m_drawingSheet ) );
m_params.emplace_back( new JOB_PARAM<IPC2581_UNITS>( "units", &m_units, m_units ) );
m_params.emplace_back( new JOB_PARAM<IPC2581_VERSION>( "version", &m_version, m_version ) );
m_params.emplace_back( new JOB_PARAM<int>( "precision", &m_precision, m_precision ) );
m_params.emplace_back( new JOB_PARAM<bool>( "compress", &m_compress, m_compress ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "field_bom_map.internal_id",
&m_colInternalId,
m_colInternalId ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "field_bom_map.mfg_pn",
&m_colMfgPn, m_colMfgPn ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "field_bom_map.mfg", &m_colMfg, m_colMfg ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "field_bom_map.dist_pn",
&m_colDistPn,
m_colDistPn ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "field_bom_map.dist", &m_colDist, m_colDist ) );
}
wxString JOB_EXPORT_PCB_IPC2581::GetDescription()
{
return wxString::Format( _( "IPC2581 export" ) );
}
void JOB_EXPORT_PCB_IPC2581::SetDefaultOutputPath( const wxString& aReferenceName )
{
wxFileName fn = aReferenceName;
fn.SetExt( FILEEXT::Ipc2581FileExtension );
SetOutputPath( fn.GetFullName() );
}
REGISTER_JOB( pcb_export_ipc2581, _HKI( "PCB: Export IPC2581" ), KIWAY::FACE_PCB,
JOB_EXPORT_PCB_IPC2581 );

View File

@ -29,6 +29,9 @@ class KICOMMON_API JOB_EXPORT_PCB_IPC2581 : public JOB
{
public:
JOB_EXPORT_PCB_IPC2581( bool aIsCli );
wxString GetDescription() override;
void SetDefaultOutputPath( const wxString& aReferenceName );
enum class IPC2581_UNITS
{
@ -43,7 +46,6 @@ public:
};
wxString m_filename;
wxString m_outputFile;
wxString m_drawingSheet;
IPC2581_UNITS m_units;

View File

@ -19,25 +19,39 @@
*/
#include <jobs/job_export_pcb_pdf.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
JOB_EXPORT_PCB_PDF::JOB_EXPORT_PCB_PDF( bool aIsCli ) :
JOB( "pdf", aIsCli ),
m_filename(),
m_outputFile(),
m_colorTheme(),
m_drawingSheet(),
m_mirror( false ),
m_blackAndWhite( false ),
m_negative( false ),
m_plotFootprintValues( true ),
m_plotRefDes( true ),
m_plotBorderTitleBlocks( false ),
m_printMaskLayer(),
m_sketchPadsOnFabLayers( false ),
m_hideDNPFPsOnFabLayers( false ),
m_sketchDNPFPsOnFabLayers( true ),
m_crossoutDNPFPsOnFabLayers( true ),
m_drillShapeOption( 2 )
JOB_EXPORT_PCB_PLOT( JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::PDF, "pdf", false, aIsCli )
{
}
m_plotDrawingSheet = false;
m_params.emplace_back( new JOB_PARAM<wxString>( "color_theme", &m_colorTheme, m_colorTheme ) );
m_params.emplace_back(
new JOB_PARAM<wxString>( "drawing_sheet", &m_drawingSheet, m_drawingSheet ) );
m_params.emplace_back( new JOB_PARAM<bool>( "mirror", &m_mirror, m_mirror ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "black_and_white", &m_blackAndWhite, m_blackAndWhite ) );
m_params.emplace_back( new JOB_PARAM<bool>( "negative", &m_negative, m_negative ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_footprint_values", &m_plotFootprintValues,
m_plotFootprintValues ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_ref_des", &m_plotRefDes, m_plotRefDes ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_border_title_blocks", &m_plotDrawingSheet,
m_plotDrawingSheet ) );
m_params.emplace_back( new JOB_PARAM<LSEQ>( "layers", &m_printMaskLayer, m_printMaskLayer ) );
m_params.emplace_back( new JOB_PARAM<bool>(
"sketch_pads_on_fab_layers", &m_sketchPadsOnFabLayers, m_sketchPadsOnFabLayers ) );
m_params.emplace_back(
new JOB_PARAM<int>( "drill_shape", &m_drillShapeOption, m_drillShapeOption ) );
}
wxString JOB_EXPORT_PCB_PDF::GetDescription()
{
return wxString::Format( _( "PCB PDF export" ) );
}
REGISTER_JOB( pcb_export_pdf, _HKI( "PCB: Export PDF" ), KIWAY::FACE_PCB, JOB_EXPORT_PCB_PDF );

View File

@ -26,35 +26,13 @@
#include <layer_ids.h>
#include <lseq.h>
#include <wx/string.h>
#include "job.h"
#include <jobs/job_export_pcb_plot.h>
class KICOMMON_API JOB_EXPORT_PCB_PDF : public JOB
class KICOMMON_API JOB_EXPORT_PCB_PDF : public JOB_EXPORT_PCB_PLOT
{
public:
JOB_EXPORT_PCB_PDF( bool aIsCli );
wxString m_filename;
wxString m_outputFile;
wxString m_colorTheme;
wxString m_drawingSheet;
bool m_mirror;
bool m_blackAndWhite;
bool m_negative;
bool m_plotFootprintValues;
bool m_plotRefDes;
bool m_plotBorderTitleBlocks;
LSEQ m_printMaskLayer;
bool m_sketchPadsOnFabLayers;
bool m_hideDNPFPsOnFabLayers;
bool m_sketchDNPFPsOnFabLayers;
bool m_crossoutDNPFPsOnFabLayers;
// How holes in pads/vias are plotted:
// 0 = no hole, 1 = small shape, 2 = actual shape
int m_drillShapeOption;
wxString GetDescription() override;
};
#endif

View File

@ -0,0 +1,27 @@
#include <jobs/job_export_pcb_plot.h>
JOB_EXPORT_PCB_PLOT::JOB_EXPORT_PCB_PLOT( PLOT_FORMAT aFormat, const std::string& aType,
bool aOutputIsDirectory,
bool aIsCli )
: JOB( aType, aOutputIsDirectory, aIsCli ),
m_plotFormat( aFormat ),
m_filename(),
m_colorTheme(),
m_drawingSheet(),
m_mirror( false ),
m_blackAndWhite( false ),
m_negative( false ),
m_sketchPadsOnFabLayers( false ),
m_hideDNPFPsOnFabLayers( false ),
m_sketchDNPFPsOnFabLayers( true ),
m_crossoutDNPFPsOnFabLayers( true ),
m_plotFootprintValues( true ),
m_plotRefDes( true ),
m_plotDrawingSheet( true ),
m_printMaskLayer(),
m_drillShapeOption( 2 )
{
}

View File

@ -0,0 +1,72 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kicommon.h>
#include <kicommon.h>
#include <layer_ids.h>
#include <lseq.h>
#include <wx/string.h>
#include "job.h"
class KICOMMON_API JOB_EXPORT_PCB_PLOT : public JOB
{
public:
enum class PLOT_FORMAT
{
HPGL,
GERBER,
POST,
DXF,
PDF,
SVG
};
JOB_EXPORT_PCB_PLOT( PLOT_FORMAT aFormat, const std::string& aType, bool aOutputIsDirectory, bool aIsCli );
PLOT_FORMAT m_plotFormat;
wxString m_filename;
wxString m_colorTheme;
wxString m_drawingSheet;
/**
* Common Options
*/
bool m_mirror;
bool m_blackAndWhite;
bool m_negative;
bool m_sketchPadsOnFabLayers;
bool m_hideDNPFPsOnFabLayers;
bool m_sketchDNPFPsOnFabLayers;
bool m_crossoutDNPFPsOnFabLayers;
bool m_plotFootprintValues;
bool m_plotRefDes;
bool m_plotDrawingSheet;
LSEQ m_printMaskLayer;
// How holes in pads/vias are plotted:
// 0 = no hole, 1 = small shape, 2 = actual shape
int m_drillShapeOption;
};

View File

@ -19,20 +19,91 @@
*/
#include <jobs/job_export_pcb_pos.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
#include <wildcards_and_files_ext.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_POS::FORMAT,
{
{ JOB_EXPORT_PCB_POS::FORMAT::ASCII, "ascii" },
{ JOB_EXPORT_PCB_POS::FORMAT::CSV, "csv" },
{ JOB_EXPORT_PCB_POS::FORMAT::GERBER, "gerber" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_POS::SIDE,
{
{ JOB_EXPORT_PCB_POS::SIDE::FRONT, "front" },
{ JOB_EXPORT_PCB_POS::SIDE::BACK, "back" },
{ JOB_EXPORT_PCB_POS::SIDE::BOTH, "both" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_PCB_POS::UNITS,
{
{ JOB_EXPORT_PCB_POS::UNITS::INCHES, "in" },
{ JOB_EXPORT_PCB_POS::UNITS::MILLIMETERS, "mm" },
} )
JOB_EXPORT_PCB_POS::JOB_EXPORT_PCB_POS( bool aIsCli ) :
JOB( "pos", aIsCli ),
JOB( "pos", false, aIsCli ),
m_filename(),
m_outputFile(),
m_useDrillPlaceFileOrigin( true ),
m_smdOnly( false ),
m_excludeFootprintsWithTh( false ),
m_excludeDNP( false ),
m_negateBottomX( false )
m_negateBottomX( false ),
m_side( SIDE::BOTH ),
m_units( UNITS::MILLIMETERS ),
m_format( FORMAT::ASCII ),
m_gerberBoardEdge( true )
{
m_side = SIDE::BOTH;
m_units = UNITS::MILLIMETERS;
m_format = FORMAT::ASCII;
m_gerberBoardEdge = true;
}
m_params.emplace_back( new JOB_PARAM<bool>( "use_drill_place_file_origin",
&m_useDrillPlaceFileOrigin,
m_useDrillPlaceFileOrigin ) );
m_params.emplace_back( new JOB_PARAM<bool>( "smd_only",
&m_smdOnly,
m_smdOnly ) );
m_params.emplace_back( new JOB_PARAM<bool>( "exclude_footprints_with_th",
&m_excludeFootprintsWithTh,
m_excludeFootprintsWithTh ) );
m_params.emplace_back( new JOB_PARAM<bool>( "exclude_dnp",
&m_excludeDNP,
m_excludeDNP ) );
m_params.emplace_back( new JOB_PARAM<bool>( "negate_bottom_x",
&m_negateBottomX,
m_negateBottomX ) );
m_params.emplace_back( new JOB_PARAM<bool>( "gerber_board_edge",
&m_gerberBoardEdge,
m_gerberBoardEdge ) );
m_params.emplace_back( new JOB_PARAM<SIDE>( "side", &m_side, m_side ) );
m_params.emplace_back( new JOB_PARAM<UNITS>( "units", &m_units, m_units ) );
m_params.emplace_back( new JOB_PARAM<FORMAT>( "format", &m_format, m_format ) );
}
wxString JOB_EXPORT_PCB_POS::GetDescription()
{
return wxString::Format( _( "Placement data export" ) );
}
void JOB_EXPORT_PCB_POS::SetDefaultOutputPath( const wxString& aReferenceName )
{
wxFileName fn = aReferenceName;
if( m_format == JOB_EXPORT_PCB_POS::FORMAT::ASCII )
fn.SetExt( FILEEXT::FootprintPlaceFileExtension );
else if( m_format == JOB_EXPORT_PCB_POS::FORMAT::CSV )
fn.SetExt( FILEEXT::CsvFileExtension );
else if( m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
fn.SetExt( FILEEXT::GerberFileExtension );
SetOutputPath( fn.GetFullName() );
}
REGISTER_JOB( pcb_export_pos, _HKI( "PCB: Export Position Data" ), KIWAY::FACE_PCB, JOB_EXPORT_PCB_POS );

View File

@ -30,9 +30,11 @@ class KICOMMON_API JOB_EXPORT_PCB_POS : public JOB
{
public:
JOB_EXPORT_PCB_POS( bool aIsCli );
wxString GetDescription() override;
void SetDefaultOutputPath( const wxString& aReferenceName );
wxString m_filename;
wxString m_outputFile;
bool m_useDrillPlaceFileOrigin;
bool m_smdOnly;

View File

@ -19,24 +19,39 @@
*/
#include <jobs/job_export_pcb_svg.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
JOB_EXPORT_PCB_SVG::JOB_EXPORT_PCB_SVG( bool aIsCli ) :
JOB( "svg", aIsCli ),
m_filename(),
m_outputFile(),
m_colorTheme(),
m_drawingSheet(),
m_mirror( false ),
m_blackAndWhite( false ),
m_negative( false ),
m_plotDrawingSheet( true ),
m_pageSizeMode( 0 ),
m_printMaskLayer(),
m_sketchPadsOnFabLayers( false ),
m_hideDNPFPsOnFabLayers( false ),
m_sketchDNPFPsOnFabLayers( true ),
m_crossoutDNPFPsOnFabLayers( true ),
m_drillShapeOption( 2 )
JOB_EXPORT_PCB_PLOT( JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::SVG, "svg", false, aIsCli ),
m_pageSizeMode( 0 )
{
}
m_plotDrawingSheet = true;
m_params.emplace_back( new JOB_PARAM<wxString>( "color_theme", &m_colorTheme, m_colorTheme ) );
m_params.emplace_back(
new JOB_PARAM<wxString>( "drawing_sheet", &m_drawingSheet, m_drawingSheet ) );
m_params.emplace_back( new JOB_PARAM<bool>( "mirror", &m_mirror, m_mirror ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "black_and_white", &m_blackAndWhite, m_blackAndWhite ) );
m_params.emplace_back( new JOB_PARAM<bool>( "negative", &m_negative, m_negative ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "plot_drawing_sheet", &m_plotDrawingSheet, m_plotDrawingSheet ) );
m_params.emplace_back( new JOB_PARAM<LSEQ>( "layers", &m_printMaskLayer, m_printMaskLayer ) );
m_params.emplace_back( new JOB_PARAM<bool>(
"sketch_pads_on_fab_layers", &m_sketchPadsOnFabLayers, m_sketchPadsOnFabLayers ) );
m_params.emplace_back(
new JOB_PARAM<int>( "page_size_mode", &m_pageSizeMode, m_pageSizeMode ) );
m_params.emplace_back(
new JOB_PARAM<int>( "drill_shape_option", &m_drillShapeOption, m_drillShapeOption ) );
}
wxString JOB_EXPORT_PCB_SVG::GetDescription()
{
return wxString::Format( _( "PCB SVG export" ) );
}
REGISTER_JOB( pcb_export_svg, _HKI( "PCB: Export SVG" ), KIWAY::FACE_PCB, JOB_EXPORT_PCB_SVG );

View File

@ -25,34 +25,16 @@
#include <layer_ids.h>
#include <lseq.h>
#include <wx/string.h>
#include <jobs/job_export_pcb_plot.h>
#include "job.h"
class KICOMMON_API JOB_EXPORT_PCB_SVG : public JOB
class KICOMMON_API JOB_EXPORT_PCB_SVG : public JOB_EXPORT_PCB_PLOT
{
public:
JOB_EXPORT_PCB_SVG( bool aIsCli );
wxString GetDescription() override;
wxString m_filename;
wxString m_outputFile;
wxString m_colorTheme;
wxString m_drawingSheet;
bool m_mirror;
bool m_blackAndWhite;
bool m_negative;
bool m_plotDrawingSheet;
int m_pageSizeMode;
LSEQ m_printMaskLayer;
bool m_sketchPadsOnFabLayers;
bool m_hideDNPFPsOnFabLayers;
bool m_sketchDNPFPsOnFabLayers;
bool m_crossoutDNPFPsOnFabLayers;
// How holes in pads/vias are plotted:
// 0 = no hole, 1 = small shape, 2 = actual shape
int m_drillShapeOption;
};
#endif

View File

@ -19,12 +19,13 @@
*/
#include <jobs/job_export_sch_bom.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
JOB_EXPORT_SCH_BOM::JOB_EXPORT_SCH_BOM( bool aIsCli ) :
JOB( "bom", aIsCli ),
JOB( "bom", false, aIsCli ),
m_filename(),
m_outputFile(),
m_fieldDelimiter(),
m_stringDelimiter(),
@ -42,4 +43,47 @@ JOB_EXPORT_SCH_BOM::JOB_EXPORT_SCH_BOM( bool aIsCli ) :
m_excludeDNP( false ),
m_includeExcludedFromBOM( false )
{
m_params.emplace_back( new JOB_PARAM<wxString>( "field_delimiter",
&m_fieldDelimiter,
m_fieldDelimiter ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "string_delimiter",
&m_stringDelimiter,
m_stringDelimiter ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "ref_delimiter",
&m_refDelimiter,
m_refDelimiter ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "ref_range_delimiter",
&m_refRangeDelimiter,
m_refRangeDelimiter ) );
m_params.emplace_back( new JOB_PARAM<bool>( "keep_tabs", &m_keepTabs, m_keepTabs ) );
m_params.emplace_back( new JOB_PARAM<bool>( "keep_line_breaks",
&m_keepLineBreaks,
m_keepLineBreaks ) );
m_params.emplace_back( new JOB_PARAM<std::vector<wxString>>( "fields_ordered",
&m_fieldsOrdered,
m_fieldsOrdered ) );
m_params.emplace_back( new JOB_PARAM<std::vector<wxString>>( "fields_labels",
&m_fieldsLabels,
m_fieldsLabels ) );
m_params.emplace_back( new JOB_PARAM<std::vector<wxString>>( "fields_group_by",
&m_fieldsGroupBy,
m_fieldsGroupBy ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "sort_field", &m_sortField, m_sortField ) );
m_params.emplace_back( new JOB_PARAM<bool>( "sort_asc", &m_sortAsc, m_sortAsc ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "filter_string",
&m_filterString,
m_filterString ) );
m_params.emplace_back( new JOB_PARAM<bool>( "exclude_dnp", &m_excludeDNP, m_excludeDNP ) );
m_params.emplace_back( new JOB_PARAM<bool>( "include_excluded_from_bom",
&m_includeExcludedFromBOM,
m_includeExcludedFromBOM ) );
}
wxString JOB_EXPORT_SCH_BOM::GetDescription()
{
return wxString::Format( _( "Schematic BOM export" ) );
}
REGISTER_JOB( sch_export_bom, _HKI( "Schematic: Export BOM" ), KIWAY::FACE_SCH, JOB_EXPORT_SCH_BOM );

View File

@ -30,10 +30,10 @@ class KICOMMON_API JOB_EXPORT_SCH_BOM : public JOB
{
public:
JOB_EXPORT_SCH_BOM( bool aIsCli );
wxString GetDescription() override;
// Basic options
wxString m_filename;
wxString m_outputFile;
// Preset options (from schematic)
wxString m_bomPresetName;

View File

@ -19,12 +19,48 @@
*/
#include <jobs/job_export_sch_netlist.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_EXPORT_SCH_NETLIST::FORMAT,
{
{ JOB_EXPORT_SCH_NETLIST::FORMAT::KICADSEXPR, "kicad" },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::KICADXML, "xml" },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::ALLEGRO, "allegro" },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::PADS, "pads" },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::CADSTAR, "cadstar" },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::ORCADPCB2, "orcadpcb2" },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::SPICE, "spice" },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::SPICEMODEL, "spicemodel" },
} )
JOB_EXPORT_SCH_NETLIST::JOB_EXPORT_SCH_NETLIST( bool aIsCli ) :
JOB( "netlist", aIsCli ),
JOB( "netlist", false, aIsCli ),
m_filename(),
m_outputFile()
format( FORMAT::KICADSEXPR ),
m_spiceSaveAllVoltages( false ),
m_spiceSaveAllCurrents( false ),
m_spiceSaveAllDissipations( false ),
m_spiceSaveAllEvents( false )
{
format = FORMAT::KICADSEXPR;
}
m_params.emplace_back( new JOB_PARAM<FORMAT>( "format", &format, format ) );
m_params.emplace_back( new JOB_PARAM<bool>( "spice.save_all_voltages", &m_spiceSaveAllVoltages,
m_spiceSaveAllVoltages ) );
m_params.emplace_back( new JOB_PARAM<bool>( "spice.save_all_currents", &m_spiceSaveAllCurrents,
m_spiceSaveAllCurrents ) );
m_params.emplace_back( new JOB_PARAM<bool>( "spice.save_all_events", &m_spiceSaveAllEvents,
m_spiceSaveAllEvents ) );
m_params.emplace_back( new JOB_PARAM<bool>( "spice.save_all_dissipations", &m_spiceSaveAllDissipations,
m_spiceSaveAllDissipations ) );
}
wxString JOB_EXPORT_SCH_NETLIST::GetDescription()
{
return wxString::Format( _( "Schematic Netlist Export" ) );
}
REGISTER_JOB( sch_export_netlist, _HKI( "Schematic: Export Netlist" ), KIWAY::FACE_SCH,
JOB_EXPORT_SCH_NETLIST );

View File

@ -29,9 +29,9 @@ class KICOMMON_API JOB_EXPORT_SCH_NETLIST : public JOB
{
public:
JOB_EXPORT_SCH_NETLIST( bool aIsCli );
wxString GetDescription() override;
wxString m_filename;
wxString m_outputFile;
enum class FORMAT
{
@ -46,6 +46,11 @@ public:
};
FORMAT format;
bool m_spiceSaveAllVoltages;
bool m_spiceSaveAllCurrents;
bool m_spiceSaveAllDissipations;
bool m_spiceSaveAllEvents;
};
#endif

View File

@ -19,12 +19,54 @@
*/
#include <jobs/job_export_sch_plot.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_PAGE_SIZE,
{
{ JOB_PAGE_SIZE::PAGE_SIZE_AUTO, "auto" },
{ JOB_PAGE_SIZE::PAGE_SIZE_A4, "A4" },
{ JOB_PAGE_SIZE::PAGE_SIZE_A, "A" },
} )
JOB_EXPORT_SCH_PLOT::JOB_EXPORT_SCH_PLOT( bool aIsCli, SCH_PLOT_FORMAT aPlotFormat, wxString aFilename ) :
JOB( "plot", aIsCli ),
m_plotFormat( aPlotFormat ),
m_filename( aFilename ),
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_HPGL_PAGE_SIZE,
{
{ JOB_HPGL_PAGE_SIZE::DEFAULT, "default" },
{ JOB_HPGL_PAGE_SIZE::SIZE_A5, "A5" },
{ JOB_HPGL_PAGE_SIZE::SIZE_A4, "A4" },
{ JOB_HPGL_PAGE_SIZE::SIZE_A3, "A3" },
{ JOB_HPGL_PAGE_SIZE::SIZE_A2, "A2" },
{ JOB_HPGL_PAGE_SIZE::SIZE_A1, "A1" },
{ JOB_HPGL_PAGE_SIZE::SIZE_A0, "A0" },
{ JOB_HPGL_PAGE_SIZE::SIZE_A, "A" },
{ JOB_HPGL_PAGE_SIZE::SIZE_B, "B" },
{ JOB_HPGL_PAGE_SIZE::SIZE_C, "C" },
{ JOB_HPGL_PAGE_SIZE::SIZE_D, "D" },
{ JOB_HPGL_PAGE_SIZE::SIZE_E, "E" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_HPGL_PLOT_ORIGIN_AND_UNITS,
{
{ JOB_HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_BOT_LEFT, "default" },
{ JOB_HPGL_PLOT_ORIGIN_AND_UNITS::PLOTTER_CENTER, "A5" },
{ JOB_HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_PAGE, "A4" },
{ JOB_HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_CONTENT, "A3" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( SCH_PLOT_FORMAT,
{
{ SCH_PLOT_FORMAT::HPGL, "hpgl" },
{ SCH_PLOT_FORMAT::PDF, "pdf" },
{ SCH_PLOT_FORMAT::GERBER, "gerber" },
{ SCH_PLOT_FORMAT::POST, "post" },
{ SCH_PLOT_FORMAT::SVG, "svg" },
{ SCH_PLOT_FORMAT::DXF, "dxf" },
} )
JOB_EXPORT_SCH_PLOT::JOB_EXPORT_SCH_PLOT( bool aIsCli ) :
JOB( "plot", false, aIsCli ),
m_plotFormat( SCH_PLOT_FORMAT::PDF ),
m_filename(),
m_drawingSheet(),
m_plotAll( true ),
m_plotDrawingSheet( true ),
@ -40,4 +82,85 @@ JOB_EXPORT_SCH_PLOT::JOB_EXPORT_SCH_PLOT( bool aIsCli, SCH_PLOT_FORMAT aPlotForm
m_outputFile(),
m_HPGLPlotOrigin( JOB_HPGL_PLOT_ORIGIN_AND_UNITS::USER_FIT_CONTENT )
{
}
m_params.emplace_back(
new JOB_PARAM<SCH_PLOT_FORMAT>( "format", &m_plotFormat, m_plotFormat ) );
m_params.emplace_back(
new JOB_PARAM<wxString>( "drawing_sheet", &m_drawingSheet, m_drawingSheet ) );
m_params.emplace_back( new JOB_PARAM<bool>( "plot_all", &m_plotAll, m_plotAll ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "plot_drawing_sheet", &m_plotDrawingSheet, m_plotDrawingSheet ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "black_and_white", &m_blackAndWhite, m_blackAndWhite ) );
m_params.emplace_back(
new JOB_PARAM<JOB_PAGE_SIZE>( "page_size", &m_pageSizeSelect, m_pageSizeSelect ) );
m_params.emplace_back( new JOB_PARAM<bool>( "use_background_color", &m_useBackgroundColor,
m_useBackgroundColor ) );
m_params.emplace_back(
new JOB_PARAM<double>( "hpgl_pen_size", &m_HPGLPenSize, m_HPGLPenSize ) );
m_params.emplace_back( new JOB_PARAM<JOB_HPGL_PAGE_SIZE>(
"hpgl_page_size", &m_HPGLPaperSizeSelect, m_HPGLPaperSizeSelect ) );
m_params.emplace_back( new JOB_PARAM<bool>( "pdf_property_popups", &m_PDFPropertyPopups,
m_PDFPropertyPopups ) );
m_params.emplace_back( new JOB_PARAM<bool>( "pdf_metadata", &m_PDFMetadata, m_PDFMetadata ) );
m_params.emplace_back( new JOB_PARAM<wxString>( "color_theme", &m_theme, m_theme ) );
m_params.emplace_back(
new JOB_PARAM<wxString>( "output_filename", &m_outputFile, m_outputFile ) );
m_params.emplace_back(
new JOB_PARAM<wxString>( "output_directory", &m_outputDirectory, m_outputDirectory ) );
m_params.emplace_back( new JOB_PARAM<JOB_HPGL_PLOT_ORIGIN_AND_UNITS>(
"hpgl_plot_origin", &m_HPGLPlotOrigin, m_HPGLPlotOrigin ) );
}
wxString JOB_EXPORT_SCH_PLOT::GetDescription()
{
return wxString::Format( _( "Schematic plot export" ) );
}
JOB_EXPORT_SCH_PLOT_PDF::JOB_EXPORT_SCH_PLOT_PDF( bool aIsCli ) :
JOB_EXPORT_SCH_PLOT( aIsCli )
{
m_plotFormat = SCH_PLOT_FORMAT::PDF;
}
JOB_EXPORT_SCH_PLOT_DXF ::JOB_EXPORT_SCH_PLOT_DXF ( bool aIsCli ) :
JOB_EXPORT_SCH_PLOT( aIsCli )
{
m_plotFormat = SCH_PLOT_FORMAT::DXF;
}
JOB_EXPORT_SCH_PLOT_SVG::JOB_EXPORT_SCH_PLOT_SVG( bool aIsCli ) :
JOB_EXPORT_SCH_PLOT( aIsCli )
{
m_plotFormat = SCH_PLOT_FORMAT::SVG;
}
JOB_EXPORT_SCH_PLOT_PS::JOB_EXPORT_SCH_PLOT_PS( bool aIsCli ) :
JOB_EXPORT_SCH_PLOT( aIsCli )
{
m_plotFormat = SCH_PLOT_FORMAT::POST;
}
JOB_EXPORT_SCH_PLOT_HPGL::JOB_EXPORT_SCH_PLOT_HPGL( bool aIsCli ) :
JOB_EXPORT_SCH_PLOT( aIsCli )
{
m_plotFormat = SCH_PLOT_FORMAT::HPGL;
}
REGISTER_JOB( sch_export_plot_svg, _HKI( "Schematic: Export SVG" ), KIWAY::FACE_SCH,
JOB_EXPORT_SCH_PLOT_SVG );
REGISTER_JOB( sch_export_plot_hpgl, _HKI( "Schematic: Export HPGL" ), KIWAY::FACE_SCH,
JOB_EXPORT_SCH_PLOT_HPGL );
REGISTER_JOB( sch_export_plot_ps, _HKI( "Schematic: Export PS" ), KIWAY::FACE_SCH,
JOB_EXPORT_SCH_PLOT_PS );
REGISTER_JOB( sch_export_plot_dxf, _HKI( "Schematic: Export DXF" ), KIWAY::FACE_SCH,
JOB_EXPORT_SCH_PLOT_DXF );
REGISTER_JOB( sch_export_plot_pdf, _HKI( "Schematic: Export PDF" ), KIWAY::FACE_SCH,
JOB_EXPORT_SCH_PLOT_PDF );

View File

@ -75,7 +75,8 @@ enum class SCH_PLOT_FORMAT
class KICOMMON_API JOB_EXPORT_SCH_PLOT : public JOB
{
public:
JOB_EXPORT_SCH_PLOT( bool aIsCli, SCH_PLOT_FORMAT aPlotFormat, wxString aFilename );
JOB_EXPORT_SCH_PLOT( bool aIsCli );
wxString GetDescription() override;
SCH_PLOT_FORMAT m_plotFormat;
wxString m_filename;
@ -100,4 +101,39 @@ public:
JOB_HPGL_PLOT_ORIGIN_AND_UNITS m_HPGLPlotOrigin;
};
class KICOMMON_API JOB_EXPORT_SCH_PLOT_PDF : public JOB_EXPORT_SCH_PLOT
{
public:
JOB_EXPORT_SCH_PLOT_PDF( bool aIsCli );
};
class KICOMMON_API JOB_EXPORT_SCH_PLOT_DXF : public JOB_EXPORT_SCH_PLOT
{
public:
JOB_EXPORT_SCH_PLOT_DXF( bool aIsCli );
};
class KICOMMON_API JOB_EXPORT_SCH_PLOT_SVG : public JOB_EXPORT_SCH_PLOT
{
public:
JOB_EXPORT_SCH_PLOT_SVG( bool aIsCli );
};
class KICOMMON_API JOB_EXPORT_SCH_PLOT_PS : public JOB_EXPORT_SCH_PLOT
{
public:
JOB_EXPORT_SCH_PLOT_PS( bool aIsCli );
};
class KICOMMON_API JOB_EXPORT_SCH_PLOT_HPGL : public JOB_EXPORT_SCH_PLOT
{
public:
JOB_EXPORT_SCH_PLOT_HPGL( bool aIsCli );
};
#endif

View File

@ -19,11 +19,22 @@
*/
#include <jobs/job_export_sch_pythonbom.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
JOB_EXPORT_SCH_PYTHONBOM::JOB_EXPORT_SCH_PYTHONBOM( bool aIsCli ) :
JOB( "pythonbom", aIsCli ),
m_filename(),
m_outputFile()
JOB( "pythonbom", false, aIsCli ),
m_filename()
{
}
}
wxString JOB_EXPORT_SCH_PYTHONBOM::GetDescription()
{
return wxString::Format( _( "Schematic PythonBOM export" ) );
}
REGISTER_JOB( sch_export_pythonbom, _HKI( "Schematic: Export PythonBOM" ), KIWAY::FACE_SCH,
JOB_EXPORT_SCH_PYTHONBOM );

View File

@ -29,9 +29,9 @@ class KICOMMON_API JOB_EXPORT_SCH_PYTHONBOM : public JOB
{
public:
JOB_EXPORT_SCH_PYTHONBOM( bool aIsCli );
wxString GetDescription() override;
wxString m_filename;
wxString m_outputFile;
};
#endif

View File

@ -22,10 +22,9 @@
JOB_FP_EXPORT_SVG::JOB_FP_EXPORT_SVG( bool aIsCli ) :
JOB( "fpsvg", aIsCli ),
JOB( "fpsvg", true, aIsCli ),
m_libraryPath(),
m_footprint(),
m_outputDirectory(),
m_blackAndWhite( false ),
m_sketchPadsOnFabLayers( false ),
m_hideDNPFPsOnFabLayers( false ),

View File

@ -22,9 +22,8 @@
JOB_FP_UPGRADE::JOB_FP_UPGRADE( bool aIsCli ) :
JOB( "fpupgrade", aIsCli ),
JOB( "fpupgrade", true, aIsCli ),
m_libraryPath(),
m_outputLibraryPath(),
m_force( false )
{
}

View File

@ -19,10 +19,24 @@
*/
#include <jobs/job_pcb_drc.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_PCB_DRC::UNITS,
{
{ JOB_PCB_DRC::UNITS::INCHES, "in" },
{ JOB_PCB_DRC::UNITS::MILLIMETERS, "mm" },
{ JOB_PCB_DRC::UNITS::MILS, "mils" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_PCB_DRC::OUTPUT_FORMAT,
{
{ JOB_PCB_DRC::OUTPUT_FORMAT::REPORT, "report" },
{ JOB_PCB_DRC::OUTPUT_FORMAT::JSON, "json" },
} )
JOB_PCB_DRC::JOB_PCB_DRC( bool aIsCli ) :
JOB( "drc", aIsCli ),
JOB( "drc", false, aIsCli ),
m_filename(),
m_reportAllTrackErrors( false ),
m_units( JOB_PCB_DRC::UNITS::MILLIMETERS ),
@ -31,4 +45,18 @@ JOB_PCB_DRC::JOB_PCB_DRC( bool aIsCli ) :
m_exitCodeViolations( false ),
m_parity( true )
{
}
m_params.emplace_back( new JOB_PARAM<UNITS>( "units", &m_units, m_units ) );
m_params.emplace_back( new JOB_PARAM<int>( "severity", &m_severity, m_severity ) );
m_params.emplace_back( new JOB_PARAM<OUTPUT_FORMAT>( "format", &m_format, m_format ) );
m_params.emplace_back( new JOB_PARAM<bool>( "parity", &m_parity, m_parity ) );
m_params.emplace_back( new JOB_PARAM<bool>( "report_all_track_errors", &m_reportAllTrackErrors, m_reportAllTrackErrors ) );
}
wxString JOB_PCB_DRC::GetDescription()
{
return wxString::Format( _( "Perform PCB DRC" ) );
}
REGISTER_JOB( pcb_drc, _HKI( "PCB: Perform DRC" ), KIWAY::FACE_PCB, JOB_PCB_DRC );

View File

@ -31,6 +31,7 @@ class KICOMMON_API JOB_PCB_DRC : public JOB
{
public:
JOB_PCB_DRC( bool aIsCli );
wxString GetDescription() override;
wxString m_filename;
wxString m_outputFile;

View File

@ -23,6 +23,6 @@
JOB_PCB_RENDER::JOB_PCB_RENDER( bool aIsCli ) :
JOB( "render", aIsCli ), m_filename(), m_outputFile()
JOB( "render", false, aIsCli ), m_filename()
{
}

View File

@ -0,0 +1,53 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <jobs/job_registry.h>
bool JOB_REGISTRY::Add( const wxString& aName, JOB_REGISTRY_ENTRY entry )
{
REGISTRY_MAP_T& registry = getRegistry();
if( registry.find( aName ) != registry.end() )
{
return false;
}
registry[aName] = entry;
return true;
}
KIWAY::FACE_T JOB_REGISTRY::GetKifaceType( const wxString& aName )
{
REGISTRY_MAP_T& registry = getRegistry();
if( registry.find( aName ) == registry.end() )
{
return KIWAY::KIWAY_FACE_COUNT;
}
return registry[aName].kifaceType;
}
JOB_REGISTRY::REGISTRY_MAP_T& JOB_REGISTRY::getRegistry()
{
static REGISTRY_MAP_T map;
return map;
}

View File

@ -0,0 +1,70 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <jobs/job.h>
#include <kiway.h>
struct KICOMMON_API JOB_REGISTRY_ENTRY
{
public:
KIWAY::FACE_T kifaceType;
std::function<JOB*()> createFunc;
wxString title;
};
class KICOMMON_API JOB_REGISTRY
{
public:
typedef std::unordered_map<wxString, JOB_REGISTRY_ENTRY> REGISTRY_MAP_T;
static bool Add( const wxString& aName, JOB_REGISTRY_ENTRY entry );
static KIWAY::FACE_T GetKifaceType( const wxString& aName );
template <typename T>
static T* CreateInstance( const wxString& aName )
{
REGISTRY_MAP_T& registry = getRegistry();
if( registry.find( aName ) == registry.end() )
{
return nullptr;
}
return registry[aName].createFunc();
}
static const REGISTRY_MAP_T& GetRegistry() {
return getRegistry();
}
private:
// Use Meyer's singleton to prevent SIOF
static REGISTRY_MAP_T& getRegistry();
};
#define REGISTER_JOB( job_name, title, face, T ) bool job_name##_entry = JOB_REGISTRY::Add( #job_name, \
{ face, []() \
{ \
return new T( true ); \
}, \
title } )
// newline required to appease warning for REGISTER_JOB macro

View File

@ -19,14 +19,40 @@
*/
#include <jobs/job_sch_erc.h>
#include <jobs/job_registry.h>
#include <i18n_utility.h>
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_SCH_ERC::UNITS,
{
{ JOB_SCH_ERC::UNITS::INCHES, "in" },
{ JOB_SCH_ERC::UNITS::MILLIMETERS, "mm" },
{ JOB_SCH_ERC::UNITS::MILS, "mils" },
} )
NLOHMANN_JSON_SERIALIZE_ENUM( JOB_SCH_ERC::OUTPUT_FORMAT,
{
{ JOB_SCH_ERC::OUTPUT_FORMAT::REPORT, "report" },
{ JOB_SCH_ERC::OUTPUT_FORMAT::JSON, "json" },
} )
JOB_SCH_ERC::JOB_SCH_ERC( bool aIsCli ) :
JOB( "erc", aIsCli ),
JOB( "erc", false, aIsCli ),
m_filename(),
m_units( JOB_SCH_ERC::UNITS::MILLIMETERS ),
m_severity( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ),
m_format( OUTPUT_FORMAT::REPORT ),
m_exitCodeViolations( false )
{
}
m_params.emplace_back( new JOB_PARAM<UNITS>( "units", &m_units, m_units ) );
m_params.emplace_back( new JOB_PARAM<int>( "severity", &m_severity, m_severity ) );
m_params.emplace_back( new JOB_PARAM<OUTPUT_FORMAT>( "format", &m_format, m_format ) );
}
wxString JOB_SCH_ERC::GetDescription()
{
return wxString::Format( _( "Perform Schematic ERC" ) );
}
REGISTER_JOB( sch_erc, _HKI( "Schematic: Perform ERC" ), KIWAY::FACE_SCH, JOB_SCH_ERC );

View File

@ -31,6 +31,7 @@ class KICOMMON_API JOB_SCH_ERC : public JOB
{
public:
JOB_SCH_ERC( bool aIsCli );
wxString GetDescription() override;
wxString m_filename;
wxString m_outputFile;

View File

@ -22,10 +22,9 @@
JOB_SYM_EXPORT_SVG::JOB_SYM_EXPORT_SVG( bool aIsCli ) :
JOB( "symsvg", aIsCli ),
JOB( "symsvg", true, aIsCli ),
m_libraryPath(),
m_symbol(),
m_outputDirectory(),
m_blackAndWhite( false ),
m_includeHiddenPins( false ),
m_includeHiddenFields( false )

View File

@ -22,7 +22,7 @@
JOB_SYM_UPGRADE::JOB_SYM_UPGRADE( bool aIsCli ) :
JOB( "symupgrade", aIsCli ),
JOB( "symupgrade", false, aIsCli ),
m_libraryPath(),
m_outputLibraryPath(),
m_force( false )

48
common/jobs/jobs_output.h Normal file
View File

@ -0,0 +1,48 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kicommon.h>
#include <vector>
#include <jobs/job.h>
class KICOMMON_API JOBS_OUTPUT_HANDLER
{
public:
JOBS_OUTPUT_HANDLER()
{
}
virtual ~JOBS_OUTPUT_HANDLER() {}
virtual bool HandleOutputs( const wxString& baseTempPath,
const std::vector<JOB_OUTPUT>& aOutputsToHandle ) = 0;
virtual void FromJson( const nlohmann::json& j ) = 0;
virtual void ToJson( nlohmann::json& j ) const = 0;
void SetOutputPath( const wxString& aPath ) { m_outputPath = aPath; }
wxString GetOutputPath() const { return m_outputPath; }
protected:
wxString m_outputPath;
};

View File

@ -0,0 +1,76 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <jobs/jobs_output_archive.h>
#include <wx/fs_zip.h>
#include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <gestfich.h>
JOBS_OUTPUT_ARCHIVE::JOBS_OUTPUT_ARCHIVE() : JOBS_OUTPUT_HANDLER(),
m_format( FORMAT::ZIP )
{
}
bool JOBS_OUTPUT_ARCHIVE::HandleOutputs( const wxString& baseTempPath,
const std::vector<JOB_OUTPUT>& aOutputsToHandle )
{
bool success = true;
wxFFileOutputStream ostream( m_outputPath );
if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
{
//msg.Printf( _( "Failed to create file '%s'." ), aDestFile );
//aReporter.Report( msg, RPT_SEVERITY_ERROR );
return false;
}
wxZipOutputStream zipstream( ostream, -1, wxConvUTF8 );
wxString errors;
if( !AddDirectoryToZip( zipstream, baseTempPath, errors ) )
{
success = false;
}
if( !zipstream.Close() )
{
success = false;
}
return success;
}
void JOBS_OUTPUT_ARCHIVE::FromJson( const nlohmann::json& j )
{
m_outputPath = j.value( "output_path", "" );
m_format = FORMAT::ZIP;
}
void JOBS_OUTPUT_ARCHIVE::ToJson( nlohmann::json& j ) const
{
j["output_path"] = m_outputPath;
j["format"] = "zip";
}

View File

@ -0,0 +1,45 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <jobs/jobs_output.h>
class KICOMMON_API JOBS_OUTPUT_ARCHIVE : public JOBS_OUTPUT_HANDLER
{
public:
JOBS_OUTPUT_ARCHIVE();
enum class FORMAT
{
ZIP
};
bool HandleOutputs( const wxString& baseTempPath, const std::vector<JOB_OUTPUT>& aOutputsToHandle ) override;
void FromJson( const nlohmann::json& j ) override;
void ToJson( nlohmann::json& j ) const override;
FORMAT GetFormat() const { return m_format; }
void SetFormat( FORMAT format ) { m_format = format; }
private:
FORMAT m_format;
};

View File

@ -0,0 +1,61 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <jobs/jobs_output_folder.h>
#include <wx/filename.h>
#include <gestfich.h>
JOBS_OUTPUT_FOLDER::JOBS_OUTPUT_FOLDER() :
JOBS_OUTPUT_HANDLER()
{
}
bool JOBS_OUTPUT_FOLDER::HandleOutputs( const wxString& baseTempPath,
const std::vector<JOB_OUTPUT>& aOutputsToHandle )
{
bool success = true;
if( !wxFileName::Mkdir( m_outputPath, wxS_DIR_DEFAULT ) )
{
return false;
}
wxString errors;
if( !CopyDirectory( baseTempPath, m_outputPath, errors ) )
{
success = false;
}
return success;
}
void JOBS_OUTPUT_FOLDER::FromJson( const nlohmann::json& j )
{
m_outputPath = j.value( "output_path", "" );
}
void JOBS_OUTPUT_FOLDER::ToJson( nlohmann::json& j ) const
{
j["output_path"] = m_outputPath;
}

View File

@ -0,0 +1,35 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <jobs/jobs_output.h>
class JOBS_OUTPUT_FOLDER : public JOBS_OUTPUT_HANDLER
{
public:
JOBS_OUTPUT_FOLDER();
bool HandleOutputs( const wxString& baseTempPath,
const std::vector<JOB_OUTPUT>& aOutputsToHandle ) override;
void FromJson( const nlohmann::json& j ) override;
void ToJson( nlohmann::json& j ) const override;
};

218
common/jobs/jobset.cpp Normal file
View File

@ -0,0 +1,218 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <nlohmann/json.hpp>
#include <settings/parameters.h>
#include <wildcards_and_files_ext.h>
#include <jobs/jobset.h>
#include <jobs/job_registry.h>
#include <jobs/jobs_output_folder.h>
#include <jobs/jobs_output_archive.h>
#include <kiid.h>
#include <algorithm>
const int jobsFileSchemaVersion = 1;
NLOHMANN_JSON_SERIALIZE_ENUM( JOBSET_OUTPUT_TYPE,
{
{ JOBSET_OUTPUT_TYPE::FOLDER, "folder" },
{ JOBSET_OUTPUT_TYPE::ARCHIVE, "archive" }
} )
KICOMMON_API void to_json( nlohmann::json& j, const JOBSET_JOB& f )
{
j = nlohmann::json{ { "id", f.m_id },
{ "type", f.m_type },
{ "settings", nlohmann::json::object( {} ) }
};
f.m_job->ToJson( j.at( "settings" ) );
}
KICOMMON_API void from_json( const nlohmann::json& j, JOBSET_JOB& f )
{
j.at( "type" ).get_to( f.m_type );
j.at( "id" ).get_to( f.m_id );
nlohmann::json settings_obj = j.at( "settings" );
f.m_job = JOB_REGISTRY::CreateInstance<JOB>( f.m_type );
if( f.m_job != nullptr )
{
f.m_job->FromJson( settings_obj );
}
}
KICOMMON_API void to_json( nlohmann::json& j, const JOBSET_OUTPUT& f )
{
j = nlohmann::json{ { "type", f.m_type }, { "settings", nlohmann::json::object( {} ) } };
f.m_outputHandler->ToJson( j.at( "settings" ) );
}
KICOMMON_API void from_json( const nlohmann::json& j, JOBSET_OUTPUT& f )
{
j.at( "type" ).get_to( f.m_type );
f.m_only = j.value( "only", std::vector<wxString>() );
nlohmann::json settings_obj = j.at( "settings" );
if( f.m_type == JOBSET_OUTPUT_TYPE::FOLDER )
{
f.m_outputHandler = new JOBS_OUTPUT_FOLDER();
}
else if( f.m_type == JOBSET_OUTPUT_TYPE::ARCHIVE )
{
f.m_outputHandler = new JOBS_OUTPUT_ARCHIVE();
}
if( f.m_outputHandler != nullptr )
{
f.m_outputHandler->FromJson( settings_obj );
}
}
bool JOBSET_JOB::operator==( const JOBSET_JOB & rhs ) const
{
return rhs.m_type == m_type;
}
bool JOBSET_OUTPUT::operator==( const JOBSET_OUTPUT& rhs ) const
{
return rhs.m_type == m_type;
}
JOBSET::JOBSET( const wxString& aFilename ) :
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, jobsFileSchemaVersion ),
m_dirty( false )
{
m_params.emplace_back( new PARAM_LIST<JOBSET_JOB>( "jobs", &m_jobs, {} ) );
m_params.emplace_back( new PARAM_LIST<JOBSET_OUTPUT>( "outputs", &m_outputs, {} ) );
m_fileNameWithoutPath = wxFileName( aFilename ).GetFullName();
}
wxString JOBSET::getFileExt() const
{
return FILEEXT::KiCadJobSetFileExtension;
}
void JOBSET::AddNewJob( wxString aType, JOB* aJob )
{
m_jobs.emplace_back( KIID().AsString(), aType, aJob );
SetDirty();
}
JOBSET_OUTPUT JOBSET::AddNewJobOutput( JOBSET_OUTPUT_TYPE aType,
JOBS_OUTPUT_HANDLER* aJobOutput )
{
m_outputs.emplace_back( KIID().AsString(), aType, aJobOutput );
SetDirty();
return m_outputs.back();
}
void JOBSET::RemoveOutput( JOBSET_OUTPUT* aOutput )
{
std::erase_if( m_outputs,
[&]( JOBSET_OUTPUT const& output )
{
return output.m_id == aOutput->m_id;
} );
}
bool JOBSET::SaveToFile( const wxString& aDirectory, bool aForce )
{
bool success = JSON_SETTINGS::SaveToFile( aDirectory, aForce );
if( success )
{
m_dirty = false;
}
return success;
}
JOBSET_OUTPUT* JOBSET::GetOutput( wxString& aOutput )
{
auto it = std::find_if( m_outputs.begin(), m_outputs.end(),
[&]( const JOBSET_OUTPUT& output )
{
if( output.m_id == aOutput )
return true;
return false;
} );
if( it != m_outputs.end() )
return &(*it);
return nullptr;
}
std::vector<JOBSET_JOB> JOBSET::GetJobsForOutput( JOBSET_OUTPUT* aOutput )
{
wxASSERT( aOutput != nullptr );
if( aOutput->m_only.size() == 0 )
{
return m_jobs;
}
std::vector<JOBSET_JOB> result;
for( wxString& onlyId : aOutput->m_only )
{
auto it = std::find_if( m_jobs.begin(), m_jobs.end(),
[&]( const JOBSET_JOB& job )
{
if( job.m_id == onlyId )
return true;
return false;
} );
if( it != m_jobs.end() )
result.push_back( *it );
}
return result;
}
#if !defined( __MINGW32__ )
template class KICOMMON_API PARAM_LIST<JOBSET_JOB>;
template class KICOMMON_API PARAM_LIST<JOBSET_OUTPUT>;
#endif

111
common/jobs/jobset.h Normal file
View File

@ -0,0 +1,111 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOBS_FILE_H
#define JOBS_FILE_H
#include <jobs/job.h>
#include <jobs/jobs_output.h>
#include <settings/json_settings.h>
#include <settings/parameters.h>
#include <ctime>
struct KICOMMON_API JOBSET_JOB
{
wxString m_id;
wxString m_type;
JOB* m_job;
bool operator==( const JOBSET_JOB& rhs ) const;
};
enum class JOBSET_OUTPUT_TYPE
{
FOLDER,
ARCHIVE
};
struct KICOMMON_API JOBSET_OUTPUT
{
wxString m_id;
JOBSET_OUTPUT_TYPE m_type;
JOBS_OUTPUT_HANDLER* m_outputHandler;
std::vector<wxString> m_only;
bool operator==( const JOBSET_OUTPUT& rhs ) const;
};
class KICOMMON_API JOBSET : public JSON_SETTINGS
{
public:
JOBSET( const wxString& aFilename );
virtual ~JOBSET() {}
std::vector<JOBSET_JOB>& GetJobs()
{
return m_jobs;
}
std::vector<JOBSET_JOB> GetJobsForOutput( JOBSET_OUTPUT* aOutput );
std::vector<JOBSET_OUTPUT>& GetOutputs() { return m_outputs; }
JOBSET_OUTPUT* GetOutput( wxString& aOutput );
bool SaveToFile( const wxString& aDirectory = "", bool aForce = false ) override;
void SetDirty() { m_dirty = true; }
bool GetDirty() const { return m_dirty; }
wxString GetFullName() const { return m_fileNameWithoutPath; }
void AddNewJob( wxString aType, JOB* aJob );
JOBSET_OUTPUT AddNewJobOutput( JOBSET_OUTPUT_TYPE aType,
JOBS_OUTPUT_HANDLER* aJobOutput );
void RemoveOutput( JOBSET_OUTPUT* aOutput );
protected:
wxString getFileExt() const override;
private:
std::vector<JOBSET_JOB> m_jobs;
std::vector<JOBSET_OUTPUT> m_outputs;
bool m_dirty;
wxString m_fileNameWithoutPath;
};
KICOMMON_API void to_json( nlohmann::json& j, const JOBSET_JOB& f );
KICOMMON_API void from_json( const nlohmann::json& j, JOBSET_JOB& f );
KICOMMON_API void to_json( nlohmann::json& j, const JOBSET_OUTPUT& f );
KICOMMON_API void from_json( const nlohmann::json& j, JOBSET_OUTPUT& f );
#if defined( __MINGW32__ )
template class KICOMMON_API PARAM_LIST<struct JOBSET_JOB>;
template class KICOMMON_API PARAM_LIST<struct JOBSET_JOB>;
#else
extern template class APIVISIBLE PARAM_LIST<JOBSET_JOB>;
extern template class APIVISIBLE PARAM_LIST<JOBSET_JOB>;
#endif
#endif

34
common/jobs/lset_json.h Normal file
View File

@ -0,0 +1,34 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <lset.h>
#include <nlohmann/json_fwd.hpp>
void to_json( nlohmann::json& aJson, const LSET& aLset )
{
aJson = nlohmann::json( aLset.FmtHex() );
}
void from_json( const nlohmann::json& aJson, LSET& aLset )
{
aLset.ParseHex( aJson.get<std::string>() );
}

View File

@ -714,6 +714,14 @@ int KIWAY::ProcessJob( KIWAY::FACE_T aFace, JOB* job )
}
bool KIWAY::ProcessJobConfigDialog( KIWAY::FACE_T aFace, JOB* aJob, wxWindow* aWindow )
{
KIFACE* kiface = KiFACE( aFace );
return kiface->HandleJobConfig( aJob, aWindow );
}
void KIWAY::OnKiCadExit()
{
if( m_ctl & KFCTL_CPP_PROJECT_SUITE )

View File

@ -349,6 +349,12 @@ std::string LSET::FmtHex() const
}
int LSET::ParseHex( const std::string& str )
{
return ParseHex( str.c_str(), str.length() );
}
int LSET::ParseHex( const char* aStart, int aCount )
{
LSET tmp;

View File

@ -56,7 +56,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
},
[&]( const std::string& aString )
{
m_VisibleLayers.ParseHex( aString.c_str(), aString.size() );
m_VisibleLayers.ParseHex( aString );
},
LSET::AllLayersMask().FmtHex() ) );

View File

@ -1035,6 +1035,12 @@ bool SETTINGS_MANAGER::IsProjectOpen() const
}
bool SETTINGS_MANAGER::IsProjectOpenNotDummy() const
{
return m_projects.size() > 1 || ( m_projects.size() == 1 && !m_projects.begin()->second->GetProjectFullName().IsEmpty() );
}
PROJECT* SETTINGS_MANAGER::GetProject( const wxString& aFullPath ) const
{
if( m_projects.count( aFullPath ) )

View File

@ -155,6 +155,7 @@ const std::string FILEEXT::EquFileExtension( "equ" );
const std::string FILEEXT::HotkeyFileExtension( "hotkeys" );
const std::string FILEEXT::DatabaseLibraryFileExtension( "kicad_dbl" );
const std::string FILEEXT::HTTPLibraryFileExtension( "kicad_httplib" );
const std::string FILEEXT::KiCadJobSetFileExtension( "kicad_jobset" );
const std::string FILEEXT::ArchiveFileExtension( "zip" );
@ -547,3 +548,9 @@ wxString FILEEXT::HotkeyFileWildcard()
{
return _( "Hotkey file" ) + AddFileExtListToFilter( { HotkeyFileExtension } );
}
wxString FILEEXT::JobsetFileWildcard()
{
return _( "KiCad jobset files" ) + AddFileExtListToFilter( { KiCadJobSetFileExtension } );
}

View File

@ -48,6 +48,7 @@
#include <eeschema_settings.h>
#include <schematic.h>
#include <paths.h>
#include <jobs/job_export_sch_netlist.h>
#include <eeschema_id.h>
#include <wx/checkbox.h>
@ -81,6 +82,17 @@ enum PANEL_NETLIST_INDEX
};
std::map<JOB_EXPORT_SCH_NETLIST::FORMAT, wxString> jobNetlistNameLookup =
{
{ JOB_EXPORT_SCH_NETLIST::FORMAT::KICADSEXPR, _( "KiCad" ) },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::ORCADPCB2, _( "OrcadPCB2" ) },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::ALLEGRO, _( "Allegro" ) },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::PADS, _( "PADS" ) },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::CADSTAR, _( "CadStar" ) },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::SPICE, _( "SPICE" ) },
{ JOB_EXPORT_SCH_NETLIST::FORMAT::SPICEMODEL, _( "SPICE Model" ) }
};
/* wxPanels for creating the NoteBook pages for each netlist format: */
class EXPORT_NETLIST_PAGE : public wxPanel
{
@ -195,7 +207,16 @@ EXPORT_NETLIST_PAGE::EXPORT_NETLIST_PAGE( wxNotebook* aParent, const wxString& a
DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* aEditFrame ) :
DIALOG_EXPORT_NETLIST_BASE( aEditFrame )
DIALOG_EXPORT_NETLIST( aEditFrame, aEditFrame )
{
}
DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* aEditFrame, wxWindow* aParent,
JOB_EXPORT_SCH_NETLIST* aJob ) :
DIALOG_EXPORT_NETLIST_BASE( aParent ),
m_job( aJob )
{
m_editFrame = aEditFrame;
@ -235,16 +256,41 @@ DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* aEditFrame ) :
InstallPageSpice();
InstallPageSpiceModel();
InstallCustomPages();
SetupStandardButtons( { { wxID_OK, _( "Export Netlist" ) },
{ wxID_CANCEL, _( "Close" ) } } );
wxString selectedPageFormatName;
if( !m_job )
{
m_outputPath->Hide();
m_staticTextOutputPath->Hide();
InstallCustomPages();
SetupStandardButtons( { { wxID_OK, _( "Export Netlist" ) },
{ wxID_CANCEL, _( "Close" ) } } );
selectedPageFormatName = settings.m_NetFormatName;
}
else
{
m_MessagesBox->Hide();
m_outputPath->SetValue( m_job->GetOutputPath() );
SetupStandardButtons( { { wxID_OK, _( "Save" ) },
{ wxID_CANCEL, _( "Close" ) } } );
// custom netlist (external invokes, not supported)
auto it = jobNetlistNameLookup.find( m_job->format );
if( it != jobNetlistNameLookup.end() )
selectedPageFormatName = it->second;
m_buttonAddGenerator->Hide();
m_buttonDelGenerator->Hide();
}
for( int ii = 0; ii < DEFINED_NETLISTS_COUNT + CUSTOMPANEL_COUNTMAX; ++ii )
{
if( EXPORT_NETLIST_PAGE* candidate = m_PanelNetType[ii] )
{
if( candidate->GetPageNetFmtName() == settings.m_NetFormatName )
if( candidate->GetPageNetFmtName() == selectedPageFormatName )
{
m_NoteBook->ChangeSelection( ii );
break;
@ -393,7 +439,6 @@ void DIALOG_EXPORT_NETLIST::OnNetlistTypeSelection( wxNotebookEvent& event )
bool DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
{
bool changed = false;
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
bool saveAllDissipations = m_PanelNetType[ PANELSPICE ]->m_SaveAllDissipations->IsChecked();
@ -402,26 +447,46 @@ bool DIALOG_EXPORT_NETLIST::NetlistUpdateOpt()
bool curSheetAsRoot = m_PanelNetType[ PANELSPICE ]->m_CurSheetAsRoot->GetValue();
bool spiceModelCurSheetAsRoot = m_PanelNetType[ PANELSPICEMODEL ]->m_CurSheetAsRoot->GetValue();
SCHEMATIC_SETTINGS& settings = m_editFrame->Schematic().Settings();
wxString netFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
if( !m_job )
{
SCHEMATIC_SETTINGS& settings = m_editFrame->Schematic().Settings();
wxString netFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
changed |= ( settings.m_SpiceSaveAllVoltages != saveAllVoltages );
changed |= ( settings.m_SpiceSaveAllCurrents != saveAllCurrents );
changed |= ( settings.m_SpiceSaveAllDissipations != saveAllDissipations );
changed |= ( settings.m_SpiceSaveAllEvents != saveAllEvents );
changed |= ( settings.m_SpiceCommandString != spiceCmdString );
changed |= ( settings.m_SpiceCurSheetAsRoot != curSheetAsRoot );
changed |= ( settings.m_SpiceModelCurSheetAsRoot != spiceModelCurSheetAsRoot );
changed |= ( settings.m_NetFormatName != netFormatName );
changed |= ( settings.m_SpiceSaveAllVoltages != saveAllVoltages );
changed |= ( settings.m_SpiceSaveAllCurrents != saveAllCurrents );
changed |= ( settings.m_SpiceSaveAllDissipations != saveAllDissipations );
changed |= ( settings.m_SpiceSaveAllEvents != saveAllEvents );
changed |= ( settings.m_SpiceCommandString != spiceCmdString );
changed |= ( settings.m_SpiceCurSheetAsRoot != curSheetAsRoot );
changed |= ( settings.m_SpiceModelCurSheetAsRoot != spiceModelCurSheetAsRoot );
changed |= ( settings.m_NetFormatName != netFormatName );
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
settings.m_SpiceSaveAllDissipations = saveAllDissipations;
settings.m_SpiceSaveAllEvents = saveAllEvents;
settings.m_SpiceCommandString = spiceCmdString;
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
settings.m_SpiceModelCurSheetAsRoot = spiceModelCurSheetAsRoot;
settings.m_NetFormatName = netFormatName;
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
settings.m_SpiceSaveAllDissipations = saveAllDissipations;
settings.m_SpiceSaveAllEvents = saveAllEvents;
settings.m_SpiceCommandString = spiceCmdString;
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
settings.m_SpiceModelCurSheetAsRoot = spiceModelCurSheetAsRoot;
settings.m_NetFormatName = netFormatName;
}
else
{
for (auto i = jobNetlistNameLookup.begin(); i != jobNetlistNameLookup.end(); ++i)
{
if( i->second == m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName() )
{
m_job->format = i->first;
break;
}
}
m_job->SetOutputPath( m_outputPath->GetValue() );
m_job->m_spiceSaveAllVoltages = saveAllVoltages;
m_job->m_spiceSaveAllCurrents = saveAllCurrents;
m_job->m_spiceSaveAllDissipations = saveAllDissipations;
m_job->m_spiceSaveAllEvents = saveAllEvents;
}
return changed;
}
@ -434,8 +499,18 @@ bool DIALOG_EXPORT_NETLIST::TransferDataFromWindow()
wxString fileExt;
wxString title = _( "Save Netlist File" );
if( NetlistUpdateOpt() )
m_editFrame->OnModify();
if (m_job)
{
NetlistUpdateOpt();
return true;
}
else
{
if( NetlistUpdateOpt() )
m_editFrame->OnModify();
}
EXPORT_NETLIST_PAGE* currPage;
currPage = (EXPORT_NETLIST_PAGE*) m_NoteBook->GetCurrentPage();

View File

@ -30,13 +30,15 @@
class SCH_EDIT_FRAME;
class EXPORT_NETLIST_PAGE;
class JOB_EXPORT_SCH_NETLIST;
/* Dialog frame for creating netlists */
class DIALOG_EXPORT_NETLIST : public DIALOG_EXPORT_NETLIST_BASE
{
public:
DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* aEditFrame );
DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* aEditFrame, wxWindow* aParent,
JOB_EXPORT_SCH_NETLIST* aJob = nullptr );
~DIALOG_EXPORT_NETLIST(){};
private:
@ -82,5 +84,6 @@ private:
private:
SCH_EDIT_FRAME* m_editFrame;
JOB_EXPORT_SCH_NETLIST* m_job;
std::vector<EXPORT_NETLIST_PAGE*> m_PanelNetType;
};

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -27,6 +27,21 @@ DIALOG_EXPORT_NETLIST_BASE::DIALOG_EXPORT_NETLIST_BASE( wxWindow* parent, wxWind
wxBoxSizer* bUpperSizer;
bUpperSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer8;
bSizer8 = new wxBoxSizer( wxHORIZONTAL );
m_staticTextOutputPath = new wxStaticText( this, wxID_ANY, _("Output Path:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextOutputPath->Wrap( -1 );
bSizer8->Add( m_staticTextOutputPath, 0, wxALL, 5 );
m_outputPath = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_outputPath->SetMinSize( wxSize( 450,-1 ) );
bSizer8->Add( m_outputPath, 0, wxALL, 5 );
bUpperSizer->Add( bSizer8, 1, wxEXPAND, 5 );
m_NoteBook = new wxNotebook( this, ID_CHANGE_NOTEBOOK_PAGE, wxDefaultPosition, wxDefaultSize, 0 );
m_NoteBook->SetMinSize( wxSize( 540,-1 ) );

View File

@ -1,34 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="17"/>
<FileVersion major="1" minor="18"/>
<object class="Project" expanded="true">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">0</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="cpp_class_decoration"></property>
<property name="cpp_disconnect_events">0</property>
<property name="cpp_event_generation">table</property>
<property name="cpp_help_provider">none</property>
<property name="cpp_namespace"></property>
<property name="cpp_precompiled_header"></property>
<property name="cpp_use_array_enum">0</property>
<property name="cpp_use_enum">1</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">table</property>
<property name="file">dialog_export_netlist_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">DIALOG_EXPORT_NETLIST_BASE</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="php_disconnect_events">0</property>
<property name="php_disconnect_mode">source_name</property>
<property name="php_skip_events">1</property>
<property name="python_disconnect_events">0</property>
<property name="python_disconnect_mode">source_name</property>
<property name="python_image_path_wrapper_function_name"></property>
<property name="python_indent_with_spaces"></property>
<property name="python_skip_events">1</property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<property name="use_native_eol">0</property>
<object class="Dialog" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
@ -71,6 +73,144 @@
<property name="name">bUpperSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer8</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="true">
<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="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="label">Output Path:</property>
<property name="markup">0</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"></property>
<property name="moveable">1</property>
<property name="name">m_staticTextOutputPath</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="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></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="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="true">
<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="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="maxlength">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">450,-1</property>
<property name="moveable">1</property>
<property name="name">m_outputPath</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="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
@ -80,10 +220,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmapsize"></property>
@ -150,10 +290,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></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>
@ -221,10 +361,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
@ -296,10 +436,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
@ -435,10 +575,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></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>
@ -497,10 +637,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></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>
@ -562,10 +702,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></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>
@ -624,10 +764,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></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>
@ -700,10 +840,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -13,21 +13,21 @@
class WX_HTML_REPORT_PANEL;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/notebook.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/panel.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/notebook.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/dialog.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
///////////////////////////////////////////////////////////////////////////
@ -50,9 +50,11 @@ class DIALOG_EXPORT_NETLIST_BASE : public DIALOG_SHIM
{
ID_CHANGE_NOTEBOOK_PAGE = 1000,
ID_ADD_PLUGIN,
ID_DEL_PLUGIN
ID_DEL_PLUGIN,
};
wxStaticText* m_staticTextOutputPath;
wxTextCtrl* m_outputPath;
wxNotebook* m_NoteBook;
WX_HTML_REPORT_PANEL* m_MessagesBox;
wxBoxSizer* m_buttonSizer;
@ -91,7 +93,7 @@ class NETLIST_DIALOG_ADD_GENERATOR_BASE : public DIALOG_SHIM
protected:
enum
{
wxID_BROWSE_PLUGINS = 1000
wxID_BROWSE_PLUGINS = 1000,
};
wxStaticText* m_staticTextName;

View File

@ -51,29 +51,47 @@
#include <kiplatform/environment.h>
#include <wx/log.h>
#include <jobs/job_export_sch_plot.h>
// static members (static to remember last state):
int DIALOG_PLOT_SCHEMATIC::m_pageSizeSelect = PAGE_SIZE_AUTO;
HPGL_PAGE_SIZE DIALOG_PLOT_SCHEMATIC::m_HPGLPaperSizeSelect = HPGL_PAGE_SIZE::DEFAULT;
DIALOG_PLOT_SCHEMATIC::DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* parent )
: DIALOG_PLOT_SCHEMATIC_BASE( parent ),
m_parent( parent ),
DIALOG_PLOT_SCHEMATIC::DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* aEditFrame ) :
DIALOG_PLOT_SCHEMATIC( aEditFrame, aEditFrame )
{
}
DIALOG_PLOT_SCHEMATIC::DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* aEditFrame, wxWindow* aParent,
JOB_EXPORT_SCH_PLOT* aJob )
: DIALOG_PLOT_SCHEMATIC_BASE( aEditFrame ),
m_editFrame( aEditFrame ),
m_plotFormat( PLOT_FORMAT::UNDEFINED ),
m_HPGLPenSize( 1.0 ),
m_defaultLineWidth( parent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits ),
m_penWidth( parent, m_penWidthLabel, m_penWidthCtrl, m_penWidthUnits )
m_defaultLineWidth( aEditFrame, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits ),
m_penWidth( aEditFrame, m_penWidthLabel, m_penWidthCtrl, m_penWidthUnits ), m_job( aJob )
{
m_configChanged = false;
m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
m_MessagesBox->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
SetupStandardButtons( { { wxID_OK, _( "Plot All Pages" ) },
{ wxID_APPLY, _( "Plot Current Page" ) },
{ wxID_CANCEL, _( "Close" ) } } );
if( !m_job )
{
m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
m_MessagesBox->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
SetupStandardButtons( { { wxID_OK, _( "Plot All Pages" ) },
{ wxID_APPLY, _( "Plot Current Page" ) },
{ wxID_CANCEL, _( "Close" ) } } );
}
else
{
m_browseButton->Hide();
m_MessagesBox->Hide();
SetupStandardButtons( { { wxID_OK, _( "Save" ) },
{ wxID_CANCEL, _( "Close" ) } } );
}
initDlg();
@ -87,72 +105,104 @@ void DIALOG_PLOT_SCHEMATIC::initDlg()
auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
wxASSERT( cfg );
if( cfg )
if( !m_job )
{
for( COLOR_SETTINGS* settings : m_parent->GetSettingsManager()->GetColorSettingsList() )
if( cfg )
{
int idx = m_colorTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
for( COLOR_SETTINGS* settings : m_editFrame->GetSettingsManager()->GetColorSettingsList() )
{
int idx = m_colorTheme->Append( settings->GetName(), static_cast<void*>( settings ) );
if( settings->GetFilename() == cfg->m_PlotPanel.color_theme )
m_colorTheme->SetSelection( idx );
if( settings->GetFilename() == cfg->m_PlotPanel.color_theme )
m_colorTheme->SetSelection( idx );
}
m_colorTheme->Enable( cfg->m_PlotPanel.color );
m_plotBackgroundColor->Enable( cfg->m_PlotPanel.color );
m_plotBackgroundColor->SetValue( cfg->m_PlotPanel.background_color );
// Set color or B&W plot option
setModeColor( cfg->m_PlotPanel.color );
// Set plot or not frame reference option
setPlotDrawingSheet( cfg->m_PlotPanel.frame_reference );
setOpenFileAfterPlot( cfg->m_PlotPanel.open_file_after_plot );
m_plotPDFPropertyPopups->SetValue( cfg->m_PlotPanel.pdf_property_popups );
m_plotPDFMetadata->SetValue( cfg->m_PlotPanel.pdf_metadata );
// HPGL plot origin and unit system configuration
m_plotOriginOpt->SetSelection( cfg->m_PlotPanel.hpgl_origin );
m_HPGLPaperSizeSelect = static_cast<HPGL_PAGE_SIZE>( cfg->m_PlotPanel.hpgl_paper_size );
// HPGL Pen Size is stored in mm in config
m_HPGLPenSize = cfg->m_PlotPanel.hpgl_pen_size * schIUScale.IU_PER_MM;
// Switch to the last save plot format
PLOT_FORMAT fmt = static_cast<PLOT_FORMAT>( cfg->m_PlotPanel.format );
switch( fmt )
{
default:
case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 0 ); break;
case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 1 ); break;
case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
}
if( fmt == PLOT_FORMAT::DXF || fmt == PLOT_FORMAT::HPGL )
m_plotBackgroundColor->Disable();
// Set the default line width (pen width which should be used for
// items that do not have a pen size defined (like frame ref)
// the default line width is stored in mils in config
m_defaultLineWidth.SetValue( schIUScale.MilsToIU( cfg->m_Drawing.default_line_thickness ) );
}
m_colorTheme->Enable( cfg->m_PlotPanel.color );
// Initialize HPGL specific widgets
m_penWidth.SetValue( m_HPGLPenSize );
m_plotBackgroundColor->Enable( cfg->m_PlotPanel.color );
m_plotBackgroundColor->SetValue( cfg->m_PlotPanel.background_color );
// Plot directory
SCHEMATIC_SETTINGS& settings = m_editFrame->Schematic().Settings();
wxString path = settings.m_PlotDirectoryName;
#ifdef __WINDOWS__
path.Replace( '/', '\\' );
#endif
m_outputDirectoryName->SetValue( path );
}
else if( m_job )
{
m_plotFormatOpt->SetSelection( static_cast<int>( m_job->m_plotFormat ) );
m_plotBackgroundColor->SetValue( m_job->m_useBackgroundColor );
m_penWidth.SetValue( m_job->m_HPGLPenSize );
m_HPGLPaperSizeSelect = static_cast<HPGL_PAGE_SIZE>( m_job->m_HPGLPaperSizeSelect );
m_plotPDFPropertyPopups->SetValue( m_job->m_PDFPropertyPopups );
m_plotPDFMetadata->SetValue( m_job->m_PDFMetadata );
m_colorTheme->Enable( m_job->m_plotFormat != SCH_PLOT_FORMAT::HPGL );
m_ModeColorOption->Enable( m_job->m_plotFormat != SCH_PLOT_FORMAT::HPGL );
m_plotOriginOpt->SetSelection( static_cast<int>( m_job->m_HPGLPlotOrigin ) );
m_pageSizeSelect = static_cast<int>( m_job->m_pageSizeSelect );
// Set color or B&W plot option
setModeColor( cfg->m_PlotPanel.color );
// Set plot or not frame reference option
setPlotDrawingSheet( cfg->m_PlotPanel.frame_reference );
setOpenFileAfterPlot( cfg->m_PlotPanel.open_file_after_plot );
m_plotPDFPropertyPopups->SetValue( cfg->m_PlotPanel.pdf_property_popups );
m_plotPDFMetadata->SetValue( cfg->m_PlotPanel.pdf_metadata );
// HPGL plot origin and unit system configuration
m_plotOriginOpt->SetSelection( cfg->m_PlotPanel.hpgl_origin );
m_HPGLPaperSizeSelect = static_cast<HPGL_PAGE_SIZE>( cfg->m_PlotPanel.hpgl_paper_size );
// HPGL Pen Size is stored in mm in config
m_HPGLPenSize = cfg->m_PlotPanel.hpgl_pen_size * schIUScale.IU_PER_MM;
// Switch to the last save plot format
PLOT_FORMAT fmt = static_cast<PLOT_FORMAT>( cfg->m_PlotPanel.format );
switch( fmt )
// Set the plot format
switch( m_job->m_plotFormat )
{
default:
case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 0 ); break;
case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 1 ); break;
case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
case SCH_PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 0 ); break;
case SCH_PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 1 ); break;
case SCH_PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
case SCH_PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
case SCH_PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
}
if( fmt == PLOT_FORMAT::DXF || fmt == PLOT_FORMAT::HPGL )
m_plotBackgroundColor->Disable();
// And then hide it
m_plotFormatOpt->Hide();
// Set the default line width (pen width which should be used for
// items that do not have a pen size defined (like frame ref)
// the default line width is stored in mils in config
m_defaultLineWidth.SetValue( schIUScale.MilsToIU( cfg->m_Drawing.default_line_thickness ) );
m_outputDirectoryName->SetValue( m_job->GetOutputPath() );
}
// Initialize HPGL specific widgets
m_penWidth.SetValue( m_HPGLPenSize );
// Plot directory
SCHEMATIC_SETTINGS& settings = m_parent->Schematic().Settings();
wxString path = settings.m_PlotDirectoryName;
#ifdef __WINDOWS__
path.Replace( '/', '\\' );
#endif
m_outputDirectoryName->SetValue( path );
}
@ -185,7 +235,7 @@ void DIALOG_PLOT_SCHEMATIC::OnOutputDirectoryBrowseClicked( wxCommandEvent& even
wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
wxFileName fn( Prj().AbsolutePath( m_parent->Schematic().Root().GetFileName() ) );
wxFileName fn( Prj().AbsolutePath( m_editFrame->Schematic().Root().GetFileName() ) );
wxString defaultPath = fn.GetPathWithSep();
wxString msg;
wxFileName relPathTest; // Used to test if we can make the path relative
@ -331,7 +381,7 @@ void DIALOG_PLOT_SCHEMATIC::getPlotOptions( RENDER_SETTINGS* aSettings )
wxString path = m_outputDirectoryName->GetValue();
path.Replace( '\\', '/' );
SCHEMATIC_SETTINGS& settings = m_parent->Schematic().Settings();
SCHEMATIC_SETTINGS& settings = m_editFrame->Schematic().Settings();
if( settings.m_PlotDirectoryName != path )
m_configChanged = true;
@ -346,7 +396,7 @@ COLOR_SETTINGS* DIALOG_PLOT_SCHEMATIC::getColorSettings()
if( selection < 0 )
{
return m_parent->GetSettingsManager()->GetColorSettings(
return m_editFrame->GetSettingsManager()->GetColorSettings(
COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT );
}
@ -370,13 +420,13 @@ void DIALOG_PLOT_SCHEMATIC::plotSchematic( bool aPlotAll )
{
wxBusyCursor dummy;
SCH_RENDER_SETTINGS renderSettings( *m_parent->GetRenderSettings() );
SCH_RENDER_SETTINGS renderSettings( *m_editFrame->GetRenderSettings() );
renderSettings.m_ShowHiddenPins = false;
renderSettings.m_ShowHiddenFields = false;
getPlotOptions( &renderSettings );
std::unique_ptr<SCH_PLOTTER> schPlotter = std::make_unique<SCH_PLOTTER>( m_parent );
std::unique_ptr<SCH_PLOTTER> schPlotter = std::make_unique<SCH_PLOTTER>( m_editFrame );
COLOR_SETTINGS* colors = getColorSettings();
@ -426,7 +476,7 @@ wxString DIALOG_PLOT_SCHEMATIC::getOutputPath()
std::function<bool( wxString* )> textResolver =
[&]( wxString* token ) -> bool
{
SCHEMATIC& schematic = m_parent->Schematic();
SCHEMATIC& schematic = m_editFrame->Schematic();
return schematic.ResolveTextVar( &schematic.CurrentSheet(), token, 0 );
};
@ -444,7 +494,7 @@ wxString DIALOG_PLOT_SCHEMATIC::getOutputPath()
// project path is not defined.
if( Prj().IsNullProject() )
{
SCH_SCREEN* screen = m_parent->Schematic().RootScreen();
SCH_SCREEN* screen = m_editFrame->Schematic().RootScreen();
if( screen && !screen->GetFileName().IsEmpty() )
{

View File

@ -42,11 +42,13 @@ class SCH_EDIT_FRAME;
class SCH_SCREEN;
class SCH_SHEET_PATH;
class JOB_EXPORT_SCH_PLOT;
class DIALOG_PLOT_SCHEMATIC : public DIALOG_PLOT_SCHEMATIC_BASE
{
public:
DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* parent );
DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* aEditFrame );
DIALOG_PLOT_SCHEMATIC( SCH_EDIT_FRAME* aEditFrame, wxWindow* aParent, JOB_EXPORT_SCH_PLOT* aJob = nullptr );
/**
* Return true if the project configuration was modified.
@ -142,7 +144,7 @@ private:
*/
wxString getOutputPath();
SCH_EDIT_FRAME* m_parent;
SCH_EDIT_FRAME* m_editFrame;
bool m_configChanged; // true if a project config param has changed
PLOT_FORMAT m_plotFormat;
static int m_pageSizeSelect; // Static to keep last option for some format
@ -150,6 +152,7 @@ private:
double m_HPGLPenSize;
UNIT_BINDER m_defaultLineWidth;
UNIT_BINDER m_penWidth;
JOB_EXPORT_SCH_PLOT* m_job;
};
#endif // __DIALOG_PLOT_SCHEMATIC__

View File

@ -346,6 +346,8 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
int HandleJob( JOB* aJob ) override;
bool HandleJobConfig( JOB* aJob, wxWindow* aParent ) override;
private:
bool loadGlobalLibTable();
bool loadGlobalDesignBlockLibTable();
@ -697,3 +699,9 @@ int IFACE::HandleJob( JOB* aJob )
{
return m_jobHandler->RunJob( aJob );
}
bool IFACE::HandleJobConfig( JOB* aJob, wxWindow* aParent )
{
return m_jobHandler->HandleJobConfig( aJob, aParent );
}

View File

@ -79,8 +79,24 @@ PROJECT* EESCHEMA_HELPERS::GetDefaultProject( bool aSetActive )
SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( const wxString& aFileName,
SCH_IO_MGR::SCH_FILE_T aFormat, bool aSetActive,
bool aForceDefaultProject )
bool aSetActive,
bool aForceDefaultProject,
PROJECT* aProject )
{
if( aFileName.EndsWith( FILEEXT::KiCadSchematicFileExtension ) )
return LoadSchematic( aFileName, SCH_IO_MGR::SCH_KICAD, aSetActive, aForceDefaultProject, aProject );
else if( aFileName.EndsWith( FILEEXT::LegacySchematicFileExtension ) )
return LoadSchematic( aFileName, SCH_IO_MGR::SCH_LEGACY, aSetActive, aForceDefaultProject, aProject );
// as fall back for any other kind use the legacy format
return LoadSchematic( aFileName, SCH_IO_MGR::SCH_LEGACY, aSetActive, aForceDefaultProject, aProject );
}
SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( const wxString& aFileName, SCH_IO_MGR::SCH_FILE_T aFormat,
bool aSetActive,
bool aForceDefaultProject,
PROJECT* aProject )
{
wxFileName pro = aFileName;
pro.SetExt( FILEEXT::ProjectFileExtension );
@ -91,7 +107,12 @@ SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( const wxString& aFileName,
// It also avoid wxWidget alerts about locale issues, later, when using Python 3
LOCALE_IO dummy;
PROJECT* project = GetSettingsManager()->GetProject( projectPath );
PROJECT* project = aProject;
if( !project )
{
project = GetSettingsManager()->GetProject( projectPath );
}
if( !aForceDefaultProject )
{

View File

@ -44,8 +44,10 @@ public:
static SETTINGS_MANAGER* GetSettingsManager();
static void SetSchEditFrame( SCH_EDIT_FRAME* aSchEditFrame );
static PROJECT* GetDefaultProject( bool aSetActive );
static SCHEMATIC* LoadSchematic( const wxString& aFileName, bool aSetActive, bool aForceDefaultProject,
PROJECT* aProject = nullptr );
static SCHEMATIC* LoadSchematic( const wxString& aFileName, SCH_IO_MGR::SCH_FILE_T aFormat,
bool aSetActive, bool aForceDefaultProject );
bool aSetActive, bool aForceDefaultProject, PROJECT* aProject = nullptr );
private:
static SCH_EDIT_FRAME* s_SchEditFrame;

View File

@ -67,27 +67,123 @@
#include <fields_data_model.h>
#include <dialogs/dialog_export_netlist.h>
#include <dialogs/dialog_plot_schematic.h>
EESCHEMA_JOBS_HANDLER::EESCHEMA_JOBS_HANDLER( KIWAY* aKiway ) :
JOB_DISPATCHER( aKiway )
JOB_DISPATCHER( aKiway ),
m_cliSchematic( nullptr )
{
Register( "bom",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportBom, this, std::placeholders::_1 ) );
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportBom, this, std::placeholders::_1 ),
[aKiway]( JOB* job, wxWindow* aParent ) -> bool
{
JOB_EXPORT_SCH_BOM* bomJob = dynamic_cast<JOB_EXPORT_SCH_BOM*>( job );
if( !bomJob )
return false;
return false;
} );
Register( "pythonbom",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPythonBom, this,
std::placeholders::_1 ) );
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPythonBom, this, std::placeholders::_1 ),
[]( JOB* job, wxWindow* aParent ) -> bool
{
return false;
});
Register( "netlist",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportNetlist, this, std::placeholders::_1 ) );
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportNetlist, this, std::placeholders::_1 ),
[aKiway]( JOB* job, wxWindow* aParent ) -> bool
{
JOB_EXPORT_SCH_NETLIST* netJob =
dynamic_cast < JOB_EXPORT_SCH_NETLIST*>( job );
if( !netJob )
return false;
SCH_EDIT_FRAME* editFrame =
dynamic_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
DIALOG_EXPORT_NETLIST dlg( editFrame, aParent, netJob );
dlg.ShowModal();
return dlg.GetReturnCode() == wxID_OK;
} );
Register( "plot",
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPlot, this, std::placeholders::_1 ) );
std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPlot, this, std::placeholders::_1 ),
[aKiway]( JOB* job, wxWindow* aParent ) -> bool
{
JOB_EXPORT_SCH_PLOT* plotJob = dynamic_cast<JOB_EXPORT_SCH_PLOT*>( job );
if( !plotJob )
return false;
SCH_EDIT_FRAME* editFrame =
dynamic_cast<SCH_EDIT_FRAME*>( aKiway->Player( FRAME_SCH, false ) );
DIALOG_PLOT_SCHEMATIC dlg( editFrame, aParent, plotJob );
dlg.ShowModal();
return false;
} );
Register( "symupgrade",
std::bind( &EESCHEMA_JOBS_HANDLER::JobSymUpgrade, this, std::placeholders::_1 ) );
std::bind( &EESCHEMA_JOBS_HANDLER::JobSymUpgrade, this, std::placeholders::_1 ),
[]( JOB* job, wxWindow* aParent ) -> bool
{
return false;
} );
Register( "symsvg",
std::bind( &EESCHEMA_JOBS_HANDLER::JobSymExportSvg, this, std::placeholders::_1 ) );
Register( "erc",
std::bind( &EESCHEMA_JOBS_HANDLER::JobSchErc, this, std::placeholders::_1 ) );
std::bind( &EESCHEMA_JOBS_HANDLER::JobSymExportSvg, this, std::placeholders::_1 ),
[]( JOB* job, wxWindow* aParent ) -> bool
{
return false;
} );
Register( "erc", std::bind( &EESCHEMA_JOBS_HANDLER::JobSchErc, this, std::placeholders::_1 ),
[]( JOB* job, wxWindow* aParent ) -> bool
{
return false;
} );
}
SCHEMATIC* EESCHEMA_JOBS_HANDLER::getSchematic( const wxString& aPath )
{
SCHEMATIC* sch = nullptr;
if( !Pgm().IsGUI() && Pgm().GetSettingsManager().IsProjectOpenNotDummy() )
{
PROJECT& project = Pgm().GetSettingsManager().Prj();
wxString schPath = aPath;
if( schPath.IsEmpty() )
{
wxFileName path = project.GetProjectFullName();
path.SetExt( FILEEXT::KiCadSchematicFileExtension );
path.MakeAbsolute();
schPath = path.GetFullPath();
}
if( !m_cliSchematic )
{
m_reporter->Report( _( "Loading schematic\n" ), RPT_SEVERITY_INFO );
m_cliSchematic = EESCHEMA_HELPERS::LoadSchematic( schPath, true, false, &project );
}
sch = m_cliSchematic;
}
else if( !aPath.IsEmpty() )
{
m_reporter->Report( _( "Loading schematic\n" ), RPT_SEVERITY_INFO );
sch = EESCHEMA_HELPERS::LoadSchematic( aPath, true, false );
}
if( !sch )
{
m_reporter->Report( _( "Failed to load schematic\n" ), RPT_SEVERITY_ERROR );
}
return sch;
}
void EESCHEMA_JOBS_HANDLER::InitRenderSettings( SCH_RENDER_SETTINGS* aRenderSettings,
const wxString& aTheme, SCHEMATIC* aSch,
@ -149,14 +245,10 @@ int EESCHEMA_JOBS_HANDLER::JobExportPlot( JOB* aJob )
if( !aPlotJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aPlotJob->m_filename, SCH_IO_MGR::SCH_KICAD,
true, false );
SCHEMATIC* sch = getSchematic( aPlotJob->m_filename );
if( sch == nullptr )
{
m_reporter->Report( _( "Failed to load schematic file\n" ), RPT_SEVERITY_ERROR );
if( !sch )
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
sch->Prj().ApplyTextVars( aJob->GetVarOverrides() );
@ -248,14 +340,10 @@ int EESCHEMA_JOBS_HANDLER::JobExportNetlist( JOB* aJob )
if( !aNetJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aNetJob->m_filename, SCH_IO_MGR::SCH_KICAD,
true, false );
SCHEMATIC* sch = getSchematic( aNetJob->m_filename );
if( sch == nullptr )
{
m_reporter->Report( _( "Failed to load schematic file\n" ), RPT_SEVERITY_ERROR );
if( !sch )
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
// Annotation warning check
SCH_REFERENCE_LIST referenceList;
@ -335,16 +423,16 @@ int EESCHEMA_JOBS_HANDLER::JobExportNetlist( JOB* aJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
}
if( aNetJob->m_outputFile.IsEmpty() )
if( aNetJob->GetOutputPath().IsEmpty() )
{
wxFileName fn = sch->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( fileExt );
aNetJob->m_outputFile = fn.GetFullName();
aNetJob->SetOutputPath( fn.GetFullName() );
}
bool res = helper->WriteNetlist( aNetJob->m_outputFile, netlistOption, *m_reporter );
bool res = helper->WriteNetlist( aNetJob->GetOutputPath(), netlistOption, *m_reporter );
if( !res )
return CLI::EXIT_CODES::ERR_UNKNOWN;
@ -360,14 +448,10 @@ int EESCHEMA_JOBS_HANDLER::JobExportBom( JOB* aJob )
if( !aBomJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aBomJob->m_filename, SCH_IO_MGR::SCH_KICAD,
true, false );
SCHEMATIC* sch = getSchematic( aBomJob->m_filename );
if( sch == nullptr )
{
m_reporter->Report( _( "Failed to load schematic file\n" ), RPT_SEVERITY_ERROR );
if( !sch )
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
sch->Prj().ApplyTextVars( aJob->GetVarOverrides() );
@ -540,21 +624,21 @@ int EESCHEMA_JOBS_HANDLER::JobExportBom( JOB* aJob )
dataModel.ApplyBomPreset( preset );
if( aBomJob->m_outputFile.IsEmpty() )
if( aBomJob->GetOutputPath().IsEmpty() )
{
wxFileName fn = sch->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( FILEEXT::CsvFileExtension );
aBomJob->m_outputFile = fn.GetFullName();
aBomJob->SetOutputPath( fn.GetFullName() );
}
wxFile f;
if( !f.Open( aBomJob->m_outputFile, wxFile::write ) )
if( !f.Open( aBomJob->GetOutputPath(), wxFile::write ) )
{
m_reporter->Report( wxString::Format( _( "Unable to open destination '%s'" ),
aBomJob->m_outputFile ),
aBomJob->GetOutputPath() ),
RPT_SEVERITY_ERROR );
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
@ -619,14 +703,10 @@ int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob )
if( !aNetJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aNetJob->m_filename, SCH_IO_MGR::SCH_KICAD,
true, false );
SCHEMATIC* sch = getSchematic( aNetJob->m_filename );
if( sch == nullptr )
{
m_reporter->Report( _( "Failed to load schematic file\n" ), RPT_SEVERITY_ERROR );
if( !sch )
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
// Annotation warning check
SCH_REFERENCE_LIST referenceList;
@ -657,16 +737,16 @@ int EESCHEMA_JOBS_HANDLER::JobExportPythonBom( JOB* aJob )
std::unique_ptr<NETLIST_EXPORTER_XML> xmlNetlist =
std::make_unique<NETLIST_EXPORTER_XML>( sch );
if( aNetJob->m_outputFile.IsEmpty() )
if( aNetJob->GetOutputPath().IsEmpty() )
{
wxFileName fn = sch->GetFileName();
fn.SetName( fn.GetName() + "-bom" );
fn.SetExt( FILEEXT::XmlFileExtension );
aNetJob->m_outputFile = fn.GetFullName();
aNetJob->SetOutputPath( fn.GetFullName() );
}
bool res = xmlNetlist->WriteNetlist( aNetJob->m_outputFile, GNL_OPT_BOM, *m_reporter );
bool res = xmlNetlist->WriteNetlist( aNetJob->GetOutputPath(), GNL_OPT_BOM, *m_reporter );
if( !res )
return CLI::EXIT_CODES::ERR_UNKNOWN;
@ -967,14 +1047,10 @@ int EESCHEMA_JOBS_HANDLER::JobSchErc( JOB* aJob )
if( !ercJob )
return CLI::EXIT_CODES::ERR_UNKNOWN;
SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( ercJob->m_filename, SCH_IO_MGR::SCH_KICAD,
true, false );
SCHEMATIC* sch = getSchematic( ercJob->m_filename );
if( sch == nullptr )
{
m_reporter->Report( _( "Failed to load schematic file\n" ), RPT_SEVERITY_ERROR );
if( !sch )
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
sch->Prj().ApplyTextVars( aJob->GetVarOverrides() );

View File

@ -62,11 +62,14 @@ public:
const wxString& aDrawingSheetOverride = wxEmptyString );
private:
SCHEMATIC* getSchematic( const wxString& aPath );
int doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob, SCH_RENDER_SETTINGS* aRenderSettings,
LIB_SYMBOL* symbol );
DS_PROXY_VIEW_ITEM* getDrawingSheetProxyView( SCHEMATIC* aSch );
SCHEMATIC* m_cliSchematic;
};
#endif

View File

@ -493,6 +493,15 @@ public:
*/
bool m_EnableGit;
/**
* Enable jobsets
*
* Setting name: "EnableJobs"
* Valid values: 0 or 1
* Default value: 0
*/
bool m_EnableJobset;
/**
* Enable option to load lib files with text editor.
*

View File

@ -25,15 +25,16 @@ namespace CLI
{
namespace EXIT_CODES
{
static const int AVOID_CLOSING = -1;
static const int SUCCESS = 0;
static const int OK = 0;
static const int ERR_ARGS = 1;
static const int ERR_UNKNOWN = 2;
static const int ERR_INVALID_INPUT_FILE = 3;
static const int ERR_INVALID_OUTPUT_CONFLICT = 4;
static const int AVOID_CLOSING = -1;
static const int SUCCESS = 0;
static const int OK = 0;
static const int ERR_ARGS = 1;
static const int ERR_UNKNOWN = 2;
static const int ERR_INVALID_INPUT_FILE = 3;
static const int ERR_INVALID_OUTPUT_CONFLICT = 4;
///< Rules check violation count was greater than 0
static const int ERR_RC_VIOLATIONS = 5;
static const int ERR_RC_VIOLATIONS = 5;
static const int ERR_JOBS_RUN_FAILED = 6;
};
}

View File

@ -28,6 +28,7 @@
#include <kicommon.h>
#include <wx/filename.h>
#include <wx/process.h>
#include <wx/zipstrm.h>
/**
@ -107,4 +108,28 @@ KICOMMON_API extern wxString QuoteFullPath( wxFileName& fn, wxPathFormat format
*/
KICOMMON_API bool RmDirRecursive( const wxString& aDirName, wxString* aErrors = nullptr );
/**
* Copy a directory and its contents to another directory.
*
* @param aSourceDir is the directory to copy.
* @param aDestDir is the directory to copy to.
* @param aErrors is a string to append any errors to.
*/
KICOMMON_API bool CopyDirectory( const wxString& aSourceDir, const wxString& aDestDir,
wxString& aErrors );
/**
* Add a directory and its contents to a zip file.
*
* @param aZip is the zip file to add to.
* @param aSourceDir is the directory to add.
* @param aErrors is a string to append any errors to.
* @param aParentDir is the parent directory to add to the zip file.
*/
KICOMMON_API bool AddDirectoryToZip( wxZipOutputStream& aZip,
const wxString& aSourceDir,
wxString& aErrors,
const wxString& aParentDir = "" );
#endif /* GESTFICH_H */

View File

@ -104,7 +104,6 @@
#include <frame_type.h>
#include <mail_type.h>
#include <ki_exception.h>
#include <jobs/job.h>
#define KIFACE_VERSION 1
@ -133,6 +132,7 @@ class KIWAY;
class KIWAY_PLAYER;
class wxTopLevelWindow;
class TOOL_ACTION;
class JOB;
/**
@ -245,6 +245,11 @@ struct KIFACE
{
return 0;
}
virtual bool HandleJobConfig( JOB* aJob, wxWindow* aParent )
{
return 0;
}
};
@ -426,7 +431,8 @@ public:
bool ProcessEvent( wxEvent& aEvent ) override;
int ProcessJob( KIWAY::FACE_T aFace, JOB* job );
int ProcessJob( KIWAY::FACE_T aFace, JOB* aJob );
bool ProcessJobConfigDialog( KIWAY::FACE_T aFace, JOB* aJob, wxWindow* aWindow );
/**
* Gets the window pointer to the blocking dialog (to send it signals)

View File

@ -260,6 +260,7 @@ public:
* @return int - number of bytes consumed
*/
int ParseHex( const char* aStart, int aCount );
int ParseHex( const std::string& str );
/**
* Return a binary string showing contents of this LSEQ.

View File

@ -287,6 +287,12 @@ public:
*/
bool IsProjectOpen() const;
/**
* Helper for checking if we have a project open that is not a dummy project
* @return true if a call to Prj() will succeed and the project is not a dummy project
*/
bool IsProjectOpenNotDummy() const;
/**
* A helper while we are not MDI-capable -- return the one and only project
* @return the loaded project

View File

@ -193,6 +193,8 @@ public:
static const std::string BrepFileExtension;
static const std::string XaoFileExtension;
static const std::string KiCadJobSetFileExtension;
static const wxString GerberFileExtensionsRegex;
static const std::string KiCadUriPrefix;
@ -269,6 +271,7 @@ public:
static wxString PngFileWildcard();
static wxString JpegFileWildcard();
static wxString HotkeyFileWildcard();
static wxString JobsetFileWildcard();
/**
* @}

View File

@ -25,7 +25,11 @@ set( KICAD_SRCS
dialogs/dialog_template_selector.cpp
dialogs/panel_kicad_launcher_base.cpp
dialogs/panel_kicad_launcher.cpp
dialogs/dialog_job_config_base.cpp
dialogs/panel_jobs_base.cpp
dialogs/panel_jobs.cpp
files-io.cpp
jobs_runner.cpp
import_proj.cpp
import_project.cpp
kicad_manager_frame.cpp
@ -41,6 +45,7 @@ set( KICAD_SRCS
set( KICAD_CLI_SRCS
cli/command.cpp
cli/command_jobset_run.cpp
cli/command_pcb_export_base.cpp
cli/command_pcb_drc.cpp
cli/command_pcb_render.cpp
@ -64,6 +69,8 @@ set( KICAD_CLI_SRCS
cli/command_sym_export_svg.cpp
cli/command_sym_upgrade.cpp
cli/command_version.cpp
jobs_runner.cpp
)
if( WIN32 )

View File

@ -0,0 +1,37 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_JOBS_H
#define COMMAND_JOBS_H
#include "command.h"
namespace CLI
{
struct JOBSET_COMMAND : public COMMAND
{
JOBSET_COMMAND() : COMMAND( "jobset" )
{
m_argParser.add_description( UTF8STDSTR( _( "Jobset" ) ) );
}
};
}
#endif

View File

@ -0,0 +1,102 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_jobset_run.h"
#include <cli/exit_codes.h>
#include <kiface_base.h>
#include <layer_ids.h>
#include <string_utils.h>
#include <wx/crt.h>
#include <jobs/jobset.h>
#include <jobs/job_registry.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <jobs_runner.h>
#include <reporter.h>
#define ARG_STOP_ON_ERROR "--stop-on-error"
#define ARG_JOB_FILE "--file"
#define ARG_OUTPUT "--output"
CLI::JOBSET_RUN_COMMAND::JOBSET_RUN_COMMAND() : COMMAND( "run" )
{
addCommonArgs( true, false, false, false );
m_argParser.add_description( UTF8STDSTR( _( "Runs a jobset file" ) ) );
m_argParser.add_argument( ARG_STOP_ON_ERROR )
.help( UTF8STDSTR(
_( "Stops processing jobs as they are executed sequentially on the first failure of a job" ) ) )
.flag();
m_argParser.add_argument( ARG_JOB_FILE, "-f" )
.help( UTF8STDSTR( _( "Jobset file to be run" ) ) )
.default_value( std::string( "" ) )
.metavar( "JOB_FILE" );
m_argParser.add_argument( ARG_OUTPUT )
.help( UTF8STDSTR( _( "Jobset file output to generate, leave blank for all outputs defined in the jobset" ) ) )
.default_value( std::string( "" ) )
.metavar( "OUTPUT" );
}
int CLI::JOBSET_RUN_COMMAND::doPerform( KIWAY& aKiway )
{
bool bail = m_argParser.get<bool>( ARG_STOP_ON_ERROR );
wxString jobsFilePath = From_UTF8( m_argParser.get<std::string>( ARG_JOB_FILE ).c_str() );
wxString projectFile = m_argInput.ToStdString();
wxString outputKey = From_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
if( !Pgm().GetSettingsManager().LoadProject( projectFile ) )
{
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
JOBSET jobFile( jobsFilePath.ToStdString() );
jobFile.LoadFromFile();
JOBS_RUNNER jobsRunner( &aKiway, &jobFile, &CLI_REPORTER::GetInstance() );
int return_code = CLI::EXIT_CODES::SUCCESS;
if( !outputKey.IsEmpty() )
{
JOBSET_OUTPUT* output = jobFile.GetOutput( outputKey );
if( output == nullptr || !jobsRunner.RunJobsForOutput( output, bail ) )
{
return_code = CLI::EXIT_CODES::ERR_JOBS_RUN_FAILED;
}
}
else
{
if( !jobsRunner.RunJobsAllOutputs( bail ) )
{
return_code = CLI::EXIT_CODES::ERR_JOBS_RUN_FAILED;
}
}
return return_code;
}

View File

@ -0,0 +1,35 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "command_pcb_export_base.h"
namespace CLI
{
class JOBSET_RUN_COMMAND : public COMMAND
{
public:
JOBSET_RUN_COMMAND();
protected:
int doPerform( KIWAY& aKiway ) override;
};
}

View File

@ -236,7 +236,7 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway )
params.m_IncludeUnspecified = !m_argParser.get<bool>( ARG_NO_UNSPECIFIED );
params.m_IncludeDNP = !m_argParser.get<bool>( ARG_NO_DNP );
params.m_Overwrite = m_argParser.get<bool>( ARG_FORCE );
params.m_OutputFile = m_argOutput;
step->SetOutputPath( m_argOutput );
step->m_filename = m_argInput;
step->m_format = m_format;

View File

@ -106,11 +106,11 @@ int CLI::PCB_EXPORT_DRILL_COMMAND::doPerform( KIWAY& aKiway )
std::unique_ptr<JOB_EXPORT_PCB_DRILL> drillJob( new JOB_EXPORT_PCB_DRILL( true ) );
drillJob->m_filename = m_argInput;
drillJob->m_outputDir = m_argOutput;
drillJob->SetOutputPath( m_argOutput );
if( !drillJob->m_outputDir.IsEmpty() )
if( !drillJob->GetOutputPath().IsEmpty() )
{
wxFileName fn( drillJob->m_outputDir, wxEmptyString );
wxFileName fn( drillJob->GetOutputPath(), wxEmptyString );
if( !fn.IsDir() )
{

View File

@ -79,7 +79,7 @@ int CLI::PCB_EXPORT_DXF_COMMAND::doPerform( KIWAY& aKiway )
std::unique_ptr<JOB_EXPORT_PCB_DXF> dxfJob( new JOB_EXPORT_PCB_DXF( true ) );
dxfJob->m_filename = m_argInput;
dxfJob->m_outputFile = m_argOutput;
dxfJob->SetOutputPath( m_argOutput );
dxfJob->m_drawingSheet = m_argDrawingSheet;
dxfJob->SetVarOverrides( m_argDefineVars );
@ -93,7 +93,7 @@ int CLI::PCB_EXPORT_DXF_COMMAND::doPerform( KIWAY& aKiway )
dxfJob->m_plotRefDes = !m_argParser.get<bool>( ARG_EXCLUDE_REFDES );
dxfJob->m_plotGraphicItemsUsingContours = m_argParser.get<bool>( ARG_USE_CONTOURS );
dxfJob->m_useDrillOrigin = m_argParser.get<bool>( ARG_USE_DRILL_ORIGIN );
dxfJob->m_plotBorderTitleBlocks = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
dxfJob->m_plotDrawingSheet = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
wxString units = From_UTF8( m_argParser.get<std::string>( ARG_OUTPUT_UNITS ).c_str() );

View File

@ -78,7 +78,6 @@ int CLI::PCB_EXPORT_GENCAD_COMMAND::doPerform( KIWAY& aKiway )
std::unique_ptr<JOB_EXPORT_PCB_GENCAD> gencadJob( new JOB_EXPORT_PCB_GENCAD( true ) );
gencadJob->m_filename = m_argInput;
gencadJob->m_outputFile = m_argOutput;
gencadJob->SetVarOverrides( m_argDefineVars );
gencadJob->m_flipBottomPads = m_argParser.get<bool>( ARG_FLIP_BOTTOM_PADS );

View File

@ -93,13 +93,13 @@ CLI::PCB_EXPORT_GERBER_COMMAND::PCB_EXPORT_GERBER_COMMAND() : PCB_EXPORT_GERBER_
int CLI::PCB_EXPORT_GERBER_COMMAND::populateJob( JOB_EXPORT_PCB_GERBER* aJob )
{
aJob->m_filename = m_argInput;
aJob->m_outputFile = m_argOutput;
aJob->SetOutputPath( m_argOutput );
aJob->m_drawingSheet = m_argDrawingSheet;
aJob->SetVarOverrides( m_argDefineVars );
aJob->m_plotFootprintValues = !m_argParser.get<bool>( ARG_EXCLUDE_VALUE );
aJob->m_plotRefDes = !m_argParser.get<bool>( ARG_EXCLUDE_REFDES );
aJob->m_plotBorderTitleBlocks = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
aJob->m_plotDrawingSheet = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
aJob->m_disableApertureMacros = m_argParser.get<bool>( ARG_DISABLE_APERTURE_MACROS );
aJob->m_subtractSolderMaskFromSilk = m_argParser.get<bool>( ARG_SUBTRACT_SOLDERMASK );
aJob->m_includeNetlistAttributes = !m_argParser.get<bool>( ARG_NO_NETLIST );

View File

@ -110,7 +110,7 @@ int CLI::PCB_EXPORT_IPC2581_COMMAND::doPerform( KIWAY& aKiway )
std::unique_ptr<JOB_EXPORT_PCB_IPC2581> ipc2581Job( new JOB_EXPORT_PCB_IPC2581( true ) );
ipc2581Job->m_filename = m_argInput;
ipc2581Job->m_outputFile = m_argOutput;
ipc2581Job->SetOutputPath( m_argOutput );
ipc2581Job->m_drawingSheet = m_argDrawingSheet;
ipc2581Job->SetVarOverrides( m_argDefineVars );

View File

@ -99,7 +99,7 @@ int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway )
std::unique_ptr<JOB_EXPORT_PCB_PDF> pdfJob( new JOB_EXPORT_PCB_PDF( true ) );
pdfJob->m_filename = m_argInput;
pdfJob->m_outputFile = m_argOutput;
pdfJob->SetOutputPath( m_argOutput );
pdfJob->m_drawingSheet = m_argDrawingSheet;
pdfJob->SetVarOverrides( m_argDefineVars );
@ -112,7 +112,7 @@ int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway )
pdfJob->m_plotFootprintValues = !m_argParser.get<bool>( ARG_EXCLUDE_VALUE );
pdfJob->m_plotRefDes = !m_argParser.get<bool>( ARG_EXCLUDE_REFDES );
pdfJob->m_plotBorderTitleBlocks = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
pdfJob->m_plotDrawingSheet = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
pdfJob->m_mirror = m_argParser.get<bool>( ARG_MIRROR );
pdfJob->m_blackAndWhite = m_argParser.get<bool>( ARG_BLACKANDWHITE );

View File

@ -99,7 +99,7 @@ int CLI::PCB_EXPORT_POS_COMMAND::doPerform( KIWAY& aKiway )
std::unique_ptr<JOB_EXPORT_PCB_POS> aPosJob( new JOB_EXPORT_PCB_POS( true ) );
aPosJob->m_filename = m_argInput;
aPosJob->m_outputFile = m_argOutput;
aPosJob->SetOutputPath( m_argOutput );
if( !wxFile::Exists( aPosJob->m_filename ) )
{

View File

@ -114,7 +114,7 @@ int CLI::PCB_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway )
svgJob->m_drawingSheet = m_argDrawingSheet;
svgJob->m_filename = m_argInput;
svgJob->m_outputFile = m_argOutput;
svgJob->SetOutputPath( m_argOutput );
svgJob->m_colorTheme = From_UTF8( m_argParser.get<std::string>( ARG_THEME ).c_str() );
svgJob->m_plotDrawingSheet = !m_argParser.get<bool>( ARG_EXCLUDE_DRAWING_SHEET );
svgJob->SetVarOverrides( m_argDefineVars );

View File

@ -134,7 +134,7 @@ int CLI::SCH_EXPORT_BOM_COMMAND::doPerform( KIWAY& aKiway )
// Basic options
bomJob->m_filename = m_argInput;
bomJob->m_outputFile = m_argOutput;
bomJob->SetOutputPath( m_argOutput );
bomJob->m_bomPresetName = From_UTF8( m_argParser.get<std::string>( ARG_PRESET ).c_str() );
bomJob->m_bomFmtPresetName =

View File

@ -49,7 +49,7 @@ int CLI::SCH_EXPORT_NETLIST_COMMAND::doPerform( KIWAY& aKiway )
std::make_unique<JOB_EXPORT_SCH_NETLIST>( true );
netJob->m_filename = m_argInput;
netJob->m_outputFile = m_argOutput;
netJob->SetOutputPath( m_argOutput );
if( !wxFile::Exists( netJob->m_filename ) )
{

View File

@ -137,8 +137,9 @@ int CLI::SCH_EXPORT_PLOT_COMMAND::doPerform( KIWAY& aKiway )
}
std::unique_ptr<JOB_EXPORT_SCH_PLOT> plotJob =
std::make_unique<JOB_EXPORT_SCH_PLOT>( true, m_plotFormat, filename );
std::make_unique<JOB_EXPORT_SCH_PLOT>( true );
plotJob->m_filename = filename;
plotJob->m_plotFormat = m_plotFormat;
plotJob->m_plotPages = pages;
plotJob->m_plotDrawingSheet = !m_argParser.get<bool>( ARG_EXCLUDE_DRAWING_SHEET );
plotJob->m_pageSizeSelect = JOB_PAGE_SIZE::PAGE_SIZE_AUTO;

View File

@ -44,7 +44,7 @@ int CLI::SCH_EXPORT_PYTHONBOM_COMMAND::doPerform( KIWAY& aKiway )
std::make_unique<JOB_EXPORT_SCH_PYTHONBOM>( true );
bomJob->m_filename = m_argInput;
bomJob->m_outputFile = m_argOutput;
bomJob->SetOutputPath( m_argOutput );
if( !wxFile::Exists( bomJob->m_filename ) )
{

View File

@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_job_config_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_JOB_CONFIG_BASE::DIALOG_JOB_CONFIG_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 );
m_mainSizer = new wxBoxSizer( wxVERTICAL );
m_staticText1 = new wxStaticText( this, wxID_ANY, wxT("Options"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText1->Wrap( -1 );
m_mainSizer->Add( m_staticText1, 0, wxALL, 5 );
m_jobOptionsPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_jobOptionsSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
m_jobOptionsSizer->SetFlexibleDirection( wxBOTH );
m_jobOptionsSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_jobOptionsPanel->SetSizer( m_jobOptionsSizer );
m_jobOptionsPanel->Layout();
m_jobOptionsSizer->Fit( m_jobOptionsPanel );
m_mainSizer->Add( m_jobOptionsPanel, 1, wxEXPAND | wxALL, 5 );
m_sdbSizer1 = new wxStdDialogButtonSizer();
m_sdbSizer1Save = new wxButton( this, wxID_SAVE );
m_sdbSizer1->AddButton( m_sdbSizer1Save );
m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
m_sdbSizer1->Realize();
m_mainSizer->Add( m_sdbSizer1, 0, wxEXPAND, 5 );
this->SetSizer( m_mainSizer );
this->Layout();
m_mainSizer->Fit( this );
this->Centre( wxBOTH );
}
DIALOG_JOB_CONFIG_BASE::~DIALOG_JOB_CONFIG_BASE()
{
}

View File

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="18"/>
<object class="Project" expanded="true">
<property name="code_generation">C++</property>
<property name="cpp_class_decoration">; </property>
<property name="cpp_disconnect_events">1</property>
<property name="cpp_event_generation">connect</property>
<property name="cpp_help_provider">none</property>
<property name="cpp_namespace"></property>
<property name="cpp_precompiled_header"></property>
<property name="cpp_use_array_enum">0</property>
<property name="cpp_use_enum">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="file">dialog_job_config_base</property>
<property name="first_id">1000</property>
<property name="internationalize">0</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">DIALOG_JOB_CONFIG_BASE</property>
<property name="path">.</property>
<property name="php_disconnect_events">0</property>
<property name="php_disconnect_mode">source_name</property>
<property name="php_skip_events">1</property>
<property name="python_disconnect_events">0</property>
<property name="python_disconnect_mode">source_name</property>
<property name="python_image_path_wrapper_function_name"></property>
<property name="python_indent_with_spaces"></property>
<property name="python_skip_events">1</property>
<property name="relative_path">1</property>
<property name="use_microsoft_bom">0</property>
<property name="use_native_eol">0</property>
<object class="Dialog" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">DIALOG_JOB_CONFIG_BASE</property>
<property name="pos"></property>
<property name="size"></property>
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
<property name="title"></property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">m_mainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="true">
<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="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="label">Options</property>
<property name="markup">0</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"></property>
<property name="moveable">1</property>
<property name="name">m_staticText1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">public</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></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="true">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">1</property>
<object class="wxPanel" expanded="true">
<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="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"></property>
<property name="moveable">1</property>
<property name="name">m_jobOptionsPanel</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="show">1</property>
<property name="size"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<object class="wxFlexGridSizer" expanded="true">
<property name="cols">2</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">m_jobOptionsSizer</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">protected</property>
<property name="rows">0</property>
<property name="vgap">0</property>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="true">
<property name="Apply">0</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">0</property>
<property name="Save">1</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">m_sdbSizer1</property>
<property name="permission">protected</property>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

Some files were not shown because too many files have changed in this diff Show More