From d74caace0ad17fe60971f4acf140f866fcdcd754 Mon Sep 17 00:00:00 2001 From: Marek Roszko <mark.roszko@gmail.com> Date: Mon, 15 Jul 2024 18:20:13 -0400 Subject: [PATCH] Initial jobset creation and running within the CLI and GUI. Incomplete, just pushing this before feature freeze, much fixing left --- common/CMakeLists.txt | 5 + common/advanced_config.cpp | 7 +- common/eda_base_frame.cpp | 2 +- common/gestfich.cpp | 100 + common/jobs/job.cpp | 148 +- common/jobs/job.h | 96 +- common/jobs/job_dispatcher.cpp | 18 +- common/jobs/job_dispatcher.h | 9 +- common/jobs/job_export_pcb_3d.cpp | 76 +- common/jobs/job_export_pcb_3d.h | 6 +- common/jobs/job_export_pcb_drill.cpp | 94 +- common/jobs/job_export_pcb_drill.h | 3 +- common/jobs/job_export_pcb_dxf.cpp | 44 +- common/jobs/job_export_pcb_dxf.h | 13 +- common/jobs/job_export_pcb_gencad.cpp | 2 +- common/jobs/job_export_pcb_gencad.h | 2 - common/jobs/job_export_pcb_gerber.cpp | 54 +- common/jobs/job_export_pcb_gerber.h | 15 +- common/jobs/job_export_pcb_gerbers.cpp | 24 +- common/jobs/job_export_pcb_gerbers.h | 1 + common/jobs/job_export_pcb_ipc2581.cpp | 54 +- common/jobs/job_export_pcb_ipc2581.h | 4 +- common/jobs/job_export_pcb_pdf.cpp | 50 +- common/jobs/job_export_pcb_pdf.h | 28 +- common/jobs/job_export_pcb_plot.cpp | 27 + common/jobs/job_export_pcb_plot.h | 72 + common/jobs/job_export_pcb_pos.cpp | 87 +- common/jobs/job_export_pcb_pos.h | 4 +- common/jobs/job_export_pcb_svg.cpp | 49 +- common/jobs/job_export_pcb_svg.h | 24 +- common/jobs/job_export_sch_bom.cpp | 48 +- common/jobs/job_export_sch_bom.h | 2 +- common/jobs/job_export_sch_netlist.cpp | 44 +- common/jobs/job_export_sch_netlist.h | 7 +- common/jobs/job_export_sch_plot.cpp | 133 +- common/jobs/job_export_sch_plot.h | 38 +- common/jobs/job_export_sch_pythonbom.cpp | 19 +- common/jobs/job_export_sch_pythonbom.h | 2 +- common/jobs/job_fp_export_svg.cpp | 3 +- common/jobs/job_fp_upgrade.cpp | 3 +- common/jobs/job_pcb_drc.cpp | 32 +- common/jobs/job_pcb_drc.h | 1 + common/jobs/job_pcb_render.cpp | 2 +- common/jobs/job_registry.cpp | 53 + common/jobs/job_registry.h | 70 + common/jobs/job_sch_erc.cpp | 30 +- common/jobs/job_sch_erc.h | 1 + common/jobs/job_sym_export_svg.cpp | 3 +- common/jobs/job_sym_upgrade.cpp | 2 +- common/jobs/jobs_output.h | 48 + common/jobs/jobs_output_archive.cpp | 76 + common/jobs/jobs_output_archive.h | 45 + common/jobs/jobs_output_folder.cpp | 61 + common/jobs/jobs_output_folder.h | 35 + common/jobs/jobset.cpp | 218 + common/jobs/jobset.h | 111 + common/jobs/lset_json.h | 34 + common/kiway.cpp | 8 + common/lset.cpp | 6 + common/project/project_local_settings.cpp | 2 +- common/settings/settings_manager.cpp | 6 + common/wildcards_and_files_ext.cpp | 7 + eeschema/dialogs/dialog_export_netlist.cpp | 127 +- eeschema/dialogs/dialog_export_netlist.h | 5 +- .../dialogs/dialog_export_netlist_base.cpp | 17 +- .../dialogs/dialog_export_netlist_base.fbp | 230 +- eeschema/dialogs/dialog_export_netlist_base.h | 18 +- eeschema/dialogs/dialog_plot_schematic.cpp | 194 +- eeschema/dialogs/dialog_plot_schematic.h | 7 +- eeschema/eeschema.cpp | 8 + eeschema/eeschema_helpers.cpp | 27 +- eeschema/eeschema_helpers.h | 4 +- eeschema/eeschema_jobs_handler.cpp | 176 +- eeschema/eeschema_jobs_handler.h | 3 + include/advanced_config.h | 9 + include/cli/exit_codes.h | 17 +- include/gestfich.h | 25 + include/kiway.h | 10 +- include/lset.h | 1 + include/settings/settings_manager.h | 6 + include/wildcards_and_files_ext.h | 3 + kicad/CMakeLists.txt | 7 + kicad/cli/command_jobset.h | 37 + kicad/cli/command_jobset_run.cpp | 102 + kicad/cli/command_jobset_run.h | 35 + kicad/cli/command_pcb_export_3d.cpp | 2 +- kicad/cli/command_pcb_export_drill.cpp | 6 +- kicad/cli/command_pcb_export_dxf.cpp | 4 +- kicad/cli/command_pcb_export_gencad.cpp | 1 - kicad/cli/command_pcb_export_gerber.cpp | 4 +- kicad/cli/command_pcb_export_ipc2581.cpp | 2 +- kicad/cli/command_pcb_export_pdf.cpp | 4 +- kicad/cli/command_pcb_export_pos.cpp | 2 +- kicad/cli/command_pcb_export_svg.cpp | 2 +- kicad/cli/command_sch_export_bom.cpp | 2 +- kicad/cli/command_sch_export_netlist.cpp | 2 +- kicad/cli/command_sch_export_plot.cpp | 5 +- kicad/cli/command_sch_export_pythonbom.cpp | 2 +- kicad/dialogs/dialog_job_config_base.cpp | 52 + kicad/dialogs/dialog_job_config_base.fbp | 221 + kicad/dialogs/dialog_job_config_base.h | 49 + kicad/dialogs/panel_jobs.cpp | 569 +++ kicad/dialogs/panel_jobs.h | 61 + kicad/dialogs/panel_jobs_base.cpp | 249 ++ kicad/dialogs/panel_jobs_base.fbp | 1799 ++++++++ kicad/dialogs/panel_jobs_base.h | 134 + kicad/jobs_runner.cpp | 169 + kicad/jobs_runner.h | 40 + kicad/kicad_cli.cpp | 12 + kicad/kicad_id.h | 2 + kicad/kicad_manager_frame.cpp | 32 +- kicad/kicad_manager_frame.h | 2 + kicad/menubar.cpp | 5 + kicad/project_tree.cpp | 2 + kicad/project_tree_item.cpp | 5 + kicad/project_tree_pane.cpp | 18 + kicad/project_tree_pane.h | 5 + kicad/tools/kicad_manager_actions.cpp | 7 + kicad/tools/kicad_manager_actions.h | 1 + kicad/tools/kicad_manager_control.cpp | 19 + kicad/tools/kicad_manager_control.h | 1 + kicad/tree_file_type.h | 1 + pcbnew/dialogs/dialog_export_2581.cpp | 127 +- pcbnew/dialogs/dialog_export_2581.h | 3 + pcbnew/dialogs/dialog_export_step.cpp | 690 +-- pcbnew/dialogs/dialog_export_step.h | 4 + pcbnew/dialogs/dialog_export_svg.cpp | 18 +- pcbnew/dialogs/dialog_export_svg.h | 11 +- .../dialogs/dialog_gen_footprint_position.cpp | 134 +- .../dialogs/dialog_gen_footprint_position.h | 3 + pcbnew/dialogs/dialog_gendrill.cpp | 148 +- pcbnew/dialogs/dialog_gendrill.h | 8 + pcbnew/dialogs/dialog_gendrill_base.cpp | 4 +- pcbnew/dialogs/dialog_gendrill_base.fbp | 3936 +++++++++-------- pcbnew/dialogs/dialog_gendrill_base.h | 5 +- pcbnew/dialogs/dialog_plot.cpp | 758 ++-- pcbnew/dialogs/dialog_plot.h | 12 +- pcbnew/exporters/export_gencad_writer.cpp | 2 +- pcbnew/exporters/export_gencad_writer.h | 2 +- pcbnew/exporters/gerber_placefile_writer.cpp | 2 +- pcbnew/exporters/gerber_placefile_writer.h | 2 +- pcbnew/pcbnew.cpp | 8 + pcbnew/pcbnew_jobs_handler.cpp | 367 +- pcbnew/pcbnew_jobs_handler.h | 3 + .../scripting/pcbnew_scripting_helpers.cpp | 32 +- .../scripting/pcbnew_scripting_helpers.h | 8 +- pcbnew/tools/board_editor_control.cpp | 2 +- qa/tests/CMakeLists.txt | 11 + qa/tests/cli/test_sch.py | 2 +- resources/schemas/jobs.v1.json | 66 + 150 files changed, 9950 insertions(+), 3247 deletions(-) create mode 100644 common/jobs/job_export_pcb_plot.cpp create mode 100644 common/jobs/job_export_pcb_plot.h create mode 100644 common/jobs/job_registry.cpp create mode 100644 common/jobs/job_registry.h create mode 100644 common/jobs/jobs_output.h create mode 100644 common/jobs/jobs_output_archive.cpp create mode 100644 common/jobs/jobs_output_archive.h create mode 100644 common/jobs/jobs_output_folder.cpp create mode 100644 common/jobs/jobs_output_folder.h create mode 100644 common/jobs/jobset.cpp create mode 100644 common/jobs/jobset.h create mode 100644 common/jobs/lset_json.h create mode 100644 kicad/cli/command_jobset.h create mode 100644 kicad/cli/command_jobset_run.cpp create mode 100644 kicad/cli/command_jobset_run.h create mode 100644 kicad/dialogs/dialog_job_config_base.cpp create mode 100644 kicad/dialogs/dialog_job_config_base.fbp create mode 100644 kicad/dialogs/dialog_job_config_base.h create mode 100644 kicad/dialogs/panel_jobs.cpp create mode 100644 kicad/dialogs/panel_jobs.h create mode 100644 kicad/dialogs/panel_jobs_base.cpp create mode 100644 kicad/dialogs/panel_jobs_base.fbp create mode 100644 kicad/dialogs/panel_jobs_base.h create mode 100644 kicad/jobs_runner.cpp create mode 100644 kicad/jobs_runner.h create mode 100644 resources/schemas/jobs.v1.json diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index cfc7af82d7..c393fe0e0e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -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 diff --git a/common/advanced_config.cpp b/common/advanced_config.cpp index d135e64159..058b455704 100644 --- a/common/advanced_config.cpp +++ b/common/advanced_config.cpp @@ -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 ) ); diff --git a/common/eda_base_frame.cpp b/common/eda_base_frame.cpp index c6a183390b..fa6a126c16 100644 --- a/common/eda_base_frame.cpp +++ b/common/eda_base_frame.cpp @@ -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; diff --git a/common/gestfich.cpp b/common/gestfich.cpp index 04c0cef3ce..d4700a1c6a 100644 --- a/common/gestfich.cpp +++ b/common/gestfich.cpp @@ -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; +} \ No newline at end of file diff --git a/common/jobs/job.cpp b/common/jobs/job.cpp index fa3678f76c..3edb4257a4 100644 --- a/common/jobs/job.cpp +++ b/common/jobs/job.cpp @@ -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 ) { } \ No newline at end of file diff --git a/common/jobs/job.h b/common/jobs/job.h index 47e24e47f6..bfcf6cb23a 100644 --- a/common/jobs/job.h +++ b/common/jobs/job.h @@ -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 \ No newline at end of file +KICOMMON_API void from_json( const nlohmann::json& j, JOB& f ); +KICOMMON_API void to_json( nlohmann::json& j, const JOB& f ); \ No newline at end of file diff --git a/common/jobs/job_dispatcher.cpp b/common/jobs/job_dispatcher.cpp index 0713ac32dd..e2e5eb1959 100644 --- a/common/jobs/job_dispatcher.cpp +++ b/common/jobs/job_dispatcher.cpp @@ -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*/ ); diff --git a/common/jobs/job_dispatcher.h b/common/jobs/job_dispatcher.h index 45eef27a45..d6368488e1 100644 --- a/common/jobs/job_dispatcher.h +++ b/common/jobs/job_dispatcher.h @@ -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; }; diff --git a/common/jobs/job_export_pcb_3d.cpp b/common/jobs/job_export_pcb_3d.cpp index a1c448962e..dd4a7eb91c 100644 --- a/common/jobs/job_export_pcb_3d.cpp +++ b/common/jobs/job_export_pcb_3d.cpp @@ -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 ); diff --git a/common/jobs/job_export_pcb_3d.h b/common/jobs/job_export_pcb_3d.h index a30dda4ff4..9192ed1bc2 100644 --- a/common/jobs/job_export_pcb_3d.h +++ b/common/jobs/job_export_pcb_3d.h @@ -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 { diff --git a/common/jobs/job_export_pcb_drill.cpp b/common/jobs/job_export_pcb_drill.cpp index 759fb53ef4..6846bf6231 100644 --- a/common/jobs/job_export_pcb_drill.cpp +++ b/common/jobs/job_export_pcb_drill.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_pcb_drill.h b/common/jobs/job_export_pcb_drill.h index 7423b2ea31..ff5887082e 100644 --- a/common/jobs/job_export_pcb_drill.h +++ b/common/jobs/job_export_pcb_drill.h @@ -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; diff --git a/common/jobs/job_export_pcb_dxf.cpp b/common/jobs/job_export_pcb_dxf.cpp index 3892cdc773..54b0185d13 100644 --- a/common/jobs/job_export_pcb_dxf.cpp +++ b/common/jobs/job_export_pcb_dxf.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_pcb_dxf.h b/common/jobs/job_export_pcb_dxf.h index 621ff40b94..8d9314318e 100644 --- a/common/jobs/job_export_pcb_dxf.h +++ b/common/jobs/job_export_pcb_dxf.h @@ -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 diff --git a/common/jobs/job_export_pcb_gencad.cpp b/common/jobs/job_export_pcb_gencad.cpp index 01a065ece2..8c7e6627ab 100644 --- a/common/jobs/job_export_pcb_gencad.cpp +++ b/common/jobs/job_export_pcb_gencad.cpp @@ -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 ), diff --git a/common/jobs/job_export_pcb_gencad.h b/common/jobs/job_export_pcb_gencad.h index ec0f4e191e..b21558ead7 100644 --- a/common/jobs/job_export_pcb_gencad.h +++ b/common/jobs/job_export_pcb_gencad.h @@ -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; diff --git a/common/jobs/job_export_pcb_gerber.cpp b/common/jobs/job_export_pcb_gerber.cpp index 732e1a7f3e..f02bcc06b7 100644 --- a/common/jobs/job_export_pcb_gerber.cpp +++ b/common/jobs/job_export_pcb_gerber.cpp @@ -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" ) ); } \ No newline at end of file diff --git a/common/jobs/job_export_pcb_gerber.h b/common/jobs/job_export_pcb_gerber.h index 669f6583e3..37366b42ce 100644 --- a/common/jobs/job_export_pcb_gerber.h +++ b/common/jobs/job_export_pcb_gerber.h @@ -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 diff --git a/common/jobs/job_export_pcb_gerbers.cpp b/common/jobs/job_export_pcb_gerbers.cpp index 112b06877f..fd9dce9380 100644 --- a/common/jobs/job_export_pcb_gerbers.cpp +++ b/common/jobs/job_export_pcb_gerbers.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_pcb_gerbers.h b/common/jobs/job_export_pcb_gerbers.h index 3312e1aa09..8f7eb00177 100644 --- a/common/jobs/job_export_pcb_gerbers.h +++ b/common/jobs/job_export_pcb_gerbers.h @@ -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; diff --git a/common/jobs/job_export_pcb_ipc2581.cpp b/common/jobs/job_export_pcb_ipc2581.cpp index 943e737b72..e1b5509c84 100644 --- a/common/jobs/job_export_pcb_ipc2581.cpp +++ b/common/jobs/job_export_pcb_ipc2581.cpp @@ -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() { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_pcb_ipc2581.h b/common/jobs/job_export_pcb_ipc2581.h index 0454228461..b965185f2f 100644 --- a/common/jobs/job_export_pcb_ipc2581.h +++ b/common/jobs/job_export_pcb_ipc2581.h @@ -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; diff --git a/common/jobs/job_export_pcb_pdf.cpp b/common/jobs/job_export_pcb_pdf.cpp index d1b4e4c186..8e502095fb 100644 --- a/common/jobs/job_export_pcb_pdf.cpp +++ b/common/jobs/job_export_pcb_pdf.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_pcb_pdf.h b/common/jobs/job_export_pcb_pdf.h index 2ded1bf74b..6b642c6271 100644 --- a/common/jobs/job_export_pcb_pdf.h +++ b/common/jobs/job_export_pcb_pdf.h @@ -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 diff --git a/common/jobs/job_export_pcb_plot.cpp b/common/jobs/job_export_pcb_plot.cpp new file mode 100644 index 0000000000..6dc647a304 --- /dev/null +++ b/common/jobs/job_export_pcb_plot.cpp @@ -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 ) +{ + +} \ No newline at end of file diff --git a/common/jobs/job_export_pcb_plot.h b/common/jobs/job_export_pcb_plot.h new file mode 100644 index 0000000000..23aec50f68 --- /dev/null +++ b/common/jobs/job_export_pcb_plot.h @@ -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; +}; diff --git a/common/jobs/job_export_pcb_pos.cpp b/common/jobs/job_export_pcb_pos.cpp index 2cf82cddfa..74fd4a416f 100644 --- a/common/jobs/job_export_pcb_pos.cpp +++ b/common/jobs/job_export_pcb_pos.cpp @@ -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; -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_pcb_pos.h b/common/jobs/job_export_pcb_pos.h index fe45a966ff..58ab0f34cb 100644 --- a/common/jobs/job_export_pcb_pos.h +++ b/common/jobs/job_export_pcb_pos.h @@ -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; diff --git a/common/jobs/job_export_pcb_svg.cpp b/common/jobs/job_export_pcb_svg.cpp index 843b32e1dd..9ccce1fc5d 100644 --- a/common/jobs/job_export_pcb_svg.cpp +++ b/common/jobs/job_export_pcb_svg.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_pcb_svg.h b/common/jobs/job_export_pcb_svg.h index c39c6db540..654cecc89c 100644 --- a/common/jobs/job_export_pcb_svg.h +++ b/common/jobs/job_export_pcb_svg.h @@ -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 \ No newline at end of file diff --git a/common/jobs/job_export_sch_bom.cpp b/common/jobs/job_export_sch_bom.cpp index 5ea88dfa08..1f72b1c3c4 100644 --- a/common/jobs/job_export_sch_bom.cpp +++ b/common/jobs/job_export_sch_bom.cpp @@ -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 ); \ No newline at end of file diff --git a/common/jobs/job_export_sch_bom.h b/common/jobs/job_export_sch_bom.h index 58a890f385..97d668680d 100644 --- a/common/jobs/job_export_sch_bom.h +++ b/common/jobs/job_export_sch_bom.h @@ -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; diff --git a/common/jobs/job_export_sch_netlist.cpp b/common/jobs/job_export_sch_netlist.cpp index 16024b2535..694f6818d7 100644 --- a/common/jobs/job_export_sch_netlist.cpp +++ b/common/jobs/job_export_sch_netlist.cpp @@ -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; -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_sch_netlist.h b/common/jobs/job_export_sch_netlist.h index fae5d3ed08..d0717811cd 100644 --- a/common/jobs/job_export_sch_netlist.h +++ b/common/jobs/job_export_sch_netlist.h @@ -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 \ No newline at end of file diff --git a/common/jobs/job_export_sch_plot.cpp b/common/jobs/job_export_sch_plot.cpp index e7d266b16b..2c3253d82e 100644 --- a/common/jobs/job_export_sch_plot.cpp +++ b/common/jobs/job_export_sch_plot.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_export_sch_plot.h b/common/jobs/job_export_sch_plot.h index 3cec6001c1..67c491c792 100644 --- a/common/jobs/job_export_sch_plot.h +++ b/common/jobs/job_export_sch_plot.h @@ -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 \ No newline at end of file diff --git a/common/jobs/job_export_sch_pythonbom.cpp b/common/jobs/job_export_sch_pythonbom.cpp index d98908cc96..c159282e9a 100644 --- a/common/jobs/job_export_sch_pythonbom.cpp +++ b/common/jobs/job_export_sch_pythonbom.cpp @@ -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() { -} \ No newline at end of file +} + + +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 ); \ No newline at end of file diff --git a/common/jobs/job_export_sch_pythonbom.h b/common/jobs/job_export_sch_pythonbom.h index 888836766a..60a79aee1b 100644 --- a/common/jobs/job_export_sch_pythonbom.h +++ b/common/jobs/job_export_sch_pythonbom.h @@ -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 \ No newline at end of file diff --git a/common/jobs/job_fp_export_svg.cpp b/common/jobs/job_fp_export_svg.cpp index ed15af6347..1bc54c56e2 100644 --- a/common/jobs/job_fp_export_svg.cpp +++ b/common/jobs/job_fp_export_svg.cpp @@ -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 ), diff --git a/common/jobs/job_fp_upgrade.cpp b/common/jobs/job_fp_upgrade.cpp index 10cfbc4ee0..621dee3525 100644 --- a/common/jobs/job_fp_upgrade.cpp +++ b/common/jobs/job_fp_upgrade.cpp @@ -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 ) { } \ No newline at end of file diff --git a/common/jobs/job_pcb_drc.cpp b/common/jobs/job_pcb_drc.cpp index 5c54c14810..b6c6c5bae9 100644 --- a/common/jobs/job_pcb_drc.cpp +++ b/common/jobs/job_pcb_drc.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_pcb_drc.h b/common/jobs/job_pcb_drc.h index 91cfa3d56f..a1d238fcd7 100644 --- a/common/jobs/job_pcb_drc.h +++ b/common/jobs/job_pcb_drc.h @@ -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; diff --git a/common/jobs/job_pcb_render.cpp b/common/jobs/job_pcb_render.cpp index 376ab2201d..2dd0c8e302 100644 --- a/common/jobs/job_pcb_render.cpp +++ b/common/jobs/job_pcb_render.cpp @@ -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() { } \ No newline at end of file diff --git a/common/jobs/job_registry.cpp b/common/jobs/job_registry.cpp new file mode 100644 index 0000000000..cfe6c81f97 --- /dev/null +++ b/common/jobs/job_registry.cpp @@ -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; +} \ No newline at end of file diff --git a/common/jobs/job_registry.h b/common/jobs/job_registry.h new file mode 100644 index 0000000000..4f529056b2 --- /dev/null +++ b/common/jobs/job_registry.h @@ -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 \ No newline at end of file diff --git a/common/jobs/job_sch_erc.cpp b/common/jobs/job_sch_erc.cpp index 722b7dadd2..02dc7a4089 100644 --- a/common/jobs/job_sch_erc.cpp +++ b/common/jobs/job_sch_erc.cpp @@ -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 ) { -} \ No newline at end of file + 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 ); \ No newline at end of file diff --git a/common/jobs/job_sch_erc.h b/common/jobs/job_sch_erc.h index ec00a186c4..5086029e1a 100644 --- a/common/jobs/job_sch_erc.h +++ b/common/jobs/job_sch_erc.h @@ -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; diff --git a/common/jobs/job_sym_export_svg.cpp b/common/jobs/job_sym_export_svg.cpp index 3bb5e31f38..c8982d2561 100644 --- a/common/jobs/job_sym_export_svg.cpp +++ b/common/jobs/job_sym_export_svg.cpp @@ -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 ) diff --git a/common/jobs/job_sym_upgrade.cpp b/common/jobs/job_sym_upgrade.cpp index caefc60134..43e923809f 100644 --- a/common/jobs/job_sym_upgrade.cpp +++ b/common/jobs/job_sym_upgrade.cpp @@ -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 ) diff --git a/common/jobs/jobs_output.h b/common/jobs/jobs_output.h new file mode 100644 index 0000000000..d2d43216fc --- /dev/null +++ b/common/jobs/jobs_output.h @@ -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; +}; \ No newline at end of file diff --git a/common/jobs/jobs_output_archive.cpp b/common/jobs/jobs_output_archive.cpp new file mode 100644 index 0000000000..e06424a73b --- /dev/null +++ b/common/jobs/jobs_output_archive.cpp @@ -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"; +} \ No newline at end of file diff --git a/common/jobs/jobs_output_archive.h b/common/jobs/jobs_output_archive.h new file mode 100644 index 0000000000..65f3946c90 --- /dev/null +++ b/common/jobs/jobs_output_archive.h @@ -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; +}; \ No newline at end of file diff --git a/common/jobs/jobs_output_folder.cpp b/common/jobs/jobs_output_folder.cpp new file mode 100644 index 0000000000..5bf5070c75 --- /dev/null +++ b/common/jobs/jobs_output_folder.cpp @@ -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; +} \ No newline at end of file diff --git a/common/jobs/jobs_output_folder.h b/common/jobs/jobs_output_folder.h new file mode 100644 index 0000000000..4225e39e6a --- /dev/null +++ b/common/jobs/jobs_output_folder.h @@ -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; +}; \ No newline at end of file diff --git a/common/jobs/jobset.cpp b/common/jobs/jobset.cpp new file mode 100644 index 0000000000..0290232820 --- /dev/null +++ b/common/jobs/jobset.cpp @@ -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 \ No newline at end of file diff --git a/common/jobs/jobset.h b/common/jobs/jobset.h new file mode 100644 index 0000000000..5b54575781 --- /dev/null +++ b/common/jobs/jobset.h @@ -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 \ No newline at end of file diff --git a/common/jobs/lset_json.h b/common/jobs/lset_json.h new file mode 100644 index 0000000000..e2da1692c3 --- /dev/null +++ b/common/jobs/lset_json.h @@ -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>() ); +} \ No newline at end of file diff --git a/common/kiway.cpp b/common/kiway.cpp index 22352e7438..c9082e14c7 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -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 ) diff --git a/common/lset.cpp b/common/lset.cpp index 442a146b6e..d1084845b0 100644 --- a/common/lset.cpp +++ b/common/lset.cpp @@ -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; diff --git a/common/project/project_local_settings.cpp b/common/project/project_local_settings.cpp index b006d4ce85..f3b64dd63d 100644 --- a/common/project/project_local_settings.cpp +++ b/common/project/project_local_settings.cpp @@ -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() ) ); diff --git a/common/settings/settings_manager.cpp b/common/settings/settings_manager.cpp index 7a6f802c35..1e96a441f8 100644 --- a/common/settings/settings_manager.cpp +++ b/common/settings/settings_manager.cpp @@ -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 ) ) diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp index c42ab64a91..92ae265a6c 100644 --- a/common/wildcards_and_files_ext.cpp +++ b/common/wildcards_and_files_ext.cpp @@ -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 } ); +} \ No newline at end of file diff --git a/eeschema/dialogs/dialog_export_netlist.cpp b/eeschema/dialogs/dialog_export_netlist.cpp index ae6130c1d0..0270a1b0f3 100644 --- a/eeschema/dialogs/dialog_export_netlist.cpp +++ b/eeschema/dialogs/dialog_export_netlist.cpp @@ -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(); diff --git a/eeschema/dialogs/dialog_export_netlist.h b/eeschema/dialogs/dialog_export_netlist.h index acb93084c8..d1606ab4a1 100644 --- a/eeschema/dialogs/dialog_export_netlist.h +++ b/eeschema/dialogs/dialog_export_netlist.h @@ -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; }; \ No newline at end of file diff --git a/eeschema/dialogs/dialog_export_netlist_base.cpp b/eeschema/dialogs/dialog_export_netlist_base.cpp index cec2b36e78..c2ca48a502 100644 --- a/eeschema/dialogs/dialog_export_netlist_base.cpp +++ b/eeschema/dialogs/dialog_export_netlist_base.cpp @@ -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 ) ); diff --git a/eeschema/dialogs/dialog_export_netlist_base.fbp b/eeschema/dialogs/dialog_export_netlist_base.fbp index 16e0c1d758..0d8d48db28 100644 --- a/eeschema/dialogs/dialog_export_netlist_base.fbp +++ b/eeschema/dialogs/dialog_export_netlist_base.fbp @@ -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> diff --git a/eeschema/dialogs/dialog_export_netlist_base.h b/eeschema/dialogs/dialog_export_netlist_base.h index 3a94be0e86..77da8f7ce1 100644 --- a/eeschema/dialogs/dialog_export_netlist_base.h +++ b/eeschema/dialogs/dialog_export_netlist_base.h @@ -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; diff --git a/eeschema/dialogs/dialog_plot_schematic.cpp b/eeschema/dialogs/dialog_plot_schematic.cpp index 4956036a64..edf4d9ec08 100644 --- a/eeschema/dialogs/dialog_plot_schematic.cpp +++ b/eeschema/dialogs/dialog_plot_schematic.cpp @@ -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() ) { diff --git a/eeschema/dialogs/dialog_plot_schematic.h b/eeschema/dialogs/dialog_plot_schematic.h index 822041f8a9..fce4499e82 100644 --- a/eeschema/dialogs/dialog_plot_schematic.h +++ b/eeschema/dialogs/dialog_plot_schematic.h @@ -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__ diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index 62342ef68d..600cad28ec 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -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 ); +} \ No newline at end of file diff --git a/eeschema/eeschema_helpers.cpp b/eeschema/eeschema_helpers.cpp index c6074baaf5..4c1d0e9b02 100644 --- a/eeschema/eeschema_helpers.cpp +++ b/eeschema/eeschema_helpers.cpp @@ -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 ) { diff --git a/eeschema/eeschema_helpers.h b/eeschema/eeschema_helpers.h index ac663879ff..f68a65a1eb 100644 --- a/eeschema/eeschema_helpers.h +++ b/eeschema/eeschema_helpers.h @@ -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; diff --git a/eeschema/eeschema_jobs_handler.cpp b/eeschema/eeschema_jobs_handler.cpp index 11da7e1a6a..c0e6e31efd 100644 --- a/eeschema/eeschema_jobs_handler.cpp +++ b/eeschema/eeschema_jobs_handler.cpp @@ -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() ); diff --git a/eeschema/eeschema_jobs_handler.h b/eeschema/eeschema_jobs_handler.h index f06ab85974..df5a96841c 100644 --- a/eeschema/eeschema_jobs_handler.h +++ b/eeschema/eeschema_jobs_handler.h @@ -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 diff --git a/include/advanced_config.h b/include/advanced_config.h index 1023be96fa..02c4814bd9 100644 --- a/include/advanced_config.h +++ b/include/advanced_config.h @@ -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. * diff --git a/include/cli/exit_codes.h b/include/cli/exit_codes.h index 3a1c2909ad..7475cc15d2 100644 --- a/include/cli/exit_codes.h +++ b/include/cli/exit_codes.h @@ -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; }; } diff --git a/include/gestfich.h b/include/gestfich.h index a4a75291ac..b8c69d6367 100644 --- a/include/gestfich.h +++ b/include/gestfich.h @@ -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 */ diff --git a/include/kiway.h b/include/kiway.h index b6ab629a2c..dbbdfd1564 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -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) diff --git a/include/lset.h b/include/lset.h index 02f348e71b..5ded02a3bb 100644 --- a/include/lset.h +++ b/include/lset.h @@ -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. diff --git a/include/settings/settings_manager.h b/include/settings/settings_manager.h index a83174b902..d2615e0697 100644 --- a/include/settings/settings_manager.h +++ b/include/settings/settings_manager.h @@ -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 diff --git a/include/wildcards_and_files_ext.h b/include/wildcards_and_files_ext.h index 796d1be2bf..3bbcbbcc44 100644 --- a/include/wildcards_and_files_ext.h +++ b/include/wildcards_and_files_ext.h @@ -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(); /** * @} diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 69e888ff94..9b03358f0c 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -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 ) diff --git a/kicad/cli/command_jobset.h b/kicad/cli/command_jobset.h new file mode 100644 index 0000000000..a3b21e3cba --- /dev/null +++ b/kicad/cli/command_jobset.h @@ -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 \ No newline at end of file diff --git a/kicad/cli/command_jobset_run.cpp b/kicad/cli/command_jobset_run.cpp new file mode 100644 index 0000000000..4693225a5e --- /dev/null +++ b/kicad/cli/command_jobset_run.cpp @@ -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; +} diff --git a/kicad/cli/command_jobset_run.h b/kicad/cli/command_jobset_run.h new file mode 100644 index 0000000000..dec974649a --- /dev/null +++ b/kicad/cli/command_jobset_run.h @@ -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; +}; +} \ No newline at end of file diff --git a/kicad/cli/command_pcb_export_3d.cpp b/kicad/cli/command_pcb_export_3d.cpp index 494faa2ae4..4e1755dff5 100644 --- a/kicad/cli/command_pcb_export_3d.cpp +++ b/kicad/cli/command_pcb_export_3d.cpp @@ -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; diff --git a/kicad/cli/command_pcb_export_drill.cpp b/kicad/cli/command_pcb_export_drill.cpp index f5b5bfba1a..5e13176101 100644 --- a/kicad/cli/command_pcb_export_drill.cpp +++ b/kicad/cli/command_pcb_export_drill.cpp @@ -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() ) { diff --git a/kicad/cli/command_pcb_export_dxf.cpp b/kicad/cli/command_pcb_export_dxf.cpp index 709c05a2c6..aaaa960399 100644 --- a/kicad/cli/command_pcb_export_dxf.cpp +++ b/kicad/cli/command_pcb_export_dxf.cpp @@ -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() ); diff --git a/kicad/cli/command_pcb_export_gencad.cpp b/kicad/cli/command_pcb_export_gencad.cpp index f7ac912001..34b4b8e887 100644 --- a/kicad/cli/command_pcb_export_gencad.cpp +++ b/kicad/cli/command_pcb_export_gencad.cpp @@ -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 ); diff --git a/kicad/cli/command_pcb_export_gerber.cpp b/kicad/cli/command_pcb_export_gerber.cpp index 001d5b4e47..ff6c287c24 100644 --- a/kicad/cli/command_pcb_export_gerber.cpp +++ b/kicad/cli/command_pcb_export_gerber.cpp @@ -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 ); diff --git a/kicad/cli/command_pcb_export_ipc2581.cpp b/kicad/cli/command_pcb_export_ipc2581.cpp index ba205bf7a6..8c0e104494 100644 --- a/kicad/cli/command_pcb_export_ipc2581.cpp +++ b/kicad/cli/command_pcb_export_ipc2581.cpp @@ -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 ); diff --git a/kicad/cli/command_pcb_export_pdf.cpp b/kicad/cli/command_pcb_export_pdf.cpp index 6e23644136..c4cbdd613c 100644 --- a/kicad/cli/command_pcb_export_pdf.cpp +++ b/kicad/cli/command_pcb_export_pdf.cpp @@ -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 ); diff --git a/kicad/cli/command_pcb_export_pos.cpp b/kicad/cli/command_pcb_export_pos.cpp index 99217a2f41..dee661e497 100644 --- a/kicad/cli/command_pcb_export_pos.cpp +++ b/kicad/cli/command_pcb_export_pos.cpp @@ -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 ) ) { diff --git a/kicad/cli/command_pcb_export_svg.cpp b/kicad/cli/command_pcb_export_svg.cpp index ae2f652180..5fd8870f2a 100644 --- a/kicad/cli/command_pcb_export_svg.cpp +++ b/kicad/cli/command_pcb_export_svg.cpp @@ -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 ); diff --git a/kicad/cli/command_sch_export_bom.cpp b/kicad/cli/command_sch_export_bom.cpp index b646a6a51c..4c98e652a8 100644 --- a/kicad/cli/command_sch_export_bom.cpp +++ b/kicad/cli/command_sch_export_bom.cpp @@ -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 = diff --git a/kicad/cli/command_sch_export_netlist.cpp b/kicad/cli/command_sch_export_netlist.cpp index da35a64aee..1be9fe6a01 100644 --- a/kicad/cli/command_sch_export_netlist.cpp +++ b/kicad/cli/command_sch_export_netlist.cpp @@ -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 ) ) { diff --git a/kicad/cli/command_sch_export_plot.cpp b/kicad/cli/command_sch_export_plot.cpp index 4d925fd4a3..9772915354 100644 --- a/kicad/cli/command_sch_export_plot.cpp +++ b/kicad/cli/command_sch_export_plot.cpp @@ -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; diff --git a/kicad/cli/command_sch_export_pythonbom.cpp b/kicad/cli/command_sch_export_pythonbom.cpp index af15a2c21a..364c442dad 100644 --- a/kicad/cli/command_sch_export_pythonbom.cpp +++ b/kicad/cli/command_sch_export_pythonbom.cpp @@ -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 ) ) { diff --git a/kicad/dialogs/dialog_job_config_base.cpp b/kicad/dialogs/dialog_job_config_base.cpp new file mode 100644 index 0000000000..0e2b3df5fc --- /dev/null +++ b/kicad/dialogs/dialog_job_config_base.cpp @@ -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() +{ +} diff --git a/kicad/dialogs/dialog_job_config_base.fbp b/kicad/dialogs/dialog_job_config_base.fbp new file mode 100644 index 0000000000..3b7faff7ec --- /dev/null +++ b/kicad/dialogs/dialog_job_config_base.fbp @@ -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> diff --git a/kicad/dialogs/dialog_job_config_base.h b/kicad/dialogs/dialog_job_config_base.h new file mode 100644 index 0000000000..7aea7b19e4 --- /dev/null +++ b/kicad/dialogs/dialog_job_config_base.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include <wx/artprov.h> +#include <wx/xrc/xmlres.h> +#include "dialog_shim.h" +#include <wx/string.h> +#include <wx/stattext.h> +#include <wx/gdicmn.h> +#include <wx/font.h> +#include <wx/colour.h> +#include <wx/settings.h> +#include <wx/sizer.h> +#include <wx/panel.h> +#include <wx/button.h> +#include <wx/dialog.h> + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_JOB_CONFIG_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_JOB_CONFIG_BASE : public DIALOG_SHIM +{ + private: + + protected: + wxBoxSizer* m_mainSizer; + wxPanel* m_jobOptionsPanel; + wxFlexGridSizer* m_jobOptionsSizer; + wxStdDialogButtonSizer* m_sdbSizer1; + wxButton* m_sdbSizer1Save; + wxButton* m_sdbSizer1Cancel; + + public: + wxStaticText* m_staticText1; + + DIALOG_JOB_CONFIG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + + ~DIALOG_JOB_CONFIG_BASE(); + +}; + diff --git a/kicad/dialogs/panel_jobs.cpp b/kicad/dialogs/panel_jobs.cpp new file mode 100644 index 0000000000..bf1a15c368 --- /dev/null +++ b/kicad/dialogs/panel_jobs.cpp @@ -0,0 +1,569 @@ +/* + * 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 "panel_jobs.h" +#include <wx/aui/auibook.h> +#include <jobs/jobset.h> +#include <jobs/job_registry.h> +#include <eda_list_dialog.h> +#include <dialogs/dialog_job_config_base.h> +#include <wx/checkbox.h> +#include <wx/menu.h> +#include <bitmaps.h> +#include <i18n_utility.h> +#include <jobs_runner.h> +#include <widgets/wx_progress_reporters.h> +#include <jobs/jobs_output_archive.h> +#include <jobs/jobs_output_folder.h> +#include <kicad_manager_frame.h> +#include <vector> + +#include <wx/dirdlg.h> +#include <wx/filedlg.h> +#include <wildcards_and_files_ext.h> +#include <widgets/std_bitmap_button.h> + +#include <confirm.h> + + +struct JOB_TYPE_INFO +{ + wxString name; + enum class BITMAPS bitmap; + bool outputPathIsFolder; + wxString fileWildcard; +}; + + +static std::map<JOBSET_OUTPUT_TYPE, JOB_TYPE_INFO> jobTypeInfos = { + { JOBSET_OUTPUT_TYPE::FOLDER, + { _HKI( "Folder" ), BITMAPS::small_folder, true, "" } }, + { JOBSET_OUTPUT_TYPE::ARCHIVE, + { _HKI( "Archive" ), BITMAPS::zip, false, FILEEXT::ZipFileWildcard() } }, +}; + + +class DIALOG_JOB_OUTPUT : public DIALOG_JOB_OUTPUT_BASE +{ +public: + DIALOG_JOB_OUTPUT( wxWindow* aParent, JOBSET* aJobsFile, JOBSET_OUTPUT* aOutput ) : + DIALOG_JOB_OUTPUT_BASE( aParent ), m_jobsFile( aJobsFile ), m_output( aOutput ) + { + SetAffirmativeId( wxID_SAVE ); + + if( m_output->m_type != JOBSET_OUTPUT_TYPE::ARCHIVE ) + { + m_textArchiveFormat->Hide(); + m_choiceArchiveformat->Hide(); + } + + m_buttonOutputPath->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); + } + + + virtual void onOutputPathBrowseClicked(wxCommandEvent& event) override + { + bool isFolder = false; + wxString fileWildcard = ""; + if( jobTypeInfos.contains( m_output->m_type ) ) + { + isFolder = jobTypeInfos[m_output->m_type].outputPathIsFolder; + fileWildcard = jobTypeInfos[m_output->m_type].fileWildcard; + } + + if( isFolder ) + { + wxFileName fn; + fn.AssignDir( m_textCtrlOutputPath->GetValue() ); + fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ); + wxString currPath = fn.GetFullPath(); + + wxDirDialog dirDialog( this, _( "Select Templates Directory" ), currPath, + wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST ); + + if( dirDialog.ShowModal() != wxID_OK ) + return; + + wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() ); + + m_textCtrlOutputPath->SetValue( dirName.GetFullPath() ); + } + else + { + wxFileDialog dlg( this, _( "Select output path" ), m_textCtrlOutputPath->GetValue(), + "test.zip", + fileWildcard, + wxFD_OVERWRITE_PROMPT | wxFD_SAVE ); + + if( dlg.ShowModal() != wxID_OK ) + { + return; + } + + wxFileName fname_log( dlg.GetPath() ); + } + + } + + bool TransferDataFromWindow() override + { + wxArrayInt selectedItems; + m_listBoxOnly->GetSelections( selectedItems ); + + // Update the only job map + m_output->m_only.clear(); + for( int i : selectedItems ) + { + if( m_onlyMap.contains( i ) ) + { + m_output->m_only.emplace_back( m_onlyMap[i] ); + } + } + + m_output->m_outputHandler->SetOutputPath( m_textCtrlOutputPath->GetValue() ); + + if( m_output->m_type == JOBSET_OUTPUT_TYPE::ARCHIVE ) + { + JOBS_OUTPUT_ARCHIVE* archive = + static_cast<JOBS_OUTPUT_ARCHIVE*>( m_output->m_outputHandler ); + + archive->SetFormat( JOBS_OUTPUT_ARCHIVE::FORMAT::ZIP ); + } + + + return true; + } + + + bool TransferDataToWindow() override + { + wxArrayString arrayStr; + std::vector<int> selectedList; + + std::vector<JOBSET_JOB> jobs = m_jobsFile->GetJobs(); + int i = 0; + for( JOBSET_JOB& job : jobs ) + { + arrayStr.Add( job.m_job->GetDescription() ); + + auto it = std::find_if( m_output->m_only.begin(), m_output->m_only.end(), + [&]( const wxString& only ) + { + if( only == job.m_id ) + return true; + + return false; + } ); + + if( it != m_output->m_only.end() ) + { + selectedList.emplace_back( i ); + } + + m_onlyMap.emplace( i, job.m_id ); + i++; + } + + m_listBoxOnly->InsertItems( arrayStr, 0 ); + + for( int idx : selectedList ) + { + m_listBoxOnly->SetSelection( idx ); + } + + m_choiceArchiveformat->AppendString( _( "Zip" ) ); + m_choiceArchiveformat->SetSelection( 0 ); + + if( m_output->m_type == JOBSET_OUTPUT_TYPE::ARCHIVE ) + { + JOBS_OUTPUT_ARCHIVE* archive = static_cast<JOBS_OUTPUT_ARCHIVE*>( m_output->m_outputHandler ); + } + else + { + JOBS_OUTPUT_FOLDER* folder = + static_cast<JOBS_OUTPUT_FOLDER*>( m_output->m_outputHandler ); + } + + return true; + } + + +private: + JOBSET* m_jobsFile; + JOBSET_OUTPUT* m_output; + std::map<int, wxString> m_onlyMap; +}; + + +class PANEL_JOB_OUTPUT : public PANEL_JOB_OUTPUT_BASE +{ +public: + PANEL_JOB_OUTPUT( wxWindow* aParent, PANEL_JOBS* aPanelParent, KICAD_MANAGER_FRAME* aFrame, + JOBSET* aFile, JOBSET_OUTPUT* aOutput ) : + PANEL_JOB_OUTPUT_BASE( aParent ), + m_jobsFile( aFile ), + m_output( aOutput ), + m_frame( aFrame ), + m_panelParent( aPanelParent ) + { + m_buttonOutputRun->SetBitmap( KiBitmapBundle( BITMAPS::sim_run ) ); + m_buttonOutputOptions->SetBitmap( KiBitmapBundle( BITMAPS::preference ) ); + + m_buttonOutputOptions->Connect( wxEVT_MENU, + wxCommandEventHandler( PANEL_JOB_OUTPUT::onMenu ), nullptr, this ); + + if( jobTypeInfos.contains( aOutput->m_type ) ) + { + JOB_TYPE_INFO& jobTypeInfo = jobTypeInfos[aOutput->m_type]; + m_textOutputType->SetLabel( wxGetTranslation( jobTypeInfo.name ) ); + m_bitmapOutputType->SetBitmap( KiBitmapBundle( jobTypeInfo.bitmap ) ); + } + } + + + ~PANEL_JOB_OUTPUT() + { + m_buttonOutputOptions->Disconnect( + wxEVT_MENU, wxCommandEventHandler( PANEL_JOB_OUTPUT::onMenu ), nullptr, this ); + } + + + virtual void OnOutputRunClick( wxCommandEvent& event ) override + { + CallAfter( + [this]() + { + PROJECT& project = m_frame->Kiway().Prj(); + m_panelParent->EnsurePcbSchFramesOpen(); + + wxFileName fn = project.GetProjectFullName(); + wxSetWorkingDirectory( fn.GetPath() ); + + JOBS_RUNNER jobRunner( &( m_frame->Kiway() ), m_jobsFile ); + + WX_PROGRESS_REPORTER* progressReporter = + new WX_PROGRESS_REPORTER( m_frame, _( "Running jobs" ), 1 ); + + jobRunner.RunJobsForOutput( m_output ); + + delete progressReporter; + } ); + } + + virtual void OnOutputOptionsClick( wxCommandEvent& event ) override + { + wxMenu menu; + menu.Append( wxID_EDIT, _( "Edit..." ) ); + menu.Append( wxID_DELETE, _( "Delete" ) ); + + m_buttonOutputOptions->PopupMenu( &menu ); + } + + +private: + void onMenu( wxCommandEvent& aEvent ) + { + switch( aEvent.GetId() ) + { + case wxID_EDIT: + { + DIALOG_JOB_OUTPUT dialog( m_frame, m_jobsFile, m_output ); + + dialog.ShowModal(); + } + break; + + case wxID_DELETE: + m_panelParent->RemoveOutput( m_output ); + break; + + default: + wxFAIL_MSG( wxT( "Unknown ID in context menu event" ) ); + } + } + + JOBSET* m_jobsFile; + JOBSET_OUTPUT* m_output; + KICAD_MANAGER_FRAME* m_frame; + PANEL_JOBS* m_panelParent; +}; + + +PANEL_JOBS::PANEL_JOBS( wxAuiNotebook* aParent, KICAD_MANAGER_FRAME* aFrame, + std::unique_ptr<JOBSET> aJobsFile ) : + PANEL_JOBS_BASE( aParent ), + m_parentBook( aParent ), + m_frame( aFrame ), + m_jobsFile( std::move( aJobsFile ) ) +{ + int jobNoColId = m_jobList->AppendColumn( _( "No." ) ); + int jobDescColId = m_jobList->AppendColumn( _( "Job Description" ) ); + m_jobList->SetColumnWidth( jobNoColId, wxLIST_AUTOSIZE_USEHEADER ); + m_jobList->SetColumnWidth( jobDescColId, wxLIST_AUTOSIZE_USEHEADER ); + + m_buttonAddJob->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) ); + m_buttonUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) ); + m_buttonDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) ); + m_buttonOutputAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) ); + + rebuildJobList(); + buildOutputList(); +} + + +void PANEL_JOBS::RemoveOutput( JOBSET_OUTPUT* aOutput ) +{ + auto it = m_outputPanelMap.find( aOutput ); + if( it != m_outputPanelMap.end() ) + { + PANEL_JOB_OUTPUT* panel = m_outputPanelMap[aOutput]; + m_outputListSizer->Detach( panel ); + panel->Destroy(); + + m_outputPanelMap.erase( it ); + + // ensure the window contents get shifted as needed + m_outputList->Layout(); + Layout(); + } + + m_jobsFile->RemoveOutput( aOutput ); +} + + +void PANEL_JOBS::rebuildJobList() +{ + m_jobList->DeleteAllItems(); + + int num = 1; + for( auto& job : m_jobsFile->GetJobs() ) + { + long itemIndex = + m_jobList->InsertItem( m_jobList->GetItemCount(), wxString::Format( "%d", num++ ) ); + m_jobList->SetItem( itemIndex, 1, job.m_job->GetDescription() ); + } + + updateTitle(); +} + + +void PANEL_JOBS::updateTitle() +{ + wxString tabName = m_jobsFile->GetFullName(); + if( m_jobsFile->GetDirty() ) + { + tabName = wxS( "*" ) + tabName; + } + int pageIdx = m_parentBook->FindPage( this ); + m_parentBook->SetPageText( pageIdx, tabName ); +} + + +void PANEL_JOBS::addJobOutputPanel( JOBSET_OUTPUT* aOutput ) +{ + PANEL_JOB_OUTPUT* outputPanel = + new PANEL_JOB_OUTPUT( m_outputList, this, m_frame, m_jobsFile.get(), aOutput ); + m_outputListSizer->Add( outputPanel, 0, wxEXPAND | wxALL, 5 ); + + m_outputPanelMap[aOutput] = outputPanel; + + m_outputList->Layout(); +} + + +void PANEL_JOBS::buildOutputList() +{ + Freeze(); + m_outputPanelMap.clear(); + + for( auto& job : m_jobsFile->GetOutputs() ) + { + addJobOutputPanel( &job ); + } + + // ensure the window contents get shifted as needed + Layout(); + Thaw(); +} + + +void PANEL_JOBS::OnJobListDoubleClicked( wxListEvent& aEvent ) +{ + EnsurePcbSchFramesOpen(); + + long item = aEvent.GetIndex(); + + JOBSET_JOB& job = m_jobsFile->GetJobs()[item]; + + KIWAY::FACE_T iface = JOB_REGISTRY::GetKifaceType( job.m_type ); + + int result = m_frame->Kiway().ProcessJobConfigDialog( iface, job.m_job, m_frame ); +} + + +void PANEL_JOBS::OnSaveButtonClick( wxCommandEvent& aEvent ) +{ + m_jobsFile->SaveToFile(); + updateTitle(); +} + + +void PANEL_JOBS::OnAddJobClick( wxCommandEvent& aEvent ) +{ + wxArrayString headers; + std::vector<wxArrayString> items; + + headers.Add( _( "Job Types" ) ); + + const JOB_REGISTRY::REGISTRY_MAP_T& jobMap = JOB_REGISTRY::GetRegistry(); + + for( const std::pair<wxString, JOB_REGISTRY_ENTRY>& entry : jobMap ) + { + wxArrayString item; + item.Add( wxGetTranslation( entry.second.title ) ); + items.emplace_back( item ); + } + + EDA_LIST_DIALOG dlg( this, _( "Add New Job" ), headers, items ); + dlg.SetListLabel( _( "Select job type:" ) ); + + if( dlg.ShowModal() == wxID_OK ) + { + wxString selectedString = dlg.GetTextSelection(); + + wxString jobKey; + if( !selectedString.IsEmpty() ) + { + for( const std::pair<wxString, JOB_REGISTRY_ENTRY>& entry : jobMap ) + { + if( wxGetTranslation( entry.second.title ) == selectedString ) + { + jobKey = entry.first; + break; + } + } + } + + if( !jobKey.IsEmpty() ) + { + JOB* job = JOB_REGISTRY::CreateInstance<JOB>( jobKey ); + m_jobsFile->AddNewJob( jobKey, job ); + + rebuildJobList(); + } + } +} + + +void PANEL_JOBS::OnAddOutputClick( wxCommandEvent& aEvent ) +{ + wxArrayString headers; + std::vector<wxArrayString> items; + + headers.Add( _( "Job Types" ) ); + + for( const std::pair<JOBSET_OUTPUT_TYPE, JOB_TYPE_INFO>& jobType : jobTypeInfos ) + { + wxArrayString item; + item.Add( wxGetTranslation( jobType.second.name ) ); + items.emplace_back( item ); + } + + EDA_LIST_DIALOG dlg( this, _( "Add New Output" ), headers, items ); + dlg.SetListLabel( _( "Select output type:" ) ); + dlg.HideFilter(); + + if( dlg.ShowModal() == wxID_OK ) + { + wxString selectedString = dlg.GetTextSelection(); + + for( const std::pair<JOBSET_OUTPUT_TYPE, JOB_TYPE_INFO>& jobType : jobTypeInfos ) + { + if( wxGetTranslation( jobType.second.name ) == selectedString ) + { + JOBSET_OUTPUT output = m_jobsFile->AddNewJobOutput( jobType.first, nullptr ); + + Freeze(); + addJobOutputPanel( &output ); + Thaw(); + } + } + } +} + + +bool PANEL_JOBS::GetCanClose() +{ + if( m_jobsFile->GetDirty() ) + { + wxFileName fileName = m_jobsFile->GetFullFilename(); + wxString msg = _( "Save changes to '%s' before closing?" ); + + if( !HandleUnsavedChanges( this, wxString::Format( msg, fileName.GetFullName() ), + [&]() -> bool + { + return m_jobsFile->SaveToFile(); + } ) ) + { + return false; + } + } + + return true; +} + + +void PANEL_JOBS::EnsurePcbSchFramesOpen() +{ + PROJECT& project = m_frame->Kiway().Prj(); + KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, false ); + + if( !frame ) + { + frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, true ); + + // frame can be null if Cvpcb cannot be run. No need to show a warning + // Kiway() generates the error messages + if( !frame ) + return; + + wxFileName boardfn = project.GetProjectFullName(); + boardfn.SetExt( FILEEXT::PcbFileExtension ); + + frame->OpenProjectFiles( std::vector<wxString>( 1, boardfn.GetFullPath() ) ); + } + + frame = m_frame->Kiway().Player( FRAME_SCH, false ); + + if( !frame ) + { + frame = m_frame->Kiway().Player( FRAME_SCH, true ); + + // frame can be null if Cvpcb cannot be run. No need to show a warning + // Kiway() generates the error messages + if( !frame ) + return; + + wxFileName schFn = project.GetProjectFullName(); + schFn.SetExt( FILEEXT::KiCadSchematicFileExtension ); + + frame->OpenProjectFiles( std::vector<wxString>( 1, schFn.GetFullPath() ) ); + } +} \ No newline at end of file diff --git a/kicad/dialogs/panel_jobs.h b/kicad/dialogs/panel_jobs.h new file mode 100644 index 0000000000..5d60720ad4 --- /dev/null +++ b/kicad/dialogs/panel_jobs.h @@ -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/>. + */ + +#pragma once + +#include "panel_jobs_base.h" +#include <memory> + +class wxAuiNotebook; +class JOBSET; +class KICAD_MANAGER_FRAME; +class PANEL_JOB_OUTPUT; +struct JOBSET_OUTPUT; + +class PANEL_JOBS : public PANEL_JOBS_BASE +{ +public: + PANEL_JOBS( wxAuiNotebook* aParent, KICAD_MANAGER_FRAME* aFrame, + std::unique_ptr<JOBSET> aJobsFile ); + + void RemoveOutput( JOBSET_OUTPUT* aOutput ); + + void EnsurePcbSchFramesOpen(); + +protected: + virtual void OnAddJobClick( wxCommandEvent& aEvent ) override; + virtual void OnAddOutputClick( wxCommandEvent& aEvent ) override; + virtual void OnJobListDoubleClicked( wxListEvent& aEvent ) override; + virtual void OnSaveButtonClick( wxCommandEvent& aEvent ) override; + + bool GetCanClose() override; + +private: + void rebuildJobList(); + void updateTitle(); + void buildOutputList(); + void addJobOutputPanel( JOBSET_OUTPUT* aOutput ); + + wxAuiNotebook* m_parentBook; + KICAD_MANAGER_FRAME* m_frame; + std::unique_ptr<JOBSET> m_jobsFile; + + std::unordered_map<JOBSET_OUTPUT*, PANEL_JOB_OUTPUT*> m_outputPanelMap; +}; \ No newline at end of file diff --git a/kicad/dialogs/panel_jobs_base.cpp b/kicad/dialogs/panel_jobs_base.cpp new file mode 100644 index 0000000000..a7a94dbe0e --- /dev/null +++ b/kicad/dialogs/panel_jobs_base.cpp @@ -0,0 +1,249 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "widgets/std_bitmap_button.h" + +#include "panel_jobs_base.h" + +/////////////////////////////////////////////////////////////////////////// + +PANEL_JOBS_BASE::PANEL_JOBS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : PANEL_NOTEBOOK_BASE( parent, id, pos, size, style, name ) +{ + wxBoxSizer* bSizer1; + bSizer1 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer( wxVERTICAL ); + + m_staticText1 = new wxStaticText( this, wxID_ANY, wxT("Jobs"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText1->Wrap( -1 ); + bSizer3->Add( m_staticText1, 0, wxALL, 5 ); + + m_jobList = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL ); + bSizer3->Add( m_jobList, 1, wxALL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 5 ); + + wxBoxSizer* bSizer2; + bSizer2 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonAddJob = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer2->Add( m_buttonAddJob, 0, wxALIGN_CENTER|wxALL, 5 ); + + m_buttonUp = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer2->Add( m_buttonUp, 0, wxALL, 5 ); + + m_buttonDown = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer2->Add( m_buttonDown, 0, wxALL, 5 ); + + + bSizer2->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonSave = new wxButton( this, wxID_ANY, wxT("Save"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer2->Add( m_buttonSave, 0, wxALIGN_CENTER|wxALL, 5 ); + + + bSizer3->Add( bSizer2, 0, wxEXPAND, 5 ); + + + bSizer1->Add( bSizer3, 2, wxEXPAND, 5 ); + + wxBoxSizer* bSizer4; + bSizer4 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer14; + bSizer14 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText4 = new wxStaticText( this, wxID_ANY, wxT("Outputs"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText4->Wrap( -1 ); + bSizer14->Add( m_staticText4, 0, wxALL, 5 ); + + m_buttonOutputAdd = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer14->Add( m_buttonOutputAdd, 0, 0, 5 ); + + + bSizer4->Add( bSizer14, 0, wxEXPAND, 5 ); + + m_outputList = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL ); + m_outputList->SetScrollRate( 5, 5 ); + m_outputListSizer = new wxBoxSizer( wxVERTICAL ); + + + m_outputList->SetSizer( m_outputListSizer ); + m_outputList->Layout(); + m_outputListSizer->Fit( m_outputList ); + bSizer4->Add( m_outputList, 1, wxEXPAND | wxALL, 0 ); + + m_buttonRunAllOutputs = new wxButton( this, wxID_ANY, wxT("Run All Jobs"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonRunAllOutputs->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + bSizer4->Add( m_buttonRunAllOutputs, 0, wxALIGN_RIGHT|wxALL, 5 ); + + + bSizer1->Add( bSizer4, 1, wxEXPAND, 5 ); + + + this->SetSizer( bSizer1 ); + this->Layout(); + + // Connect Events + m_jobList->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( PANEL_JOBS_BASE::OnJobListDoubleClicked ), NULL, this ); + m_jobList->Connect( wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler( PANEL_JOBS_BASE::OnJobListItemRightClick ), NULL, this ); + m_buttonAddJob->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnAddJobClick ), NULL, this ); + m_buttonSave->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnSaveButtonClick ), NULL, this ); + m_buttonOutputAdd->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnAddOutputClick ), NULL, this ); + m_buttonRunAllOutputs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnRunAllJobsClick ), NULL, this ); +} + +PANEL_JOBS_BASE::~PANEL_JOBS_BASE() +{ + // Disconnect Events + m_jobList->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( PANEL_JOBS_BASE::OnJobListDoubleClicked ), NULL, this ); + m_jobList->Disconnect( wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler( PANEL_JOBS_BASE::OnJobListItemRightClick ), NULL, this ); + m_buttonAddJob->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnAddJobClick ), NULL, this ); + m_buttonSave->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnSaveButtonClick ), NULL, this ); + m_buttonOutputAdd->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnAddOutputClick ), NULL, this ); + m_buttonRunAllOutputs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOBS_BASE::OnRunAllJobsClick ), NULL, this ); + +} + +PANEL_JOB_OUTPUT_BASE::PANEL_JOB_OUTPUT_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) +{ + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); + + wxBoxSizer* bSizer11; + bSizer11 = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmapOutputType = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer11->Add( m_bitmapOutputType, 0, wxALL, 5 ); + + wxBoxSizer* bSizer12; + bSizer12 = new wxBoxSizer( wxVERTICAL ); + + m_textOutputType = new wxStaticText( this, wxID_ANY, wxT("Placeholder"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textOutputType->Wrap( -1 ); + m_textOutputType->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); + + bSizer12->Add( m_textOutputType, 0, wxALL, 5 ); + + + bSizer11->Add( bSizer12, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer13; + bSizer13 = new wxBoxSizer( wxVERTICAL ); + + m_buttonOutputRun = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer13->Add( m_buttonOutputRun, 0, wxALL, 5 ); + + m_buttonOutputOptions = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer13->Add( m_buttonOutputOptions, 0, wxALL, 5 ); + + + bSizer11->Add( bSizer13, 0, wxEXPAND, 5 ); + + + this->SetSizer( bSizer11 ); + this->Layout(); + bSizer11->Fit( this ); + + // Connect Events + m_buttonOutputRun->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOB_OUTPUT_BASE::OnOutputRunClick ), NULL, this ); + m_buttonOutputOptions->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOB_OUTPUT_BASE::OnOutputOptionsClick ), NULL, this ); +} + +PANEL_JOB_OUTPUT_BASE::~PANEL_JOB_OUTPUT_BASE() +{ + // Disconnect Events + m_buttonOutputRun->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOB_OUTPUT_BASE::OnOutputRunClick ), NULL, this ); + m_buttonOutputOptions->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_JOB_OUTPUT_BASE::OnOutputOptionsClick ), NULL, this ); + +} + +DIALOG_JOB_OUTPUT_BASE::DIALOG_JOB_OUTPUT_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 ); + + wxBoxSizer* bSizer15; + bSizer15 = new wxBoxSizer( wxVERTICAL ); + + m_staticText9 = new wxStaticText( this, wxID_ANY, wxT("Options"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText9->Wrap( -1 ); + m_staticText9->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); + + bSizer15->Add( m_staticText9, 0, wxALL, 5 ); + + m_panel9 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxFlexGridSizer* fgSizer1; + fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer1->SetFlexibleDirection( wxBOTH ); + fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_textArchiveFormat = new wxStaticText( m_panel9, wxID_ANY, wxT("Format"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textArchiveFormat->Wrap( -1 ); + fgSizer1->Add( m_textArchiveFormat, 0, wxALL, 5 ); + + wxArrayString m_choiceArchiveformatChoices; + m_choiceArchiveformat = new wxChoice( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceArchiveformatChoices, 0 ); + m_choiceArchiveformat->SetSelection( 0 ); + fgSizer1->Add( m_choiceArchiveformat, 0, wxALL, 5 ); + + m_textOutputPath = new wxStaticText( m_panel9, wxID_ANY, wxT("Output Path"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textOutputPath->Wrap( -1 ); + fgSizer1->Add( m_textOutputPath, 0, wxALL, 5 ); + + wxBoxSizer* bSizer16; + bSizer16 = new wxBoxSizer( wxHORIZONTAL ); + + m_textCtrlOutputPath = new wxTextCtrl( m_panel9, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlOutputPath->SetMinSize( wxSize( 350,-1 ) ); + + bSizer16->Add( m_textCtrlOutputPath, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_buttonOutputPath = new STD_BITMAP_BUTTON( m_panel9, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer16->Add( m_buttonOutputPath, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + fgSizer1->Add( bSizer16, 1, wxEXPAND, 5 ); + + m_staticText10 = new wxStaticText( m_panel9, wxID_ANY, wxT("Only Jobs"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText10->Wrap( -1 ); + fgSizer1->Add( m_staticText10, 0, wxALL, 5 ); + + m_listBoxOnly = new wxListBox( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_ALWAYS_SB|wxLB_MULTIPLE ); + m_listBoxOnly->SetMinSize( wxSize( 300,200 ) ); + + fgSizer1->Add( m_listBoxOnly, 0, wxALL, 5 ); + + + m_panel9->SetSizer( fgSizer1 ); + m_panel9->Layout(); + fgSizer1->Fit( m_panel9 ); + bSizer15->Add( m_panel9, 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(); + + bSizer15->Add( m_sdbSizer1, 0, wxEXPAND, 5 ); + + + this->SetSizer( bSizer15 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + m_buttonOutputPath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_JOB_OUTPUT_BASE::onOutputPathBrowseClicked ), NULL, this ); +} + +DIALOG_JOB_OUTPUT_BASE::~DIALOG_JOB_OUTPUT_BASE() +{ + // Disconnect Events + m_buttonOutputPath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_JOB_OUTPUT_BASE::onOutputPathBrowseClicked ), NULL, this ); + +} diff --git a/kicad/dialogs/panel_jobs_base.fbp b/kicad/dialogs/panel_jobs_base.fbp new file mode 100644 index 0000000000..81ade8b07f --- /dev/null +++ b/kicad/dialogs/panel_jobs_base.fbp @@ -0,0 +1,1799 @@ +<?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">panel_jobs_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">PANEL_JOBS_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="Panel" expanded="true"> + <property name="aui_managed">0</property> + <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property> + <property name="bg"></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="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">PANEL_JOBS_BASE</property> + <property name="pos"></property> + <property name="size">600,400</property> + <property name="subclass">PANEL_NOTEBOOK_BASE; dialogs/panel_notebook_base.h; forward_declare</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">wxTAB_TRAVERSAL</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bSizer1</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">2</property> + <object class="wxBoxSizer" expanded="false"> + <property name="minimum_size"></property> + <property name="name">bSizer3</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Jobs</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">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="false"> + <property name="border">5</property> + <property name="flag">wxALL|wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property> + <property name="proportion">1</property> + <object class="wxListCtrl" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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_jobList</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">wxLC_REPORT|wxLC_SINGLE_SEL</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnListItemActivated">OnJobListDoubleClicked</event> + <event name="OnListItemRightClick">OnJobListItemRightClick</event> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="false"> + <property name="minimum_size"></property> + <property name="name">bSizer2</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER|wxALL</property> + <property name="proportion">0</property> + <object class="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">MyButton</property> + <property name="margins"></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_buttonAddJob</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="position"></property> + <property name="pressed"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnAddJobClick</event> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">MyButton</property> + <property name="margins"></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_buttonUp</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="position"></property> + <property name="pressed"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></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="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">MyButton</property> + <property name="margins"></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_buttonDown</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="position"></property> + <property name="pressed"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="spacer" expanded="false"> + <property name="height">0</property> + <property name="permission">protected</property> + <property name="width">0</property> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER|wxALL</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Save</property> + <property name="margins"></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_buttonSave</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="position"></property> + <property name="pressed"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnSaveButtonClick</event> + </object> + </object> + </object> + </object> + </object> + </object> + <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">bSizer4</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">0</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bSizer14</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Outputs</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_staticText4</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"></property> + <property name="proportion">0</property> + <object class="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">MyButton</property> + <property name="margins"></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_buttonOutputAdd</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="position"></property> + <property name="pressed"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnAddOutputClick</event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">0</property> + <property name="flag">wxEXPAND | wxALL</property> + <property name="proportion">1</property> + <object class="wxScrolledWindow" 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_outputList</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="scroll_rate_x">5</property> + <property name="scroll_rate_y">5</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">wxVSCROLL</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">m_outputListSizer</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">protected</property> + </object> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT|wxALL</property> + <property name="proportion">0</property> + <object class="wxButton" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg">wxSYS_COLOUR_WINDOW</property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Run All Jobs</property> + <property name="margins"></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_buttonRunAllOutputs</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="position"></property> + <property name="pressed"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnRunAllJobsClick</event> + </object> + </object> + </object> + </object> + </object> + </object> + <object class="Panel" expanded="true"> + <property name="aui_managed">0</property> + <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property> + <property name="bg">wxSYS_COLOUR_3DLIGHT</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="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">PANEL_JOB_OUTPUT_BASE</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="subclass">; ; forward_declare</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">wxBORDER_SIMPLE|wxTAB_TRAVERSAL</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bSizer11</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="wxStaticBitmap" 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="bitmap"></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_bitmapOutputType</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"></property> + </object> + </object> + <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">bSizer12</property> + <property name="orient">wxVERTICAL</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">,90,700,-1,70,0</property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Placeholder</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_textOutputType</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> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bSizer13</property> + <property name="orient">wxVERTICAL</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="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Run</property> + <property name="margins"></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_buttonOutputRun</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="position"></property> + <property name="pressed"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnOutputRunClick</event> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></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="margins"></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_buttonOutputOptions</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="position"></property> + <property name="pressed"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnOutputOptionsClick</event> + </object> + </object> + </object> + </object> + </object> + </object> + <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_OUTPUT_BASE</property> + <property name="pos"></property> + <property name="size">495,369</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">bSizer15</property> + <property name="orient">wxVERTICAL</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">,90,700,-1,70,0</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_staticText9</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">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_panel9</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">fgSizer1</property> + <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> + <property name="permission">none</property> + <property name="rows">0</property> + <property name="vgap">0</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">Format</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_textArchiveFormat</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="wxChoice" 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="choices"></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_choiceArchiveformat</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="selection">0</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></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="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_textOutputPath</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">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bSizer16</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|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">350,-1</property> + <property name="moveable">1</property> + <property name="name">m_textCtrlOutputPath</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 class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> + <property name="proportion">0</property> + <object class="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">MyButton</property> + <property name="margins"></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_buttonOutputPath</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="position"></property> + <property name="pressed"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">onOutputPathBrowseClicked</event> + </object> + </object> + </object> + </object> + <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">Only Jobs</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_staticText10</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="wxListBox" 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="choices"></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">300,200</property> + <property name="moveable">1</property> + <property name="name">m_listBoxOnly</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">wxLB_ALWAYS_SB|wxLB_MULTIPLE</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + </object> + </object> + </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> diff --git a/kicad/dialogs/panel_jobs_base.h b/kicad/dialogs/panel_jobs_base.h new file mode 100644 index 0000000000..5b7b73b1ea --- /dev/null +++ b/kicad/dialogs/panel_jobs_base.h @@ -0,0 +1,134 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include <wx/artprov.h> +#include <wx/xrc/xmlres.h> +class STD_BITMAP_BUTTON; + +#include "dialogs/panel_notebook_base.h" +#include "dialog_shim.h" +#include <wx/string.h> +#include <wx/stattext.h> +#include <wx/gdicmn.h> +#include <wx/font.h> +#include <wx/colour.h> +#include <wx/settings.h> +#include <wx/listctrl.h> +#include <wx/bmpbuttn.h> +#include <wx/bitmap.h> +#include <wx/image.h> +#include <wx/icon.h> +#include <wx/button.h> +#include <wx/sizer.h> +#include <wx/scrolwin.h> +#include <wx/panel.h> +#include <wx/statbmp.h> +#include <wx/choice.h> +#include <wx/textctrl.h> +#include <wx/listbox.h> +#include <wx/dialog.h> + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// Class PANEL_JOBS_BASE +/////////////////////////////////////////////////////////////////////////////// +class PANEL_JOBS_BASE : public PANEL_NOTEBOOK_BASE +{ + private: + + protected: + wxStaticText* m_staticText1; + wxListCtrl* m_jobList; + wxBitmapButton* m_buttonAddJob; + wxBitmapButton* m_buttonUp; + wxBitmapButton* m_buttonDown; + wxButton* m_buttonSave; + wxStaticText* m_staticText4; + wxBitmapButton* m_buttonOutputAdd; + wxScrolledWindow* m_outputList; + wxBoxSizer* m_outputListSizer; + wxButton* m_buttonRunAllOutputs; + + // Virtual event handlers, override them in your derived class + virtual void OnJobListDoubleClicked( wxListEvent& event ) { event.Skip(); } + virtual void OnJobListItemRightClick( wxListEvent& event ) { event.Skip(); } + virtual void OnAddJobClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnSaveButtonClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnAddOutputClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRunAllJobsClick( wxCommandEvent& event ) { event.Skip(); } + + + public: + + PANEL_JOBS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 600,400 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); + + ~PANEL_JOBS_BASE(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class PANEL_JOB_OUTPUT_BASE +/////////////////////////////////////////////////////////////////////////////// +class PANEL_JOB_OUTPUT_BASE : public wxPanel +{ + private: + + protected: + wxStaticBitmap* m_bitmapOutputType; + wxStaticText* m_textOutputType; + wxBitmapButton* m_buttonOutputRun; + wxBitmapButton* m_buttonOutputOptions; + + // Virtual event handlers, override them in your derived class + virtual void OnOutputRunClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnOutputOptionsClick( wxCommandEvent& event ) { event.Skip(); } + + + public: + + PANEL_JOB_OUTPUT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxBORDER_SIMPLE|wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); + + ~PANEL_JOB_OUTPUT_BASE(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_JOB_OUTPUT_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_JOB_OUTPUT_BASE : public DIALOG_SHIM +{ + private: + + protected: + wxStaticText* m_staticText9; + wxPanel* m_panel9; + wxStaticText* m_textArchiveFormat; + wxChoice* m_choiceArchiveformat; + wxStaticText* m_textOutputPath; + wxTextCtrl* m_textCtrlOutputPath; + STD_BITMAP_BUTTON* m_buttonOutputPath; + wxStaticText* m_staticText10; + wxListBox* m_listBoxOnly; + wxStdDialogButtonSizer* m_sdbSizer1; + wxButton* m_sdbSizer1Save; + wxButton* m_sdbSizer1Cancel; + + // Virtual event handlers, override them in your derived class + virtual void onOutputPathBrowseClicked( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_JOB_OUTPUT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 495,369 ), long style = wxDEFAULT_DIALOG_STYLE ); + + ~DIALOG_JOB_OUTPUT_BASE(); + +}; + diff --git a/kicad/jobs_runner.cpp b/kicad/jobs_runner.cpp new file mode 100644 index 0000000000..b5a1b5aa4a --- /dev/null +++ b/kicad/jobs_runner.cpp @@ -0,0 +1,169 @@ +/* + * 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_runner.h> +#include <jobs/job_registry.h> +#include <jobs/jobset.h> +#include <kiway.h> +#include <kiway_express.h> +#include <reporter.h> + +JOBS_RUNNER::JOBS_RUNNER( KIWAY* aKiway, JOBSET* aJobsFile, + REPORTER* aReporter ) : + m_kiway( aKiway ), + m_jobsFile( aJobsFile ), + m_reporter( aReporter ) +{ + if( !m_reporter ) + { + m_reporter = &NULL_REPORTER::GetInstance(); + } +} + + +bool JOBS_RUNNER::RunJobsAllOutputs( bool aBail ) +{ + bool success = true; + + for( JOBSET_OUTPUT& output : m_jobsFile->GetOutputs() ) + { + success &= RunJobsForOutput( &output, aBail ); + } + + return success; +} + + +bool JOBS_RUNNER::RunJobsForOutput( JOBSET_OUTPUT* aOutput, bool aBail ) +{ + bool success = true; + std::vector<JOBSET_JOB> jobsForOutput = m_jobsFile->GetJobsForOutput( aOutput ); + wxString msg; + + wxFileName tmp; + tmp.AssignDir( wxFileName::GetTempDir() ); + tmp.AppendDir( KIID().AsString() ); + + wxString tempDirPath = tmp.GetFullPath(); + if( !wxFileName::Mkdir( tempDirPath, wxS_DIR_DEFAULT ) ) + { + if( m_reporter ) + { + msg = wxString::Format( wxT( "Failed to create temporary directory %s" ), tempDirPath ); + m_reporter->Report( msg, RPT_SEVERITY_ERROR ); + } + + return false; + } + + if( m_reporter != nullptr ) + { + msg += wxT( "|--------------------------------\n" ); + msg += wxT( "| " ); + msg += wxString::Format( "Performing jobs" ); + msg += wxT( "\n" ); + msg += wxT( "|--------------------------------\n" ); + + msg += wxString::Format( wxT( "|%-5s | %-50s\n" ), wxT( "No." ), wxT( "Description" ) ); + + int jobNum = 1; + for( const JOBSET_JOB& job : jobsForOutput ) + { + msg += wxString::Format( wxT( "|%-5d | %-50s\n" ), jobNum, + job.m_job->GetDescription() ); + jobNum++; + } + msg += wxT( "|--------------------------------\n" ); + msg += wxT( "\n" ); + msg += wxT( "\n" ); + + m_reporter->Report( msg, RPT_SEVERITY_INFO ); + } + + std::vector<JOB_OUTPUT> outputs; + + int jobNum = 1; + int failCount = 0; + int successCount = 0; + for( const JOBSET_JOB& job : jobsForOutput ) + { + if( m_reporter != nullptr ) + { + msg = wxT( "|--------------------------------\n" ); + msg += wxString::Format( wxT( "| Running job %d, %s" ), jobNum, job.m_job->GetDescription() ); + msg += _( "\n" ); + msg += wxT( "|--------------------------------\n" ); + + m_reporter->Report( msg, RPT_SEVERITY_INFO ); + } + + KIWAY::FACE_T iface = JOB_REGISTRY::GetKifaceType( job.m_type ); + + job.m_job->SetTempOutputDirectory( tempDirPath ); + + int result = m_kiway->ProcessJob( iface, job.m_job ); + + if( m_reporter ) + { + if( result == 0 ) + { + msg = _( "\033[32;1mJob successful\033[0m\n" ); + + successCount++; + } + else + { + msg = _( "\033[31;1mJob failed\033[0m\n" ); + + failCount++; + } + + msg += _( "\n\n" ); + m_reporter->Report( msg, RPT_SEVERITY_INFO ); + } + + if( result != 0 ) + { + if( aBail ) + { + return result; + } + else + { + success = false; + } + } + } + + if( success ) + { + aOutput->m_outputHandler->HandleOutputs( tempDirPath, outputs ); + } + + if( m_reporter ) + { + msg = wxString::Format( _( "\n\n\033[33;1m%d jobs succeeded, %d job failed\033[0m\n" ), + successCount, failCount ); + + m_reporter->Report( msg, RPT_SEVERITY_INFO ); + } + + return success; +} \ No newline at end of file diff --git a/kicad/jobs_runner.h b/kicad/jobs_runner.h new file mode 100644 index 0000000000..9dcc74c49b --- /dev/null +++ b/kicad/jobs_runner.h @@ -0,0 +1,40 @@ +/* + * 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 + +class JOBSET; +struct JOBSET_OUTPUT; +class KIWAY; +class REPORTER; + +class JOBS_RUNNER +{ +public: + JOBS_RUNNER( KIWAY* aKiway, JOBSET* aJobsFile, REPORTER* aReporter = nullptr ); + + bool RunJobsAllOutputs( bool aBail = false ); + bool RunJobsForOutput( JOBSET_OUTPUT* aOutput, bool aBail = false ); + +private: + KIWAY* m_kiway; + JOBSET* m_jobsFile; + REPORTER* m_reporter; +}; \ No newline at end of file diff --git a/kicad/kicad_cli.cpp b/kicad/kicad_cli.cpp index ffa65723a6..32af3a4c68 100644 --- a/kicad/kicad_cli.cpp +++ b/kicad/kicad_cli.cpp @@ -46,6 +46,8 @@ #include <kiplatform/environment.h> #include <locale_io.h> +#include "cli/command_jobset.h" +#include "cli/command_jobset_run.h" #include "cli/command_pcb.h" #include "cli/command_pcb_export.h" #include "cli/command_pcb_drc.h" @@ -106,6 +108,8 @@ struct COMMAND_ENTRY handler( aHandler ), subCommands( aSub ){}; }; +static CLI::JOBSET_COMMAND jobsetCmd{}; +static CLI::JOBSET_RUN_COMMAND jobsetRunCmd{}; static CLI::PCB_COMMAND pcbCmd{}; static CLI::PCB_DRC_COMMAND pcbDrcCmd{}; static CLI::PCB_RENDER_COMMAND pcbRenderCmd{}; @@ -147,6 +151,14 @@ static CLI::VERSION_COMMAND versionCmd{}; static std::vector<COMMAND_ENTRY> commandStack = { + { + &jobsetCmd, + { + { + &jobsetRunCmd + } + } + }, { &fpCmd, { diff --git a/kicad/kicad_id.h b/kicad/kicad_id.h index 60e6cd8228..9630f60c39 100644 --- a/kicad/kicad_id.h +++ b/kicad/kicad_id.h @@ -94,6 +94,8 @@ enum id_kicad_frm { ID_GIT_SWITCH_QUICK4, // Switch the local repository to the fourth quick branch ID_GIT_SWITCH_QUICK5, // Switch the local repository to the fifth quick branch + ID_JOBS_RUN, + // Please, verify: the number of items in this list should be // less than ROOM_FOR_KICADMANAGER (see id.h) ID_KICADMANAGER_END_LIST diff --git a/kicad/kicad_manager_frame.cpp b/kicad/kicad_manager_frame.cpp index 3a1b692037..cc0be494ae 100644 --- a/kicad/kicad_manager_frame.cpp +++ b/kicad/kicad_manager_frame.cpp @@ -35,6 +35,7 @@ #include <build_version.h> #include <dialogs/panel_kicad_launcher.h> #include <dialogs/dialog_update_check_prompt.h> +#include <dialogs/panel_jobs.h> #include <eda_base_frame.h> #include <executable_names.h> #include <file_history.h> @@ -67,7 +68,7 @@ #include <wx/process.h> #include <atomic> #include <update_manager.h> - +#include <jobs/jobset.h> #include <../pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h> // for SEXPR_BOARD_FILE_VERSION def @@ -117,6 +118,8 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME ) END_EVENT_TABLE() + static JOBSET* test = new JOBSET( "" ); + // See below the purpose of this include #include <wx/xml/xml.h> @@ -704,6 +707,33 @@ bool KICAD_MANAGER_FRAME::CloseProject( bool aSave ) } +void KICAD_MANAGER_FRAME::OpenJobsFile( const wxFileName& aFileName, bool aCreate ) +{ + if( !ADVANCED_CFG::GetCfg().m_EnableJobset ) + { + return; + } + + try + { + std::unique_ptr<JOBSET> jobsFile = + std::make_unique<JOBSET>( aFileName.GetFullPath().ToStdString() ); + + jobsFile->LoadFromFile(); + + PANEL_JOBS* jobPanel = new PANEL_JOBS( m_notebook, this, std::move( jobsFile ) ); + jobPanel->SetProjectTied( true ); + jobPanel->SetClosable( true ); + m_notebook->AddPage( jobPanel, aFileName.GetFullName(), + true ); + } + catch( ... ) + { + + } +} + + void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName ) { // The project file should be valid by the time we get here or something has gone wrong. diff --git a/kicad/kicad_manager_frame.h b/kicad/kicad_manager_frame.h index e00b7640fa..7d321ea34e 100644 --- a/kicad/kicad_manager_frame.h +++ b/kicad/kicad_manager_frame.h @@ -142,6 +142,8 @@ public: bool CloseProject( bool aSave ); void LoadProject( const wxFileName& aProjectFileName ); + void OpenJobsFile( const wxFileName& aFileName, bool aCreate = false ); + void LoadSettings( APP_SETTINGS_BASE* aCfg ) override; diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp index e12b6778d8..6432bb2651 100644 --- a/kicad/menubar.cpp +++ b/kicad/menubar.cpp @@ -81,6 +81,11 @@ void KICAD_MANAGER_FRAME::doReCreateMenuBar() fileMenu->Add( KICAD_MANAGER_ACTIONS::newFromRepository ); } + if( ADVANCED_CFG::GetCfg().m_EnableJobset ) + { + fileMenu->Add( KICAD_MANAGER_ACTIONS::newJobsetFile ); + } + if( wxDir::Exists( PATHS::GetStockDemosPath() ) ) { fileMenu->Add( KICAD_MANAGER_ACTIONS::openDemoProject ); diff --git a/kicad/project_tree.cpp b/kicad/project_tree.cpp index 1f9aa3bc61..ba8e71c59a 100644 --- a/kicad/project_tree.cpp +++ b/kicad/project_tree.cpp @@ -102,6 +102,7 @@ void PROJECT_TREE::LoadIcons() images.push_back( KiBitmapBundle( BITMAPS::library ) ); // TREE_SEXPR_SYMBOL_LIB_FILE images.push_back( KiBitmapBundle( BITMAPS::editor ) ); // DESIGN_RULES images.push_back( KiBitmapBundle( BITMAPS::zip ) ); // ZIP_ARCHIVE + images.push_back( KiBitmapBundle( BITMAPS::editor ) ); // JOBSET_FILE SetImages( images ); wxVector<wxBitmapBundle> stateImages; @@ -176,6 +177,7 @@ void PROJECT_TREE::LoadIcons() m_imageList->Add( toBitmap( BITMAPS::library ) ); // TREE_SEXPR_SYMBOL_LIB_FILE m_imageList->Add( toBitmap( BITMAPS::editor ) ); // DESIGN_RULES m_imageList->Add( toBitmap( BITMAPS::zip ) ); // ZIP_ARCHIVE + m_imageList->Add( toBitmap( BITMAPS::editor ) ); // JOBSET_FILE SetImageList( m_imageList ); diff --git a/kicad/project_tree_item.cpp b/kicad/project_tree_item.cpp index 2811c0e511..6824189196 100644 --- a/kicad/project_tree_item.cpp +++ b/kicad/project_tree_item.cpp @@ -193,6 +193,11 @@ void PROJECT_TREE_ITEM::Activate( PROJECT_TREE_PANE* aTreePrjFrame ) break; + case TREE_FILE_TYPE::JOBSET_FILE: + frame->OpenJobsFile( fullFileName ); + + break; + case TREE_FILE_TYPE::DIRECTORY: m_parent->Toggle( id ); break; diff --git a/kicad/project_tree_pane.cpp b/kicad/project_tree_pane.cpp index 6723c5c837..5701f79eda 100644 --- a/kicad/project_tree_pane.cpp +++ b/kicad/project_tree_pane.cpp @@ -131,6 +131,7 @@ static const wxChar* s_allowedExtensionsToList[] = { wxT( "^.*\\.svg$" ), // SVG print/plot files wxT( "^.*\\.ps$" ), // PostScript plot files wxT( "^.*\\.zip$" ), // Zip archive files + wxT( "^.*\\.kicad_jobset" ), // KiCad jobs file nullptr // end of list }; @@ -168,6 +169,7 @@ BEGIN_EVENT_TABLE( PROJECT_TREE_PANE, wxSashLayoutWindow ) EVT_MENU( ID_GIT_ADD_TO_INDEX, PROJECT_TREE_PANE::onGitAddToIndex ) EVT_MENU( ID_GIT_REMOVE_FROM_INDEX, PROJECT_TREE_PANE::onGitRemoveFromIndex ) + EVT_MENU( ID_JOBS_RUN, PROJECT_TREE_PANE::onRunSelectedJobsFile ) EVT_IDLE( PROJECT_TREE_PANE::onIdle ) EVT_PAINT( PROJECT_TREE_PANE::onPaint ) @@ -331,6 +333,7 @@ wxString PROJECT_TREE_PANE::GetFileExt( TREE_FILE_TYPE type ) case TREE_FILE_TYPE::SEXPR_SYMBOL_LIB_FILE: return FILEEXT::KiCadSymbolLibFileExtension; case TREE_FILE_TYPE::DESIGN_RULES: return FILEEXT::DesignRulesFileExtension; case TREE_FILE_TYPE::ZIP_ARCHIVE: return FILEEXT::ArchiveFileExtension; + case TREE_FILE_TYPE::JOBSET_FILE: return FILEEXT::KiCadJobSetFileExtension; case TREE_FILE_TYPE::ROOT: case TREE_FILE_TYPE::UNKNOWN: @@ -751,6 +754,7 @@ void PROJECT_TREE_PANE::onRight( wxTreeEvent& Event ) bool can_edit = true; bool can_rename = true; bool can_delete = true; + bool run_jobs = false; bool vcs_has_repo = m_TreeProject->GetGitRepo() != nullptr; bool vcs_can_commit = hasChangedFiles(); @@ -820,6 +824,11 @@ void PROJECT_TREE_PANE::onRight( wxTreeEvent& Event ) can_edit = false; break; + case TREE_FILE_TYPE::JOBSET_FILE: + run_jobs = true; + can_edit = false; + KI_FALLTHROUGH; + case TREE_FILE_TYPE::SEXPR_SCHEMATIC: case TREE_FILE_TYPE::SEXPR_PCB: KI_FALLTHROUGH; @@ -889,6 +898,12 @@ void PROJECT_TREE_PANE::onRight( wxTreeEvent& Event ) KiBitmap( BITMAPS::editor ) ); } + if( run_jobs && selection.size() == 1 ) + { + KIUI::AddMenuItem( &popup_menu, ID_JOBS_RUN, _( "Run Jobs" ), help_text, + KiBitmap( BITMAPS::exchange ) ); + } + if( can_rename ) { if( selection.size() == 1 ) @@ -2403,4 +2418,7 @@ void PROJECT_TREE_PANE::onGitRemoveFromIndex( wxCommandEvent& aEvent ) } +void PROJECT_TREE_PANE::onRunSelectedJobsFile(wxCommandEvent& event) +{ +} \ No newline at end of file diff --git a/kicad/project_tree_pane.h b/kicad/project_tree_pane.h index 99eb02abcf..550bc76f47 100644 --- a/kicad/project_tree_pane.h +++ b/kicad/project_tree_pane.h @@ -220,6 +220,11 @@ private: */ void onGitRevertLocal( wxCommandEvent& event ); + /** + * Run a selected jobs file + */ + void onRunSelectedJobsFile( wxCommandEvent& event ); + /** * Updates the icons shown in the tree project to reflect the current git status */ diff --git a/kicad/tools/kicad_manager_actions.cpp b/kicad/tools/kicad_manager_actions.cpp index 683fc66b33..3a6f4585ac 100644 --- a/kicad/tools/kicad_manager_actions.cpp +++ b/kicad/tools/kicad_manager_actions.cpp @@ -60,6 +60,13 @@ TOOL_ACTION KICAD_MANAGER_ACTIONS::newFromRepository( TOOL_ACTION_ARGS() .FriendlyName( _( "Clone Project from Repository..." ) ) .Icon( BITMAPS::new_project_from_template ) ); +TOOL_ACTION KICAD_MANAGER_ACTIONS::newJobsetFile( TOOL_ACTION_ARGS() + .Name( "kicad.Control.newJobs" ) + .Scope( AS_GLOBAL ) + .LegacyHotkeyName( "New Jobset File" ) + .FriendlyName( _( "New Jobset File..." ) ) + .Icon( BITMAPS::new_document ) ); + TOOL_ACTION KICAD_MANAGER_ACTIONS::openDemoProject( TOOL_ACTION_ARGS() .Name( "kicad.Control.openDemoProject" ) .Scope( AS_GLOBAL ) diff --git a/kicad/tools/kicad_manager_actions.h b/kicad/tools/kicad_manager_actions.h index 040013ec8b..36cd7172e4 100644 --- a/kicad/tools/kicad_manager_actions.h +++ b/kicad/tools/kicad_manager_actions.h @@ -34,6 +34,7 @@ public: static TOOL_ACTION newProject; static TOOL_ACTION newFromTemplate; static TOOL_ACTION newFromRepository; + static TOOL_ACTION newJobsetFile; static TOOL_ACTION openDemoProject; static TOOL_ACTION openProject; static TOOL_ACTION closeProject; diff --git a/kicad/tools/kicad_manager_control.cpp b/kicad/tools/kicad_manager_control.cpp index 385cf5f9a8..a82070e826 100644 --- a/kicad/tools/kicad_manager_control.cpp +++ b/kicad/tools/kicad_manager_control.cpp @@ -205,6 +205,24 @@ int KICAD_MANAGER_CONTROL::NewFromRepository( const TOOL_EVENT& aEvent ) } +int KICAD_MANAGER_CONTROL::NewJobsetFile( const TOOL_EVENT& aEvent ) +{ + wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep(); + wxFileDialog dlg( m_frame, _( "Create New Jobset" ), default_dir, wxEmptyString, + FILEEXT::JobsetFileWildcard(), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + + if( dlg.ShowModal() == wxID_CANCEL ) + return -1; + + wxFileName jobsetFn( dlg.GetPath() ); + + m_frame->OpenJobsFile( jobsetFn.GetFullPath(), true ); + + return 0; +} + + int KICAD_MANAGER_CONTROL::NewFromTemplate( const TOOL_EVENT& aEvent ) { DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( m_frame ); @@ -960,6 +978,7 @@ void KICAD_MANAGER_CONTROL::setTransitions() Go( &KICAD_MANAGER_CONTROL::NewProject, KICAD_MANAGER_ACTIONS::newProject.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::NewFromTemplate, KICAD_MANAGER_ACTIONS::newFromTemplate.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::NewFromRepository, KICAD_MANAGER_ACTIONS::newFromRepository.MakeEvent() ); + Go( &KICAD_MANAGER_CONTROL::NewJobsetFile, KICAD_MANAGER_ACTIONS::newJobsetFile.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::OpenDemoProject, KICAD_MANAGER_ACTIONS::openDemoProject.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::OpenProject, KICAD_MANAGER_ACTIONS::openProject.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::CloseProject, KICAD_MANAGER_ACTIONS::closeProject.MakeEvent() ); diff --git a/kicad/tools/kicad_manager_control.h b/kicad/tools/kicad_manager_control.h index bf1c2dd5b0..6e7727a580 100644 --- a/kicad/tools/kicad_manager_control.h +++ b/kicad/tools/kicad_manager_control.h @@ -47,6 +47,7 @@ public: int NewProject( const TOOL_EVENT& aEvent ); int NewFromTemplate( const TOOL_EVENT& aEvent ); int NewFromRepository( const TOOL_EVENT& aEvent ); + int NewJobsetFile( const TOOL_EVENT& aEvent ); int OpenProject( const TOOL_EVENT& aEvent ); int OpenDemoProject( const TOOL_EVENT& aEvent ); int CloseProject( const TOOL_EVENT& aEvent ); diff --git a/kicad/tree_file_type.h b/kicad/tree_file_type.h index 5106e868dd..be5967da8f 100644 --- a/kicad/tree_file_type.h +++ b/kicad/tree_file_type.h @@ -63,6 +63,7 @@ enum class TREE_FILE_TYPE SEXPR_SYMBOL_LIB_FILE, // s-expression symbol library file (.kicad_sym) DESIGN_RULES, // design rules (.kicad_dru) ZIP_ARCHIVE, // .zip file + JOBSET_FILE, // jobs (.kicad_jobs) MAX // Sentinel }; diff --git a/pcbnew/dialogs/dialog_export_2581.cpp b/pcbnew/dialogs/dialog_export_2581.cpp index 8b27e44075..408213dab8 100644 --- a/pcbnew/dialogs/dialog_export_2581.cpp +++ b/pcbnew/dialogs/dialog_export_2581.cpp @@ -30,6 +30,7 @@ #include <project/project_file.h> #include <settings/settings_manager.h> #include <widgets/std_bitmap_button.h> +#include <jobs/job_export_pcb_ipc2581.h> #include <set> #include <vector> @@ -67,6 +68,29 @@ DIALOG_EXPORT_2581::DIALOG_EXPORT_2581( PCB_EDIT_FRAME* aParent ) : } +DIALOG_EXPORT_2581::DIALOG_EXPORT_2581(JOB_EXPORT_PCB_IPC2581* aJob, PCB_EDIT_FRAME* aEditFrame, + wxWindow* aParent ) : + DIALOG_EXPORT_2581_BASE( aParent ), + m_parent( aEditFrame ), + m_job( aJob ) +{ + m_browseButton->Hide(); + + SetupStandardButtons( { { wxID_OK, _( "Save" ) }, { wxID_CANCEL, _( "Close" ) } } ); + + m_outputFileName->SetValue( m_job->GetOutputPath() ); + + m_textDistributor->SetSize( m_choiceDistPN->GetSize() ); + + // Fill wxChoice (and others) items with data before calling finishDialogSettings() + // to calculate suitable widgets sizes + Init(); + + // Now all widgets have the size fixed, call FinishDialogSettings + finishDialogSettings(); +} + + void DIALOG_EXPORT_2581::onBrowseClicked( wxCommandEvent& event ) { // Build the absolute path of current output directory to preselect it in the file browser. @@ -88,7 +112,10 @@ void DIALOG_EXPORT_2581::onBrowseClicked( wxCommandEvent& event ) void DIALOG_EXPORT_2581::onOKClick( wxCommandEvent& event ) { - m_parent->SetLastPath( LAST_PATH_2581, m_outputFileName->GetValue() ); + if( !m_job ) + { + m_parent->SetLastPath( LAST_PATH_2581, m_outputFileName->GetValue() ); + } event.Skip(); } @@ -226,10 +253,20 @@ bool DIALOG_EXPORT_2581::Init() options.insert( field->GetName() ); } - m_choiceUnits->SetSelection( cfg->m_Export2581.units ); - m_precision->SetValue( cfg->m_Export2581.precision ); - m_versionChoice->SetSelection( cfg->m_Export2581.version ); - m_cbCompress->SetValue( cfg->m_Export2581.compress ); + if( !m_job ) + { + m_choiceUnits->SetSelection( cfg->m_Export2581.units ); + m_precision->SetValue( cfg->m_Export2581.precision ); + m_versionChoice->SetSelection( cfg->m_Export2581.version ); + m_cbCompress->SetValue( cfg->m_Export2581.compress ); + } + else + { + m_choiceUnits->SetSelection( static_cast<int>( m_job->m_units ) ); + m_precision->SetValue( static_cast<int>( m_job->m_precision ) ); + m_versionChoice->SetSelection( m_job->m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::B ? 0 : 1 ); + m_cbCompress->SetValue( m_job->m_compress ); + } wxCommandEvent dummy; onCompressCheck( dummy ); @@ -244,14 +281,37 @@ bool DIALOG_EXPORT_2581::Init() PROJECT_FILE& prj = Prj().GetProjectFile(); - if( !m_choiceMPN->SetStringSelection( prj.m_IP2581Bom.id ) ) + wxString internalIdCol; + wxString mpnCol; + wxString distPnCol; + wxString mfgCol; + wxString distCol; + + if( !m_job ) + { + internalIdCol = prj.m_IP2581Bom.id; + mpnCol = prj.m_IP2581Bom.MPN; + distPnCol = prj.m_IP2581Bom.distPN; + mfgCol = prj.m_IP2581Bom.mfg; + distCol = prj.m_IP2581Bom.dist; + } + else + { + internalIdCol = m_job->m_colInternalId; + mpnCol = m_job->m_colMfgPn; + distPnCol = m_job->m_colDistPn; + mfgCol = m_job->m_colMfg; + distCol = m_job->m_colDist; + } + + if( !m_choiceMPN->SetStringSelection( internalIdCol ) ) m_choiceMPN->SetSelection( 0 ); - if( m_choiceMPN->SetStringSelection( prj.m_IP2581Bom.MPN ) ) + if( m_choiceMPN->SetStringSelection( mpnCol ) ) { m_choiceMfg->Enable( true ); - if( !m_choiceMfg->SetStringSelection( prj.m_IP2581Bom.mfg ) ) + if( !m_choiceMfg->SetStringSelection( mfgCol ) ) m_choiceMfg->SetSelection( 0 ); } else @@ -261,14 +321,14 @@ bool DIALOG_EXPORT_2581::Init() m_choiceMfg->Enable( false ); } - if( m_choiceDistPN->SetStringSelection( prj.m_IP2581Bom.distPN ) ) + if( m_choiceDistPN->SetStringSelection( distPnCol ) ) { m_textDistributor->Enable( true ); // The combo box selection can be fixed, so any value can be entered if( !prj.m_IP2581Bom.distPN.empty() ) { - m_textDistributor->SetValue( prj.m_IP2581Bom.dist ); + m_textDistributor->SetValue( distCol ); } else { @@ -288,22 +348,43 @@ bool DIALOG_EXPORT_2581::Init() bool DIALOG_EXPORT_2581::TransferDataFromWindow() { - PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>(); + if( !m_job ) + { + PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>(); - cfg->m_Export2581.units = m_choiceUnits->GetSelection(); - cfg->m_Export2581.precision = m_precision->GetValue(); - cfg->m_Export2581.version = m_versionChoice->GetSelection(); - cfg->m_Export2581.compress = m_cbCompress->GetValue(); + cfg->m_Export2581.units = m_choiceUnits->GetSelection(); + cfg->m_Export2581.precision = m_precision->GetValue(); + cfg->m_Export2581.version = m_versionChoice->GetSelection(); + cfg->m_Export2581.compress = m_cbCompress->GetValue(); - PROJECT_FILE& prj = Prj().GetProjectFile(); - wxString empty; + PROJECT_FILE& prj = Prj().GetProjectFile(); + wxString empty; - prj.m_IP2581Bom.id = GetOEM(); - prj.m_IP2581Bom.mfg = GetMfg(); - prj.m_IP2581Bom.MPN = GetMPN(); - prj.m_IP2581Bom.distPN = GetDistPN(); - prj.m_IP2581Bom.dist = GetDist(); + prj.m_IP2581Bom.id = GetOEM(); + prj.m_IP2581Bom.mfg = GetMfg(); + prj.m_IP2581Bom.MPN = GetMPN(); + prj.m_IP2581Bom.distPN = GetDistPN(); + prj.m_IP2581Bom.dist = GetDist(); + + s_oemColumn = m_oemRef->GetStringSelection(); + } + else + { + m_job->SetOutputPath( m_outputFileName->GetValue() ); + + m_job->m_colInternalId = GetOEM(); + m_job->m_colDist = GetDist(); + m_job->m_colDistPn = GetDistPN(); + m_job->m_colMfg = GetMfg(); + m_job->m_colMfgPn = GetMPN(); + + m_job->m_version = GetVersion() == 'B' ? JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::B + : JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::C; + m_job->m_units = GetUnitsString() == wxT( "mm" ) ? JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MILLIMETERS + : JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::INCHES; + m_job->m_precision = m_precision->GetValue(); + m_job->m_compress = GetCompress(); + } - s_oemColumn = m_oemRef->GetStringSelection(); return true; } \ No newline at end of file diff --git a/pcbnew/dialogs/dialog_export_2581.h b/pcbnew/dialogs/dialog_export_2581.h index 308778d0ae..3b59974e49 100644 --- a/pcbnew/dialogs/dialog_export_2581.h +++ b/pcbnew/dialogs/dialog_export_2581.h @@ -22,11 +22,13 @@ #include "dialog_export_2581_base.h" class PCB_EDIT_FRAME; +class JOB_EXPORT_PCB_IPC2581; class DIALOG_EXPORT_2581 : public DIALOG_EXPORT_2581_BASE { public: DIALOG_EXPORT_2581( PCB_EDIT_FRAME* aParent ); + DIALOG_EXPORT_2581( JOB_EXPORT_PCB_IPC2581* aJob, PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent ); wxString GetOutputPath() const { @@ -108,6 +110,7 @@ private: bool TransferDataFromWindow() override; PCB_EDIT_FRAME* m_parent; + JOB_EXPORT_PCB_IPC2581* m_job; }; #endif // IPC2581_EXPORT_DIALOG_H \ No newline at end of file diff --git a/pcbnew/dialogs/dialog_export_step.cpp b/pcbnew/dialogs/dialog_export_step.cpp index 62d2fc23bb..96b2e34320 100644 --- a/pcbnew/dialogs/dialog_export_step.cpp +++ b/pcbnew/dialogs/dialog_export_step.cpp @@ -49,6 +49,7 @@ #include <filename_resolver.h> #include <core/map_helpers.h> #include <settings/settings_manager.h> +#include <jobs/job_export_pcb_3d.h> // Maps m_choiceFormat selection to extension (and kicad-cli command) @@ -81,16 +82,33 @@ bool DIALOG_EXPORT_STEP::m_fuseShapes = false; DIALOG_EXPORT_STEP::COMPONENT_MODE DIALOG_EXPORT_STEP::m_componentMode = COMPONENT_MODE::EXPORT_ALL; wxString DIALOG_EXPORT_STEP::m_componentFilter; + DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, const wxString& aBoardPath ) : - DIALOG_EXPORT_STEP_BASE( aEditFrame ) + DIALOG_EXPORT_STEP( aEditFrame, aEditFrame, aBoardPath ) { - m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); +} - m_editFrame = aEditFrame; - m_boardPath = aBoardPath; - SetupStandardButtons( { { wxID_OK, _( "Export" ) }, - { wxID_CANCEL, _( "Close" ) } } ); +DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent, + const wxString& aBoardPath, + JOB_EXPORT_PCB_3D* aJob ) : + DIALOG_EXPORT_STEP_BASE( aEditFrame ), + m_editFrame( aEditFrame ), + m_job( aJob ), + m_boardPath( aBoardPath ) +{ + if( m_job == nullptr ) + { + m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); + SetupStandardButtons( { { wxID_OK, _( "Export" ) }, + { wxID_CANCEL, _( "Close" ) } } ); + } + else + { + m_browseButton->Hide(); + SetupStandardButtons( { { wxID_OK, _( "Save" ) }, + { wxID_CANCEL, _( "Close" ) } } ); + } // Build default output file name // (last saved filename in project or built from board filename) @@ -110,62 +128,65 @@ DIALOG_EXPORT_STEP::DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, const wxStri SetFocus(); - PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings(); - - m_origin = static_cast<STEP_ORIGIN_OPTION>( cfg->m_ExportStep.origin_mode ); - - switch( m_origin ) + if( !m_job ) { - default: - case STEP_ORIGIN_PLOT_AXIS: m_rbDrillAndPlotOrigin->SetValue( true ); break; - case STEP_ORIGIN_GRID_AXIS: m_rbGridOrigin->SetValue( true ); break; - case STEP_ORIGIN_USER: m_rbUserDefinedOrigin->SetValue( true ); break; - case STEP_ORIGIN_BOARD_CENTER: m_rbBoardCenterOrigin->SetValue( true ); break; + PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings(); + + m_origin = static_cast<STEP_ORIGIN_OPTION>( cfg->m_ExportStep.origin_mode ); + + switch( m_origin ) + { + default: + case STEP_ORIGIN_PLOT_AXIS: m_rbDrillAndPlotOrigin->SetValue( true ); break; + case STEP_ORIGIN_GRID_AXIS: m_rbGridOrigin->SetValue( true ); break; + case STEP_ORIGIN_USER: m_rbUserDefinedOrigin->SetValue( true ); break; + case STEP_ORIGIN_BOARD_CENTER: m_rbBoardCenterOrigin->SetValue( true ); break; + } + + m_originUnits = cfg->m_ExportStep.origin_units; + m_userOriginX = cfg->m_ExportStep.origin_x; + m_userOriginY = cfg->m_ExportStep.origin_y; + m_noUnspecified = cfg->m_ExportStep.no_unspecified; + m_noDNP = cfg->m_ExportStep.no_dnp; + + m_txtNetFilter->SetValue( m_netFilter ); + m_cbOptimizeStep->SetValue( m_optimizeStep ); + m_cbExportBody->SetValue( m_exportBoardBody ); + m_cbExportComponents->SetValue( m_exportComponents ); + m_cbExportTracks->SetValue( m_exportTracks ); + m_cbExportPads->SetValue( m_exportPads ); + m_cbExportZones->SetValue( m_exportZones ); + m_cbExportInnerCopper->SetValue( m_exportInnerCopper ); + m_cbExportSilkscreen->SetValue( m_exportSilkscreen ); + m_cbExportSoldermask->SetValue( m_exportSoldermask ); + m_cbFuseShapes->SetValue( m_fuseShapes ); + m_cbRemoveUnspecified->SetValue( m_noUnspecified ); + m_cbRemoveDNP->SetValue( m_noDNP ); + m_cbSubstModels->SetValue( cfg->m_ExportStep.replace_models ); + m_cbOverwriteFile->SetValue( cfg->m_ExportStep.overwrite_file ); + + m_txtComponentFilter->SetValue( m_componentFilter ); + + switch( m_componentMode ) + { + case COMPONENT_MODE::EXPORT_ALL: m_rbAllComponents->SetValue( true ); break; + case COMPONENT_MODE::EXPORT_SELECTED: m_rbOnlySelected->SetValue( true ); break; + case COMPONENT_MODE::CUSTOM_FILTER: m_rbFilteredComponents->SetValue( true ); break; + } + + // Sync the enabled states + wxCommandEvent dummy; + DIALOG_EXPORT_STEP::onCbExportComponents( dummy ); + + m_STEP_OrgUnitChoice->SetSelection( m_originUnits ); + wxString tmpStr; + tmpStr << m_userOriginX; + m_STEP_Xorg->SetValue( tmpStr ); + tmpStr = wxEmptyString; + tmpStr << m_userOriginY; + m_STEP_Yorg->SetValue( tmpStr ); } - m_originUnits = cfg->m_ExportStep.origin_units; - m_userOriginX = cfg->m_ExportStep.origin_x; - m_userOriginY = cfg->m_ExportStep.origin_y; - m_noUnspecified = cfg->m_ExportStep.no_unspecified; - m_noDNP = cfg->m_ExportStep.no_dnp; - - m_txtNetFilter->SetValue( m_netFilter ); - m_cbOptimizeStep->SetValue( m_optimizeStep ); - m_cbExportBody->SetValue( m_exportBoardBody ); - m_cbExportComponents->SetValue( m_exportComponents ); - m_cbExportTracks->SetValue( m_exportTracks ); - m_cbExportPads->SetValue( m_exportPads ); - m_cbExportZones->SetValue( m_exportZones ); - m_cbExportInnerCopper->SetValue( m_exportInnerCopper ); - m_cbExportSilkscreen->SetValue( m_exportSilkscreen ); - m_cbExportSoldermask->SetValue( m_exportSoldermask ); - m_cbFuseShapes->SetValue( m_fuseShapes ); - m_cbRemoveUnspecified->SetValue( m_noUnspecified ); - m_cbRemoveDNP->SetValue( m_noDNP ); - m_cbSubstModels->SetValue( cfg->m_ExportStep.replace_models ); - m_cbOverwriteFile->SetValue( cfg->m_ExportStep.overwrite_file ); - - m_txtComponentFilter->SetValue( m_componentFilter ); - - switch( m_componentMode ) - { - case COMPONENT_MODE::EXPORT_ALL: m_rbAllComponents->SetValue( true ); break; - case COMPONENT_MODE::EXPORT_SELECTED: m_rbOnlySelected->SetValue( true ); break; - case COMPONENT_MODE::CUSTOM_FILTER: m_rbFilteredComponents->SetValue( true ); break; - } - - // Sync the enabled states - wxCommandEvent dummy; - DIALOG_EXPORT_STEP::onCbExportComponents( dummy ); - - m_STEP_OrgUnitChoice->SetSelection( m_originUnits ); - wxString tmpStr; - tmpStr << m_userOriginX; - m_STEP_Xorg->SetValue( tmpStr ); - tmpStr = wxEmptyString; - tmpStr << m_userOriginY; - m_STEP_Yorg->SetValue( tmpStr ); - wxString bad_scales; size_t bad_count = 0; @@ -424,261 +445,324 @@ void DIALOG_EXPORT_STEP::OnComponentModeChange( wxCommandEvent& event ) void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent ) { - wxString path = m_outputFileName->GetValue(); - m_editFrame->SetLastPath( LAST_PATH_STEP, path ); - - // Build the absolute path of current output directory to preselect it in the file browser. - std::function<bool( wxString* )> textResolver = - [&]( wxString* token ) -> bool - { - return m_editFrame->GetBoard()->ResolveTextVar( token, 0 ); - }; - - path = ExpandTextVars( path, &textResolver ); - path = ExpandEnvVarSubstitutions( path, &Prj() ); - path = Prj().AbsolutePath( path ); - - if( path.IsEmpty() ) + if( !m_job ) { - DisplayErrorMessage( this, _( "No filename for output file" ) ); - return; - } + wxString path = m_outputFileName->GetValue(); + m_editFrame->SetLastPath( LAST_PATH_STEP, path ); - m_netFilter = m_txtNetFilter->GetValue(); - m_componentFilter = m_txtComponentFilter->GetValue(); + // Build the absolute path of current output directory to preselect it in the file browser. + std::function<bool( wxString* )> textResolver = + [&]( wxString* token ) -> bool + { + return m_editFrame->GetBoard()->ResolveTextVar( token, 0 ); + }; - if( m_rbAllComponents->GetValue() ) - m_componentMode = COMPONENT_MODE::EXPORT_ALL; - else if( m_rbOnlySelected->GetValue() ) - m_componentMode = COMPONENT_MODE::EXPORT_SELECTED; - else - m_componentMode = COMPONENT_MODE::CUSTOM_FILTER; + path = ExpandTextVars( path, &textResolver ); + path = ExpandEnvVarSubstitutions( path, &Prj() ); + path = Prj().AbsolutePath( path ); - double tolerance; // default value in mm - m_toleranceLastChoice = m_choiceTolerance->GetSelection(); - m_formatLastChoice = m_choiceFormat->GetSelection(); - m_optimizeStep = m_cbOptimizeStep->GetValue(); - m_exportBoardBody = m_cbExportBody->GetValue(); - m_exportComponents = m_cbExportComponents->GetValue(); - m_exportTracks = m_cbExportTracks->GetValue(); - m_exportPads = m_cbExportPads->GetValue(); - m_exportZones = m_cbExportZones->GetValue(); - m_exportInnerCopper = m_cbExportInnerCopper->GetValue(); - m_exportSilkscreen = m_cbExportSilkscreen->GetValue(); - m_exportSoldermask = m_cbExportSoldermask->GetValue(); - m_fuseShapes = m_cbFuseShapes->GetValue(); - - switch( m_choiceTolerance->GetSelection() ) - { - case 0: tolerance = 0.001; break; - default: - case 1: tolerance = 0.01; break; - case 2: tolerance = 0.1; break; - } - - SHAPE_POLY_SET outline; - wxString msg; - - // Check if the board outline is continuous - // max dist from one endPt to next startPt to build a closed shape: - int chainingEpsilon = pcbIUScale.mmToIU( tolerance ); - - // Arc to segment approx error (not critical here: we do not use the outline shape): - int maxError = pcbIUScale.mmToIU( 0.005 ); - bool success = BuildBoardPolygonOutlines( m_editFrame->GetBoard(), outline, maxError, - chainingEpsilon, nullptr ); - if( !success ) - { - DisplayErrorMessage( this, wxString::Format( - _( "Board outline is missing or not closed using %.3f mm tolerance.\n" - "Run DRC for a full analysis." ), tolerance ) ); - return; - } - - wxFileName fn( Prj().AbsolutePath( path ) ); - - if( fn.FileExists() && !GetOverwriteFile() ) - { - msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ), - fn.GetFullPath() ); - - if( wxMessageBox( msg, _( "STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO ) - return; - } - - wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() ); -#ifdef __WXMAC__ - // On macOS, we have standalone applications inside the main bundle, so we handle that here: - if( appK2S.GetPath().Find( "/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND ) - { - appK2S.AppendDir( wxT( ".." ) ); - appK2S.AppendDir( wxT( ".." ) ); - appK2S.AppendDir( wxT( ".." ) ); - appK2S.AppendDir( wxT( ".." ) ); - appK2S.AppendDir( wxT( "MacOS" ) ); - } -#else - if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) ) - { - appK2S.RemoveLastDir(); - appK2S.AppendDir( "kicad" ); - } -#endif - - appK2S.SetName( wxT( "kicad-cli" ) ); - appK2S.Normalize( FN_NORMALIZE_FLAGS ); - - wxString cmdK2S = wxT( "\"" ); - cmdK2S.Append( appK2S.GetFullPath() ); - cmdK2S.Append( wxT( "\"" ) ); - - cmdK2S.Append( wxT( " pcb" ) ); - cmdK2S.Append( wxT( " export" ) ); - - cmdK2S.Append( wxT( " " ) ); - cmdK2S.Append( c_formatCommand[m_choiceFormat->GetSelection()] ); - - if( GetNoUnspecifiedOption() ) - cmdK2S.Append( wxT( " --no-unspecified" ) ); - - if( GetNoDNPOption() ) - cmdK2S.Append( wxT( " --no-dnp" ) ); - - if( GetSubstOption() ) - cmdK2S.Append( wxT( " --subst-models" ) ); - - if( !m_optimizeStep ) - cmdK2S.Append( wxT( " --no-optimize-step" ) ); - - if( !m_exportBoardBody ) - cmdK2S.Append( wxT( " --no-board-body" ) ); - - if( !m_exportComponents ) - cmdK2S.Append( wxT( " --no-components" ) ); - - if( m_exportTracks ) - cmdK2S.Append( wxT( " --include-tracks" ) ); - - if( m_exportPads ) - cmdK2S.Append( wxT( " --include-pads" ) ); - - if( m_exportZones ) - cmdK2S.Append( wxT( " --include-zones" ) ); - - if( m_exportInnerCopper ) - cmdK2S.Append( wxT( " --include-inner-copper" ) ); - - if( m_exportSilkscreen ) - cmdK2S.Append( wxT( " --include-silkscreen" ) ); - - if( m_exportSoldermask ) - cmdK2S.Append( wxT( " --include-soldermask" ) ); - - if( m_fuseShapes ) - cmdK2S.Append( wxT( " --fuse-shapes" ) ); - - // Note: for some reason, using \" to insert a quote in a format string, under MacOS - // wxString::Format does not work. So use a %c format in string - int quote = '\''; - int dblquote = '"'; - - if( !m_netFilter.empty() ) - { - cmdK2S.Append( wxString::Format( wxT( " --net-filter %c%s%c" ), dblquote, m_netFilter, - dblquote ) ); - } - - switch( m_componentMode ) - { - case COMPONENT_MODE::EXPORT_SELECTED: - { - wxArrayString components; - SELECTION& selection = m_editFrame->GetCurrentSelection(); - - std::for_each( selection.begin(), selection.end(), - [&components]( EDA_ITEM* item ) - { - if( item->Type() == PCB_FOOTPRINT_T ) - components.push_back( static_cast<FOOTPRINT*>( item )->GetReference() ); - } ); - - cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote, - wxJoin( components, ',' ), dblquote ) ); - break; - } - - case COMPONENT_MODE::CUSTOM_FILTER: - cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote, - m_componentFilter, dblquote ) ); - break; - - default: - break; - } - - switch( GetOriginOption() ) - { - case STEP_ORIGIN_0: - wxFAIL_MSG( wxT( "Unsupported origin option: how did we get here?" ) ); - break; - - case STEP_ORIGIN_PLOT_AXIS: - cmdK2S.Append( wxT( " --drill-origin" ) ); - break; - - case STEP_ORIGIN_GRID_AXIS: - cmdK2S.Append( wxT( " --grid-origin" ) ); - break; - - case STEP_ORIGIN_USER: - { - double xOrg = GetXOrg(); - double yOrg = GetYOrg(); - - if( GetOrgUnitsChoice() == 1 ) + if( path.IsEmpty() ) { - // selected reference unit is in inches, and STEP units are mm - xOrg *= 25.4; - yOrg *= 25.4; + DisplayErrorMessage( this, _( "No filename for output file" ) ); + return; } - LOCALE_IO dummy; - cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ), - quote, xOrg, yOrg, quote ) ); - break; - } + m_netFilter = m_txtNetFilter->GetValue(); + m_componentFilter = m_txtComponentFilter->GetValue(); - case STEP_ORIGIN_BOARD_CENTER: + if( m_rbAllComponents->GetValue() ) + m_componentMode = COMPONENT_MODE::EXPORT_ALL; + else if( m_rbOnlySelected->GetValue() ) + m_componentMode = COMPONENT_MODE::EXPORT_SELECTED; + else + m_componentMode = COMPONENT_MODE::CUSTOM_FILTER; + + double tolerance; // default value in mm + m_toleranceLastChoice = m_choiceTolerance->GetSelection(); + m_formatLastChoice = m_choiceFormat->GetSelection(); + m_optimizeStep = m_cbOptimizeStep->GetValue(); + m_exportBoardBody = m_cbExportBody->GetValue(); + m_exportComponents = m_cbExportComponents->GetValue(); + m_exportTracks = m_cbExportTracks->GetValue(); + m_exportPads = m_cbExportPads->GetValue(); + m_exportZones = m_cbExportZones->GetValue(); + m_exportInnerCopper = m_cbExportInnerCopper->GetValue(); + m_exportSilkscreen = m_cbExportSilkscreen->GetValue(); + m_exportSoldermask = m_cbExportSoldermask->GetValue(); + m_fuseShapes = m_cbFuseShapes->GetValue(); + + switch( m_choiceTolerance->GetSelection() ) + { + case 0: tolerance = 0.001; break; + default: + case 1: tolerance = 0.01; break; + case 2: tolerance = 0.1; break; + } + + SHAPE_POLY_SET outline; + wxString msg; + + // Check if the board outline is continuous + // max dist from one endPt to next startPt to build a closed shape: + int chainingEpsilon = pcbIUScale.mmToIU( tolerance ); + + // Arc to segment approx error (not critical here: we do not use the outline shape): + int maxError = pcbIUScale.mmToIU( 0.005 ); + bool success = BuildBoardPolygonOutlines( m_editFrame->GetBoard(), outline, maxError, + chainingEpsilon, nullptr ); + if( !success ) + { + DisplayErrorMessage( this, wxString::Format( + _( "Board outline is missing or not closed using %.3f mm tolerance.\n" + "Run DRC for a full analysis." ), tolerance ) ); + return; + } + + wxFileName fn( Prj().AbsolutePath( path ) ); + + if( fn.FileExists() && !GetOverwriteFile() ) + { + msg.Printf( _( "File '%s' already exists. Do you want overwrite this file?" ), + fn.GetFullPath() ); + + if( wxMessageBox( msg, _( "STEP/GLTF Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO ) + return; + } + + wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() ); + #ifdef __WXMAC__ + // On macOS, we have standalone applications inside the main bundle, so we handle that here: + if( appK2S.GetPath().Find( "/Contents/Applications/pcbnew.app/Contents/MacOS" ) != wxNOT_FOUND ) + { + appK2S.AppendDir( wxT( ".." ) ); + appK2S.AppendDir( wxT( ".." ) ); + appK2S.AppendDir( wxT( ".." ) ); + appK2S.AppendDir( wxT( ".." ) ); + appK2S.AppendDir( wxT( "MacOS" ) ); + } + #else + if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) ) + { + appK2S.RemoveLastDir(); + appK2S.AppendDir( "kicad" ); + } + #endif + + appK2S.SetName( wxT( "kicad-cli" ) ); + appK2S.Normalize( FN_NORMALIZE_FLAGS ); + + wxString cmdK2S = wxT( "\"" ); + cmdK2S.Append( appK2S.GetFullPath() ); + cmdK2S.Append( wxT( "\"" ) ); + + cmdK2S.Append( wxT( " pcb" ) ); + cmdK2S.Append( wxT( " export" ) ); + + cmdK2S.Append( wxT( " " ) ); + cmdK2S.Append( c_formatCommand[m_choiceFormat->GetSelection()] ); + + if( GetNoUnspecifiedOption() ) + cmdK2S.Append( wxT( " --no-unspecified" ) ); + + if( GetNoDNPOption() ) + cmdK2S.Append( wxT( " --no-dnp" ) ); + + if( GetSubstOption() ) + cmdK2S.Append( wxT( " --subst-models" ) ); + + if( !m_optimizeStep ) + cmdK2S.Append( wxT( " --no-optimize-step" ) ); + + if( !m_exportBoardBody ) + cmdK2S.Append( wxT( " --no-board-body" ) ); + + if( !m_exportComponents ) + cmdK2S.Append( wxT( " --no-components" ) ); + + if( m_exportTracks ) + cmdK2S.Append( wxT( " --include-tracks" ) ); + + if( m_exportPads ) + cmdK2S.Append( wxT( " --include-pads" ) ); + + if( m_exportZones ) + cmdK2S.Append( wxT( " --include-zones" ) ); + + if( m_exportInnerCopper ) + cmdK2S.Append( wxT( " --include-inner-copper" ) ); + + if( m_exportSilkscreen ) + cmdK2S.Append( wxT( " --include-silkscreen" ) ); + + if( m_exportSoldermask ) + cmdK2S.Append( wxT( " --include-soldermask" ) ); + + if( m_fuseShapes ) + cmdK2S.Append( wxT( " --fuse-shapes" ) ); + + // Note: for some reason, using \" to insert a quote in a format string, under MacOS + // wxString::Format does not work. So use a %c format in string + int quote = '\''; + int dblquote = '"'; + + if( !m_netFilter.empty() ) + { + cmdK2S.Append( wxString::Format( wxT( " --net-filter %c%s%c" ), dblquote, m_netFilter, + dblquote ) ); + } + + switch( m_componentMode ) + { + case COMPONENT_MODE::EXPORT_SELECTED: + { + wxArrayString components; + SELECTION& selection = m_editFrame->GetCurrentSelection(); + + std::for_each( selection.begin(), selection.end(), + [&components]( EDA_ITEM* item ) + { + if( item->Type() == PCB_FOOTPRINT_T ) + components.push_back( static_cast<FOOTPRINT*>( item )->GetReference() ); + } ); + + cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote, + wxJoin( components, ',' ), dblquote ) ); + break; + } + + case COMPONENT_MODE::CUSTOM_FILTER: + cmdK2S.Append( wxString::Format( wxT( " --component-filter %c%s%c" ), dblquote, + m_componentFilter, dblquote ) ); + break; + + default: + break; + } + + switch( GetOriginOption() ) + { + case STEP_ORIGIN_0: + wxFAIL_MSG( wxT( "Unsupported origin option: how did we get here?" ) ); + break; + + case STEP_ORIGIN_PLOT_AXIS: + cmdK2S.Append( wxT( " --drill-origin" ) ); + break; + + case STEP_ORIGIN_GRID_AXIS: + cmdK2S.Append( wxT( " --grid-origin" ) ); + break; + + case STEP_ORIGIN_USER: + { + double xOrg = GetXOrg(); + double yOrg = GetYOrg(); + + if( GetOrgUnitsChoice() == 1 ) + { + // selected reference unit is in inches, and STEP units are mm + xOrg *= 25.4; + yOrg *= 25.4; + } + + LOCALE_IO dummy; + cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ), + quote, xOrg, yOrg, quote ) ); + break; + } + + case STEP_ORIGIN_BOARD_CENTER: + { + BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true ); + double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x ); + double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y ); + LOCALE_IO dummy; + + cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ), + quote, xOrg, yOrg, quote ) ); + break; + } + } + + { + LOCALE_IO dummy; + cmdK2S.Append( wxString::Format( wxT( " --min-distance=%c%.3fmm%c" ), + quote, tolerance, quote ) ); + } + + // Output file path. + cmdK2S.Append( wxString::Format( wxT( " -f -o %c%s%c" ), + dblquote, fn.GetFullPath(), dblquote ) ); + + + // Input file path. + cmdK2S.Append( wxString::Format( wxT( " %c%s%c" ), dblquote, m_boardPath, dblquote ) ); + + wxLogTrace( traceKiCad2Step, wxT( "export step command: %s" ), cmdK2S ); + + DIALOG_EXPORT_STEP_LOG* log = new DIALOG_EXPORT_STEP_LOG( this, cmdK2S ); + log->ShowModal(); + } + else { - BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true ); - double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x ); - double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y ); - LOCALE_IO dummy; + m_job->SetOutputPath( m_outputFileName->GetValue() ); + m_job->m_3dparams.m_NetFilter = m_txtNetFilter->GetValue(); + m_job->m_3dparams.m_ComponentFilter = m_txtComponentFilter->GetValue(); + m_job->m_3dparams.m_ExportBoardBody = m_cbExportBody->GetValue(); + m_job->m_3dparams.m_ExportComponents = m_cbExportComponents->GetValue(); + m_job->m_3dparams.m_ExportTracksVias = m_cbExportTracks->GetValue(); + m_job->m_3dparams.m_ExportPads = m_cbExportPads->GetValue(); + m_job->m_3dparams.m_ExportZones = m_cbExportZones->GetValue(); + m_job->m_3dparams.m_ExportInnerCopper = m_cbExportInnerCopper->GetValue(); + m_job->m_3dparams.m_ExportSilkscreen = m_cbExportSilkscreen->GetValue(); + m_job->m_3dparams.m_ExportSoldermask = m_cbExportSoldermask->GetValue(); + m_job->m_3dparams.m_FuseShapes = m_cbFuseShapes->GetValue(); + m_job->m_3dparams.m_OptimizeStep = m_cbOptimizeStep->GetValue(); + m_job->m_3dparams.m_Format = static_cast<EXPORTER_STEP_PARAMS::FORMAT>( m_choiceFormat->GetSelection() ); + m_job->m_3dparams.m_Overwrite = m_cbOverwriteFile->GetValue(); + m_job->m_3dparams.m_IncludeUnspecified = !m_cbRemoveUnspecified->GetValue(); + m_job->m_3dparams.m_IncludeDNP = !m_cbRemoveDNP->GetValue(); + m_job->m_3dparams.m_SubstModels = m_cbSubstModels->GetValue(); + + switch( GetOriginOption() ) + { + case STEP_ORIGIN_0: + break; + case STEP_ORIGIN_PLOT_AXIS: + m_job->m_3dparams.m_UseDrillOrigin = true; + break; + case STEP_ORIGIN_GRID_AXIS: + m_job->m_3dparams.m_UseGridOrigin = true; + break; + case STEP_ORIGIN_USER: + { + double xOrg = GetXOrg(); + double yOrg = GetYOrg(); + + if( GetOrgUnitsChoice() == 1 ) + { + // selected reference unit is in inches, and STEP units are mm + xOrg *= 25.4; + yOrg *= 25.4; + } + + m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg ); + break; + } + + case STEP_ORIGIN_BOARD_CENTER: + { + BOX2I bbox = m_editFrame->GetBoard()->ComputeBoundingBox( true ); + double xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x ); + double yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y ); + LOCALE_IO dummy; + + m_job->m_3dparams.m_Origin = VECTOR2D( xOrg, yOrg ); + break; + } + } - cmdK2S.Append( wxString::Format( wxT( " --user-origin=%c%.6fx%.6fmm%c" ), - quote, xOrg, yOrg, quote ) ); - break; } - } - - { - LOCALE_IO dummy; - cmdK2S.Append( wxString::Format( wxT( " --min-distance=%c%.3fmm%c" ), - quote, tolerance, quote ) ); - } - - // Output file path. - cmdK2S.Append( wxString::Format( wxT( " -f -o %c%s%c" ), - dblquote, fn.GetFullPath(), dblquote ) ); - - - // Input file path. - cmdK2S.Append( wxString::Format( wxT( " %c%s%c" ), dblquote, m_boardPath, dblquote ) ); - - wxLogTrace( traceKiCad2Step, wxT( "export step command: %s" ), cmdK2S ); - - DIALOG_EXPORT_STEP_LOG* log = new DIALOG_EXPORT_STEP_LOG( this, cmdK2S ); - log->ShowModal(); } diff --git a/pcbnew/dialogs/dialog_export_step.h b/pcbnew/dialogs/dialog_export_step.h index ff1ca89769..290414cc53 100644 --- a/pcbnew/dialogs/dialog_export_step.h +++ b/pcbnew/dialogs/dialog_export_step.h @@ -27,6 +27,7 @@ #include "dialog_export_step_base.h" class PCB_EDIT_FRAME; +class JOB_EXPORT_PCB_3D; class DIALOG_EXPORT_STEP : public DIALOG_EXPORT_STEP_BASE { @@ -41,6 +42,8 @@ public: }; DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, const wxString& aBoardPath ); + DIALOG_EXPORT_STEP( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent, const wxString& aBoardPath, + JOB_EXPORT_PCB_3D* aJob = nullptr ); ~DIALOG_EXPORT_STEP(); protected: @@ -96,6 +99,7 @@ private: }; PCB_EDIT_FRAME* m_editFrame; + JOB_EXPORT_PCB_3D* m_job; STEP_ORIGIN_OPTION m_origin; // The last preference for STEP origin option double m_userOriginX; // remember last User Origin X value double m_userOriginY; // remember last User Origin Y value diff --git a/pcbnew/dialogs/dialog_export_svg.cpp b/pcbnew/dialogs/dialog_export_svg.cpp index 2640e6ac49..c1e4d7f315 100644 --- a/pcbnew/dialogs/dialog_export_svg.cpp +++ b/pcbnew/dialogs/dialog_export_svg.cpp @@ -41,10 +41,11 @@ #include <pgm_base.h> #include <project/project_file.h> #include <exporters/export_svg.h> +#include <jobs/job_export_pcb_svg.h> -DIALOG_EXPORT_SVG::DIALOG_EXPORT_SVG( PCB_EDIT_FRAME* aEditFrame, BOARD* aBoard ) : - DIALOG_EXPORT_SVG_BASE( aEditFrame ), +DIALOG_EXPORT_SVG::DIALOG_EXPORT_SVG( PCB_EDIT_FRAME* aEditFrame, BOARD* aBoard, wxWindow* aParent ) : + DIALOG_EXPORT_SVG_BASE( aParent ), m_board( aBoard ), m_editFrame( aEditFrame ), m_printBW( false ), @@ -78,6 +79,17 @@ DIALOG_EXPORT_SVG::DIALOG_EXPORT_SVG( PCB_EDIT_FRAME* aEditFrame, BOARD* aBoard } +DIALOG_EXPORT_SVG::DIALOG_EXPORT_SVG( JOB_EXPORT_PCB_SVG* aJob, PCB_EDIT_FRAME* aEditFrame, + wxWindow* aParent ) : + DIALOG_EXPORT_SVG( aEditFrame, aEditFrame->GetBoard(), aParent ) +{ + m_job = aJob; + + SetupStandardButtons( { { wxID_OK, _( "Save" ) }, + { wxID_CANCEL, _( "Close" ) } } ); +} + + DIALOG_EXPORT_SVG::~DIALOG_EXPORT_SVG() { m_printBW = m_ModeColorOption->GetSelection(); @@ -350,7 +362,7 @@ void DIALOG_EXPORT_SVG::OnButtonPlot( wxCommandEvent& event ) bool InvokeExportSVG( PCB_EDIT_FRAME* aCaller, BOARD* aBoard ) { - DIALOG_EXPORT_SVG dlg( aCaller, aBoard ); + DIALOG_EXPORT_SVG dlg( aCaller, aBoard, aCaller ); dlg.ShowModal(); diff --git a/pcbnew/dialogs/dialog_export_svg.h b/pcbnew/dialogs/dialog_export_svg.h index 6fad0b089b..4b0b6c7bec 100644 --- a/pcbnew/dialogs/dialog_export_svg.h +++ b/pcbnew/dialogs/dialog_export_svg.h @@ -29,17 +29,20 @@ class BOARD; class PCB_EDIT_FRAME; +class JOB_EXPORT_PCB_SVG; class DIALOG_EXPORT_SVG : public DIALOG_EXPORT_SVG_BASE { public: - DIALOG_EXPORT_SVG( PCB_EDIT_FRAME* aEditFrame, BOARD* aBoard ); + DIALOG_EXPORT_SVG( JOB_EXPORT_PCB_SVG* aJob, PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent ); + DIALOG_EXPORT_SVG( PCB_EDIT_FRAME* aEditFrame, BOARD* aBoard, wxWindow* aParent ); ~DIALOG_EXPORT_SVG() override; private: - BOARD* m_board; - PCB_EDIT_FRAME* m_editFrame; - LSEQ m_printMaskLayer; + BOARD* m_board; + JOB_EXPORT_PCB_SVG* m_job; + PCB_EDIT_FRAME* m_editFrame; + LSEQ m_printMaskLayer; // the list of existing board layers in wxCheckListBox, with the // board layers id: std::pair<wxCheckListBox*, int> m_boxSelectLayer[PCB_LAYER_ID_COUNT]; diff --git a/pcbnew/dialogs/dialog_gen_footprint_position.cpp b/pcbnew/dialogs/dialog_gen_footprint_position.cpp index 10ddd915d1..3aa1ff6056 100644 --- a/pcbnew/dialogs/dialog_gen_footprint_position.cpp +++ b/pcbnew/dialogs/dialog_gen_footprint_position.cpp @@ -40,6 +40,7 @@ #include <widgets/std_bitmap_button.h> #include <exporters/place_file_exporter.h> #include "gerber_placefile_writer.h" +#include <jobs/job_export_pcb_pos.h> #include <wx/dirdlg.h> #include <wx/msgdlg.h> @@ -61,30 +62,74 @@ DIALOG_GEN_FOOTPRINT_POSITION::DIALOG_GEN_FOOTPRINT_POSITION( PCB_EDIT_FRAME* aE } + +DIALOG_GEN_FOOTPRINT_POSITION::DIALOG_GEN_FOOTPRINT_POSITION( JOB_EXPORT_PCB_POS* aJob, + PCB_EDIT_FRAME* aEditFrame, + wxWindow* aParent ) : + DIALOG_GEN_FOOTPRINT_POSITION_BASE( aParent ), + m_editFrame( aEditFrame ), + m_job( aJob ) +{ + m_messagesPanel->Hide(); + initDialog(); + + SetupStandardButtons( { { wxID_OK, _( "Save" ) }, { wxID_CANCEL, _( "Close" ) } } ); + + GetSizer()->SetSizeHints( this ); + Centre(); +} + + void DIALOG_GEN_FOOTPRINT_POSITION::initDialog() { - m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); + if( !m_job ) + { + m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); - PROJECT_FILE& projectFile = m_editFrame->Prj().GetProjectFile(); - PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings(); + PROJECT_FILE& projectFile = m_editFrame->Prj().GetProjectFile(); + PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings(); - m_units = cfg->m_PlaceFile.units == 0 ? EDA_UNITS::INCHES : EDA_UNITS::MILLIMETRES; + m_units = cfg->m_PlaceFile.units == 0 ? EDA_UNITS::INCHES : EDA_UNITS::MILLIMETRES; - // Output directory - m_outputDirectoryName->SetValue( projectFile.m_PcbLastPath[ LAST_PATH_POS_FILES ] ); + // Output directory + m_outputDirectoryName->SetValue( projectFile.m_PcbLastPath[LAST_PATH_POS_FILES] ); + + // Update Options + m_radioBoxUnits->SetSelection( cfg->m_PlaceFile.units ); + m_radioBoxFilesCount->SetSelection( cfg->m_PlaceFile.file_options ); + m_rbFormat->SetSelection( cfg->m_PlaceFile.file_format ); + m_cbIncludeBoardEdge->SetValue( cfg->m_PlaceFile.include_board_edge ); + m_useDrillPlaceOrigin->SetValue( cfg->m_PlaceFile.use_aux_origin ); + m_onlySMD->SetValue( cfg->m_PlaceFile.only_SMD ); + m_negateXcb->SetValue( cfg->m_PlaceFile.negate_xcoord ); + m_excludeTH->SetValue( cfg->m_PlaceFile.exclude_TH ); + + // Update sizes and sizers: + m_messagesPanel->MsgPanelSetMinSize( wxSize( -1, 160 ) ); + } + else + { + m_browseButton->Hide(); + + m_units = m_job->m_units == JOB_EXPORT_PCB_POS::UNITS::INCHES ? EDA_UNITS::INCHES + : EDA_UNITS::MILLIMETRES; + + + m_outputDirectoryName->SetValue( m_job->GetOutputPath() ); + + m_radioBoxUnits->SetSelection( static_cast<int>( m_job->m_units ) ); + m_radioBoxFilesCount->SetSelection( 0 ); + m_rbFormat->SetSelection( static_cast<int>( m_job->m_format ) ); + m_cbIncludeBoardEdge->SetValue( m_job->m_gerberBoardEdge ); + m_useDrillPlaceOrigin->SetValue( m_job->m_useDrillPlaceFileOrigin ); + m_onlySMD->SetValue( m_job->m_smdOnly ); + m_negateXcb->SetValue( m_job->m_negateBottomX ); + m_excludeTH->SetValue( m_job->m_excludeFootprintsWithTh ); + + m_messagesPanel->Hide(); + } - // Update Options - m_radioBoxUnits->SetSelection( cfg->m_PlaceFile.units ); - m_radioBoxFilesCount->SetSelection( cfg->m_PlaceFile.file_options ); - m_rbFormat->SetSelection( cfg->m_PlaceFile.file_format ); - m_cbIncludeBoardEdge->SetValue( cfg->m_PlaceFile.include_board_edge ); - m_useDrillPlaceOrigin->SetValue( cfg->m_PlaceFile.use_aux_origin ); - m_onlySMD->SetValue( cfg->m_PlaceFile.only_SMD ); - m_negateXcb->SetValue( cfg->m_PlaceFile.negate_xcoord ); - m_excludeTH->SetValue( cfg->m_PlaceFile.exclude_TH ); - // Update sizes and sizers: - m_messagesPanel->MsgPanelSetMinSize( wxSize( -1, 160 ) ); GetSizer()->SetSizeHints( this ); } @@ -212,29 +257,48 @@ void DIALOG_GEN_FOOTPRINT_POSITION::OnOutputDirectoryBrowseClicked( wxCommandEve void DIALOG_GEN_FOOTPRINT_POSITION::OnGenerate( wxCommandEvent& event ) { - m_units = m_radioBoxUnits->GetSelection() == 0 ? EDA_UNITS::INCHES : EDA_UNITS::MILLIMETRES; + if( !m_job ) + { + m_units = m_radioBoxUnits->GetSelection() == 0 ? EDA_UNITS::INCHES : EDA_UNITS::MILLIMETRES; - PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings(); + PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings(); - wxString dirStr = m_outputDirectoryName->GetValue(); - // Keep unix directory format convention in cfg files - dirStr.Replace( wxT( "\\" ), wxT( "/" ) ); + wxString dirStr = m_outputDirectoryName->GetValue(); + // Keep unix directory format convention in cfg files + dirStr.Replace( wxT( "\\" ), wxT( "/" ) ); - m_editFrame->Prj().GetProjectFile().m_PcbLastPath[LAST_PATH_POS_FILES] = dirStr; - cfg->m_PlaceFile.output_directory = dirStr; - cfg->m_PlaceFile.units = m_units == EDA_UNITS::INCHES ? 0 : 1; - cfg->m_PlaceFile.file_options = m_radioBoxFilesCount->GetSelection(); - cfg->m_PlaceFile.file_format = m_rbFormat->GetSelection(); - cfg->m_PlaceFile.include_board_edge = m_cbIncludeBoardEdge->GetValue(); - cfg->m_PlaceFile.exclude_TH = m_excludeTH->GetValue(); - cfg->m_PlaceFile.only_SMD = m_onlySMD->GetValue(); - cfg->m_PlaceFile.use_aux_origin = m_useDrillPlaceOrigin->GetValue(); - cfg->m_PlaceFile.negate_xcoord = m_negateXcb->GetValue(); + m_editFrame->Prj().GetProjectFile().m_PcbLastPath[LAST_PATH_POS_FILES] = dirStr; + cfg->m_PlaceFile.output_directory = dirStr; + cfg->m_PlaceFile.units = m_units == EDA_UNITS::INCHES ? 0 : 1; + cfg->m_PlaceFile.file_options = m_radioBoxFilesCount->GetSelection(); + cfg->m_PlaceFile.file_format = m_rbFormat->GetSelection(); + cfg->m_PlaceFile.include_board_edge = m_cbIncludeBoardEdge->GetValue(); + cfg->m_PlaceFile.exclude_TH = m_excludeTH->GetValue(); + cfg->m_PlaceFile.only_SMD = m_onlySMD->GetValue(); + cfg->m_PlaceFile.use_aux_origin = m_useDrillPlaceOrigin->GetValue(); + cfg->m_PlaceFile.negate_xcoord = m_negateXcb->GetValue(); - if( m_rbFormat->GetSelection() == 2 ) - CreateGerberFiles(); + if( m_rbFormat->GetSelection() == 2 ) + CreateGerberFiles(); + else + CreateAsciiFiles(); + } else - CreateAsciiFiles(); + { + m_job->SetOutputPath( m_outputDirectoryName->GetValue() ); + m_job->m_units = m_radioBoxUnits->GetSelection() == 0 + ? JOB_EXPORT_PCB_POS::UNITS::INCHES + : JOB_EXPORT_PCB_POS::UNITS::MILLIMETERS; + m_job->m_format = static_cast<JOB_EXPORT_PCB_POS::FORMAT>( m_rbFormat->GetSelection() ); + m_job->m_gerberBoardEdge = m_cbIncludeBoardEdge->GetValue(); + m_job->m_excludeFootprintsWithTh = m_excludeTH->GetValue(); + m_job->m_smdOnly = m_onlySMD->GetValue(); + m_job->m_useDrillPlaceFileOrigin = m_useDrillPlaceOrigin->GetValue(); + m_job->m_negateBottomX = m_negateXcb->GetValue(); + m_job->m_excludeDNP = m_excludeDNP->GetValue(); + + Close(); + } } diff --git a/pcbnew/dialogs/dialog_gen_footprint_position.h b/pcbnew/dialogs/dialog_gen_footprint_position.h index 3816af7bd9..74f2a94d22 100644 --- a/pcbnew/dialogs/dialog_gen_footprint_position.h +++ b/pcbnew/dialogs/dialog_gen_footprint_position.h @@ -27,6 +27,7 @@ class PCB_EDIT_FRAME; class REPORTER; +class JOB_EXPORT_PCB_POS; /** * The dialog to create footprint position files and choose options (one or 2 files, units @@ -36,6 +37,7 @@ class DIALOG_GEN_FOOTPRINT_POSITION : public DIALOG_GEN_FOOTPRINT_POSITION_BASE { public: DIALOG_GEN_FOOTPRINT_POSITION( PCB_EDIT_FRAME* aEditFrame ); + DIALOG_GEN_FOOTPRINT_POSITION( JOB_EXPORT_PCB_POS* aJob, PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent ); private: void initDialog(); @@ -78,4 +80,5 @@ private: private: PCB_EDIT_FRAME* m_editFrame; REPORTER* m_reporter; + JOB_EXPORT_PCB_POS* m_job; }; \ No newline at end of file diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp index bbc0bdf7b7..e6eb92b0a4 100644 --- a/pcbnew/dialogs/dialog_gendrill.cpp +++ b/pcbnew/dialogs/dialog_gendrill.cpp @@ -45,6 +45,7 @@ #include <wx/msgdlg.h> #include <wx/dirdlg.h> #include <wx/filedlg.h> +#include <jobs/job_export_pcb_drill.h> // list of allowed precision for EXCELLON files, for integer format: // Due to difference between inches and mm, @@ -66,7 +67,7 @@ int BOARD_EDITOR_CONTROL::GenerateDrillFiles( const TOOL_EVENT& aEvent ) } -DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, wxWindow* aParent ) : +DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, wxWindow* aParent ) : DIALOG_GENDRILL_BASE( aParent ) { m_pcbEditFrame = aPcbEditFrame; @@ -85,6 +86,30 @@ DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, wxWindow* aPar } + +DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, JOB_EXPORT_PCB_DRILL* aJob, + wxWindow* aParent ) : + DIALOG_GENDRILL_BASE( aParent ) +{ + m_pcbEditFrame = aPcbEditFrame; + m_board = m_pcbEditFrame->GetBoard(); + m_job = aJob; + + // hide ui elements that dont belong for job config + m_buttonReport->Hide(); + bMainSizer->Remove( bMsgSizer ); + m_messagesBox->Hide(); + + m_sdbSizerApply->Hide(); + SetupStandardButtons( { { wxID_OK, _( "Save" ) }, { wxID_CANCEL, _( "Cancel" ) } } ); + m_buttonsSizer->Layout(); + + SetReturnCode( 1 ); + + GetSizer()->SetSizeHints( this ); +} + + // Static members of DIALOG_GENDRILL int DIALOG_GENDRILL::m_UnitDrillIsInch = true; // Only for Excellon format int DIALOG_GENDRILL::m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT; @@ -100,46 +125,87 @@ DIALOG_GENDRILL::~DIALOG_GENDRILL() } +bool DIALOG_GENDRILL::TransferDataFromWindow() +{ + return true; +} + + +bool DIALOG_GENDRILL::TransferDataToWindow() +{ + initDialog(); + return true; +} + + void DIALOG_GENDRILL::initDialog() { - auto cfg = m_pcbEditFrame->GetPcbNewSettings(); + if( !m_job ) + { + auto cfg = m_pcbEditFrame->GetPcbNewSettings(); - m_Merge_PTH_NPTH = cfg->m_GenDrill.merge_pth_npth; - m_MinimalHeader = cfg->m_GenDrill.minimal_header; - m_Mirror = cfg->m_GenDrill.mirror; - m_UnitDrillIsInch = cfg->m_GenDrill.unit_drill_is_inch; - m_UseRouteModeForOvalHoles = cfg->m_GenDrill.use_route_for_oval_holes; - m_drillFileType = cfg->m_GenDrill.drill_file_type; - m_mapFileType = cfg->m_GenDrill.map_file_type; - m_ZerosFormat = cfg->m_GenDrill.zeros_format; + m_Merge_PTH_NPTH = cfg->m_GenDrill.merge_pth_npth; + m_MinimalHeader = cfg->m_GenDrill.minimal_header; + m_Mirror = cfg->m_GenDrill.mirror; + m_UnitDrillIsInch = cfg->m_GenDrill.unit_drill_is_inch; + m_UseRouteModeForOvalHoles = cfg->m_GenDrill.use_route_for_oval_holes; + m_drillFileType = cfg->m_GenDrill.drill_file_type; + m_mapFileType = cfg->m_GenDrill.map_file_type; + m_ZerosFormat = cfg->m_GenDrill.zeros_format; + + // Ensure validity of m_mapFileType + if( m_mapFileType < 0 || m_mapFileType >= (int) m_Choice_Drill_Map->GetCount() ) + m_mapFileType = m_Choice_Drill_Map->GetCount() - 1; // last item in list = default = PDF + } m_drillOriginIsAuxAxis = m_plotOpts.GetUseAuxOrigin(); - // Ensure validity of m_mapFileType - if( m_mapFileType < 0 || m_mapFileType >= (int)m_Choice_Drill_Map->GetCount() ) - m_mapFileType = m_Choice_Drill_Map->GetCount() - 1; // last item in list = default = PDF - InitDisplayParams(); } void DIALOG_GENDRILL::InitDisplayParams() { - m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); + if( !m_job ) + { + m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); - m_rbExcellon->SetValue( m_drillFileType == 0 ); - m_rbGerberX2->SetValue( m_drillFileType == 1 ); - m_Choice_Unit->SetSelection( m_UnitDrillIsInch ? 1 : 0 ); - m_Choice_Zeros_Format->SetSelection( m_ZerosFormat ); - UpdatePrecisionOptions(); - m_Check_Minimal->SetValue( m_MinimalHeader ); + m_rbExcellon->SetValue( m_drillFileType == 0 ); + m_rbGerberX2->SetValue( m_drillFileType == 1 ); + m_Choice_Unit->SetSelection( m_UnitDrillIsInch ? 1 : 0 ); + m_Choice_Zeros_Format->SetSelection( m_ZerosFormat ); + UpdatePrecisionOptions(); + m_Check_Minimal->SetValue( m_MinimalHeader ); - m_Choice_Drill_Offset->SetSelection( m_drillOriginIsAuxAxis ? 1 : 0 ); + m_Choice_Drill_Offset->SetSelection( m_drillOriginIsAuxAxis ? 1 : 0 ); - m_Check_Mirror->SetValue( m_Mirror ); - m_Check_Merge_PTH_NPTH->SetValue( m_Merge_PTH_NPTH ); - m_Choice_Drill_Map->SetSelection( m_mapFileType ); - m_radioBoxOvalHoleMode->SetSelection( m_UseRouteModeForOvalHoles ? 0 : 1 ); + m_Check_Mirror->SetValue( m_Mirror ); + m_Check_Merge_PTH_NPTH->SetValue( m_Merge_PTH_NPTH ); + m_Choice_Drill_Map->SetSelection( m_mapFileType ); + m_radioBoxOvalHoleMode->SetSelection( m_UseRouteModeForOvalHoles ? 0 : 1 ); + + // Output directory + m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() ); + } + else + { + m_browseButton->Hide(); + m_outputDirectoryName->SetValue( m_job->GetOutputPath() ); + + m_rbExcellon->SetValue( m_job->m_format == JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::EXCELLON ); + m_rbGerberX2->SetValue( m_job->m_format == JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::GERBER ); + m_Choice_Unit->SetSelection( m_job->m_drillUnits == JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCHES ); + m_Choice_Zeros_Format->SetSelection( static_cast<int>( m_job->m_zeroFormat ) ); + UpdatePrecisionOptions(); + m_Check_Minimal->SetValue( m_job->m_excellonMinimalHeader ); + + m_Choice_Drill_Offset->SetSelection( m_job->m_drillOrigin == JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::PLOT ); + + m_Check_Mirror->SetValue( m_job->m_excellonMirrorY ); + m_Check_Merge_PTH_NPTH->SetValue( m_job->m_excellonCombinePTHNPTH ); + m_Choice_Drill_Map->SetSelection( static_cast<int>( m_job->m_mapFormat ) ); + m_radioBoxOvalHoleMode->SetSelection( m_job->m_excellonOvalDrillRoute ? 0 : 1 ); + } m_platedPadsHoleCount = 0; m_notplatedPadsHoleCount = 0; @@ -197,9 +263,6 @@ void DIALOG_GENDRILL::InitDisplayParams() m_MicroViasInfoMsg->SetLabel( wxString() << m_microViasCount ); m_BuriedViasInfoMsg->SetLabel( wxString() << m_blindOrBuriedViasCount ); - // Output directory - m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() ); - wxCommandEvent dummy; onFileFormatSelection( dummy ); } @@ -256,13 +319,36 @@ void DIALOG_GENDRILL::OnSelDrillUnitsSelected( wxCommandEvent& event ) void DIALOG_GENDRILL::OnGenMapFile( wxCommandEvent& event ) { - GenDrillAndMapFiles( false, true ); + if( !m_job ) + { + GenDrillAndMapFiles( false, true ); + } } void DIALOG_GENDRILL::OnGenDrillFile( wxCommandEvent& event ) { - GenDrillAndMapFiles( true, false ); + if( !m_job ) + { + GenDrillAndMapFiles( true, false ); + } + else + { + m_job->SetOutputPath( m_outputDirectoryName->GetValue() ); + m_job->m_format = m_rbExcellon->GetValue() ? JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::EXCELLON + : JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::GERBER; + m_job->m_drillUnits = m_Choice_Unit->GetSelection() == 0 + ? JOB_EXPORT_PCB_DRILL::DRILL_UNITS::MILLIMETERS + : JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCHES; + m_job->m_drillOrigin = static_cast<JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN>( m_Choice_Drill_Offset->GetSelection() ); + m_job->m_excellonCombinePTHNPTH = m_Check_Merge_PTH_NPTH->IsChecked(); + m_job->m_excellonMinimalHeader = m_Check_Minimal->IsChecked(); + m_job->m_excellonMirrorY = m_Check_Mirror->IsChecked(); + m_job->m_excellonOvalDrillRoute = m_radioBoxOvalHoleMode->GetSelection() == 0; + m_job->m_mapFormat = static_cast<JOB_EXPORT_PCB_DRILL::MAP_FORMAT>( m_Choice_Drill_Map->GetSelection() ); + m_job->m_zeroFormat = static_cast<JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT>( m_Choice_Zeros_Format->GetSelection() ); + Close(); + } } diff --git a/pcbnew/dialogs/dialog_gendrill.h b/pcbnew/dialogs/dialog_gendrill.h index 1b6bc4643e..03c2e900d6 100644 --- a/pcbnew/dialogs/dialog_gendrill.h +++ b/pcbnew/dialogs/dialog_gendrill.h @@ -28,6 +28,8 @@ #include <gendrill_file_writer_base.h> // for DRILL_PRECISION definition #include <dialog_gendrill_base.h> +class JOB_EXPORT_PCB_DRILL; + class DIALOG_GENDRILL : public DIALOG_GENDRILL_BASE { public: @@ -36,6 +38,7 @@ public: * @param aParent is the parent window caller ( the board edit frame or a dialog ). */ DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, wxWindow* aParent ); + DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, JOB_EXPORT_PCB_DRILL* aJob, wxWindow* aParent ); ~DIALOG_GENDRILL(); /** @@ -43,6 +46,9 @@ public: */ void UpdateDrillParams(); + bool TransferDataFromWindow() override; + bool TransferDataToWindow() override; + private: void initDialog(); void InitDisplayParams(); @@ -108,6 +114,8 @@ private: PCB_EDIT_FRAME* m_pcbEditFrame; BOARD* m_board; PCB_PLOT_PARAMS m_plotOpts; + JOB_EXPORT_PCB_DRILL* m_job; + bool m_drillOriginIsAuxAxis; // Axis selection (main / auxiliary) // for drill origin coordinates int m_platedPadsHoleCount; diff --git a/pcbnew/dialogs/dialog_gendrill_base.cpp b/pcbnew/dialogs/dialog_gendrill_base.cpp index 6a15882af1..53f1443aff 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.cpp +++ b/pcbnew/dialogs/dialog_gendrill_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -15,7 +15,6 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con { this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - wxBoxSizer* bMainSizer; bMainSizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer* bupperSizer; @@ -200,7 +199,6 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con bMainSizer->Add( bmiddlerSizer, 0, wxEXPAND|wxTOP, 8 ); - wxStaticBoxSizer* bMsgSizer; bMsgSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages") ), wxVERTICAL ); m_messagesBox = new wxTextCtrl( bMsgSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); diff --git a/pcbnew/dialogs/dialog_gendrill_base.fbp b/pcbnew/dialogs/dialog_gendrill_base.fbp index d5425bdc44..d5b7582b59 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.fbp +++ b/pcbnew/dialogs/dialog_gendrill_base.fbp @@ -1,1967 +1,1997 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <wxFormBuilder_Project> - <FileVersion major="1" minor="16" /> - <object class="Project" expanded="1"> - <property name="class_decoration"></property> - <property name="code_generation">C++</property> - <property name="disconnect_events">1</property> - <property name="disconnect_mode">source_name</property> - <property name="disconnect_php_events">0</property> - <property name="disconnect_python_events">0</property> - <property name="embedded_files_path">res</property> - <property name="encoding">UTF-8</property> - <property name="event_generation">connect</property> - <property name="file">dialog_gendrill_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="name">dialog_gendrill_base</property> - <property name="namespace"></property> - <property name="path">.</property> - <property name="precompiled_header"></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">0</property> - <property name="use_microsoft_bom">0</property> - <object class="Dialog" expanded="1"> - <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="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> + <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_gendrill_base</property> + <property name="first_id">1000</property> + <property name="internationalize">1</property> + <property name="lua_skip_events">1</property> + <property name="lua_ui_table">UI</property> + <property name="name">dialog_gendrill_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_GENDRILL_BASE</property> + <property name="pos"></property> + <property name="size">-1,-1</property> + <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> + <property name="subclass">DIALOG_SHIM; dialog_shim.h</property> + <property name="title">Generate Drill Files</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> + <event name="OnClose">onCloseDlg</event> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">bMainSizer</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">protected</property> + <object class="sizeritem" expanded="true"> + <property name="border">10</property> + <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="true"> <property name="minimum_size"></property> - <property name="name">DIALOG_GENDRILL_BASE</property> - <property name="pos"></property> - <property name="size">-1,-1</property> - <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> - <property name="subclass">DIALOG_SHIM; dialog_shim.h</property> - <property name="title">Generate Drill Files</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> - <event name="OnClose">onCloseDlg</event> - <object class="wxBoxSizer" expanded="1"> + <property name="name">bupperSizer</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="true"> + <property name="border">10</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</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 folder:</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="name">bMainSizer</property> + <property name="moveable">1</property> + <property name="name">staticTextOutputDir</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">0</property> + <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> + <property name="proportion">1</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">-1,-1</property> + <property name="moveable">1</property> + <property name="name">m_outputDirectoryName</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"></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 class="sizeritem" expanded="true"> + <property name="border">7</property> + <property name="flag">wxALIGN_CENTER_VERTICAL</property> + <property name="proportion">0</property> + <object class="wxBitmapButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Browse</property> + <property name="margins"></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">-1,-1</property> + <property name="moveable">1</property> + <property name="name">m_browseButton</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="position"></property> + <property name="pressed"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size">-1,-1</property> + <property name="style"></property> + <property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnOutputDirectoryBrowseClicked</event> + </object> + </object> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">8</property> + <property name="flag">wxEXPAND|wxTOP</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="false"> + <property name="minimum_size"></property> + <property name="name">bmiddlerSizer</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="false"> + <property name="minimum_size"></property> + <property name="name">bMiddleSizer</property> <property name="orient">wxVERTICAL</property> <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">10</property> - <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property> - <property name="proportion">0</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bupperSizer</property> - <property name="orient">wxHORIZONTAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">10</property> - <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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 folder:</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">staticTextOutputDir</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="1"> - <property name="border">0</property> - <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> - <property name="proportion">1</property> - <object class="wxTextCtrl" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">-1,-1</property> - <property name="moveable">1</property> - <property name="name">m_outputDirectoryName</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"></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 class="sizeritem" expanded="1"> - <property name="border">7</property> - <property name="flag">wxALIGN_CENTER_VERTICAL</property> - <property name="proportion">0</property> - <object class="wxBitmapButton" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="auth_needed">0</property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="bitmap"></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="current"></property> - <property name="default">0</property> - <property name="default_pane">0</property> - <property name="disabled"></property> - <property name="dock">Dock</property> - <property name="dock_fixed">0</property> - <property name="docking">Left</property> - <property name="enabled">1</property> - <property name="fg"></property> - <property name="floatable">1</property> - <property name="focus"></property> - <property name="font"></property> - <property name="gripper">0</property> - <property name="hidden">0</property> - <property name="id">wxID_ANY</property> - <property name="label">Browse</property> - <property name="margins"></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">-1,-1</property> - <property name="moveable">1</property> - <property name="name">m_browseButton</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="position"></property> - <property name="pressed"></property> - <property name="resize">Resizable</property> - <property name="show">1</property> - <property name="size">-1,-1</property> - <property name="style"></property> - <property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnButtonClick">OnOutputDirectoryBrowseClicked</event> - </object> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">8</property> - <property name="flag">wxEXPAND|wxTOP</property> - <property name="proportion">0</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bmiddlerSizer</property> - <property name="orient">wxHORIZONTAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">1</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bMiddleSizer</property> - <property name="orient">wxVERTICAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND|wxALL</property> - <property name="proportion">1</property> - <object class="wxStaticBoxSizer" expanded="1"> - <property name="id">wxID_ANY</property> - <property name="label">Drill File Format</property> - <property name="minimum_size"></property> - <property name="name">sbSizer6</property> - <property name="orient">wxVERTICAL</property> - <property name="parent">1</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxBOTTOM|wxRIGHT</property> - <property name="proportion">0</property> - <object class="wxRadioButton" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Excellon</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_rbExcellon</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">0</property> - <property name="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnRadioButton">onFileFormatSelection</event> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">12</property> - <property name="flag">wxEXPAND|wxLEFT</property> - <property name="proportion">1</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bSizerExcellonOptions</property> - <property name="orient">wxVERTICAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxLEFT</property> - <property name="proportion">0</property> - <object class="wxCheckBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="checked">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="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">Mirror Y axis</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_Check_Mirror</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"></property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Not recommended.
Used mostly by users who make the boards themselves.</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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxRIGHT|wxLEFT</property> - <property name="proportion">0</property> - <object class="wxCheckBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="checked">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="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">Minimal header</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_Check_Minimal</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"></property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Not recommended.
Only use it for board houses which do not accept fully featured headers.</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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxLEFT</property> - <property name="proportion">0</property> - <object class="wxCheckBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="checked">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="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">PTH and NPTH in single file</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_Check_Merge_PTH_NPTH</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"></property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Not recommended.
Only use for board houses which ask for merged PTH and NPTH into a single file.</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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxRadioBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="choices">"Use route command (recommended)" "Use alternate drill mode"</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="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">Oval Holes Drill Mode</property> - <property name="majorDimension">1</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_radioBoxOvalHoleMode</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="selection">0</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style">wxRA_SPECIFY_COLS</property> - <property name="subclass">; ; forward_declare</property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Oval holes frequently create problems for board houses.
"Use route command" uses the usual G00 route command (recommended)
 "Use alternate mode" uses another drill/ route command (G85)
