New kicad-cli will now be the cli interface
This commit is contained in:
parent
85623656a6
commit
3fe004fd1b
|
@ -287,9 +287,9 @@ set( COMMON_SRCS
|
|||
${PLUGINS_CADSTAR_SRCS}
|
||||
${PLUGINS_EAGLE_SRCS}
|
||||
${FONT_SRCS}
|
||||
cli/command_export_kicad_pcbnew.cpp
|
||||
cli/command_export_pcb_svg.cpp
|
||||
cli/command_export_pcbnew.cpp
|
||||
cli/command_pcb.cpp
|
||||
cli/command_pcb_export.cpp
|
||||
cli/command_export_step.cpp
|
||||
jobs/job_export_step.cpp
|
||||
jobs/job_dispatcher.cpp
|
||||
|
|
|
@ -18,13 +18,15 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "command_export_pcbnew.h"
|
||||
#include "command_pcb.h"
|
||||
|
||||
CLI::EXPORT_PCBNEW_COMMAND::EXPORT_PCBNEW_COMMAND() : COMMAND( "export" )
|
||||
CLI::PCB_COMMAND::PCB_COMMAND() : COMMAND( "pcb" )
|
||||
{
|
||||
}
|
||||
|
||||
int CLI::EXPORT_PCBNEW_COMMAND::Perform( KIWAY& aKiway ) const
|
||||
int CLI::PCB_COMMAND::Perform( KIWAY& aKiway ) const
|
||||
{
|
||||
return 0;
|
||||
std::cout << m_argParser;
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
namespace CLI
|
||||
{
|
||||
struct EXPORT_PCBNEW_COMMAND : public COMMAND
|
||||
struct PCB_COMMAND : public COMMAND
|
||||
{
|
||||
EXPORT_PCBNEW_COMMAND();
|
||||
PCB_COMMAND();
|
||||
|
||||
int Perform( KIWAY& aKiway ) const override;
|
||||
};
|
|
@ -18,14 +18,16 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "command_export_kicad_pcbnew.h"
|
||||
#include "command_pcb_export.h"
|
||||
|
||||
CLI::EXPORT_KICAD_PCBNEW_COMMAND::EXPORT_KICAD_PCBNEW_COMMAND() : COMMAND( "export-pcb" )
|
||||
CLI::EXPORT_PCB_COMMAND::EXPORT_PCB_COMMAND() : COMMAND( "export" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int CLI::EXPORT_KICAD_PCBNEW_COMMAND::Perform( KIWAY& aKiway ) const
|
||||
int CLI::EXPORT_PCB_COMMAND::Perform( KIWAY& aKiway ) const
|
||||
{
|
||||
return 0;
|
||||
std::cout << m_argParser;
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
namespace CLI
|
||||
{
|
||||
struct EXPORT_KICAD_PCBNEW_COMMAND : public COMMAND
|
||||
struct EXPORT_PCB_COMMAND : public COMMAND
|
||||
{
|
||||
EXPORT_KICAD_PCBNEW_COMMAND();
|
||||
EXPORT_PCB_COMMAND();
|
||||
|
||||
int Perform( KIWAY& aKiway ) const override;
|
||||
};
|
|
@ -506,8 +506,11 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit )
|
|||
|
||||
// This sets the maximum tooltip display duration to 10s (up from 5) but only affects
|
||||
// Windows as other platforms display tooltips while the mouse is not moving
|
||||
wxToolTip::Enable( true );
|
||||
wxToolTip::SetAutoPop( 10000 );
|
||||
if( !aHeadless )
|
||||
{
|
||||
wxToolTip::Enable( true );
|
||||
wxToolTip::SetAutoPop( 10000 );
|
||||
}
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval != 0 )
|
||||
wxUpdateUIEvent::SetUpdateInterval( ADVANCED_CFG::GetCfg().m_UpdateUIEventInterval );
|
||||
|
|
|
@ -483,7 +483,7 @@ bool SETTINGS_MANAGER::MigrateIfNeeded()
|
|||
if( m_headless )
|
||||
{
|
||||
wxLogTrace( traceSettings, wxT( "Settings migration not checked; running headless" ) );
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
wxFileName path( GetUserSettingsPath(), "" );
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <wx/stdpaths.h>
|
||||
#include <wx/snglinst.h>
|
||||
#include <wx/html/htmlwin.h>
|
||||
#include <argparse/argparse.hpp>
|
||||
|
||||
#include <kiway.h>
|
||||
#include <pgm_base.h>
|
||||
|
@ -49,14 +48,9 @@
|
|||
#include <confirm.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
#include <kicad_build_version.h>
|
||||
#include <kiplatform/app.h>
|
||||
#include <kiplatform/environment.h>
|
||||
|
||||
#include "cli/command_export_pcbnew.h"
|
||||
#include "cli/command_export_pcb_svg.h"
|
||||
#include "cli/command_export_step.h"
|
||||
#include "cli/exit_codes.h"
|
||||
|
||||
// Only a single KIWAY is supported in this single_top top level component,
|
||||
// which is dedicated to loading only a single DSO.
|
||||
|
@ -280,36 +274,8 @@ struct APP_SINGLE_TOP : public wxApp
|
|||
IMPLEMENT_APP( APP_SINGLE_TOP )
|
||||
|
||||
|
||||
|
||||
struct COMMAND_ENTRY
|
||||
{
|
||||
CLI::COMMAND* handler;
|
||||
|
||||
std::vector<COMMAND_ENTRY> subCommands;
|
||||
|
||||
COMMAND_ENTRY( CLI::COMMAND* aHandler ) : handler( aHandler ){};
|
||||
COMMAND_ENTRY( CLI::COMMAND* aHandler, std::vector<COMMAND_ENTRY> aSub ) :
|
||||
handler( aHandler ), subCommands( aSub ) {};
|
||||
};
|
||||
|
||||
#ifdef PCBNEW
|
||||
static CLI::EXPORT_STEP_COMMAND stepCmd{};
|
||||
static CLI::EXPORT_PCB_SVG_COMMAND svgCmd{};
|
||||
static CLI::EXPORT_PCBNEW_COMMAND exportCmd{};
|
||||
|
||||
static std::vector<COMMAND_ENTRY> commandStack = {
|
||||
{ &exportCmd, { &stepCmd, &svgCmd } }
|
||||
};
|
||||
#else
|
||||
|
||||
static std::vector<COMMAND_ENTRY> commandStack = {
|
||||
};
|
||||
#endif
|
||||
|
||||
bool PGM_SINGLE_TOP::OnPgmInit()
|
||||
{
|
||||
PGM_BASE::BuildArgvUtf8();
|
||||
|
||||
#if defined(DEBUG)
|
||||
wxString absoluteArgv0 = wxStandardPaths::Get().GetExecutablePath();
|
||||
|
||||
|
@ -319,60 +285,10 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
wxString pgm_name;
|
||||
if( App().argc == 0 )
|
||||
pgm_name = wxT( "kicad" );
|
||||
else
|
||||
pgm_name = wxFileName( App().argv[0] ).GetName().Lower();
|
||||
|
||||
argparse::ArgumentParser argParser( std::string( pgm_name.utf8_str() ), KICAD_MAJOR_MINOR_VERSION );
|
||||
|
||||
for(COMMAND_ENTRY& entry : commandStack)
|
||||
{
|
||||
argParser.add_subparser( entry.handler->GetArgParser() );
|
||||
|
||||
for( COMMAND_ENTRY& subentry : entry.subCommands )
|
||||
{
|
||||
entry.handler->GetArgParser().add_subparser( subentry.handler->GetArgParser() );
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
argParser.parse_args( m_argcUtf8, m_argvUtf8 );
|
||||
}
|
||||
catch( const std::runtime_error& )
|
||||
{
|
||||
// Ignore any argParser "errors"
|
||||
// unforunately there are cases like the only arg being a file (double click open)
|
||||
// that we need to fall through
|
||||
}
|
||||
|
||||
bool cliCmdRequested = false;
|
||||
CLI::COMMAND* cliCmd = nullptr;
|
||||
for( COMMAND_ENTRY& entry : commandStack )
|
||||
{
|
||||
if( argParser.is_subcommand_used( entry.handler->GetName() ) )
|
||||
{
|
||||
for( COMMAND_ENTRY& subentry : entry.subCommands )
|
||||
{
|
||||
if( entry.handler->GetArgParser().is_subcommand_used( subentry.handler->GetName() ) )
|
||||
{
|
||||
cliCmd = subentry.handler;
|
||||
cliCmdRequested = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !cliCmdRequested )
|
||||
{
|
||||
cliCmd = entry.handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not all kicad applications use the python stuff. skip python init
|
||||
// for these apps.
|
||||
bool skip_python_initialization = cliCmdRequested;
|
||||
bool skip_python_initialization = false;
|
||||
#if defined( BITMAP_2_CMP ) || defined( PL_EDITOR ) || defined( GERBVIEW ) ||\
|
||||
defined( PCB_CALCULATOR_BUILD )
|
||||
skip_python_initialization = true;
|
||||
|
@ -404,33 +320,13 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
|||
Kiway.set_kiface( KIWAY::KifaceType( TOP_FRAME ), kiface );
|
||||
#endif
|
||||
|
||||
FRAME_T appType = TOP_FRAME;
|
||||
|
||||
// Tell the settings manager about the current Kiway
|
||||
GetSettingsManager().SetKiway( &Kiway );
|
||||
|
||||
if( cliCmdRequested )
|
||||
{
|
||||
int exitCode = CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
if( cliCmd )
|
||||
{
|
||||
exitCode = cliCmd->Perform( Kiway );
|
||||
}
|
||||
|
||||
if( exitCode != CLI::EXIT_CODES::AVOID_CLOSING )
|
||||
{
|
||||
std::exit( exitCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Use KIWAY to create a top window, which registers its existence also.
|
||||
// "TOP_FRAME" is a macro that is passed on compiler command line from CMake,
|
||||
// and is one of the types in FRAME_T.
|
||||
KIWAY_PLAYER* frame = Kiway.Player( appType, true );
|
||||
KIWAY_PLAYER* frame = Kiway.Player( TOP_FRAME, true );
|
||||
|
||||
if( frame == nullptr )
|
||||
{
|
||||
|
@ -453,7 +349,17 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
|||
// Now after the frame processing, the rest of the positional args are files
|
||||
std::vector<wxString> fileArgs;
|
||||
|
||||
if( App().argc > 1 )
|
||||
|
||||
static const wxCmdLineEntryDesc desc[] = {
|
||||
{ wxCMD_LINE_PARAM, nullptr, nullptr, "File to load", wxCMD_LINE_VAL_STRING,
|
||||
wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL },
|
||||
{ wxCMD_LINE_NONE, nullptr, nullptr, nullptr, wxCMD_LINE_VAL_NONE, 0 }
|
||||
};
|
||||
|
||||
wxCmdLineParser parser( App().argc, App().argv );
|
||||
parser.SetDesc( desc );
|
||||
parser.Parse( false );
|
||||
if( parser.GetParamCount() )
|
||||
{
|
||||
/*
|
||||
gerbview handles multiple project data files, i.e. gerber files on
|
||||
|
@ -464,15 +370,15 @@ bool PGM_SINGLE_TOP::OnPgmInit()
|
|||
launcher.
|
||||
*/
|
||||
|
||||
for( int i = 1; i < App().argc; i++ )
|
||||
fileArgs.push_back( App().argv[i] );
|
||||
for( size_t i = 0; i < parser.GetParamCount(); i++ )
|
||||
fileArgs.push_back( parser.GetParam( i ) );
|
||||
|
||||
// special attention to a single argument: argv[1] (==argSet[0])
|
||||
if( fileArgs.size() == 1 )
|
||||
{
|
||||
wxFileName argv1( fileArgs[0] );
|
||||
|
||||
#if defined( PGM_DATA_FILE_EXT )
|
||||
#if defined(PGM_DATA_FILE_EXT)
|
||||
// PGM_DATA_FILE_EXT, if present, may be different for each compile,
|
||||
// it may come from CMake on the compiler command line, but often does not.
|
||||
// This facility is mostly useful for those program footprints
|
||||
|
|
|
@ -23,7 +23,6 @@ set( KICAD_SRCS
|
|||
files-io.cpp
|
||||
import_proj.cpp
|
||||
import_project.cpp
|
||||
kicad.cpp
|
||||
kicad_manager_frame.cpp
|
||||
menubar.cpp
|
||||
project_template.cpp
|
||||
|
@ -57,11 +56,29 @@ if( APPLE )
|
|||
endif()
|
||||
|
||||
add_executable( kicad WIN32 MACOSX_BUNDLE
|
||||
kicad.cpp
|
||||
${KICAD_SRCS}
|
||||
${KICAD_EXTRA_SRCS}
|
||||
${KICAD_RESOURCES}
|
||||
)
|
||||
|
||||
add_executable( kicad-cli WIN32 MACOSX_BUNDLE
|
||||
kicad_cli.cpp
|
||||
${KICAD_SRCS}
|
||||
${KICAD_EXTRA_SRCS}
|
||||
${KICAD_RESOURCES}
|
||||
)
|
||||
|
||||
if( MSVC )
|
||||
# The cli needs subsystem:console or else we can't link wmain/main
|
||||
set_target_properties(kicad-cli PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
|
||||
set_target_properties(kicad-cli PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "_CONSOLE")
|
||||
set_target_properties(kicad-cli PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(kicad-cli PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(kicad-cli PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(kicad-cli PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE")
|
||||
endif()
|
||||
|
||||
if( UNIX )
|
||||
# for build directory: create kiface symlinks so kicad (exe) can be run in-situ
|
||||
add_custom_target( kiface_sym_links
|
||||
|
@ -81,6 +98,16 @@ if( APPLE )
|
|||
common
|
||||
${wxWidgets_LIBRARIES}
|
||||
)
|
||||
|
||||
set_target_properties( kicad-cli PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${PROJECT_BINARY_DIR}/kicad/Info.plist
|
||||
)
|
||||
|
||||
target_link_libraries( kicad-cli
|
||||
nlohmann_json
|
||||
common
|
||||
${wxWidgets_LIBRARIES}
|
||||
)
|
||||
else()
|
||||
target_link_libraries( kicad
|
||||
nlohmann_json
|
||||
|
@ -89,15 +116,28 @@ else()
|
|||
common #repeated due to a circular dependency between gal and common
|
||||
${wxWidgets_LIBRARIES}
|
||||
)
|
||||
|
||||
target_link_libraries( kicad-cli
|
||||
nlohmann_json
|
||||
common
|
||||
gal
|
||||
common #repeated due to a circular dependency between gal and common
|
||||
${wxWidgets_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries( kicad pcm )
|
||||
target_link_libraries( kicad-cli pcm )
|
||||
|
||||
target_include_directories( kicad PRIVATE
|
||||
$<TARGET_PROPERTY:thread-pool,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
install( TARGETS kicad
|
||||
target_include_directories( kicad-cli PRIVATE
|
||||
$<TARGET_PROPERTY:thread-pool,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
install( TARGETS kicad kicad-cli
|
||||
DESTINATION ${KICAD_BIN}
|
||||
COMPONENT binary
|
||||
)
|
||||
|
@ -107,14 +147,6 @@ if( KICAD_WIN32_INSTALL_PDBS )
|
|||
install(FILES $<TARGET_PDB_FILE:kicad> DESTINATION ${KICAD_BIN})
|
||||
endif()
|
||||
|
||||
if( WIN32 )
|
||||
add_custom_command( TARGET kicad POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/kicad.cmd" "$<TARGET_FILE_DIR:kicad>"
|
||||
)
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/kicad.cmd" DESTINATION ${KICAD_BIN})
|
||||
endif()
|
||||
|
||||
if( APPLE )
|
||||
# "install( CODE ... )" will launch its own CMake, so no variables from
|
||||
# this CMake instance are accessible... use helper to transfer
|
||||
|
|
265
kicad/kicad.cpp
265
kicad/kicad.cpp
|
@ -33,6 +33,7 @@
|
|||
#include <wx/app.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/cmdline.h>
|
||||
|
||||
#include <filehistory.h>
|
||||
#include <hotkeys_basic.h>
|
||||
|
@ -51,13 +52,9 @@
|
|||
#include "pgm_kicad.h"
|
||||
#include "kicad_manager_frame.h"
|
||||
|
||||
#include <kicad_build_version.h>
|
||||
#include <kiplatform/app.h>
|
||||
#include <kiplatform/environment.h>
|
||||
|
||||
#include "cli/command_export_kicad_pcbnew.h"
|
||||
#include "cli/command_export_step.h"
|
||||
#include "cli/exit_codes.h"
|
||||
|
||||
// a dummy to quiet linking with EDA_BASE_FRAME::config();
|
||||
#include <kiface_base.h>
|
||||
|
@ -93,25 +90,9 @@ PGM_KICAD& PgmTop()
|
|||
return program;
|
||||
}
|
||||
|
||||
struct COMMAND_ENTRY
|
||||
{
|
||||
CLI::COMMAND* handler;
|
||||
|
||||
std::vector<COMMAND_ENTRY> subCommands;
|
||||
|
||||
COMMAND_ENTRY( CLI::COMMAND* aHandler ) : handler( aHandler ){};
|
||||
COMMAND_ENTRY( CLI::COMMAND* aHandler, std::vector<COMMAND_ENTRY> aSub ) :
|
||||
handler( aHandler ), subCommands( aSub ){};
|
||||
};
|
||||
|
||||
static CLI::EXPORT_STEP_COMMAND stepCmd{};
|
||||
static CLI::EXPORT_KICAD_PCBNEW_COMMAND exportPcbCmd{};
|
||||
|
||||
static std::vector<COMMAND_ENTRY> commandStack = { { &exportPcbCmd, { &stepCmd } } };
|
||||
|
||||
bool PGM_KICAD::OnPgmInit()
|
||||
{
|
||||
PGM_BASE::BuildArgvUtf8();
|
||||
App().SetAppDisplayName( wxT( "KiCad" ) );
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
@ -124,54 +105,60 @@ bool PGM_KICAD::OnPgmInit()
|
|||
}
|
||||
#endif
|
||||
|
||||
argparse::ArgumentParser argParser( std::string( "kicad" ),
|
||||
KICAD_MAJOR_MINOR_VERSION );
|
||||
static const wxCmdLineEntryDesc desc[] = {
|
||||
{ wxCMD_LINE_OPTION, "f", "frame", "Frame to load", wxCMD_LINE_VAL_STRING, 0 },
|
||||
{ wxCMD_LINE_PARAM, nullptr, nullptr, "File to load", wxCMD_LINE_VAL_STRING,
|
||||
wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL },
|
||||
{ wxCMD_LINE_NONE, nullptr, nullptr, nullptr, wxCMD_LINE_VAL_NONE, 0 }
|
||||
};
|
||||
|
||||
for( COMMAND_ENTRY& entry : commandStack )
|
||||
wxCmdLineParser parser( App().argc, App().argv );
|
||||
parser.SetDesc( desc );
|
||||
parser.Parse( false );
|
||||
|
||||
FRAME_T appType = KICAD_MAIN_FRAME_T;
|
||||
|
||||
const struct
|
||||
{
|
||||
argParser.add_subparser( entry.handler->GetArgParser() );
|
||||
wxString name;
|
||||
FRAME_T type;
|
||||
} frameTypes[] = { { wxT( "pcb" ), FRAME_PCB_EDITOR },
|
||||
{ wxT( "fpedit" ), FRAME_FOOTPRINT_EDITOR },
|
||||
{ wxT( "sch" ), FRAME_SCH },
|
||||
{ wxT( "calc" ), FRAME_CALC },
|
||||
{ wxT( "bm2cmp" ), FRAME_BM2CMP },
|
||||
{ wxT( "ds" ), FRAME_PL_EDITOR },
|
||||
{ wxT( "gerb" ), FRAME_GERBER },
|
||||
{ wxT( "" ), FRAME_T_COUNT } };
|
||||
|
||||
for( COMMAND_ENTRY& subentry : entry.subCommands )
|
||||
wxString frameName;
|
||||
|
||||
if( parser.Found( "frame", &frameName ) )
|
||||
{
|
||||
appType = FRAME_T_COUNT;
|
||||
|
||||
for( const auto& it : frameTypes )
|
||||
{
|
||||
entry.handler->GetArgParser().add_subparser( subentry.handler->GetArgParser() );
|
||||
if( it.name == frameName )
|
||||
appType = it.type;
|
||||
}
|
||||
|
||||
if( appType == FRAME_T_COUNT )
|
||||
{
|
||||
wxLogError( wxT( "Unknown frame: %s" ), frameName );
|
||||
// Clean up
|
||||
OnPgmExit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
argParser.parse_args( m_argcUtf8, m_argvUtf8 );
|
||||
}
|
||||
catch( const std::runtime_error& err )
|
||||
{
|
||||
// Ignore any argParser "errors"
|
||||
// unforunately there are cases like the only arg being a file (double click open)
|
||||
// that we need to fall through
|
||||
}
|
||||
bool skipPythonInit = false;
|
||||
|
||||
bool cliCmdRequested = false;
|
||||
CLI::COMMAND* cliCmd = nullptr;
|
||||
for( COMMAND_ENTRY& entry : commandStack )
|
||||
{
|
||||
if( argParser.is_subcommand_used( entry.handler->GetName() ) )
|
||||
{
|
||||
for( COMMAND_ENTRY& subentry : entry.subCommands )
|
||||
{
|
||||
if( entry.handler->GetArgParser().is_subcommand_used(
|
||||
subentry.handler->GetName() ) )
|
||||
{
|
||||
cliCmd = subentry.handler;
|
||||
cliCmdRequested = true;
|
||||
}
|
||||
}
|
||||
if( appType == FRAME_BM2CMP || appType == FRAME_PL_EDITOR || appType == FRAME_GERBER
|
||||
|| appType == FRAME_CALC )
|
||||
skipPythonInit = true;
|
||||
|
||||
if( !cliCmdRequested )
|
||||
{
|
||||
cliCmd = entry.handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !InitPgm() )
|
||||
if( !InitPgm( false, skipPythonInit ) )
|
||||
return false;
|
||||
|
||||
m_bm.InitSettings( new KICAD_SETTINGS );
|
||||
|
@ -215,76 +202,142 @@ bool PGM_KICAD::OnPgmInit()
|
|||
m_bm.m_search.Insert( it->second.GetValue(), 0 );
|
||||
}
|
||||
|
||||
if( cliCmdRequested )
|
||||
{
|
||||
int exitCode = CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
if( cliCmd )
|
||||
{
|
||||
exitCode = cliCmd->Perform( Kiway );
|
||||
}
|
||||
wxFrame* frame = nullptr;
|
||||
KIWAY_PLAYER* playerFrame = nullptr;
|
||||
KICAD_MANAGER_FRAME* managerFrame = nullptr;
|
||||
|
||||
if( exitCode != CLI::EXIT_CODES::AVOID_CLOSING )
|
||||
if( appType == KICAD_MAIN_FRAME_T )
|
||||
{
|
||||
managerFrame = new KICAD_MANAGER_FRAME( nullptr, wxT( "KiCad" ), wxDefaultPosition,
|
||||
wxSize( 775, -1 ) );
|
||||
frame = managerFrame;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use KIWAY to create a top window, which registers its existence also.
|
||||
// "TOP_FRAME" is a macro that is passed on compiler command line from CMake,
|
||||
// and is one of the types in FRAME_T.
|
||||
playerFrame = Kiway.Player( appType, true );
|
||||
frame = playerFrame;
|
||||
|
||||
if( frame == nullptr )
|
||||
{
|
||||
std::exit( exitCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
KICAD_MANAGER_FRAME* frame = new KICAD_MANAGER_FRAME( nullptr, wxT( "KiCad" ),
|
||||
wxDefaultPosition, wxSize( 775, -1 ) );
|
||||
App().SetTopWindow( frame );
|
||||
|
||||
if( playerFrame )
|
||||
App().SetAppDisplayName( playerFrame->GetAboutTitle() );
|
||||
|
||||
Kiway.SetTop( frame );
|
||||
|
||||
KICAD_SETTINGS* settings = static_cast<KICAD_SETTINGS*>( PgmSettings() );
|
||||
|
||||
wxString projToLoad;
|
||||
|
||||
if( App().argc > 1 )
|
||||
|
||||
if( playerFrame && parser.GetParamCount() )
|
||||
{
|
||||
wxFileName tmp = App().argv[1];
|
||||
// Now after the frame processing, the rest of the positional args are files
|
||||
std::vector<wxString> fileArgs;
|
||||
/*
|
||||
gerbview handles multiple project data files, i.e. gerber files on
|
||||
cmd line. Others currently do not, they handle only one. For common
|
||||
code simplicity we simply pass all the arguments in however, each
|
||||
program module can do with them what they want, ignore, complain
|
||||
whatever. We don't establish policy here, as this is a multi-purpose
|
||||
launcher.
|
||||
*/
|
||||
|
||||
if( tmp.GetExt() != ProjectFileExtension && tmp.GetExt() != LegacyProjectFileExtension )
|
||||
for( size_t i = 0; i < parser.GetParamCount(); i++ )
|
||||
fileArgs.push_back( parser.GetParam( i ) );
|
||||
|
||||
// special attention to a single argument: argv[1] (==argSet[0])
|
||||
if( fileArgs.size() == 1 )
|
||||
{
|
||||
wxString msg;
|
||||
wxFileName argv1( fileArgs[0] );
|
||||
|
||||
msg.Printf( _( "File '%s'\ndoes not appear to be a valid KiCad project file." ),
|
||||
tmp.GetFullPath() );
|
||||
wxMessageDialog dlg( nullptr, msg, _( "Error" ), wxOK | wxICON_EXCLAMATION );
|
||||
dlg.ShowModal();
|
||||
#if defined( PGM_DATA_FILE_EXT )
|
||||
// PGM_DATA_FILE_EXT, if present, may be different for each compile,
|
||||
// it may come from CMake on the compiler command line, but often does not.
|
||||
// This facility is mostly useful for those program footprints
|
||||
// supporting a single argv[1].
|
||||
if( !argv1.GetExt() )
|
||||
argv1.SetExt( wxT( PGM_DATA_FILE_EXT ) );
|
||||
#endif
|
||||
argv1.MakeAbsolute();
|
||||
|
||||
fileArgs[0] = argv1.GetFullPath();
|
||||
}
|
||||
else
|
||||
|
||||
// Use the KIWAY_PLAYER::OpenProjectFiles() API function:
|
||||
if( !playerFrame->OpenProjectFiles( fileArgs ) )
|
||||
{
|
||||
projToLoad = tmp.GetFullPath();
|
||||
// OpenProjectFiles() API asks that it report failure to the UI.
|
||||
// Nothing further to say here.
|
||||
|
||||
// We've already initialized things at this point, but wx won't call OnExit if
|
||||
// we fail out. Call our own cleanup routine here to ensure the relevant resources
|
||||
// are freed at the right time (if they aren't, segfaults will occur).
|
||||
OnPgmExit();
|
||||
|
||||
// Fail the process startup if the file could not be opened,
|
||||
// although this is an optional choice, one that can be reversed
|
||||
// also in the KIFACE specific OpenProjectFiles() return value.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If no file was given as an argument, check that there was a file open.
|
||||
if( projToLoad.IsEmpty() && settings->m_OpenProjects.size() )
|
||||
else if( managerFrame )
|
||||
{
|
||||
wxString last_pro = settings->m_OpenProjects.front();
|
||||
settings->m_OpenProjects.erase( settings->m_OpenProjects.begin() );
|
||||
|
||||
if( wxFileExists( last_pro ) )
|
||||
if( App().argc > 1 )
|
||||
{
|
||||
// Try to open the last opened project,
|
||||
// if a project name is not given when starting Kicad
|
||||
projToLoad = last_pro;
|
||||
wxFileName tmp = App().argv[1];
|
||||
|
||||
if( tmp.GetExt() != ProjectFileExtension && tmp.GetExt() != LegacyProjectFileExtension )
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "File '%s'\ndoes not appear to be a valid KiCad project file." ),
|
||||
tmp.GetFullPath() );
|
||||
wxMessageDialog dlg( nullptr, msg, _( "Error" ), wxOK | wxICON_EXCLAMATION );
|
||||
dlg.ShowModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
projToLoad = tmp.GetFullPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do not attempt to load a non-existent project file.
|
||||
if( !projToLoad.empty() )
|
||||
{
|
||||
wxFileName fn( projToLoad );
|
||||
|
||||
if( fn.Exists() )
|
||||
// If no file was given as an argument, check that there was a file open.
|
||||
if( projToLoad.IsEmpty() && settings->m_OpenProjects.size() )
|
||||
{
|
||||
fn.MakeAbsolute();
|
||||
frame->LoadProject( fn );
|
||||
wxString last_pro = settings->m_OpenProjects.front();
|
||||
settings->m_OpenProjects.erase( settings->m_OpenProjects.begin() );
|
||||
|
||||
if( wxFileExists( last_pro ) )
|
||||
{
|
||||
// Try to open the last opened project,
|
||||
// if a project name is not given when starting Kicad
|
||||
projToLoad = last_pro;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not attempt to load a non-existent project file.
|
||||
if( !projToLoad.empty() )
|
||||
{
|
||||
wxFileName fn( projToLoad );
|
||||
|
||||
if( fn.Exists() )
|
||||
{
|
||||
fn.MakeAbsolute();
|
||||
|
||||
if( appType == KICAD_MAIN_FRAME_T )
|
||||
{
|
||||
managerFrame->LoadProject( fn );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,6 +348,12 @@ bool PGM_KICAD::OnPgmInit()
|
|||
}
|
||||
|
||||
|
||||
int PGM_KICAD::OnPgmRun()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PGM_KICAD::OnPgmExit()
|
||||
{
|
||||
Kiway.OnKiwayEnd();
|
||||
|
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2004-2021 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file kicad.cpp
|
||||
* Main KiCad project manager file.
|
||||
*/
|
||||
|
||||
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/app.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include <kiway.h>
|
||||
#include <macros.h>
|
||||
#include <paths.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <settings/kicad_settings.h>
|
||||
#include <systemdirsappend.h>
|
||||
#include <trace_helpers.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "pgm_kicad.h"
|
||||
#include "kicad_manager_frame.h"
|
||||
|
||||
#include <kicad_build_version.h>
|
||||
#include <kiplatform/app.h>
|
||||
#include <kiplatform/environment.h>
|
||||
|
||||
#include "cli/command_pcb.h"
|
||||
#include "cli/command_pcb_export.h"
|
||||
#include "cli/command_export_pcb_svg.h"
|
||||
#include "cli/command_export_step.h"
|
||||
#include "cli/exit_codes.h"
|
||||
|
||||
// a dummy to quiet linking with EDA_BASE_FRAME::config();
|
||||
#include <kiface_base.h>
|
||||
KIFACE_BASE& Kiface()
|
||||
{
|
||||
// This function should never be called. It is only referenced from
|
||||
// EDA_BASE_FRAME::config() and this is only provided to satisfy the linker,
|
||||
// not to be actually called.
|
||||
wxLogFatalError( wxT( "Unexpected call to Kiface() in kicad/kicad.cpp" ) );
|
||||
|
||||
throw std::logic_error( "Unexpected call to Kiface() in kicad/kicad.cpp" );
|
||||
}
|
||||
|
||||
|
||||
static PGM_KICAD program;
|
||||
|
||||
|
||||
PGM_BASE& Pgm()
|
||||
{
|
||||
return program;
|
||||
}
|
||||
|
||||
|
||||
// Similar to PGM_BASE& Pgm(), but return nullptr when a *.ki_face is run from a python script.
|
||||
PGM_BASE* PgmOrNull()
|
||||
{
|
||||
return &program;
|
||||
}
|
||||
|
||||
|
||||
PGM_KICAD& PgmTop()
|
||||
{
|
||||
return program;
|
||||
}
|
||||
|
||||
struct COMMAND_ENTRY
|
||||
{
|
||||
CLI::COMMAND* handler;
|
||||
|
||||
std::vector<COMMAND_ENTRY> subCommands;
|
||||
|
||||
COMMAND_ENTRY( CLI::COMMAND* aHandler ) : handler( aHandler ){};
|
||||
COMMAND_ENTRY( CLI::COMMAND* aHandler, std::vector<COMMAND_ENTRY> aSub ) :
|
||||
handler( aHandler ), subCommands( aSub ){};
|
||||
};
|
||||
|
||||
static CLI::EXPORT_STEP_COMMAND stepCmd{};
|
||||
static CLI::EXPORT_PCB_SVG_COMMAND svgCmd{};
|
||||
static CLI::EXPORT_PCB_COMMAND exportPcbCmd{};
|
||||
static CLI::PCB_COMMAND pcbCmd{};
|
||||
|
||||
static std::vector<COMMAND_ENTRY> commandStack = {
|
||||
{
|
||||
&pcbCmd,
|
||||
{
|
||||
{ &exportPcbCmd,
|
||||
{
|
||||
&stepCmd,
|
||||
&svgCmd
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static void recurseArgParserBuild( argparse::ArgumentParser& aArgParser, COMMAND_ENTRY& aEntry )
|
||||
{
|
||||
aArgParser.add_subparser( aEntry.handler->GetArgParser() );
|
||||
|
||||
for( COMMAND_ENTRY& subEntry : aEntry.subCommands )
|
||||
{
|
||||
recurseArgParserBuild( aEntry.handler->GetArgParser(), subEntry );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static COMMAND_ENTRY* recurseArgParserSubCommandUsed( argparse::ArgumentParser& aArgParser,
|
||||
COMMAND_ENTRY& aEntry )
|
||||
{
|
||||
COMMAND_ENTRY* cliCmd = nullptr;
|
||||
|
||||
if( aArgParser.is_subcommand_used( aEntry.handler->GetName() ) )
|
||||
{
|
||||
for( COMMAND_ENTRY& subentry : aEntry.subCommands )
|
||||
{
|
||||
cliCmd = recurseArgParserSubCommandUsed( aEntry.handler->GetArgParser(), subentry );
|
||||
if( cliCmd )
|
||||
break;
|
||||
}
|
||||
|
||||
if(!cliCmd)
|
||||
cliCmd = &aEntry;
|
||||
}
|
||||
|
||||
return cliCmd;
|
||||
}
|
||||
|
||||
|
||||
bool PGM_KICAD::OnPgmInit()
|
||||
{
|
||||
PGM_BASE::BuildArgvUtf8();
|
||||
App().SetAppDisplayName( wxT( "KiCad" ) );
|
||||
|
||||
#if defined( DEBUG )
|
||||
wxString absoluteArgv0 = wxStandardPaths::Get().GetExecutablePath();
|
||||
|
||||
if( !wxIsAbsolutePath( absoluteArgv0 ) )
|
||||
{
|
||||
wxLogError( wxT( "No meaningful argv[0]" ) );
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( !InitPgm( true, true) )
|
||||
return false;
|
||||
|
||||
m_bm.InitSettings( new KICAD_SETTINGS );
|
||||
GetSettingsManager().RegisterSettings( PgmSettings() );
|
||||
GetSettingsManager().SetKiway( &Kiway );
|
||||
m_bm.Init();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int PGM_KICAD::OnPgmRun()
|
||||
{
|
||||
argparse::ArgumentParser argParser( std::string( "kicad-cli" ), KICAD_MAJOR_MINOR_VERSION );
|
||||
|
||||
for( COMMAND_ENTRY& entry : commandStack )
|
||||
{
|
||||
recurseArgParserBuild( argParser, entry );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
argParser.parse_args( m_argcUtf8, m_argvUtf8 );
|
||||
}
|
||||
catch( const std::runtime_error& err )
|
||||
{
|
||||
std::cout << err.what() << std::endl;
|
||||
std::cout << argParser;
|
||||
return CLI::EXIT_CODES::ERR_ARGS;
|
||||
}
|
||||
|
||||
COMMAND_ENTRY* cliCmd = nullptr;
|
||||
for( COMMAND_ENTRY& entry : commandStack )
|
||||
{
|
||||
if( argParser.is_subcommand_used( entry.handler->GetName() ) )
|
||||
{
|
||||
cliCmd = recurseArgParserSubCommandUsed( argParser, entry );
|
||||
}
|
||||
}
|
||||
|
||||
if( cliCmd )
|
||||
{
|
||||
int exitCode = CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||
if( cliCmd )
|
||||
{
|
||||
exitCode = cliCmd->handler->Perform( Kiway );
|
||||
}
|
||||
|
||||
if( exitCode != CLI::EXIT_CODES::AVOID_CLOSING )
|
||||
{
|
||||
return exitCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << argParser;
|
||||
return CLI::EXIT_CODES::ERR_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PGM_KICAD::OnPgmExit()
|
||||
{
|
||||
Kiway.OnKiwayEnd();
|
||||
|
||||
if( m_settings_manager && m_settings_manager->IsOK() )
|
||||
{
|
||||
SaveCommonSettings();
|
||||
m_settings_manager->Save();
|
||||
}
|
||||
|
||||
// Destroy everything in PGM_KICAD,
|
||||
// especially wxSingleInstanceCheckerImpl earlier than wxApp and earlier
|
||||
// than static destruction would.
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
void PGM_KICAD::MacOpenFile( const wxString& aFileName )
|
||||
{
|
||||
#if defined( __WXMAC__ )
|
||||
|
||||
KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) App().GetTopWindow();
|
||||
|
||||
if( !aFileName.empty() && wxFileExists( aFileName ) )
|
||||
frame->LoadProject( wxFileName( aFileName ) );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PGM_KICAD::Destroy()
|
||||
{
|
||||
// unlike a normal destructor, this is designed to be called more
|
||||
// than once safely:
|
||||
|
||||
m_bm.End();
|
||||
|
||||
PGM_BASE::Destroy();
|
||||
}
|
||||
|
||||
|
||||
KIWAY Kiway( &Pgm(), KFCTL_CPP_PROJECT_SUITE );
|
||||
|
||||
|
||||
/**
|
||||
* Not publicly visible because most of the action is in #PGM_KICAD these days.
|
||||
*/
|
||||
struct APP_KICAD_CLI : public wxAppConsole
|
||||
{
|
||||
APP_KICAD_CLI() : wxAppConsole()
|
||||
{
|
||||
// Init the environment each platform wants
|
||||
KIPLATFORM::ENV::Init();
|
||||
}
|
||||
|
||||
|
||||
bool OnInit() override
|
||||
{
|
||||
// Perform platform-specific init tasks
|
||||
if( !KIPLATFORM::APP::Init() )
|
||||
return false;
|
||||
|
||||
if( !program.OnPgmInit() )
|
||||
{
|
||||
program.OnPgmExit();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int OnExit() override
|
||||
{
|
||||
program.OnPgmExit();
|
||||
|
||||
#if defined( __FreeBSD__ )
|
||||
// Avoid wxLog crashing when used in destructors.
|
||||
wxLog::EnableLogging( false );
|
||||
#endif
|
||||
|
||||
return wxAppConsole::OnExit();
|
||||
}
|
||||
|
||||
int OnRun() override
|
||||
{
|
||||
try
|
||||
{
|
||||
return program.OnPgmRun();
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
|
||||
FROM_UTF8( typeid( e ).name() ), FROM_UTF8( e.what() ) );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
wxLogError( ioe.What() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
wxLogError( wxT( "Unhandled exception of unknown type" ) );
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FilterEvent( wxEvent& aEvent ) override
|
||||
{
|
||||
if( aEvent.GetEventType() == wxEVT_SHOW )
|
||||
{
|
||||
wxShowEvent& event = static_cast<wxShowEvent&>( aEvent );
|
||||
wxDialog* dialog = dynamic_cast<wxDialog*>( event.GetEventObject() );
|
||||
|
||||
if( dialog && dialog->IsModal() )
|
||||
Pgm().m_ModalDialogCount += event.IsShown() ? 1 : -1;
|
||||
}
|
||||
|
||||
return Event_Skip;
|
||||
}
|
||||
|
||||
#if defined( DEBUG )
|
||||
/**
|
||||
* Process any unhandled events at the application level.
|
||||
*/
|
||||
bool ProcessEvent( wxEvent& aEvent ) override
|
||||
{
|
||||
if( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
|
||||
{
|
||||
wxKeyEvent* keyEvent = static_cast<wxKeyEvent*>( &aEvent );
|
||||
|
||||
if( keyEvent )
|
||||
{
|
||||
wxLogTrace( kicadTraceKeyEvent, "APP_KICAD::ProcessEvent %s", dump( *keyEvent ) );
|
||||
}
|
||||
}
|
||||
|
||||
aEvent.Skip();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override main loop exception handling on debug builds.
|
||||
*
|
||||
* It can be painfully difficult to debug exceptions that happen in wxUpdateUIEvent
|
||||
* handlers. The override provides a bit more useful information about the exception
|
||||
* and a breakpoint can be set to pin point the event where the exception was thrown.
|
||||
*/
|
||||
bool OnExceptionInMainLoop() override
|
||||
{
|
||||
try
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
wxLogError( "Unhandled exception class: %s what: %s", FROM_UTF8( typeid( e ).name() ),
|
||||
FROM_UTF8( e.what() ) );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
wxLogError( ioe.What() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
wxLogError( "Unhandled exception of unknown type" );
|
||||
}
|
||||
|
||||
return false; // continue on. Return false to abort program
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set MacOS file associations.
|
||||
*
|
||||
* @see http://wiki.wxwidgets.org/WxMac-specific_topics
|
||||
*/
|
||||
#if defined( __WXMAC__ )
|
||||
void MacOpenFile( const wxString& aFileName ) override
|
||||
{
|
||||
Pgm().MacOpenFile( aFileName );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
IMPLEMENT_APP_CONSOLE( APP_KICAD_CLI )
|
||||
|
||||
|
||||
// The C++ project manager supports one open PROJECT, so Prj() calls within
|
||||
// this link image need this function.
|
||||
PROJECT& Prj()
|
||||
{
|
||||
return Kiway.Prj();
|
||||
}
|
|
@ -48,6 +48,7 @@ public:
|
|||
|
||||
bool OnPgmInit();
|
||||
void OnPgmExit();
|
||||
int OnPgmRun();
|
||||
|
||||
void MacOpenFile( const wxString& aFileName ) override;
|
||||
|
||||
|
|
|
@ -756,12 +756,6 @@ if( WIN32 )
|
|||
add_custom_command( TARGET pcbnew POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:kicad_3dsg>" "$<TARGET_FILE_DIR:pcbnew>"
|
||||
)
|
||||
|
||||
add_custom_command( TARGET pcbnew POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/pcbnew.cmd" "$<TARGET_FILE_DIR:pcbnew>"
|
||||
)
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/pcbnew.cmd" DESTINATION ${KICAD_BIN})
|
||||
endif()
|
||||
|
||||
# these 2 binaries are a matched set, keep them together:
|
||||
|
|
|
@ -380,17 +380,24 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
|
|||
appK2S.AppendDir( wxT( ".." ) );
|
||||
appK2S.AppendDir( wxT( "MacOS" ) );
|
||||
}
|
||||
#else
|
||||
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
|
||||
{
|
||||
fn.RemoveLastDir();
|
||||
fn.AppendDir( "kicad" );
|
||||
}
|
||||
#endif
|
||||
|
||||
appK2S.SetName( wxT( "pcbnew" ) );
|
||||
|
||||
appK2S.SetName( wxT( "kicad-cli" ) );
|
||||
|
||||
wxString cmdK2S = wxT( "\"" );
|
||||
cmdK2S.Append( appK2S.GetFullPath() );
|
||||
cmdK2S.Append( wxT( "\"" ) );
|
||||
|
||||
cmdK2S.Append( wxT( " pcb" ) );
|
||||
cmdK2S.Append( wxT( " export" ) );
|
||||
cmdK2S.Append( wxT( " step" ) );
|
||||
cmdK2S.Append( wxT( " --gui" ) );
|
||||
|
||||
if( GetNoVirtOption() )
|
||||
cmdK2S.Append( wxT( " --no-virtual" ) );
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
@"%~dp0kicad.exe" %*
|
|
@ -1 +0,0 @@
|
|||
@"%~dp0pcbnew.exe" %*
|
Loading…
Reference in New Issue