(Use it only if the recommended command does not work)</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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - </object> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxTOP|wxBOTTOM|wxRIGHT</property> - <property name="proportion">0</property> - <object class="wxRadioButton" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Gerber X2</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_rbGerberX2</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">0</property> - <property name="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnRadioButton">onFileFormatSelection</event> - </object> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxRadioBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="choices">"PostScript" "Gerber X2" "DXF" "SVG" "PDF"</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="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">Map File Format</property> - <property name="majorDimension">1</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_Choice_Drill_Map</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="selection">4</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style">wxRA_SPECIFY_COLS</property> - <property name="subclass"></property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Creates a drill map in PDF or other formats</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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - </object> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">bLeftSizer</property> - <property name="orient">wxVERTICAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxRadioBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="choices">"Absolute" "Drill/place file origin"</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="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">Drill Origin</property> - <property name="majorDimension">1</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_Choice_Drill_Offset</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="selection">0</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style">wxRA_SPECIFY_COLS</property> - <property name="subclass"></property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Choose the coordinate origin: absolute or relative to the drill/place file origin</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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxRadioBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="choices">"Millimeters" "Inches"</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="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">Drill Units</property> - <property name="majorDimension">1</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_Choice_Unit</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="selection">0</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style">wxRA_SPECIFY_COLS</property> - <property name="subclass"></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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnRadioBox">OnSelDrillUnitsSelected</event> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxRadioBox" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="caption"></property> - <property name="caption_visible">1</property> - <property name="center_pane">0</property> - <property name="choices">"Decimal format (recommended)" "Suppress leading zeros" "Suppress trailing zeros" "Keep zeros"</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="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">Zeros Format</property> - <property name="majorDimension">1</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_Choice_Zeros_Format</property> - <property name="pane_border">1</property> - <property name="pane_position"></property> - <property name="pane_size"></property> - <property name="permission">protected</property> - <property name="pin_button">1</property> - <property name="pos"></property> - <property name="resize">Resizable</property> - <property name="selection">0</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style">wxRA_SPECIFY_COLS</property> - <property name="subclass"></property> - <property name="toolbar_pane">0</property> - <property name="tooltip">Choose EXCELLON numbers notation</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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnRadioBox">OnSelZerosFmtSelected</event> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxFlexGridSizer" expanded="1"> - <property name="cols">2</property> - <property name="flexible_direction">wxBOTH</property> - <property name="growablecols">1</property> - <property name="growablerows"></property> - <property name="hgap">0</property> - <property name="minimum_size"></property> - <property name="name">fgSizer1</property> - <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> - <property name="permission">none</property> - <property name="rows">0</property> - <property name="vgap">0</property> - <object class="sizeritem" expanded="1"> - <property name="border">10</property> - <property name="flag">wxALL</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Precision:</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_staticTextTitle</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"></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="1"> - <property name="border">10</property> - <property name="flag">wxALL</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Precision</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_staticTextPrecision</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"></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> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND|wxTOP</property> - <property name="proportion">0</property> - <object class="wxBoxSizer" expanded="0"> - <property name="minimum_size"></property> - <property name="name">bRightBoxSizer</property> - <property name="orient">wxVERTICAL</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="0"> - <property name="border">5</property> - <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property> - <property name="proportion">1</property> - <object class="wxStaticBoxSizer" expanded="0"> - <property name="id">wxID_ANY</property> - <property name="label">Hole Counts</property> - <property name="minimum_size"></property> - <property name="name">sbSizerHoles</property> - <property name="orient">wxVERTICAL</property> - <property name="parent">1</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="0"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">1</property> - <object class="wxFlexGridSizer" expanded="0"> - <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">fgSizer2</property> - <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> - <property name="permission">none</property> - <property name="rows">0</property> - <property name="vgap">0</property> - <object class="sizeritem" expanded="0"> - <property name="border">5</property> - <property name="flag">wxLEFT|wxRIGHT</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Plated pads:</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">staticTextPlatedPads</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="0"> - <property name="border">5</property> - <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">0</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_PlatedPadsCountInfoMsg</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"></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="0"> - <property name="border">5</property> - <property name="flag">wxLEFT|wxRIGHT|wxTOP</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Non-plated pads:</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">staticTextNonPlatedPads</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="0"> - <property name="border">5</property> - <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT|wxTOP</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">0</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_NotPlatedPadsCountInfoMsg</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"></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="0"> - <property name="border">4</property> - <property name="flag">wxLEFT|wxRIGHT|wxTOP|wxALIGN_BOTTOM</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Through vias:</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">staticTextThroughVias</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="0"> - <property name="border">5</property> - <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT|wxTOP</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">0</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_ThroughViasInfoMsg</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"></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="0"> - <property name="border">5</property> - <property name="flag">wxLEFT|wxRIGHT|wxTOP</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Micro vias:</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">staticTextMicroVias</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="0"> - <property name="border">5</property> - <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT|wxTOP</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">0</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_MicroViasInfoMsg</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"></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="0"> - <property name="border">5</property> - <property name="flag">wxALL</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">Buried vias:</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">staticTextBuriedVias</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="0"> - <property name="border">5</property> - <property name="flag">wxALIGN_RIGHT|wxALL</property> - <property name="proportion">0</property> - <object class="wxStaticText" expanded="0"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">0</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_BuriedViasInfoMsg</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"></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> - </object> - </object> - </object> - </object> - </object> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">1</property> - <object class="wxStaticBoxSizer" expanded="1"> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxALL</property> + <property name="proportion">1</property> + <object class="wxStaticBoxSizer" expanded="false"> + <property name="id">wxID_ANY</property> + <property name="label">Drill File Format</property> + <property name="minimum_size"></property> + <property name="name">sbSizer6</property> + <property name="orient">wxVERTICAL</property> + <property name="parent">1</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxBOTTOM|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxRadioButton" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Messages</property> + <property name="label">Excellon</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="name">bMsgSizer</property> - <property name="orient">wxVERTICAL</property> - <property name="parent">1</property> - <property name="permission">none</property> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">1</property> - <object class="wxTextCtrl" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></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="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">-1,90</property> - <property name="moveable">1</property> - <property name="name">m_messagesBox</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">wxTE_MULTILINE|wxTE_READONLY</property> - <property name="subclass"></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="1"> - <property name="border">5</property> - <property name="flag">wxALL|wxEXPAND</property> - <property name="proportion">0</property> - <object class="wxBoxSizer" expanded="1"> - <property name="minimum_size"></property> - <property name="name">m_buttonsSizer</property> - <property name="orient">wxHORIZONTAL</property> + <property name="moveable">1</property> + <property name="name">m_rbExcellon</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> <property name="permission">protected</property> - <object class="sizeritem" expanded="1"> - <property name="border">10</property> - <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property> - <property name="proportion">0</property> - <object class="wxButton" expanded="1"> - <property name="BottomDockable">1</property> - <property name="LeftDockable">1</property> - <property name="RightDockable">1</property> - <property name="TopDockable">1</property> - <property name="aui_layer"></property> - <property name="aui_name"></property> - <property name="aui_position"></property> - <property name="aui_row"></property> - <property name="auth_needed">0</property> - <property name="best_size"></property> - <property name="bg"></property> - <property name="bitmap"></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="current"></property> - <property name="default">0</property> - <property name="default_pane">0</property> - <property name="disabled"></property> - <property name="dock">Dock</property> - <property name="dock_fixed">0</property> - <property name="docking">Left</property> - <property name="enabled">1</property> - <property name="fg"></property> - <property name="floatable">1</property> - <property name="focus"></property> - <property name="font"></property> - <property name="gripper">0</property> - <property name="hidden">0</property> - <property name="id">wxID_ANY</property> - <property name="label">Generate Report File...</property> - <property name="margins"></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_buttonReport</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="position"></property> - <property name="pressed"></property> - <property name="resize">Resizable</property> - <property name="show">1</property> - <property name="size"></property> - <property name="style"></property> - <property name="subclass"></property> - <property name="toolbar_pane">0</property> - <property name="tooltip"></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="window_extra_style"></property> - <property name="window_name"></property> - <property name="window_style"></property> - <event name="OnButtonClick">OnGenReportFile</event> - </object> - </object> - <object class="sizeritem" expanded="1"> - <property name="border">5</property> - <property name="flag">wxEXPAND</property> - <property name="proportion">1</property> - <object class="wxStdDialogButtonSizer" expanded="1"> - <property name="Apply">1</property> - <property name="Cancel">1</property> - <property name="ContextHelp">0</property> - <property name="Help">0</property> - <property name="No">0</property> - <property name="OK">1</property> - <property name="Save">0</property> - <property name="Yes">0</property> - <property name="minimum_size"></property> - <property name="name">m_sdbSizer</property> - <property name="permission">protected</property> - <event name="OnApplyButtonClick">OnGenMapFile</event> - <event name="OnCancelButtonClick">onQuitDlg</event> - <event name="OnOKButtonClick">OnGenDrillFile</event> - </object> - </object> + <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">0</property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnRadioButton">onFileFormatSelection</event> + </object> </object> + <object class="sizeritem" expanded="false"> + <property name="border">12</property> + <property name="flag">wxEXPAND|wxLEFT</property> + <property name="proportion">1</property> + <object class="wxBoxSizer" expanded="false"> + <property name="minimum_size"></property> + <property name="name">bSizerExcellonOptions</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxLEFT</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="checked">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">Mirror Y axis</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_Check_Mirror</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"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Not recommended.
Used mostly by users who make the boards themselves.</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="checked">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">Minimal header</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_Check_Minimal</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"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Not recommended.
Only use it for board houses which do not accept fully featured headers.</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxLEFT</property> + <property name="proportion">0</property> + <object class="wxCheckBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="checked">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">PTH and NPTH in single file</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_Check_Merge_PTH_NPTH</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"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Not recommended.
Only use for board houses which ask for merged PTH and NPTH into a single file.</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxRadioBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="choices">"Use route command (recommended)" "Use alternate drill mode"</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">Oval Holes Drill Mode</property> + <property name="majorDimension">1</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_radioBoxOvalHoleMode</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="selection">0</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style">wxRA_SPECIFY_COLS</property> + <property name="subclass">; ; forward_declare</property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Oval holes frequently create problems for board houses.
"Use route command" uses the usual G00 route command (recommended)
 "Use alternate mode" uses another drill/ route command (G85)
(Use it only if the recommended command does not work)</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="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">wxTOP|wxBOTTOM|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxRadioButton" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Gerber X2</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_rbGerberX2</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">0</property> + <property name="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnRadioButton">onFileFormatSelection</event> + </object> + </object> + </object> </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxRadioBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="choices">"PostScript" "Gerber X2" "DXF" "SVG" "PDF"</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">Map File Format</property> + <property name="majorDimension">1</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_Choice_Drill_Map</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="selection">4</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style">wxRA_SPECIFY_COLS</property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Creates a drill map in PDF or other formats</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="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</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="false"> + <property name="minimum_size"></property> + <property name="name">bLeftSizer</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxRadioBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="choices">"Absolute" "Drill/place file origin"</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">Drill Origin</property> + <property name="majorDimension">1</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_Choice_Drill_Offset</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="selection">0</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style">wxRA_SPECIFY_COLS</property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Choose the coordinate origin: absolute or relative to the drill/place file origin</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxRadioBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="choices">"Millimeters" "Inches"</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">Drill Units</property> + <property name="majorDimension">1</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_Choice_Unit</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="selection">0</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style">wxRA_SPECIFY_COLS</property> + <property name="subclass"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnRadioBox">OnSelDrillUnitsSelected</event> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxRadioBox" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="choices">"Decimal format (recommended)" "Suppress leading zeros" "Suppress trailing zeros" "Keep zeros"</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">Zeros Format</property> + <property name="majorDimension">1</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_Choice_Zeros_Format</property> + <property name="pane_border">1</property> + <property name="pane_position"></property> + <property name="pane_size"></property> + <property name="permission">protected</property> + <property name="pin_button">1</property> + <property name="pos"></property> + <property name="resize">Resizable</property> + <property name="selection">0</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style">wxRA_SPECIFY_COLS</property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip">Choose EXCELLON numbers notation</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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnRadioBox">OnSelZerosFmtSelected</event> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxFlexGridSizer" expanded="false"> + <property name="cols">2</property> + <property name="flexible_direction">wxBOTH</property> + <property name="growablecols">1</property> + <property name="growablerows"></property> + <property name="hgap">0</property> + <property name="minimum_size"></property> + <property name="name">fgSizer1</property> + <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> + <property name="permission">none</property> + <property name="rows">0</property> + <property name="vgap">0</property> + <object class="sizeritem" expanded="false"> + <property name="border">10</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Precision:</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_staticTextTitle</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"></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="false"> + <property name="border">10</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Precision</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_staticTextPrecision</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"></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> + </object> + </object> + </object> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND|wxTOP</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="false"> + <property name="minimum_size"></property> + <property name="name">bRightBoxSizer</property> + <property name="orient">wxVERTICAL</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property> + <property name="proportion">1</property> + <object class="wxStaticBoxSizer" expanded="false"> + <property name="id">wxID_ANY</property> + <property name="label">Hole Counts</property> + <property name="minimum_size"></property> + <property name="name">sbSizerHoles</property> + <property name="orient">wxVERTICAL</property> + <property name="parent">1</property> + <property name="permission">none</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxFlexGridSizer" expanded="false"> + <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">fgSizer2</property> + <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> + <property name="permission">none</property> + <property name="rows">0</property> + <property name="vgap">0</property> + <object class="sizeritem" expanded="false"> + <property name="border">5</property> + <property name="flag">wxLEFT|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Plated pads:</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">staticTextPlatedPads</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="false"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">0</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_PlatedPadsCountInfoMsg</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"></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="false"> + <property name="border">5</property> + <property name="flag">wxLEFT|wxRIGHT|wxTOP</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Non-plated pads:</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">staticTextNonPlatedPads</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="false"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT|wxTOP</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">0</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_NotPlatedPadsCountInfoMsg</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"></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="false"> + <property name="border">4</property> + <property name="flag">wxLEFT|wxRIGHT|wxTOP|wxALIGN_BOTTOM</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Through vias:</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">staticTextThroughVias</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="false"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT|wxTOP</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">0</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_ThroughViasInfoMsg</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"></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="false"> + <property name="border">5</property> + <property name="flag">wxLEFT|wxRIGHT|wxTOP</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Micro vias:</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">staticTextMicroVias</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="false"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT|wxLEFT|wxRIGHT|wxTOP</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">0</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_MicroViasInfoMsg</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"></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="false"> + <property name="border">5</property> + <property name="flag">wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">Buried vias:</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">staticTextBuriedVias</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="false"> + <property name="border">5</property> + <property name="flag">wxALIGN_RIGHT|wxALL</property> + <property name="proportion">0</property> + <object class="wxStaticText" expanded="false"> + <property name="BottomDockable">1</property> + <property name="LeftDockable">1</property> + <property name="RightDockable">1</property> + <property name="TopDockable">1</property> + <property name="aui_layer">0</property> + <property name="aui_name"></property> + <property name="aui_position">0</property> + <property name="aui_row">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="caption"></property> + <property name="caption_visible">1</property> + <property name="center_pane">0</property> + <property name="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">0</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_BuriedViasInfoMsg</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"></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> + </object> + </object> + </object> + </object> + </object> + </object> </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxStaticBoxSizer" expanded="true"> + <property name="id">wxID_ANY</property> + <property name="label">Messages</property> + <property name="minimum_size"></property> + <property name="name">bMsgSizer</property> + <property name="orient">wxVERTICAL</property> + <property name="parent">1</property> + <property name="permission">protected</property> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">1</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">-1,90</property> + <property name="moveable">1</property> + <property name="name">m_messagesBox</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">wxTE_MULTILINE|wxTE_READONLY</property> + <property name="subclass"></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="true"> + <property name="border">5</property> + <property name="flag">wxALL|wxEXPAND</property> + <property name="proportion">0</property> + <object class="wxBoxSizer" expanded="true"> + <property name="minimum_size"></property> + <property name="name">m_buttonsSizer</property> + <property name="orient">wxHORIZONTAL</property> + <property name="permission">protected</property> + <object class="sizeritem" expanded="true"> + <property name="border">10</property> + <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property> + <property name="proportion">0</property> + <object class="wxButton" 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="auth_needed">0</property> + <property name="best_size"></property> + <property name="bg"></property> + <property name="bitmap"></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="current"></property> + <property name="default">0</property> + <property name="default_pane">0</property> + <property name="disabled"></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="focus"></property> + <property name="font"></property> + <property name="gripper">0</property> + <property name="hidden">0</property> + <property name="id">wxID_ANY</property> + <property name="label">Generate Report File...</property> + <property name="margins"></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_buttonReport</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="position"></property> + <property name="pressed"></property> + <property name="resize">Resizable</property> + <property name="show">1</property> + <property name="size"></property> + <property name="style"></property> + <property name="subclass"></property> + <property name="toolbar_pane">0</property> + <property name="tooltip"></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="window_extra_style"></property> + <property name="window_name"></property> + <property name="window_style"></property> + <event name="OnButtonClick">OnGenReportFile</event> + </object> + </object> + <object class="sizeritem" expanded="true"> + <property name="border">5</property> + <property name="flag">wxEXPAND</property> + <property name="proportion">1</property> + <object class="wxStdDialogButtonSizer" expanded="true"> + <property name="Apply">1</property> + <property name="Cancel">1</property> + <property name="ContextHelp">0</property> + <property name="Help">0</property> + <property name="No">0</property> + <property name="OK">1</property> + <property name="Save">0</property> + <property name="Yes">0</property> + <property name="minimum_size"></property> + <property name="name">m_sdbSizer</property> + <property name="permission">protected</property> + <event name="OnApplyButtonClick">OnGenMapFile</event> + <event name="OnCancelButtonClick">onQuitDlg</event> + <event name="OnOKButtonClick">OnGenDrillFile</event> + </object> + </object> + </object> + </object> + </object> </object> + </object> </wxFormBuilder_Project> diff --git a/pcbnew/dialogs/dialog_gendrill_base.h b/pcbnew/dialogs/dialog_gendrill_base.h index 5d16421bbd..1a96e31374 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.h +++ b/pcbnew/dialogs/dialog_gendrill_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -34,7 +34,6 @@ class STD_BITMAP_BUTTON; /////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////// /// Class DIALOG_GENDRILL_BASE /////////////////////////////////////////////////////////////////////////////// @@ -43,6 +42,7 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM private: protected: + wxBoxSizer* bMainSizer; wxStaticText* staticTextOutputDir; wxTextCtrl* m_outputDirectoryName; STD_BITMAP_BUTTON* m_browseButton; @@ -68,6 +68,7 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM wxStaticText* m_MicroViasInfoMsg; wxStaticText* staticTextBuriedVias; wxStaticText* m_BuriedViasInfoMsg; + wxStaticBoxSizer* bMsgSizer; wxTextCtrl* m_messagesBox; wxBoxSizer* m_buttonsSizer; wxButton* m_buttonReport; diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index a5d5a8e4e1..c625d32ab8 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -46,6 +46,9 @@ #include <tools/drc_tool.h> #include <math/util.h> // for KiROUND #include <macros.h> +#include <jobs/job_export_pcb_gerbers.h> +#include <jobs/job_export_pcb_dxf.h> +#include <jobs/job_export_pcb_pdf.h> #include <wx/dirdlg.h> #include <wx/msgdlg.h> @@ -84,19 +87,39 @@ PCB_LAYER_ID_CLIENT_DATA* getLayerClientData( const wxRearrangeList* aList, int } -DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aParent ) : - DIALOG_PLOT_BASE( aParent ), - m_parent( aParent ), - m_defaultPenSize( aParent, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits ), - m_trackWidthCorrection( aParent, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits ) +DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aEditFrame ) + : DIALOG_PLOT( aEditFrame, aEditFrame ) { - BOARD* board = m_parent->GetBoard(); +} + + +DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent, + JOB_EXPORT_PCB_PLOT* aJob ) : + DIALOG_PLOT_BASE( aParent ), + m_editFrame( aEditFrame ), + m_defaultPenSize( m_editFrame, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits ), + m_trackWidthCorrection( m_editFrame, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits ), + m_job( aJob ) +{ + BOARD* board = m_editFrame->GetBoard(); SetName( DLG_WINDOW_NAME ); - m_plotOpts = aParent->GetPlotSettings(); + m_plotOpts = m_editFrame->GetPlotSettings(); m_DRCWarningTemplate = m_DRCExclusionsWarning->GetLabel(); - m_messagesPanel->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) ); + if( m_job ) + { + m_messagesPanel->Hide(); + + m_browseButton->Hide(); + m_staticTextPlotFmt->Hide(); + m_plotFormatOpt->Hide(); + m_sdbSizer1Apply->Hide(); + } + else + { + m_messagesPanel->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) ); + } int order = 0; LSET plotOnAllLayersSelection = m_plotOpts.GetPlotOnAllLayersSelection(); @@ -185,9 +208,17 @@ DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aParent ) : init_Dialog(); - SetupStandardButtons( { { wxID_OK, _( "Plot" ) }, - { wxID_APPLY, _( "Generate Drill Files..." ) }, - { wxID_CANCEL, _( "Close" ) } } ); + if( m_job ) + { + SetupStandardButtons( { { wxID_OK, _( "Save" ) }, + { wxID_CANCEL, _( "Close" ) } } ); + } + else + { + SetupStandardButtons( { { wxID_OK, _( "Plot" ) }, + { wxID_APPLY, _( "Generate Drill Files..." ) }, + { wxID_CANCEL, _( "Close" ) } } ); + } GetSizer()->Fit( this ); GetSizer()->SetSizeHints( this ); @@ -219,165 +250,183 @@ DIALOG_PLOT::~DIALOG_PLOT() void DIALOG_PLOT::init_Dialog() { - BOARD* board = m_parent->GetBoard(); + BOARD* board = m_editFrame->GetBoard(); wxFileName fileName; - PROJECT_FILE& projectFile = m_parent->Prj().GetProjectFile(); - PCBNEW_SETTINGS* cfg = m_parent->GetPcbNewSettings(); - - if( !projectFile.m_PcbLastPath[ LAST_PATH_PLOT ].IsEmpty() ) - m_plotOpts.SetOutputDirectory( projectFile.m_PcbLastPath[ LAST_PATH_PLOT ] ); - - m_XScaleAdjust = cfg->m_Plot.fine_scale_x; - m_YScaleAdjust = cfg->m_Plot.fine_scale_y; - - m_zoneFillCheck->SetValue( cfg->m_Plot.check_zones_before_plotting ); - - m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); - - // m_PSWidthAdjust is stored in mm in user config - m_PSWidthAdjust = KiROUND( cfg->m_Plot.ps_fine_width_adjust * pcbIUScale.IU_PER_MM ); - - // The reasonable width correction value must be in a range of - // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils. - m_widthAdjustMinValue = -( board->GetDesignSettings().m_TrackMinWidth - 1 ); - m_widthAdjustMaxValue = board->GetDesignSettings().GetSmallestClearanceValue() - 1; - - switch( m_plotOpts.GetFormat() ) - { - default: - case PLOT_FORMAT::GERBER: m_plotFormatOpt->SetSelection( 0 ); break; - case PLOT_FORMAT::POST: 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 PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 5 ); break; - } - - // Set units and value for HPGL pen size (this param is in mils). - m_defaultPenSize.SetValue( m_plotOpts.GetHPGLPenDiameter() * pcbIUScale.IU_PER_MILS ); - - // Test for a reasonable scale value. Set to 1 if problem - if( m_XScaleAdjust < PLOT_MIN_SCALE || m_YScaleAdjust < PLOT_MIN_SCALE - || m_XScaleAdjust > PLOT_MAX_SCALE || m_YScaleAdjust > PLOT_MAX_SCALE ) - { - m_XScaleAdjust = m_YScaleAdjust = 1.0; - } - - m_fineAdjustXCtrl->SetValue( EDA_UNIT_UTILS::UI::StringFromValue( unityScale, - EDA_UNITS::UNSCALED, - m_XScaleAdjust ) ); - - m_fineAdjustYCtrl->SetValue( EDA_UNIT_UTILS::UI::StringFromValue( unityScale, - EDA_UNITS::UNSCALED, - m_YScaleAdjust ) ); - - // Test for a reasonable PS width correction value. Set to 0 if problem. - if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue ) - m_PSWidthAdjust = 0.; - - m_trackWidthCorrection.SetValue( m_PSWidthAdjust ); - - m_plotPSNegativeOpt->SetValue( m_plotOpts.GetNegative() ); - m_forcePSA4OutputOpt->SetValue( m_plotOpts.GetA4Output() ); + PROJECT_FILE& projectFile = m_editFrame->Prj().GetProjectFile(); // Could devote a PlotOrder() function in place of UIOrder(). m_layerList = board->GetEnabledLayers().UIOrder(); - // Populate the check list box by all enabled layers names. - for( PCB_LAYER_ID layer : m_layerList ) + if( !m_job ) { - int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) ); + PCBNEW_SETTINGS* cfg = m_editFrame->GetPcbNewSettings(); - if( m_plotOpts.GetLayerSelection()[layer] ) - m_layerCheckListBox->Check( checkIndex ); + if( !projectFile.m_PcbLastPath[ LAST_PATH_PLOT ].IsEmpty() ) + m_plotOpts.SetOutputDirectory( projectFile.m_PcbLastPath[ LAST_PATH_PLOT ] ); + + m_XScaleAdjust = cfg->m_Plot.fine_scale_x; + m_YScaleAdjust = cfg->m_Plot.fine_scale_y; + + m_zoneFillCheck->SetValue( cfg->m_Plot.check_zones_before_plotting ); + + m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); + + // m_PSWidthAdjust is stored in mm in user config + m_PSWidthAdjust = KiROUND( cfg->m_Plot.ps_fine_width_adjust * pcbIUScale.IU_PER_MM ); + + // The reasonable width correction value must be in a range of + // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils. + m_widthAdjustMinValue = -( board->GetDesignSettings().m_TrackMinWidth - 1 ); + m_widthAdjustMaxValue = board->GetDesignSettings().GetSmallestClearanceValue() - 1; + + switch( m_plotOpts.GetFormat() ) + { + default: + case PLOT_FORMAT::GERBER: m_plotFormatOpt->SetSelection( 0 ); break; + case PLOT_FORMAT::POST: 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 PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 5 ); break; + } + + // Set units and value for HPGL pen size (this param is in mils). + m_defaultPenSize.SetValue( m_plotOpts.GetHPGLPenDiameter() * pcbIUScale.IU_PER_MILS ); + + // Test for a reasonable scale value. Set to 1 if problem + if( m_XScaleAdjust < PLOT_MIN_SCALE || m_YScaleAdjust < PLOT_MIN_SCALE + || m_XScaleAdjust > PLOT_MAX_SCALE || m_YScaleAdjust > PLOT_MAX_SCALE ) + { + m_XScaleAdjust = m_YScaleAdjust = 1.0; + } + + m_fineAdjustXCtrl->SetValue( EDA_UNIT_UTILS::UI::StringFromValue( + unityScale, EDA_UNITS::UNSCALED, m_XScaleAdjust ) ); + + m_fineAdjustYCtrl->SetValue( EDA_UNIT_UTILS::UI::StringFromValue( + unityScale, EDA_UNITS::UNSCALED, m_YScaleAdjust ) ); + + // Test for a reasonable PS width correction value. Set to 0 if problem. + if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue ) + m_PSWidthAdjust = 0.; + + m_trackWidthCorrection.SetValue( m_PSWidthAdjust ); + + m_plotPSNegativeOpt->SetValue( m_plotOpts.GetNegative() ); + m_forcePSA4OutputOpt->SetValue( m_plotOpts.GetA4Output() ); + + // Populate the check list box by all enabled layers names. + for( PCB_LAYER_ID layer : m_layerList ) + { + int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) ); + + if( m_plotOpts.GetLayerSelection()[layer] ) + m_layerCheckListBox->Check( checkIndex ); + } + + arrangeAllLayersList( s_lastAllLayersOrder ); + + // Option for disabling Gerber Aperture Macro (for broken Gerber readers) + m_disableApertMacros->SetValue( m_plotOpts.GetDisableGerberMacros() ); + + // Option for using proper Gerber extensions. Note also Protel extensions are + // a broken feature. However, for now, we need to handle it. + m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberProtelExtensions() ); + + // Option for including Gerber attributes, from Gerber X2 format, in the output + // In X1 format, they will be added as comments + m_useGerberX2Format->SetValue( m_plotOpts.GetUseGerberX2format() ); + + // Option for including Gerber netlist info (from Gerber X2 format) in the output + m_useGerberNetAttributes->SetValue( m_plotOpts.GetIncludeGerberNetlistInfo() ); + + // Option to generate a Gerber job file + m_generateGerberJobFile->SetValue( m_plotOpts.GetCreateGerberJobFile() ); + + // Gerber precision for coordinates + m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 ); + + // SVG precision and units for coordinates + m_svgPrecsision->SetValue( m_plotOpts.GetSvgPrecision() ); + + // Option to exclude pads from silkscreen layers + m_sketchPadsOnFabLayers->SetValue( m_plotOpts.GetSketchPadsOnFabLayers() ); + m_plotPadNumbers->SetValue( m_plotOpts.GetPlotPadNumbers() ); + m_plotPadNumbers->Enable( m_plotOpts.GetSketchPadsOnFabLayers() ); + + m_plotDNP->SetValue( m_plotOpts.GetHideDNPFPsOnFabLayers() + || m_plotOpts.GetSketchDNPFPsOnFabLayers() + || m_plotOpts.GetCrossoutDNPFPsOnFabLayers() ); + + if( m_plotDNP->GetValue() ) + { + if( m_plotOpts.GetHideDNPFPsOnFabLayers() ) + m_hideDNP->SetValue( true ); + else + m_crossoutDNP->SetValue( true ); + } + + m_hideDNP->Enable( m_plotDNP->GetValue() ); + m_crossoutDNP->Enable( m_plotDNP->GetValue() ); + + // Option to tent vias + m_subtractMaskFromSilk->SetValue( m_plotOpts.GetSubtractMaskFromSilk() ); + + // Option to use aux origin + m_useAuxOriginCheckBox->SetValue( m_plotOpts.GetUseAuxOrigin() ); + + // Option to plot page references: + m_plotSheetRef->SetValue( m_plotOpts.GetPlotFrameRef() ); + + // Option to force ploting of hidden text in footprints + m_plotInvisibleText->SetValue( m_plotOpts.GetPlotInvisibleText() ); + + // Options to plot pads and vias holes + m_drillShapeOpt->SetSelection( (int) m_plotOpts.GetDrillMarksType() ); + + // Scale option + m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() ); + + // Plot mode + setPlotModeChoiceSelection( m_plotOpts.GetPlotMode() ); + + // DXF outline mode + m_DXF_plotModeOpt->SetValue( m_plotOpts.GetDXFPlotPolygonMode() ); + + // DXF text mode + m_DXF_plotTextStrokeFontOpt->SetValue( m_plotOpts.GetTextMode() + == PLOT_TEXT_MODE::DEFAULT ); + + // DXF units selection + m_DXF_plotUnits->SetSelection( m_plotOpts.GetDXFPlotUnits() == DXF_UNITS::INCHES ? 0 : 1 ); + + // Plot mirror option + m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() ); + + // Black and white plotting + m_SVGColorChoice->SetSelection( m_plotOpts.GetBlackAndWhite() ? 1 : 0 ); + m_PDFColorChoice->SetSelection( m_plotOpts.GetBlackAndWhite() ? 1 : 0 ); + m_frontFPPropertyPopups->SetValue( m_plotOpts.m_PDFFrontFPPropertyPopups ); + m_backFPPropertyPopups->SetValue( m_plotOpts.m_PDFBackFPPropertyPopups ); + m_pdfMetadata->SetValue( m_plotOpts.m_PDFMetadata ); } - - arrangeAllLayersList( s_lastAllLayersOrder ); - - // Option for disabling Gerber Aperture Macro (for broken Gerber readers) - m_disableApertMacros->SetValue( m_plotOpts.GetDisableGerberMacros() ); - - // Option for using proper Gerber extensions. Note also Protel extensions are - // a broken feature. However, for now, we need to handle it. - m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberProtelExtensions() ); - - // Option for including Gerber attributes, from Gerber X2 format, in the output - // In X1 format, they will be added as comments - m_useGerberX2Format->SetValue( m_plotOpts.GetUseGerberX2format() ); - - // Option for including Gerber netlist info (from Gerber X2 format) in the output - m_useGerberNetAttributes->SetValue( m_plotOpts.GetIncludeGerberNetlistInfo() ); - - // Option to generate a Gerber job file - m_generateGerberJobFile->SetValue( m_plotOpts.GetCreateGerberJobFile() ); - - // Gerber precision for coordinates - m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 ); - - // SVG precision and units for coordinates - m_svgPrecsision->SetValue( m_plotOpts.GetSvgPrecision() ); - - // Option to exclude pads from silkscreen layers - m_sketchPadsOnFabLayers->SetValue( m_plotOpts.GetSketchPadsOnFabLayers() ); - m_plotPadNumbers->SetValue( m_plotOpts.GetPlotPadNumbers() ); - m_plotPadNumbers->Enable( m_plotOpts.GetSketchPadsOnFabLayers() ); - - m_plotDNP->SetValue( m_plotOpts.GetHideDNPFPsOnFabLayers() - || m_plotOpts.GetSketchDNPFPsOnFabLayers() - || m_plotOpts.GetCrossoutDNPFPsOnFabLayers() ); - - if( m_plotDNP->GetValue() ) + else { - if( m_plotOpts.GetHideDNPFPsOnFabLayers() ) - m_hideDNP->SetValue( true ); - else - m_crossoutDNP->SetValue( true ); + m_plotFormatOpt->Hide(); + + switch( m_job->m_plotFormat ) + { + default: + case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::GERBER: m_plotFormatOpt->SetSelection( 0 ); break; + case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 1 ); break; + case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break; + case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break; + case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break; + case JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 5 ); break; + } } - m_hideDNP->Enable( m_plotDNP->GetValue() ); - m_crossoutDNP->Enable( m_plotDNP->GetValue() ); - - // Option to tent vias - m_subtractMaskFromSilk->SetValue( m_plotOpts.GetSubtractMaskFromSilk() ); - - // Option to use aux origin - m_useAuxOriginCheckBox->SetValue( m_plotOpts.GetUseAuxOrigin() ); - - // Option to plot page references: - m_plotSheetRef->SetValue( m_plotOpts.GetPlotFrameRef() ); - - // Option to force ploting of hidden text in footprints - m_plotInvisibleText->SetValue( m_plotOpts.GetPlotInvisibleText() ); - - // Options to plot pads and vias holes - m_drillShapeOpt->SetSelection( (int)m_plotOpts.GetDrillMarksType() ); - - // Scale option - m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() ); - - // Plot mode - setPlotModeChoiceSelection( m_plotOpts.GetPlotMode() ); - - // DXF outline mode - m_DXF_plotModeOpt->SetValue( m_plotOpts.GetDXFPlotPolygonMode() ); - - // DXF text mode - m_DXF_plotTextStrokeFontOpt->SetValue( m_plotOpts.GetTextMode() == PLOT_TEXT_MODE::DEFAULT ); - - // DXF units selection - m_DXF_plotUnits->SetSelection( m_plotOpts.GetDXFPlotUnits() == DXF_UNITS::INCHES ? 0 : 1); - - // Plot mirror option - m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() ); - - // Black and white plotting - m_SVGColorChoice->SetSelection( m_plotOpts.GetBlackAndWhite() ? 1 : 0 ); - m_PDFColorChoice->SetSelection( m_plotOpts.GetBlackAndWhite() ? 1 : 0 ); - m_frontFPPropertyPopups->SetValue( m_plotOpts.m_PDFFrontFPPropertyPopups ); - m_backFPPropertyPopups->SetValue( m_plotOpts.m_PDFBackFPPropertyPopups ); - m_pdfMetadata->SetValue( m_plotOpts.m_PDFMetadata ); - // Initialize a few other parameters, which can also be modified // from the drill dialog reInitDialog(); @@ -402,7 +451,7 @@ void DIALOG_PLOT::reInitDialog() int knownViolations = 0; int exclusions = 0; - for( PCB_MARKER* marker : m_parent->GetBoard()->Markers() ) + for( PCB_MARKER* marker : m_editFrame->GetBoard()->Markers() ) { if( marker->GetSeverity() == RPT_SEVERITY_EXCLUSION ) exclusions++; @@ -421,7 +470,7 @@ void DIALOG_PLOT::reInitDialog() m_DRCExclusionsWarning->Hide(); } - BOARD* board = m_parent->GetBoard(); + BOARD* board = m_editFrame->GetBoard(); const BOARD_DESIGN_SETTINGS& brd_settings = board->GetDesignSettings(); if( getPlotFormat() == PLOT_FORMAT::GERBER && @@ -578,7 +627,7 @@ void DIALOG_PLOT::OnRightClickAllLayers( wxMouseEvent& event ) case ID_STACKUP_ORDER: { - LSEQ stackup = m_parent->GetBoard()->GetEnabledLayers().SeqStackupForPlotting(); + LSEQ stackup = m_editFrame->GetBoard()->GetEnabledLayers().SeqStackupForPlotting(); arrangeAllLayersList( stackup ); m_plotAllLayersList->Select( -1 ); break; @@ -598,11 +647,11 @@ void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event ) // Be sure drill file use the same settings (axis option, plot directory) as plot files: applyPlotSettings(); - DIALOG_GENDRILL dlg( m_parent, this ); + DIALOG_GENDRILL dlg( m_editFrame, this ); dlg.ShowModal(); // a few plot settings can be modified: take them in account - m_plotOpts = m_parent->GetPlotSettings(); + m_plotOpts = m_editFrame->GetPlotSettings(); reInitDialog(); } @@ -638,7 +687,7 @@ void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) std::function<bool( wxString* )> textResolver = [&]( wxString* token ) -> bool { - return m_parent->GetBoard()->ResolveTextVar( token, 0 ); + return m_editFrame->GetBoard()->ResolveTextVar( token, 0 ); }; wxString path = m_outputDirectoryName->GetValue(); @@ -653,7 +702,7 @@ void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() ); - wxFileName fn( Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() ) ); + wxFileName fn( Prj().AbsolutePath( m_editFrame->GetBoard()->GetFileName() ) ); wxString defaultPath = fn.GetPathWithSep(); wxString msg; wxFileName relPathTest; // Used to test if we can make the path relative @@ -698,7 +747,7 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event ) // The alert message about non 0 solder mask min width and margin is shown // only in gerber format and if min mask width or mask margin is not 0 - BOARD* board = m_parent->GetBoard(); + BOARD* board = m_editFrame->GetBoard(); const BOARD_DESIGN_SETTINGS& brd_settings = board->GetDesignSettings(); if( getPlotFormat() == PLOT_FORMAT::GERBER @@ -996,7 +1045,7 @@ void DIALOG_PLOT::applyPlotSettings() reporter.Report( msg, RPT_SEVERITY_INFO ); } - auto cfg = m_parent->GetPcbNewSettings(); + auto cfg = m_editFrame->GetPcbNewSettings(); cfg->m_Plot.fine_scale_x = m_XScaleAdjust; cfg->m_Plot.fine_scale_y = m_YScaleAdjust; @@ -1010,8 +1059,8 @@ void DIALOG_PLOT::applyPlotSettings() m_trackWidthCorrection.SetValue( m_PSWidthAdjust ); msg.Printf( _( "Width correction constrained. The width correction value must be in the" " range of [%s; %s] for the current design rules." ), - m_parent->StringFromValue( m_widthAdjustMinValue, true ), - m_parent->StringFromValue( m_widthAdjustMaxValue, true ) ); + m_editFrame->StringFromValue( m_widthAdjustMinValue, true ), + m_editFrame->StringFromValue( m_widthAdjustMaxValue, true ) ); reporter.Report( msg, RPT_SEVERITY_WARNING ); } @@ -1038,7 +1087,7 @@ void DIALOG_PLOT::applyPlotSettings() } // Get a list of copper layers that aren't being used by inverting enabled layers. - LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers(); + LSET disabledCopperLayers = LSET::AllCuMask() & ~m_editFrame->GetBoard()->GetEnabledLayers(); LSET plotOnAllLayers; @@ -1075,12 +1124,12 @@ void DIALOG_PLOT::applyPlotSettings() dirStr = m_outputDirectoryName->GetValue(); dirStr.Replace( wxT( "\\" ), wxT( "/" ) ); tempOptions.SetOutputDirectory( dirStr ); - m_parent->Prj().GetProjectFile().m_PcbLastPath[ LAST_PATH_PLOT ] = dirStr; + m_editFrame->Prj().GetProjectFile().m_PcbLastPath[ LAST_PATH_PLOT ] = dirStr; if( !m_plotOpts.IsSameAs( tempOptions ) ) { - m_parent->SetPlotSettings( tempOptions ); - m_parent->OnModify(); + m_editFrame->SetPlotSettings( tempOptions ); + m_editFrame->OnModify(); m_plotOpts = tempOptions; } } @@ -1092,209 +1141,228 @@ void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event ) } +void DIALOG_PLOT::updateJobFromDialog() +{ + m_job->m_mirror = m_plotMirrorOpt->GetValue(); + m_job->m_plotDrawingSheet = m_plotSheetRef->GetValue(); + m_job->m_hideDNPFPsOnFabLayers = m_plotDNP->GetValue() && m_hideDNP->GetValue(); + m_job->m_sketchDNPFPsOnFabLayers = m_plotDNP->GetValue() && m_crossoutDNP->GetValue(); + m_job->m_crossoutDNPFPsOnFabLayers = m_plotDNP->GetValue() && m_crossoutDNP->GetValue(); + //m_job->m_plotInvisibleText = m_plotInvisibleText->GetValue(); + m_job->m_drillShapeOption = static_cast<int>( m_drillShapeOpt->GetSelection() ); +} + + void DIALOG_PLOT::Plot( wxCommandEvent& event ) { - BOARD* board = m_parent->GetBoard(); - - applyPlotSettings(); - - SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); - PCBNEW_SETTINGS* cfg = mgr.GetAppSettings<PCBNEW_SETTINGS>(); - - m_plotOpts.SetColorSettings( mgr.GetColorSettings( cfg->m_ColorTheme ) ); - - m_plotOpts.SetSketchPadLineWidth( board->GetDesignSettings().GetLineThickness( F_Fab ) ); - - // If no layer selected, we have nothing plotted. - // Prompt user if it happens because he could think there is a bug in Pcbnew. - if( !m_plotOpts.GetLayerSelection().any() ) + if( m_job ) { - DisplayError( this, _( "No layer selected, Nothing to plot" ) ); - return; + updateJobFromDialog(); } - - // Create output directory if it does not exist (also transform it in absolute form). - // Bail if it fails. - - std::function<bool( wxString* )> textResolver = - [&]( wxString* token ) -> bool - { - // Handles board->GetTitleBlock() *and* board->GetProject() - return m_parent->GetBoard()->ResolveTextVar( token, 0 ); - }; - - wxString path = m_plotOpts.GetOutputDirectory(); - path = ExpandTextVars( path, &textResolver ); - path = ExpandEnvVarSubstitutions( path, board->GetProject() ); - - wxFileName outputDir = wxFileName::DirName( path ); - wxString boardFilename = m_parent->GetBoard()->GetFileName(); - REPORTER& reporter = m_messagesPanel->Reporter(); - - if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) ) + else { - wxString msg; - msg.Printf( _( "Could not write plot files to folder '%s'." ), outputDir.GetPath() ); - DisplayError( this, msg ); - return; - } + BOARD* board = m_editFrame->GetBoard(); - if( m_zoneFillCheck->GetValue() ) - m_parent->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this ); + applyPlotSettings(); - m_plotOpts.SetAutoScale( false ); + SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); + PCBNEW_SETTINGS* cfg = mgr.GetAppSettings<PCBNEW_SETTINGS>(); - switch( m_plotOpts.GetScaleSelection() ) - { - default: m_plotOpts.SetScale( 1 ); break; - case 0: m_plotOpts.SetAutoScale( true ); break; - case 2: m_plotOpts.SetScale( 1.5 ); break; - case 3: m_plotOpts.SetScale( 2 ); break; - case 4: m_plotOpts.SetScale( 3 ); break; - } + m_plotOpts.SetColorSettings( mgr.GetColorSettings( cfg->m_ColorTheme ) ); - /* If the scale factor edit controls are disabled or the scale value - * is 0, don't adjust the base scale factor. This fixes a bug when - * the default scale adjust is initialized to 0 and saved in program - * settings resulting in a divide by zero fault. - */ - if( getPlotFormat() == PLOT_FORMAT::POST ) - { - if( m_XScaleAdjust != 0.0 ) - m_plotOpts.SetFineScaleAdjustX( m_XScaleAdjust ); + m_plotOpts.SetSketchPadLineWidth( board->GetDesignSettings().GetLineThickness( F_Fab ) ); - if( m_YScaleAdjust != 0.0 ) - m_plotOpts.SetFineScaleAdjustY( m_YScaleAdjust ); - - m_plotOpts.SetWidthAdjust( m_PSWidthAdjust ); - } - - wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) ); - - // Test for a reasonable scale value - // XXX could this actually happen? isn't it constrained in the apply function? - if( m_plotOpts.GetScale() < PLOT_MIN_SCALE ) - DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) ); - - if( m_plotOpts.GetScale() > PLOT_MAX_SCALE ) - DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) ); - - GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter ); - - // Save the current plot options in the board - m_parent->SetPlotSettings( m_plotOpts ); - - wxBusyCursor dummy; - - for( PCB_LAYER_ID layer : m_plotOpts.GetLayerSelection().UIOrder() ) - { - LSEQ plotSequence; - - // Base layer always gets plotted first. - plotSequence.push_back( layer ); - - // Add selected layers from plot on all layers list in order set by user. - wxArrayInt plotOnAllLayers; - - if( m_plotAllLayersList->GetCheckedItems( plotOnAllLayers ) ) + // If no layer selected, we have nothing plotted. + // Prompt user if it happens because he could think there is a bug in Pcbnew. + if( !m_plotOpts.GetLayerSelection().any() ) { - size_t count = plotOnAllLayers.GetCount(); - - for( size_t i = 0; i < count; i++ ) - { - int index = plotOnAllLayers.Item( i ); - PCB_LAYER_ID client_layer = getLayerClientData( m_plotAllLayersList, index )->Layer(); - - // Don't plot the same layer more than once; - if( find( plotSequence.begin(), plotSequence.end(), client_layer ) != plotSequence.end() ) - continue; - - plotSequence.push_back( client_layer ); - } + DisplayError( this, _( "No layer selected, Nothing to plot" ) ); + return; } - wxString layerName = board->GetLayerName( layer ); - //@todo allow controlling the sheet name and path that will be displayed in the title block - // Leave blank for now - wxString sheetName; - wxString sheetPath; + // Create output directory if it does not exist (also transform it in absolute form). + // Bail if it fails. - // All copper layers that are disabled are actually selected - // This is due to wonkyness in automatically selecting copper layers - // for plotting when adding more than two layers to a board. - // If plot options become accessible to the layers setup dialog - // please move this functionality there! - // This skips a copper layer if it is actually disabled on the board. - if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] ) - continue; + std::function<bool( wxString* )> textResolver = + [&]( wxString* token ) -> bool + { + // Handles board->GetTitleBlock() *and* board->GetProject() + return m_editFrame->GetBoard()->ResolveTextVar( token, 0 ); + }; - // Pick the basename from the board file - wxFileName fn( boardFilename ); + wxString path = m_plotOpts.GetOutputDirectory(); + path = ExpandTextVars( path, &textResolver ); + path = ExpandEnvVarSubstitutions( path, board->GetProject() ); - // Use Gerber Extensions based on layer number - // (See http://en.wikipedia.org/wiki/Gerber_File) - if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && m_useGerberExtensions->GetValue() ) - file_ext = GetGerberProtelExtension( layer ); + wxFileName outputDir = wxFileName::DirName( path ); + wxString boardFilename = m_editFrame->GetBoard()->GetFileName(); + REPORTER& reporter = m_messagesPanel->Reporter(); - BuildPlotFileName( &fn, outputDir.GetPath(), layerName, file_ext ); - wxString fullname = fn.GetFullName(); - jobfile_writer.AddGbrFile( layer, fullname ); - - LOCALE_IO toggle; - - PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, layerName, fn.GetFullPath(), - sheetName, sheetPath ); - - // Print diags in messages box: - wxString msg; - - if( plotter ) + if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) ) { - plotter->SetTitle( ExpandTextVars( board->GetTitleBlock().GetTitle(), &textResolver ) ); + wxString msg; + msg.Printf( _( "Could not write plot files to folder '%s'." ), outputDir.GetPath() ); + DisplayError( this, msg ); + return; + } - if( m_plotOpts.m_PDFMetadata ) + if( m_zoneFillCheck->GetValue() ) + m_editFrame->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this ); + + m_plotOpts.SetAutoScale( false ); + + switch( m_plotOpts.GetScaleSelection() ) + { + default: m_plotOpts.SetScale( 1 ); break; + case 0: m_plotOpts.SetAutoScale( true ); break; + case 2: m_plotOpts.SetScale( 1.5 ); break; + case 3: m_plotOpts.SetScale( 2 ); break; + case 4: m_plotOpts.SetScale( 3 ); break; + } + + /* If the scale factor edit controls are disabled or the scale value + * is 0, don't adjust the base scale factor. This fixes a bug when + * the default scale adjust is initialized to 0 and saved in program + * settings resulting in a divide by zero fault. + */ + if( getPlotFormat() == PLOT_FORMAT::POST ) + { + if( m_XScaleAdjust != 0.0 ) + m_plotOpts.SetFineScaleAdjustX( m_XScaleAdjust ); + + if( m_YScaleAdjust != 0.0 ) + m_plotOpts.SetFineScaleAdjustY( m_YScaleAdjust ); + + m_plotOpts.SetWidthAdjust( m_PSWidthAdjust ); + } + + wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) ); + + // Test for a reasonable scale value + // XXX could this actually happen? isn't it constrained in the apply function? + if( m_plotOpts.GetScale() < PLOT_MIN_SCALE ) + DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) ); + + if( m_plotOpts.GetScale() > PLOT_MAX_SCALE ) + DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) ); + + GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter ); + + // Save the current plot options in the board + m_editFrame->SetPlotSettings( m_plotOpts ); + + wxBusyCursor dummy; + + for( PCB_LAYER_ID layer : m_plotOpts.GetLayerSelection().UIOrder() ) + { + LSEQ plotSequence; + + // Base layer always gets plotted first. + plotSequence.push_back( layer ); + + // Add selected layers from plot on all layers list in order set by user. + wxArrayInt plotOnAllLayers; + + if( m_plotAllLayersList->GetCheckedItems( plotOnAllLayers ) ) { - msg = wxS( "AUTHOR" ); + size_t count = plotOnAllLayers.GetCount(); - if( board->ResolveTextVar( &msg, 0 ) ) - plotter->SetAuthor( msg ); + for( size_t i = 0; i < count; i++ ) + { + int index = plotOnAllLayers.Item( i ); + PCB_LAYER_ID client_layer = getLayerClientData( m_plotAllLayersList, index )->Layer(); - msg = wxS( "SUBJECT" ); + // Don't plot the same layer more than once; + if( find( plotSequence.begin(), plotSequence.end(), client_layer ) != plotSequence.end() ) + continue; - if( board->ResolveTextVar( &msg, 0 ) ) - plotter->SetSubject( msg ); + plotSequence.push_back( client_layer ); + } } - PlotBoardLayers( board, plotter, plotSequence, m_plotOpts ); - PlotInteractiveLayer( board, plotter, m_plotOpts ); - plotter->EndPlot(); - delete plotter->RenderSettings(); - delete plotter; + wxString layerName = board->GetLayerName( layer ); + //@todo allow controlling the sheet name and path that will be displayed in the title block + // Leave blank for now + wxString sheetName; + wxString sheetPath; - msg.Printf( _( "Plotted to '%s'." ), fn.GetFullPath() ); - reporter.Report( msg, RPT_SEVERITY_ACTION ); + // All copper layers that are disabled are actually selected + // This is due to wonkyness in automatically selecting copper layers + // for plotting when adding more than two layers to a board. + // If plot options become accessible to the layers setup dialog + // please move this functionality there! + // This skips a copper layer if it is actually disabled on the board. + if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] ) + continue; + + // Pick the basename from the board file + wxFileName fn( boardFilename ); + + // Use Gerber Extensions based on layer number + // (See http://en.wikipedia.org/wiki/Gerber_File) + if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && m_useGerberExtensions->GetValue() ) + file_ext = GetGerberProtelExtension( layer ); + + BuildPlotFileName( &fn, outputDir.GetPath(), layerName, file_ext ); + wxString fullname = fn.GetFullName(); + jobfile_writer.AddGbrFile( layer, fullname ); + + LOCALE_IO toggle; + + PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, layerName, fn.GetFullPath(), + sheetName, sheetPath ); + + // Print diags in messages box: + wxString msg; + + if( plotter ) + { + plotter->SetTitle( ExpandTextVars( board->GetTitleBlock().GetTitle(), &textResolver ) ); + + if( m_plotOpts.m_PDFMetadata ) + { + msg = wxS( "AUTHOR" ); + + if( board->ResolveTextVar( &msg, 0 ) ) + plotter->SetAuthor( msg ); + + msg = wxS( "SUBJECT" ); + + if( board->ResolveTextVar( &msg, 0 ) ) + plotter->SetSubject( msg ); + } + + PlotBoardLayers( board, plotter, plotSequence, m_plotOpts ); + PlotInteractiveLayer( board, plotter, m_plotOpts ); + plotter->EndPlot(); + delete plotter->RenderSettings(); + delete plotter; + + msg.Printf( _( "Plotted to '%s'." ), fn.GetFullPath() ); + reporter.Report( msg, RPT_SEVERITY_ACTION ); + } + else + { + msg.Printf( _( "Failed to create file '%s'." ), fn.GetFullPath() ); + reporter.Report( msg, RPT_SEVERITY_ERROR ); + } + + wxSafeYield(); // displays report message. } - else + + if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && m_plotOpts.GetCreateGerberJobFile() ) { - msg.Printf( _( "Failed to create file '%s'." ), fn.GetFullPath() ); - reporter.Report( msg, RPT_SEVERITY_ERROR ); + // Pick the basename from the board file + wxFileName fn( boardFilename ); + + // Build gerber job file from basename + BuildPlotFileName( &fn, outputDir.GetPath(), wxT( "job" ), + FILEEXT::GerberJobFileExtension ); + jobfile_writer.CreateJobFile( fn.GetFullPath() ); } - wxSafeYield(); // displays report message. + reporter.ReportTail( _( "Done." ), RPT_SEVERITY_INFO ); } - - if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && m_plotOpts.GetCreateGerberJobFile() ) - { - // Pick the basename from the board file - wxFileName fn( boardFilename ); - - // Build gerber job file from basename - BuildPlotFileName( &fn, outputDir.GetPath(), wxT( "job" ), - FILEEXT::GerberJobFileExtension ); - jobfile_writer.CreateJobFile( fn.GetFullPath() ); - } - - reporter.ReportTail( _( "Done." ), RPT_SEVERITY_INFO ); } diff --git a/pcbnew/dialogs/dialog_plot.h b/pcbnew/dialogs/dialog_plot.h index d527bb776d..73a6fef510 100644 --- a/pcbnew/dialogs/dialog_plot.h +++ b/pcbnew/dialogs/dialog_plot.h @@ -32,6 +32,7 @@ class wxRearrangeList; class wxBitmapButton; +class JOB_EXPORT_PCB_PLOT; /** * A dialog to set the plot options and create plot files in various formats. @@ -39,11 +40,14 @@ class wxBitmapButton; class DIALOG_PLOT : public DIALOG_PLOT_BASE { public: - DIALOG_PLOT( PCB_EDIT_FRAME* parent ); + DIALOG_PLOT( PCB_EDIT_FRAME* aEditFrame ); + DIALOG_PLOT( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent, + JOB_EXPORT_PCB_PLOT* aJob = nullptr ); virtual ~DIALOG_PLOT(); private: + // Event called functions void Plot( wxCommandEvent& event ) override; void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) override; @@ -69,6 +73,8 @@ private: void applyPlotSettings(); PLOT_FORMAT getPlotFormat(); + void updateJobFromDialog(); + void setPlotModeChoiceSelection( OUTLINE_MODE aPlotMode ) { m_plotModeOpt->SetSelection( aPlotMode == SKETCH ? 1 : 0 ); @@ -77,7 +83,7 @@ private: void arrangeAllLayersList( const LSEQ& aSeq ); private: - PCB_EDIT_FRAME* m_parent; + PCB_EDIT_FRAME* m_editFrame; LSEQ m_layerList; // List to hold CheckListBox layer numbers double m_XScaleAdjust; // X scale factor adjust to compensate // plotter X scaling error @@ -102,6 +108,8 @@ private: STD_BITMAP_BUTTON* m_bpMoveUp; STD_BITMAP_BUTTON* m_bpMoveDown; + JOB_EXPORT_PCB_PLOT* m_job; + /// The plot layer set that last time the dialog was opened. static LSET s_lastLayerSet; static LSET s_lastAllLayersSet; diff --git a/pcbnew/exporters/export_gencad_writer.cpp b/pcbnew/exporters/export_gencad_writer.cpp index 479d3bf5d9..08abdedd6f 100644 --- a/pcbnew/exporters/export_gencad_writer.cpp +++ b/pcbnew/exporters/export_gencad_writer.cpp @@ -153,7 +153,7 @@ double GENCAD_EXPORTER::MapYTo( int aY ) } -bool GENCAD_EXPORTER::WriteFile( wxString& aFullFileName ) +bool GENCAD_EXPORTER::WriteFile( const wxString& aFullFileName ) { componentShapes.clear(); shapeNames.clear(); diff --git a/pcbnew/exporters/export_gencad_writer.h b/pcbnew/exporters/export_gencad_writer.h index 9f8c47dd4a..e104cedfb2 100644 --- a/pcbnew/exporters/export_gencad_writer.h +++ b/pcbnew/exporters/export_gencad_writer.h @@ -39,7 +39,7 @@ public: * @param aFullFileName is the full filenam to create * @return true on success */ - bool WriteFile( wxString& aFullFileName ); + bool WriteFile( const wxString& aFullFileName ); /// Set the coordinates offet when exporting items void SetPlotOffet( VECTOR2I aOffset ) { GencadOffset = aOffset; } diff --git a/pcbnew/exporters/gerber_placefile_writer.cpp b/pcbnew/exporters/gerber_placefile_writer.cpp index e3c472f2ee..bd4e02e3f8 100644 --- a/pcbnew/exporters/gerber_placefile_writer.cpp +++ b/pcbnew/exporters/gerber_placefile_writer.cpp @@ -48,7 +48,7 @@ PLACEFILE_GERBER_WRITER::PLACEFILE_GERBER_WRITER( BOARD* aPcb ) } -int PLACEFILE_GERBER_WRITER::CreatePlaceFile( wxString& aFullFilename, PCB_LAYER_ID aLayer, +int PLACEFILE_GERBER_WRITER::CreatePlaceFile( const wxString& aFullFilename, PCB_LAYER_ID aLayer, bool aIncludeBrdEdges ) { m_layer = aLayer; diff --git a/pcbnew/exporters/gerber_placefile_writer.h b/pcbnew/exporters/gerber_placefile_writer.h index c72ef9675b..7356305fda 100644 --- a/pcbnew/exporters/gerber_placefile_writer.h +++ b/pcbnew/exporters/gerber_placefile_writer.h @@ -66,7 +66,7 @@ public: * @param aIncludeBrdEdges use true to include board outlines. * @return component count, or -1 if the file cannot be created. */ - int CreatePlaceFile( wxString& aFullFilename, PCB_LAYER_ID aLayer, bool aIncludeBrdEdges ); + int CreatePlaceFile( const wxString& aFullFilename, PCB_LAYER_ID aLayer, bool aIncludeBrdEdges ); /** * @param aFullBaseFilename = a full filename. it will be modified diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 548dfc5e57..50b91049ce 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -338,6 +338,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(); @@ -573,3 +575,9 @@ int IFACE::HandleJob( JOB* aJob ) { return m_jobHandler->RunJob( aJob ); } + + +bool IFACE::HandleJobConfig( JOB* aJob, wxWindow* aParent ) +{ + return m_jobHandler->HandleJobConfig( aJob, aParent ); +} diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index 1fb4bf23ec..03b422169d 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -76,6 +76,13 @@ #include <export_vrml.h> #include <wx/wfstream.h> #include <wx/zipstrm.h> +#include <settings/settings_manager.h> +#include <dialogs/dialog_export_svg.h> +#include <dialogs/dialog_gendrill.h> +#include <dialogs/dialog_gen_footprint_position.h> +#include <dialogs/dialog_export_2581.h> +#include <dialogs/dialog_export_step.h> +#include <dialogs/dialog_plot.h> #include "pcbnew_scripting_helpers.h" @@ -88,29 +95,191 @@ PCBNEW_JOBS_HANDLER::PCBNEW_JOBS_HANDLER( KIWAY* aKiway ) : - JOB_DISPATCHER( aKiway ) + JOB_DISPATCHER( aKiway ), + m_cliBoard( nullptr ) { - Register( "3d", std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ) ); - Register( "render", std::bind( &PCBNEW_JOBS_HANDLER::JobExportRender, this, std::placeholders::_1 ) ); - Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ) ); + Register( "3d", std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_3D* svgJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( + aKiway->Player( FRAME_PCB_EDITOR, false ) ); + DIALOG_EXPORT_STEP dlg( editFrame, aParent, "", svgJob ); + dlg.ShowModal(); + + return dlg.GetReturnCode() == wxID_OK; + } ); + Register( "render", + std::bind( &PCBNEW_JOBS_HANDLER::JobExportRender, this, std::placeholders::_1 ), + []( JOB* job, wxWindow* aParent ) -> bool + { + return false; + } ); + Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_SVG* svgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( + aKiway->Player( FRAME_PCB_EDITOR, false ) ); + DIALOG_EXPORT_SVG dlg( svgJob, editFrame, aParent ); + dlg.ShowModal(); + + return dlg.GetReturnCode() == wxID_OK; + } ); Register( "gencad", - std::bind( &PCBNEW_JOBS_HANDLER::JobExportGencad, this, std::placeholders::_1 ) ); - Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ) ); - Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) ); + std::bind( &PCBNEW_JOBS_HANDLER::JobExportGencad, this, std::placeholders::_1 ), + []( JOB* job, wxWindow* aParent ) -> bool + { + return false; + } ); + Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_DXF* dxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( + aKiway->Player( FRAME_PCB_EDITOR, false ) ); + + DIALOG_PLOT dlg( editFrame, aParent, dxfJob ); + dlg.ShowModal(); + + return dlg.GetReturnCode() == wxID_OK; + } ); + Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_PDF* pdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( + aKiway->Player( FRAME_PCB_EDITOR, false ) ); + + DIALOG_PLOT dlg( editFrame, aParent, pdfJob ); + dlg.ShowModal(); + + return dlg.GetReturnCode() == wxID_OK; + } ); Register( "gerber", - std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ) ); + std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_GERBER* gJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( + aKiway->Player( FRAME_PCB_EDITOR, false ) ); + + DIALOG_PLOT dlg( editFrame, aParent, gJob ); + dlg.ShowModal(); + + return dlg.GetReturnCode() == wxID_OK; + } ); Register( "gerbers", - std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ) ); + std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_GERBERS* gJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( + aKiway->Player( FRAME_PCB_EDITOR, false ) ); + + DIALOG_PLOT dlg( editFrame, aParent, gJob ); + dlg.ShowModal(); + + return dlg.GetReturnCode() == wxID_OK; + } ); Register( "drill", - std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ) ); - Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ) ); + std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_DRILL* drillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) ); + DIALOG_GENDRILL dlg( editFrame, drillJob, aParent ); + dlg.ShowModal(); + return dlg.GetReturnCode() == wxID_OK; + } ); + Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_POS* posJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) ); + DIALOG_GEN_FOOTPRINT_POSITION dlg( posJob, editFrame, aParent ); + dlg.ShowModal(); + return dlg.GetReturnCode() == wxID_OK; + } ); Register( "fpupgrade", - std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ) ); + std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ), + []( JOB* job, wxWindow* aParent ) -> bool + { + return false; + } ); Register( "fpsvg", - std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ) ); - Register( "drc", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrc, this, std::placeholders::_1 ) ); + std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ), + []( JOB* job, wxWindow* aParent ) -> bool + { + return false; + } ); + Register( "drc", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrc, this, std::placeholders::_1 ), + []( JOB* job, wxWindow* aParent ) -> bool + { + return false; + } ); Register( "ipc2581", - std::bind( &PCBNEW_JOBS_HANDLER::JobExportIpc2581, this, std::placeholders::_1 ) ); + std::bind( &PCBNEW_JOBS_HANDLER::JobExportIpc2581, this, std::placeholders::_1 ), + [aKiway]( JOB* job, wxWindow* aParent ) -> bool + { + JOB_EXPORT_PCB_IPC2581* ipcJob = dynamic_cast<JOB_EXPORT_PCB_IPC2581*>( job ); + + PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) ); + + DIALOG_EXPORT_2581 dlg( ipcJob, editFrame, aParent ); + dlg.ShowModal(); + + return dlg.GetReturnCode() == wxID_OK; + } ); +} + + +BOARD* PCBNEW_JOBS_HANDLER::getBoard( const wxString& aPath ) +{ + BOARD* brd = nullptr; + + if( !Pgm().IsGUI() && + Pgm().GetSettingsManager().IsProjectOpen() ) + { + PROJECT& project = Pgm().GetSettingsManager().Prj(); + + wxString pcbPath = aPath; + if( pcbPath.IsEmpty() ) + { + wxFileName path = project.GetProjectFullName(); + path.SetExt( FILEEXT::KiCadPcbFileExtension ); + path.MakeAbsolute(); + pcbPath = path.GetFullPath(); + } + + if( !m_cliBoard ) + { + m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + m_cliBoard = LoadBoard( pcbPath, true, &project ); + } + + brd = m_cliBoard; + } + else + { + m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + brd = LoadBoard( aPath, true, &Pgm().GetSettingsManager().Prj() ); + } + + if ( !brd ) + { + m_reporter->Report( _( "Failed to load board\n" ), RPT_SEVERITY_ERROR ); + } + + return brd; } @@ -121,14 +290,15 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) if( aStepJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aStepJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( aStepJob->m_filename, true ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); - if( aStepJob->m_3dparams.m_OutputFile.IsEmpty() ) + if( aStepJob->GetOutputPath().IsEmpty() ) { wxFileName fn = brd->GetFileName(); fn.SetName( fn.GetName() ); @@ -149,7 +319,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here } - aStepJob->m_3dparams.m_OutputFile = fn.GetFullName(); + aStepJob->SetOutputPath( fn.GetFullName() ); } if( aStepJob->m_format == JOB_EXPORT_PCB_3D::FORMAT::VRML ) @@ -178,7 +348,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) } bool success = vrmlExporter.ExportVRML_File( - brd->GetProject(), &messages, aStepJob->m_3dparams.m_OutputFile, scale, + brd->GetProject(), &messages, aStepJob->GetFullOutputPath(), scale, aStepJob->m_3dparams.m_IncludeUnspecified, aStepJob->m_3dparams.m_IncludeDNP, !aStepJob->m_vrmlModelDir.IsEmpty(), aStepJob->m_vrmlRelativePaths, aStepJob->m_vrmlModelDir, originX, originY ); @@ -186,7 +356,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) if ( success ) { m_reporter->Report( wxString::Format( _( "Successfully exported VRML to %s" ), - aStepJob->m_3dparams.m_OutputFile ), + aStepJob->GetFullOutputPath() ), RPT_SEVERITY_INFO ); } else @@ -218,7 +388,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) } EXPORTER_STEP stepExporter( brd, params ); - stepExporter.m_outputFile = params.m_OutputFile; + stepExporter.m_outputFile = aStepJob->GetFullOutputPath(); if( !stepExporter.Export() ) return CLI::EXIT_CODES::ERR_UNKNOWN; @@ -235,10 +405,11 @@ int PCBNEW_JOBS_HANDLER::JobExportRender( JOB* aJob ) if( aRenderJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aRenderJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( aRenderJob->m_filename, true ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); @@ -419,7 +590,7 @@ int PCBNEW_JOBS_HANDLER::JobExportSvg( JOB* aJob ) PCB_PLOT_SVG_OPTIONS svgPlotOptions; svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite; svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme; - svgPlotOptions.m_outputFile = aSvgJob->m_outputFile; + svgPlotOptions.m_outputFile = aSvgJob->GetFullOutputPath(); svgPlotOptions.m_mirror = aSvgJob->m_mirror; svgPlotOptions.m_negative = aSvgJob->m_negative; svgPlotOptions.m_pageSizeMode = aSvgJob->m_pageSizeMode; @@ -431,10 +602,11 @@ int PCBNEW_JOBS_HANDLER::JobExportSvg( JOB* aJob ) svgPlotOptions.m_crossoutDNPFPsOnFabLayers = aSvgJob->m_crossoutDNPFPsOnFabLayers; svgPlotOptions.m_drillShapeOption = aSvgJob->m_drillShapeOption; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aSvgJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( aSvgJob->m_filename, true ); loadOverrideDrawingSheet( brd, aSvgJob->m_drawingSheet ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); @@ -458,21 +630,22 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob ) if( aDxfJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aDxfJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( aDxfJob->m_filename, true ); loadOverrideDrawingSheet( brd, aDxfJob->m_drawingSheet ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); - if( aDxfJob->m_outputFile.IsEmpty() ) + if( aDxfJob->GetOutputPath().IsEmpty() ) { wxFileName fn = brd->GetFileName(); fn.SetName( fn.GetName() ); fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) ); - aDxfJob->m_outputFile = fn.GetFullName(); + aDxfJob->SetOutputPath( fn.GetFullName() ); } PCB_PLOT_PARAMS plotOpts; @@ -486,7 +659,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob ) else plotOpts.SetDXFPlotUnits( DXF_UNITS::INCHES ); - plotOpts.SetPlotFrameRef( aDxfJob->m_plotBorderTitleBlocks ); + plotOpts.SetPlotFrameRef( aDxfJob->m_plotDrawingSheet ); plotOpts.SetPlotValue( aDxfJob->m_plotFootprintValues ); plotOpts.SetPlotReference( aDxfJob->m_plotRefDes ); plotOpts.SetLayerSelection( aDxfJob->m_printMaskLayer ); @@ -511,8 +684,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob ) if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) ) sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) ); - DXF_PLOTTER* plotter = (DXF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, - aDxfJob->m_outputFile, sheetName, + DXF_PLOTTER* plotter = (DXF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, aDxfJob->GetFullOutputPath(), sheetName, sheetPath ); if( plotter ) @@ -534,27 +706,28 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob ) if( aPdfJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aPdfJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( aPdfJob->m_filename, true ); loadOverrideDrawingSheet( brd, aPdfJob->m_drawingSheet ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); - if( aPdfJob->m_outputFile.IsEmpty() ) + if( aPdfJob->OutputPathFullSpecified() ) { wxFileName fn = brd->GetFileName(); fn.SetName( fn.GetName() ); fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) ); - aPdfJob->m_outputFile = fn.GetFullName(); + aPdfJob->SetOutputPath( fn.GetFullName() ); } PCB_PLOT_PARAMS plotOpts; plotOpts.SetFormat( PLOT_FORMAT::PDF ); - plotOpts.SetPlotFrameRef( aPdfJob->m_plotBorderTitleBlocks ); + plotOpts.SetPlotFrameRef( aPdfJob->m_plotDrawingSheet ); plotOpts.SetPlotValue( aPdfJob->m_plotFootprintValues ); plotOpts.SetPlotReference( aPdfJob->m_plotRefDes ); @@ -604,8 +777,7 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob ) if( aPdfJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) ) sheetPath = aPdfJob->GetVarOverrides().at( wxT( "SHEETPATH" ) ); - PDF_PLOTTER* plotter = (PDF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, - aPdfJob->m_outputFile, sheetName, + PDF_PLOTTER* plotter = (PDF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, aPdfJob->GetFullOutputPath(), sheetName, sheetPath ); if( plotter ) @@ -629,10 +801,11 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) if( aGerberJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aGerberJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( aGerberJob->m_filename, true ); loadOverrideDrawingSheet( brd, aGerberJob->m_drawingSheet ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); @@ -701,7 +874,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) else fileExt = FILEEXT::GerberFileExtension; - BuildPlotFileName( &fn, aGerberJob->m_outputFile, layerName, fileExt ); + BuildPlotFileName( &fn, aGerberJob->GetFullOutputPath(), layerName, fileExt ); wxString fullname = fn.GetFullName(); jobfile_writer.AddGbrFile( layer, fullname ); @@ -741,7 +914,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) wxFileName fn( aGerberJob->m_filename ); // Build gerber job file from basename - BuildPlotFileName( &fn, aGerberJob->m_outputFile, wxT( "job" ), + BuildPlotFileName( &fn, aGerberJob->GetFullOutputPath(), wxT( "job" ), FILEEXT::GerberJobFileExtension ); jobfile_writer.CreateJobFile( fn.GetFullPath() ); @@ -773,23 +946,19 @@ int PCBNEW_JOBS_HANDLER::JobExportGencad( JOB* aJob ) exporter.SetPlotOffet( GencadOffset ); exporter.StoreOriginCoordsInFile( aGencadJob->m_storeOriginCoords ); - m_reporter->Report( aGencadJob->m_outputFile, RPT_SEVERITY_ERROR ); - - wxString outputFile = aGencadJob->m_outputFile; - - if( outputFile.IsEmpty() ) + if( aGencadJob->GetOutputPath().IsEmpty() ) { wxFileName fn = aBoard->GetFileName(); fn.SetName( fn.GetName() ); - fn.SetExt( wxS( "cad" ) ); + fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) ); - outputFile = fn.GetFullName(); + aGencadJob->SetOutputPath( fn.GetFullName() ); } - if( !exporter.WriteFile( outputFile ) ) + if( !exporter.WriteFile( aGencadJob->GetFullOutputPath() ) ) { wxString msg; - msg.Printf( _( "Failed to create file '%s'.\n" ), outputFile ); + msg.Printf( _( "Failed to create file '%s'.\n" ), aGencadJob->GetFullOutputPath() ); if( aJob->IsCli() ) m_reporter->Report( msg, RPT_SEVERITY_ERROR ); @@ -809,7 +978,7 @@ void PCBNEW_JOBS_HANDLER::populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPl { aPlotOpts.SetFormat( PLOT_FORMAT::GERBER ); - aPlotOpts.SetPlotFrameRef( aJob->m_plotBorderTitleBlocks ); + aPlotOpts.SetPlotFrameRef( aJob->m_plotDrawingSheet ); aPlotOpts.SetPlotValue( aJob->m_plotFootprintValues ); aPlotOpts.SetPlotReference( aJob->m_plotRefDes ); @@ -835,20 +1004,21 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) if( aGerberJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aGerberJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( aGerberJob->m_filename, true ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); - if( aGerberJob->m_outputFile.IsEmpty() ) + if( aGerberJob->GetOutputPath().IsEmpty() ) { wxFileName fn = brd->GetFileName(); fn.SetName( fn.GetName() ); fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::GERBER ) ); - aGerberJob->m_outputFile = fn.GetFullName(); + aGerberJob->SetOutputPath( fn.GetFullName() ); } PCB_PLOT_PARAMS plotOpts; @@ -877,7 +1047,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) // We are feeding it one layer at the start here to silence a logic check GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, - aGerberJob->m_outputFile, + aGerberJob->GetFullOutputPath(), sheetName, sheetPath ); if( plotter ) @@ -888,7 +1058,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) else { m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ), - aGerberJob->m_outputFile ), + aGerberJob->GetFullOutputPath() ), RPT_SEVERITY_ERROR ); exitCode = CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; } @@ -909,13 +1079,13 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob ) if( aDrillJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aDrillJob->m_filename ); - BOARD* brd = LoadBoard( aDrillJob->m_filename, true ); + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; // ensure output dir exists - wxFileName fn( aDrillJob->m_outputDir + wxT( "/" ) ); + wxFileName fn( aDrillJob->GetFullOutputPath() + wxT( "/" ) ); if( !fn.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) ) { @@ -990,7 +1160,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob ) excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute ); excellonWriter->SetMapFileFormat( mapFormat ); - if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, + if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->GetFullOutputPath(), true, aDrillJob->m_generateMap, m_reporter ) ) { return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; @@ -1010,7 +1180,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob ) gerberWriter->SetOptions( offset ); gerberWriter->SetMapFileFormat( mapFormat ); - if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, + if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->GetFullOutputPath(), true, aDrillJob->m_generateMap, m_reporter ) ) { return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; @@ -1028,12 +1198,14 @@ int PCBNEW_JOBS_HANDLER::JobExportPos( JOB* aJob ) if( aPosJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( aPosJob->m_filename ); - BOARD* brd = LoadBoard( aPosJob->m_filename, true ); + if( !brd ) + { + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; + } - if( aPosJob->m_outputFile.IsEmpty() ) + if( aPosJob->GetOutputPath().IsEmpty() ) { wxFileName fn = brd->GetFileName(); fn.SetName( fn.GetName() ); @@ -1045,14 +1217,14 @@ int PCBNEW_JOBS_HANDLER::JobExportPos( JOB* aJob ) else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER ) fn.SetExt( FILEEXT::GerberFileExtension ); - aPosJob->m_outputFile = fn.GetFullName(); + aPosJob->SetOutputPath( fn.GetFullName() ); } if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::ASCII || aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::CSV ) { FILE* file = nullptr; - file = wxFopen( aPosJob->m_outputFile, wxS( "wt" ) ); + file = wxFopen( aPosJob->GetFullOutputPath(), wxS( "wt" ) ); if( file == nullptr ) return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; @@ -1077,6 +1249,8 @@ int PCBNEW_JOBS_HANDLER::JobExportPos( JOB* aJob ) fputs( data.c_str(), file ); fclose( file ); + + aPosJob->AddOutput( aPosJob->GetFullOutputPath() ); } else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER ) { @@ -1087,7 +1261,15 @@ int PCBNEW_JOBS_HANDLER::JobExportPos( JOB* aJob ) if( aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK ) gbrLayer = B_Cu; - exporter.CreatePlaceFile( aPosJob->m_outputFile, gbrLayer, aPosJob->m_gerberBoardEdge ); + if( exporter.CreatePlaceFile( aPosJob->GetFullOutputPath(), gbrLayer, aPosJob->m_gerberBoardEdge ) + >= 0 ) + { + aPosJob->AddOutput( aPosJob->GetFullOutputPath() ); + } + else + { + return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } } return CLI::EXIT_CODES::OK; @@ -1332,10 +1514,11 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob ) if( drcJob == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( aJob->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( drcJob->m_filename ); + + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - BOARD* brd = LoadBoard( drcJob->m_filename, true ); brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); brd->SynchronizeProperties(); @@ -1500,18 +1683,18 @@ int PCBNEW_JOBS_HANDLER::JobExportIpc2581( JOB* aJob ) if( job == nullptr ) return CLI::EXIT_CODES::ERR_UNKNOWN; - if( job->IsCli() ) - m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); + BOARD* brd = getBoard( job->m_filename ); - BOARD* brd = LoadBoard( job->m_filename, true ); + if( !brd ) + return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE; - if( job->m_outputFile.IsEmpty() ) + if( job->OutputPathFullSpecified() ) { wxFileName fn = brd->GetFileName(); fn.SetName( fn.GetName() ); fn.SetExt( FILEEXT::Ipc2581FileExtension ); - job->m_outputFile = fn.GetFullName(); + job->SetOutputPath( fn.GetName() ); } std::map<std::string, UTF8> props; @@ -1545,7 +1728,7 @@ int PCBNEW_JOBS_HANDLER::JobExportIpc2581( JOB* aJob ) if( job->m_compress ) { - wxFileName tempfn = job->m_outputFile; + wxFileName tempfn = job->GetFullOutputPath(); tempfn.SetExt( FILEEXT::Ipc2581FileExtension ); wxFileName zipfn = tempFile; zipfn.SetExt( "zip" ); @@ -1564,12 +1747,12 @@ int PCBNEW_JOBS_HANDLER::JobExportIpc2581( JOB* aJob ) } // If save succeeded, replace the original with what we just wrote - if( !wxRenameFile( tempFile, job->m_outputFile ) ) + if( !wxRenameFile( tempFile, job->GetFullOutputPath() ) ) { m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n" "Failed to rename temporary file '%s." ) + wxS( "\n" ), - job->m_outputFile, tempFile ), + job->GetFullOutputPath(), tempFile ), RPT_SEVERITY_ERROR ); } diff --git a/pcbnew/pcbnew_jobs_handler.h b/pcbnew/pcbnew_jobs_handler.h index 7d1bfa2a0b..31b4773515 100644 --- a/pcbnew/pcbnew_jobs_handler.h +++ b/pcbnew/pcbnew_jobs_handler.h @@ -51,12 +51,15 @@ public: int JobExportIpc2581( JOB* aJob ); private: + BOARD* getBoard( const wxString& aPath = wxEmptyString ); void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts, JOB_EXPORT_PCB_GERBER* aJob ); int doFpExportSvg( JOB_FP_EXPORT_SVG* aSvgJob, const FOOTPRINT* aFootprint ); void loadOverrideDrawingSheet( BOARD* brd, const wxString& aSheetPath ); DS_PROXY_VIEW_ITEM* getDrawingSheetProxyView( BOARD* aBrd ); + + BOARD* m_cliBoard; }; #endif \ No newline at end of file diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp index 221f7a307f..e712e4d9fa 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp @@ -87,19 +87,19 @@ void ScriptingOnDestructPcbEditFrame( PCB_EDIT_FRAME* aPcbEditFrame ) } -BOARD* LoadBoard( wxString& aFileName, bool aSetActive ) +BOARD* LoadBoard( const wxString& aFileName, bool aSetActive, PROJECT* aProject ) { if( aFileName.EndsWith( FILEEXT::KiCadPcbFileExtension ) ) - return LoadBoard( aFileName, PCB_IO_MGR::KICAD_SEXP, aSetActive ); + return LoadBoard( aFileName, PCB_IO_MGR::KICAD_SEXP, aSetActive, aProject ); else if( aFileName.EndsWith( FILEEXT::LegacyPcbFileExtension ) ) - return LoadBoard( aFileName, PCB_IO_MGR::LEGACY, aSetActive ); + return LoadBoard( aFileName, PCB_IO_MGR::LEGACY, aSetActive, aProject ); // as fall back for any other kind use the legacy format - return LoadBoard( aFileName, PCB_IO_MGR::LEGACY, aSetActive ); + return LoadBoard( aFileName, PCB_IO_MGR::LEGACY, aSetActive, aProject ); } -BOARD* LoadBoard( wxString& aFileName ) +BOARD* LoadBoard( const wxString& aFileName ) { return LoadBoard( aFileName, false ); } @@ -142,12 +142,13 @@ PROJECT* GetDefaultProject() return project; } -BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat ) +BOARD* LoadBoard( const wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat ) { return LoadBoard( aFileName, aFormat, false ); } -BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, bool aSetActive ) +BOARD* LoadBoard( const wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, bool aSetActive, + PROJECT* aProject ) { wxFileName pro = aFileName; pro.SetExt( FILEEXT::ProjectFileExtension ); @@ -158,7 +159,12 @@ BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, bool aSet // 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 ) + { + GetSettingsManager()->GetProject( projectPath ); + } if( !project ) { @@ -181,7 +187,15 @@ BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, bool aSet BASE_SCREEN::m_DrawingSheetFileName = project->GetProjectFile().m_BoardDrawingSheetFile; - BOARD* brd = PCB_IO_MGR::Load( aFormat, aFileName ); + BOARD* brd = nullptr; + try + { + brd = PCB_IO_MGR::Load( aFormat, aFileName ); + } + catch( ... ) + { + brd = nullptr; + } if( brd ) { diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.h b/pcbnew/python/scripting/pcbnew_scripting_helpers.h index 76f47d1267..7f72a5ebac 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.h +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.h @@ -55,7 +55,7 @@ BOARD* GetBoard(); * This function does not set the board project as the active one * @return a pointer to the board if it was created, or None if not */ -BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat ); +BOARD* LoadBoard( const wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat ); #ifndef SWIG /** @@ -63,7 +63,7 @@ BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat ); * * Hidden from SWIG as aSetActive should not be used by python, but cli also leverages this function */ -BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, bool aSetActive ); +BOARD* LoadBoard( const wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, bool aSetActive, PROJECT* aProject = nullptr ); #endif // Default LoadBoard() to load .kicad_pcb files:. @@ -75,7 +75,7 @@ BOARD* LoadBoard( wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, bool aSet * * Hidden from SWIG as aSetActive should not be used by python, but cli also leverages this function */ -BOARD* LoadBoard( wxString& aFileName, bool aSetActive ); +BOARD* LoadBoard( const wxString& aFileName, bool aSetActive, PROJECT* aProject = nullptr ); #endif /** @@ -85,7 +85,7 @@ BOARD* LoadBoard( wxString& aFileName, bool aSetActive ); * This function does not set the board project as the active one * @return a pointer to the board if it was created, or None if not */ -BOARD* LoadBoard( wxString& aFileName ); +BOARD* LoadBoard( const wxString& aFileName ); /** * Creates a new board and project with the given filename (will overwrite existing files!) diff --git a/pcbnew/tools/board_editor_control.cpp b/pcbnew/tools/board_editor_control.cpp index 36a63de0bd..3d0e9b4b78 100644 --- a/pcbnew/tools/board_editor_control.cpp +++ b/pcbnew/tools/board_editor_control.cpp @@ -430,7 +430,7 @@ int BOARD_EDITOR_CONTROL::ExportSpecctraDSN( const TOOL_EVENT& aEvent ) int BOARD_EDITOR_CONTROL::ExportNetlist( const TOOL_EVENT& aEvent ) { wxCHECK( m_frame, 0 ); - + wxFileName fn = m_frame->Prj().GetProjectFullName(); // Use a different file extension for the board netlist so the schematic netlist file diff --git a/qa/tests/CMakeLists.txt b/qa/tests/CMakeLists.txt index a8b68afd18..05424f1937 100644 --- a/qa/tests/CMakeLists.txt +++ b/qa/tests/CMakeLists.txt @@ -41,6 +41,7 @@ endif() set( NEW_PATHS "${CMAKE_BINARY_DIR}/kicad/;\ ${CMAKE_BINARY_DIR}/common/;\ +${CMAKE_BINARY_DIR}/api/;\ ${CMAKE_BINARY_DIR}/common/gal/;\ ${CMAKE_BINARY_DIR}/pcbnew/;\ ${CMAKE_BINARY_DIR}/eeschema/;\ @@ -55,6 +56,16 @@ if( APPLE ) ${NEW_PATHS};" ) get_filename_component( CAIRO_LIB_BASE "${CAIRO_LIBRARY}" DIRECTORY ) set( EXTRA_PYTEST_ENVIRONMENT "DYLD_FALLBACK_LIBRARY_PATH=${CAIRO_LIB_BASE}" ) +elseif ( MSVC ) + if( CMAKE_BUILD_TYPE STREQUAL "Debug" ) + set( NEW_PATHS + "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/bin;\ + ${NEW_PATHS};" ) + else() + set( NEW_PATHS + "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin;\ + ${NEW_PATHS};" ) + endif() endif() set( QA_PATH_REPLACEMENT "PATH=${NEW_PATHS};$ENV{PATH}" ) diff --git a/qa/tests/cli/test_sch.py b/qa/tests/cli/test_sch.py index a126cf1252..1553b48824 100644 --- a/qa/tests/cli/test_sch.py +++ b/qa/tests/cli/test_sch.py @@ -53,7 +53,7 @@ def test_sch_export_svg( kitest, assert stderr == '' assert stdout is not None - stdout_regex = re.match("^Plotted to '(.+)'", stdout) + stdout_regex = re.search("Plotted to '(.+)'", stdout) assert stdout_regex # now try and manipulate the extracted path diff --git a/resources/schemas/jobs.v1.json b/resources/schemas/jobs.v1.json new file mode 100644 index 0000000000..c31b40a87f --- /dev/null +++ b/resources/schemas/jobs.v1.json @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.kicad.org/jobs.v1.json", + "title": "KiCad Jobs Schema", + "description": "KiCad Jobs", + "type": "object", + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "description": "JSON schema reference" + }, + "meta": { + "type": "object", + "$ref": "#/definitions/Meta" + }, + "jobs": { + "type": "array", + "items": { + "$ref": "#/definitions/Job" + } + }, + }, + "required": [ + "meta", + "jobs" + ], + "definitions": { + "Job": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "description": "Job type", + "enum": ["pcb_drill"] + }, + "meta": { + "type": "object", + "$ref": "#/definitions/Meta" + }, + "settings": { + "type": "object" + }, + }, + "required": [ + "meta", + "type", + "settings" + ] + }, + "Meta": { + "type": "object", + "additionalProperties": false, + "properties": { + "version": { + "type": "integer", + "description": "File format version" + } + }, + "required": [ + "version" + ] + }, + } +} \ No newline at end of file