7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 13:21:43 +00:00

Working python window

This commit is contained in:
Seth Hillbrand 2021-03-08 06:54:22 -08:00
parent 6fbbba8db3
commit 81d58bcea9
557 changed files with 95774 additions and 59718 deletions
CMakeLists.txt
common
include
kicad
pcbnew
qa
scripting
CMakeLists.txt
kicad_pyshell
kicad_scripting_main.cppkipython_settings.cppkipython_settings.h
pybind11
.clang-tidy.gitignore.modules.sourcesCMakeLists.txtLICENSEMANIFEST.inREADME.rst
bits/types
common.cpp
core
docs
eda_rect.cppeda_units.cppeda_units_1.cpp
gal
gr_basic.cpp
include/pybind11
inspectable.cppki_exception.cppkicad_binder.cfgkicad_include.hppkiid.cpplayers_id_colors_and_visibility.cpplayers_id_colors_and_visibility_1.cpplib_circle.cpplib_field.cpplib_item.cpplib_pin.cpplib_rectangle.cpplib_symbol.cppmacros.cpp
pybind11
pyproject.tomlrender_settings.cpprichio.cppsetup.cfgsetup.py
tests
CMakeLists.txtconftest.pyconstructor_stats.hcross_module_gil_utils.cppenv.py
extra_python_package
extra_setuptools
local_bindings.hobject.hpybind11_cross_module_tests.cpppybind11_tests.cpppybind11_tests.hpytest.inirequirements.txttest_async.cpptest_async.pytest_buffers.cpptest_buffers.pytest_builtin_casters.cpptest_builtin_casters.pytest_call_policies.cpptest_call_policies.pytest_callbacks.cpptest_callbacks.pytest_chrono.cpptest_chrono.pytest_class.cpptest_class.py
test_cmake_build
CMakeLists.txtembed.cpp
installed_embed
installed_function
installed_target
main.cpp
subdirectory_embed
subdirectory_function
subdirectory_target
test.py
test_constants_and_functions.cpptest_constants_and_functions.pytest_copy_move.cpptest_copy_move.pytest_custom_type_casters.cpptest_custom_type_casters.pytest_docstring_options.cpptest_docstring_options.pytest_eigen.cpptest_eigen.py
test_embed
test_enum.cpptest_enum.pytest_eval.cpptest_eval.pytest_eval_call.pytest_exceptions.cpptest_exceptions.pytest_factory_constructors.cpptest_factory_constructors.pytest_gil_scoped.cpptest_gil_scoped.pytest_iostream.cpptest_iostream.pytest_kwargs_and_defaults.cpptest_kwargs_and_defaults.pytest_local_bindings.cpptest_local_bindings.pytest_methods_and_attributes.cpptest_methods_and_attributes.pytest_modules.cpptest_modules.pytest_multiple_inheritance.cpptest_multiple_inheritance.pytest_numpy_array.cpptest_numpy_array.pytest_numpy_dtypes.cpptest_numpy_dtypes.pytest_numpy_vectorize.cpptest_numpy_vectorize.pytest_opaque_types.cpptest_opaque_types.pytest_operator_overloading.cpptest_operator_overloading.pytest_pickling.cpptest_pickling.pytest_pytypes.cpptest_pytypes.pytest_sequences_and_iterators.cpptest_sequences_and_iterators.pytest_smart_ptr.cpptest_smart_ptr.pytest_stl.cpptest_stl.pytest_stl_binders.cpptest_stl_binders.pytest_tagbased_polymorphic.cpptest_tagbased_polymorphic.pytest_union.cpptest_union.pytest_virtual_functions.cpptest_virtual_functions.pyvalgrind-numpy-scipy.suppvalgrind-python.supp
tool
tools
unknown
view
wx
python_scripting.cpppython_scripting.h
thirdparty/pybind11
CMakeLists.txtLICENSEMANIFEST.inREADME.rst
docs
include/pybind11
pybind11
pyproject.tomlsetup.cfgsetup.py
tests
CMakeLists.txtconftest.pyconstructor_stats.hcross_module_gil_utils.cppenv.py
extra_python_package
extra_setuptools
local_bindings.hobject.hpybind11_cross_module_tests.cpppybind11_tests.cpppybind11_tests.hpytest.inirequirements.txttest_async.cpptest_async.pytest_buffers.cpptest_buffers.pytest_builtin_casters.cpptest_builtin_casters.pytest_call_policies.cpptest_call_policies.pytest_callbacks.cpptest_callbacks.pytest_chrono.cpptest_chrono.pytest_class.cpptest_class.py
test_cmake_build
CMakeLists.txtembed.cpp
installed_embed
installed_function
installed_target
main.cpp
subdirectory_embed
subdirectory_function
subdirectory_target
test.py
test_constants_and_functions.cpptest_constants_and_functions.pytest_copy_move.cpptest_copy_move.pytest_custom_type_casters.cpptest_custom_type_casters.pytest_docstring_options.cpptest_docstring_options.pytest_eigen.cpptest_eigen.py
test_embed
test_enum.cpptest_enum.pytest_eval.cpptest_eval.pytest_eval_call.pytest_exceptions.cpptest_exceptions.pytest_factory_constructors.cpptest_factory_constructors.pytest_gil_scoped.cpptest_gil_scoped.pytest_iostream.cpptest_iostream.pytest_kwargs_and_defaults.cpptest_kwargs_and_defaults.pytest_local_bindings.cpptest_local_bindings.pytest_methods_and_attributes.cpptest_methods_and_attributes.pytest_modules.cpptest_modules.pytest_multiple_inheritance.cpptest_multiple_inheritance.pytest_numpy_array.cpptest_numpy_array.pytest_numpy_dtypes.cpptest_numpy_dtypes.pytest_numpy_vectorize.cpptest_numpy_vectorize.pytest_opaque_types.cpptest_opaque_types.pytest_operator_overloading.cpptest_operator_overloading.pytest_pickling.cpptest_pickling.pytest_pytypes.cpptest_pytypes.pytest_sequences_and_iterators.cpptest_sequences_and_iterators.pytest_smart_ptr.cpptest_smart_ptr.pytest_stl.cpptest_stl.pytest_stl_binders.cpptest_stl_binders.pytest_tagbased_polymorphic.cpptest_tagbased_polymorphic.pytest_union.cpptest_union.pytest_virtual_functions.cpptest_virtual_functions.pyvalgrind-numpy-scipy.suppvalgrind-python.supp
tools

View File

@ -54,14 +54,6 @@ cmake_dependent_option( BUILD_SMALL_DEBUG_FILES "In debug build: create smaller
# so that build option settings can be included in bug reports.
#
option( KICAD_SCRIPTING_PYTHON3
"Build for Python 3 instead of 2 (default OFF)."
OFF )
option( KICAD_SCRIPTING_WXPYTHON_PHOENIX
"Use new wxPython binding (default OFF)."
OFF )
option( KICAD_USE_OCE
"Build tools and plugins related to OpenCascade Community Edition (default ON)"
ON )
@ -457,30 +449,6 @@ if( MSVC )
endif()
endif()
if( KICAD_SCRIPTING )
add_definitions( -DKICAD_SCRIPTING )
endif()
if( KICAD_SCRIPTING_MODULES )
add_definitions( -DKICAD_SCRIPTING_MODULES )
endif()
if( KICAD_SCRIPTING_PYTHON3 )
add_definitions( -DKICAD_SCRIPTING_PYTHON3 )
endif()
if( KICAD_SCRIPTING_WXPYTHON )
add_definitions( -DKICAD_SCRIPTING_WXPYTHON )
endif()
if( KICAD_SCRIPTING_WXPYTHON_PHOENIX )
add_definitions( -DKICAD_SCRIPTING_WXPYTHON_PHOENIX )
endif()
if( KICAD_SCRIPTING_ACTION_MENU )
add_definitions( -DKICAD_SCRIPTING_ACTION_MENU )
endif()
if( KICAD_SPICE )
add_definitions( -DKICAD_SPICE )
endif()
@ -785,104 +753,77 @@ set( INC_AFTER
#
# Find Python and other scripting resources
#
if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
# SWIG 3.0 or later require for C++11 support.
find_package( SWIG 3.0 REQUIRED )
include( ${SWIG_USE_FILE} )
# SWIG 3.0 or later require for C++11 support.
find_package( SWIG 3.0 REQUIRED )
include( ${SWIG_USE_FILE} )
if( KICAD_SCRIPTING_PYTHON3 )
set( PythonInterp_FIND_VERSION 3.3 )
set( PythonLibs_FIND_VERSION 3.3 )
else()
# force a python version < 3.0
set( PythonInterp_FIND_VERSION 2.6 )
set( PythonLibs_FIND_VERSION 2.6 )
endif()
# pybind11 is header-only, so include the subdir
add_subdirectory(thirdparty/pybind11)
find_package( PythonInterp )
set( PythonInterp_FIND_VERSION 3.6 )
set( PythonLibs_FIND_VERSION 3.6 )
check_find_package_result( PYTHONINTERP_FOUND "Python Interpreter" )
find_package( PythonInterp )
if( NOT KICAD_SCRIPTING_PYTHON3 AND NOT PYTHON_VERSION_MAJOR EQUAL 2 )
message( FATAL_ERROR "Python 2.x is required." )
endif()
check_find_package_result( PYTHONINTERP_FOUND "Python Interpreter" )
# Get the correct Python site package install path from the Python interpreter found by
# FindPythonInterp unless the user specifically defined a custom path.
if( NOT PYTHON_SITE_PACKAGE_PATH )
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig;print(\"%s\"%distutils.sysconfig.get_python_lib(plat_specific=0, standard_lib=0, prefix=''))"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGE_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Get the correct Python site package install path from the Python interpreter found by
# FindPythonInterp unless the user specifically defined a custom path.
if( NOT PYTHON_SITE_PACKAGE_PATH )
execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig;print(\"%s\"%distutils.sysconfig.get_python_lib(plat_specific=0, standard_lib=0, prefix=''))"
OUTPUT_VARIABLE PYTHON_SITE_PACKAGE_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if( NOT PYTHON_SITE_PACKAGE_PATH )
message( FATAL_ERROR "Error occurred while attempting to find the Python site library path." )
endif()
message( FATAL_ERROR "Error occurred while attempting to find the Python site library path." )
endif()
if( APPLE )
set( OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR ${OSX_BUNDLE_LIB_DIR}/Python.framework/Versions/${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
set( OSX_BUNDLE_INSTALL_PYTHON_SITE_PACKAGES_DIR "${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR}")
set( PYTHON_DEST "${OSX_BUNDLE_BUILD_DIR}/${OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR}"
CACHE PATH "Python module install path."
)
# change to add_compile_definitions() after minimum required CMake version is 3.12
set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR="${OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR}")
elseif( VCPKG_TOOLCHAIN )
set( PYTHON_DEST "${CMAKE_INSTALL_PREFIX}/bin/Lib/site-packages"
CACHE PATH "Python module install path."
)
else()
set( PYTHON_DEST "${PYTHON_SITE_PACKAGE_PATH}"
CACHE PATH "Python module install path."
)
endif()
mark_as_advanced( PYTHON_DEST )
message( STATUS "Python module install path: ${PYTHON_DEST}" )
if( KICAD_SCRIPTING_PYTHON3 )
find_package( PythonLibs 3.3 REQUIRED )
else()
find_package( PythonLibs 2.6 REQUIRED )
endif()
# Infrequently needed headers go at end of search paths, append to INC_AFTER which
# although is used for all components, should be a harmless hit for something like eeschema
# so long as unused search paths are at the end like this.
set( INC_AFTER ${INC_AFTER} ${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/scripting )
endif()
# Find the wxPython installation if requested
if( KICAD_SCRIPTING_WXPYTHON )
find_package( wxPython REQUIRED )
if( APPLE )
set( OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR ${OSX_BUNDLE_LIB_DIR}/Python.framework/Versions/${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
set( OSX_BUNDLE_INSTALL_PYTHON_SITE_PACKAGES_DIR "${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR}")
set( PYTHON_DEST "${OSX_BUNDLE_BUILD_DIR}/${OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR}"
CACHE PATH "Python module install path."
)
# change to add_compile_definitions() after minimum required CMake version is 3.12
set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR="${OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR}")
elseif( VCPKG_TOOLCHAIN )
set( PYTHON_DEST "${CMAKE_INSTALL_PREFIX}/bin/Lib/site-packages"
CACHE PATH "Python module install path."
)
else()
set( PYTHON_DEST "${PYTHON_SITE_PACKAGE_PATH}"
CACHE PATH "Python module install path."
)
endif()
message( STATUS "Python module install path: ${PYTHON_DEST}" )
if( KICAD_SCRIPTING_WXPYTHON_PHOENIX AND WXPYTHON_VERSION VERSION_LESS 4.0.0 )
message( FATAL_ERROR
"Unable to find wxPython Phoenix,"
" instead found wxPython Classic ${WXPYTHON_VERSION}" )
endif()
find_package( PythonLibs 3.6 REQUIRED )
# The test VERSION_GREATER_EQUAL is only available in cmake >3.7, so use the max possible
# version for the 3.0 line as the basis of the comparison
if( NOT KICAD_SCRIPTING_WXPYTHON_PHOENIX AND WXPYTHON_VERSION VERSION_GREATER 3.9.999 )
message( FATAL_ERROR
"Unable to find wxPython Classic,"
" instead found wxPython Phoenix ${WXPYTHON_VERSION}" )
endif()
# Infrequently needed headers go at end of search paths, append to INC_AFTER which
# although is used for all components, should be a harmless hit for something like eeschema
# so long as unused search paths are at the end like this.
set( INC_AFTER ${INC_AFTER} ${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/scripting )
# GTK3 is required on Linux
if( UNIX AND NOT APPLE )
if( NOT "${WXPYTHON_TOOLKIT}" STREQUAL "gtk3" )
message( FATAL_ERROR "GTK3-based wxPython/Phoenix toolkit is required.")
endif()
endif()
# Find the wxPython installation
find_package( wxPython REQUIRED )
message( STATUS "Found ${WXPYTHON_FLAVOR} "
"${WXPYTHON_VERSION}/${WXPYTHON_TOOLKIT} "
"(wxWidgets ${WXPYTHON_WXVERSION})" )
if( WXPYTHON_VERSION VERSION_LESS 4.0.0 )
message( FATAL_ERROR "wxPython Phoenix is required" )
endif()
# GTK3 is required on Linux
if( UNIX AND NOT APPLE )
if( NOT "${WXPYTHON_TOOLKIT}" STREQUAL "gtk3" )
message( FATAL_ERROR "GTK3-based wxPython/Phoenix toolkit is required.")
endif()
endif()
message( STATUS "Found ${WXPYTHON_FLAVOR} "
"${WXPYTHON_VERSION}/${WXPYTHON_TOOLKIT} "
"(wxWidgets ${WXPYTHON_WXVERSION})" )
#
# Find wxWidgets library, required
@ -891,31 +832,27 @@ endif()
# Turn on wxWidgets compatibility mode for some classes
add_definitions( -DWX_COMPATIBILITY )
if( KICAD_SCRIPTING_WXPYTHON )
# Check if '--toolkit=xxx' option has been passed
string( REGEX MATCH "--toolkit=([a-zA-Z0-9]+)"
WXWIDGETS_REQUESTED_TOOLKIT "${wxWidgets_CONFIG_OPTIONS}" )
if( WXWIDGETS_REQUESTED_TOOLKIT
AND NOT WXWIDGETS_REQUESTED_TOOLKIT STREQUAL "--toolkit=${WXPYTHON_TOOLKIT}" )
message( WARNING "wxWidgets and wxPython must be based on the same toolkit.\n"
"It will be fixed automatically if you skip the '--toolkit=xxx' "
"wxWidgets_CONFIG_OPTIONS parameter.")
elseif( UNIX AND NOT APPLE )
# Force the use of GTK3 on Linux
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} "--toolkit=gtk3" )
else()
# Use the same toolkit as wxPython otherwise there will be a symbol conflict
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} "--toolkit=${WXPYTHON_TOOLKIT}" )
endif()
# Check if '--toolkit=xxx' option has been passed
string( REGEX MATCH "--toolkit=([a-zA-Z0-9]+)"
WXWIDGETS_REQUESTED_TOOLKIT "${wxWidgets_CONFIG_OPTIONS}" )
# Require the same wxWidgets version as is used by wxPython
set( wxWidgets_REQ_VERSION ${WXPYTHON_WXVERSION} )
if( WXWIDGETS_REQUESTED_TOOLKIT
AND NOT WXWIDGETS_REQUESTED_TOOLKIT STREQUAL "--toolkit=${WXPYTHON_TOOLKIT}" )
message( WARNING "wxWidgets and wxPython must be based on the same toolkit.\n"
"It will be fixed automatically if you skip the '--toolkit=xxx' "
"wxWidgets_CONFIG_OPTIONS parameter.")
elseif( UNIX AND NOT APPLE )
# Force the use of GTK3 on Linux
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} "--toolkit=gtk3" )
else()
# Require wxWidgets 3.0.0 as the minimum when wxPython is disabled
set( wxWidgets_REQ_VERSION 3.0.0 )
# Use the same toolkit as wxPython otherwise there will be a symbol conflict
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} "--toolkit=${WXPYTHON_TOOLKIT}" )
endif()
# Require the same wxWidgets version as is used by wxPython
set( wxWidgets_REQ_VERSION ${WXPYTHON_WXVERSION} )
# See line 49 of CMakeModules/FindwxWidgets.cmake
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} --static=no )
@ -924,25 +861,6 @@ find_package( wxWidgets ${wxWidgets_REQ_VERSION} COMPONENTS gl aui adv html core
# Include wxWidgets macros.
include( ${wxWidgets_USE_FILE} )
if( KICAD_SCRIPTING_WXPYTHON AND NOT KICAD_SCRIPTING_WXPYTHON_PHOENIX )
# wxPython appears to be installed and valid so make sure the headers are available.
foreach( path ${wxWidgets_INCLUDE_DIRS} )
#message( STATUS "Searching for wx/wxPython/wxPython.h in ${path}" )
find_path( wxPYTHON_INCLUDE_DIRS wx/wxPython/wxPython.h
PATHS "${path}" )
if( wxPYTHON_INCLUDE_DIRS )
message( STATUS "Found wxPython.h in ${path}/wx/wxPython" )
break()
endif()
endforeach()
if( NOT wxPYTHON_INCLUDE_DIRS )
message( FATAL_ERROR "Cannot find wxPython.h" )
endif()
endif()
if( MINGW )
# This needs to be on a separate line to protect against a broken FindWxWidgets.cmake in vcpkg
if( ${wxWidgets_VERSION_STRING} VERSION_LESS 3.1 )
@ -1051,6 +969,7 @@ add_subdirectory( resources )
add_subdirectory( thirdparty )
add_subdirectory( bitmaps_png )
add_subdirectory( libs )
add_subdirectory( scripting )
add_subdirectory( common )
add_subdirectory( 3d-viewer )
add_subdirectory( eeschema )

View File

@ -682,61 +682,3 @@ make_lexer(
add_executable( dsntest EXCLUDE_FROM_ALL dsnlexer.cpp )
target_link_libraries( dsntest common ${wxWidgets_LIBRARIES} rt )
# _kiway.so
if( false ) # future
#if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
set( SWIG_FLAGS
-I${CMAKE_CURRENT_SOURCE_DIR}/../include
)
if( DEBUG )
set( SWIG_FLAGS ${SWIG_FLAGS} -DDEBUG )
endif()
# call SWIG in C++ mode: https://cmake.org/cmake/help/v3.2/module/UseSWIG.html
set_source_files_properties( swig/kiway.i PROPERTIES CPLUSPLUS ON )
# collect CFLAGS , and pass them to swig later
get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS )
foreach( d ${DirDefs} )
set( SWIG_FLAGS ${SWIG_FLAGS} -D${d} )
endforeach()
set( CMAKE_SWIG_FLAGS ${SWIG_FLAGS} )
include_directories( BEFORE ${INC_BEFORE} )
include_directories(
${CMAKE_SOURCE_DIR}/common
${INC_AFTER}
)
set( SWIG_MODULE_kiway_EXTRA_DEPS
${CMAKE_SOURCE_DIR}/common/swig/ki_exception.i
${CMAKE_SOURCE_DIR}/common/swig/kicad.i
)
swig_add_module( kiway python
swig/kiway.i
)
swig_link_libraries( kiway
common
${wxWidgets_LIBRARIES}
${PYTHON_LIBRARIES}
)
set_source_files_properties( ${swig_generated_file_fullname} PROPERTIES
# See section 16.3 "The SWIG runtime code"
# http://www.swig.org/Doc3.0/SWIGDocumentation.html#Modules_nn2
COMPILE_FLAGS "-DSWIG_TYPE_TABLE=WXPYTHON_TYPE_TABLE -Wno-delete-non-virtual-dtor"
)
if( MAKE_LINK_MAPS )
set_target_properties( _kiway PROPERTIES
LINK_FLAGS "-Wl,-cref,-Map=_kiway.so.map"
)
endif()
endif()

View File

@ -208,20 +208,6 @@ wxString GetVersionInfoData( const wxString& aTitle, bool aHtml, bool aBrief )
// Add build settings config (build options):
aMsg << "Build settings:" << eol;
aMsg << indent4 << "KICAD_SCRIPTING_PYTHON3=";
#ifdef KICAD_SCRIPTING_PYTHON3
aMsg << ON;
#else
aMsg << OFF;
#endif
aMsg << indent4 << "KICAD_SCRIPTING_WXPYTHON_PHOENIX=";
#ifdef KICAD_SCRIPTING_WXPYTHON_PHOENIX
aMsg << ON;
#else
aMsg << OFF;
#endif
#ifdef KICAD_USE_OCE
aMsg << indent4 << "KICAD_USE_OCE=" << ON;
#endif

View File

@ -109,6 +109,7 @@ const wxString KIWAY::dso_search_path( FACE_T aFaceId )
case FACE_PL_EDITOR: name = KIFACE_PREFIX "pl_editor"; break;
case FACE_PCB_CALCULATOR: name = KIFACE_PREFIX "pcb_calculator"; break;
case FACE_BMP2CMP: name = KIFACE_PREFIX "bitmap2component"; break;
case FACE_PYTHON: name = KIFACE_PREFIX "kipython"; break;
default:
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
@ -122,7 +123,6 @@ const wxString KIWAY::dso_search_path( FACE_T aFaceId )
{
// The 2 *.cpp program launchers: single_top.cpp and kicad.cpp expect
// the *.kiface's to reside in same directory as their binaries do.
// Not so for python launcher, identified by KFCTL_PY_PROJECT_SUITE
path = wxStandardPaths::Get().GetExecutablePath();
}
@ -338,6 +338,9 @@ KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType )
case FRAME_CVPCB_DISPLAY:
return FACE_CVPCB;
case FRAME_PYTHON:
return FACE_PYTHON;
case FRAME_GERBER:
return FACE_GERBVIEW;

View File

@ -1,249 +0,0 @@
//%module(directors="1") kiway
%module kiway
%import(module="wx") wx_kiway_player_hierarchy.h
%include ki_exception.i // affects all that follow it
/*
By default we do not translate exceptions for EVERY C++ function since not every
C++ function throws, and that would be unused and very bulky mapping code.
Therefore please help gather the subset of C++ functions for this class that do
throw and add them here, before the class declarations.
*/
HANDLE_EXCEPTIONS(KIWAY::Player)
%include pgm_base.h
%include frame_type.h
%include mail_type.h
%include project.h
%include kiway.h
%include kiway_express.h
%include kiway_player.i
%constant KIWAY Kiway;
%pythoncode
%{
#import wx
%}
%{
#include <kiway.h>
#include <kiway_express.h>
#include <pgm_base.h>
#include <wx/app.h>
#include <wx/stdpaths.h>
#include <wx/wxPython/wxPython_int.h>
// Only a single KIWAY is supported in this single_top top level component,
// which is dedicated to loading only a single DSO.
KIWAY Kiway( &Pgm(), KFCTL_PY_PROJECT_SUITE );
// a dummy to quiet linking with EDA_BASE_FRAME::config();
#include <kiface_i.h>
KIFACE_I& 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" ) );
return (KIFACE_I&) *(KIFACE_I*) 0;
}
/**
* Struct PGM_PYTHON
* implements PGM_BASE with its own OnPgmInit() and OnPgmExit().
*/
static struct PGM_PYTHON : public PGM_BASE
{
#if 0
bool OnPgmInit( wxApp* aWxApp )
{
// first thing: set m_wx_app
SetApp( aWxApp );
if( !initPgm() )
return false;
// 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( FRAME_PCB, true );
Kiway.SetTop( frame );
App().SetTopWindow( frame ); // wxApp gets a face.
// Open project or file specified on the command line:
int argc = App().argc;
if( argc > 1 )
{
/*
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.
*/
std::vector<wxString> argSet;
for( int i=1; i<argc; ++i )
{
argSet.push_back( App().argv[i] );
}
// special attention to the first argument: argv[1] (==argSet[0])
wxFileName argv1( argSet[0] );
if( argc == 2 )
{
#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 facillity 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();
argSet[0] = argv1.GetFullPath();
}
// Use the KIWAY_PLAYER::OpenProjectFiles() API function:
if( !frame->OpenProjectFiles( argSet ) )
{
// 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;
}
}
frame->Show();
return true;
}
void OnPgmExit()
{
Kiway.OnKiwayEnd();
saveCommonSettings();
// Destroy everything in PGM_BASE, especially wxSingleInstanceCheckerImpl
// earlier than wxApp and earlier than static destruction would.
PGM_BASE::destroy();
}
#endif
#if 0 // multi-project
void PGM_KICAD::MacOpenFile( const wxString& aFileName )
{
#if defined(__WXMAC__)
KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) App().GetTopWindow();
frame->SetProjectFileName( aFileName );
wxCommandEvent loadEvent( 0, wxID_ANY );
frame->OnLoadProject( loadEvent );
#endif
}
#else
void MacOpenFile( const wxString& aFileName ) override
{
wxFileName filename( aFileName );
if( filename.FileExists() )
{
#if 0
// this pulls in EDA_DRAW_FRAME type info, which we don't want in
// the link image.
KIWAY_PLAYER* frame = dynamic_cast<KIWAY_PLAYER*>( App().GetTopWindow() );
#else
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow();
#endif
if( frame )
frame->OpenProjectFiles( std::vector<wxString>( 1, aFileName ) );
}
}
#endif
} program;
PGM_BASE& Pgm()
{
return program;
}
%}
/*
import ctypes, os, sys
libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libcef.so')
if os.path.exists(libcef_so):
*/
%extend PGM_BASE {
%pythoncode
%{
def OnPgmInit(self):
print("hereA")
if not self.InitPgm():
return False;
print("hereB")
try:
# A KIWAY_PLAYER is a wx.Window
frame = Kiway.Player( FRAME_SCH, True )
print("here0")
except IOError as e:
print('Player()', e)
return None
print("here1")
Kiway.SetTop(frame)
print("here2")
return frame
%}
};

View File

@ -1,8 +0,0 @@
// Swig interface to classes KIWAY_PLAYER and KIWAY_HOLDER
%include kiway_player.h
%{
#include <kiway_player.h>
%}

View File

@ -74,29 +74,17 @@ wxString* newWxStringFromPy( PyObject* src )
PyObject* uni_str = src;
// if not an str or unicode, try to str(src)
#if PY_MAJOR_VERSION >= 3
if( !PyBytes_Check( src ) && !PyUnicode_Check( src ) )
#else
if( !PyString_Check( src ) && !PyUnicode_Check( src ) )
#endif
{
obj = PyObject_Str( src );
#if PY_MAJOR_VERSION >= 3
uni_str = obj; // in case of Python 3 our string is already correctly encoded
#endif
must_unref_obj = true;
if( PyErr_Occurred() )
return NULL;
}
#if PY_MAJOR_VERSION >= 3
if( PyBytes_Check( obj ) )
#else
if( PyString_Check( obj ) )
#endif
{
uni_str = PyUnicode_FromEncodedObject( obj, wxPythonEncoding, "strict" );
must_unref_str = true;
@ -106,21 +94,11 @@ wxString* newWxStringFromPy( PyObject* src )
}
result = new wxString();
#if PY_MAJOR_VERSION >= 3
size_t len = PyUnicode_GET_LENGTH( uni_str );
#else
size_t len = PyUnicode_GET_SIZE( uni_str );
#endif
if( len )
{
#if PY_MAJOR_VERSION >= 3
PyUnicode_AsWideChar( uni_str,
wxStringBuffer( *result, len ), len );
#else
PyUnicode_AsWideChar( (PyUnicodeObject*) uni_str,
wxStringBuffer( *result, len ), len );
#endif
PyUnicode_AsWideChar( uni_str, wxStringBuffer( *result, len ), len );
}
if( must_unref_str )
@ -144,11 +122,7 @@ wxString* newWxStringFromPy( PyObject* src )
if( PyErr_Occurred() )
return NULL;
}
#if PY_MAJOR_VERSION >= 3
else if( !PyUnicode_Check( src ) )
#else
else if( !PyString_Check( src ) ) // if it's not a string, str(obj)
#endif
{
str = PyObject_Str( src );
must_unref_str = true;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -48,6 +48,8 @@ enum FRAME_T
FRAME_CVPCB,
FRAME_CVPCB_DISPLAY,
FRAME_PYTHON,
FRAME_GERBER,
FRAME_PL_EDITOR,

View File

@ -55,7 +55,8 @@ enum KIFACE_ADDR_ID : int
KIFACE_NEW_DRC_ENGINE,
KIFACE_LOAD_PCB,
KIFACE_LOAD_SCHEMATIC,
KIFACE_NETLIST_SCHEMATIC
KIFACE_NETLIST_SCHEMATIC,
KIFACE_SCRIPTING_WINDOW
};
#endif // KIFACE_IDS

View File

@ -154,7 +154,6 @@ struct KIFACE
#define KFCTL_STANDALONE (1<<0) ///< Running as a standalone Top.
#define KFCTL_CPP_PROJECT_SUITE (1<<1) ///< Running under C++ project mgr, possibly with others.
#define KFCTL_PY_PROJECT_SUITE (1<<2) ///< Running under python project mgr, possibly with others.
/**

View File

@ -98,12 +98,8 @@ install( TARGETS kicad
if( APPLE )
# "install( CODE ... )" will launch its own CMake, so no variables from
# this CMake instance are accessible... use helper to transfer
if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
set( SCRIPTING_HELPER "1" )
else()
set( SCRIPTING_HELPER "0" )
endif()
set( SCRIPTING_HELPER "1" )
if( KICAD_SPICE )
set( SPICE_HELPER "1" )
else()

View File

@ -17,15 +17,12 @@ add_subdirectory(router)
# psnrouter depends on make_lexer outputs in common (bug #1285878 )
add_dependencies( pnsrouter pcbcommon )
if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/swig )
# Infrequently needed headers go at end of search paths, append to INC_AFTER
set( INC_AFTER ${INC_AFTER} swig )
set( INC_AFTER ${INC_AFTER} ${CMAKE_SOURCE_DIR}/common/swig )
file( MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/swig )
#message( STATUS "pcbnew INC_AFTER:${INC_AFTER}" )
endif()
# Infrequently needed headers go at end of search paths, append to INC_AFTER
set( INC_AFTER ${INC_AFTER} swig )
set( INC_AFTER ${INC_AFTER} ${CMAKE_SOURCE_DIR}/common/swig )
include_directories( BEFORE ${INC_BEFORE} )
include_directories(
@ -158,6 +155,8 @@ set( PCBNEW_DIALOGS
dialogs/panel_fp_editor_color_settings.cpp
dialogs/panel_fp_editor_defaults.cpp
dialogs/panel_fp_editor_defaults_base.cpp
dialogs/panel_pcbnew_action_plugins.cpp
dialogs/panel_pcbnew_action_plugins_base.cpp
dialogs/panel_pcbnew_color_settings.cpp
dialogs/panel_pcbnew_display_origin.cpp
dialogs/panel_pcbnew_display_origin_base.cpp
@ -178,13 +177,6 @@ set( PCBNEW_DIALOGS
footprint_wizard_frame_functions.cpp
)
if( KICAD_SCRIPTING AND KICAD_SCRIPTING_ACTION_MENU )
set( PCBNEW_DIALOGS ${PCBNEW_DIALOGS}
dialogs/panel_pcbnew_action_plugins.cpp
dialogs/panel_pcbnew_action_plugins_base.cpp
)
endif()
set( PCBNEW_BRDSTACKUP_MGR
board_stackup_manager/dielectric_material.cpp
board_stackup_manager/stackup_predefined_prms.cpp
@ -382,7 +374,7 @@ set( PCBNEW_SCRIPTING_PYTHON_HELPERS
swig/pcbnew_action_plugins.cpp
swig/pcbnew_footprint_wizards.cpp
swig/pcbnew_scripting_helpers.cpp
swig/python_scripting.cpp
swig/pcbnew_scripting.cpp
)
@ -396,123 +388,111 @@ if( COMPILER_SUPPORTS_WARNINGS )
endif()
if( KICAD_SCRIPTING )
# Disable all warnings for the SWIG file
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
if( MSYS )
# For some reason the .cxx file generated by SWIG cannot be linked if compiled with debug options:
# it creates a *lot* of not found symbols. So compile it with release mode
set_source_files_properties( pcbnew_wrap.cxx PROPERTIES COMPILE_FLAGS "-O2 -Wno-everything" )
else()
set_source_files_properties( pcbnew_wrap.cxx PROPERTIES COMPILE_FLAGS "-Wno-everything" )
endif()
# Disable all warnings for the SWIG file
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
if( MSYS )
# For some reason the .cxx file generated by SWIG cannot be linked if compiled with debug options:
# it creates a *lot* of not found symbols. So compile it with release mode
set_source_files_properties( pcbnew_wrap.cxx PROPERTIES COMPILE_FLAGS "-O2 -Wno-everything" )
else()
set_source_files_properties( pcbnew_wrap.cxx PROPERTIES COMPILE_FLAGS "-Wno-everything" )
endif()
set( PCBNEW_SCRIPTING_SRCS
${PCBNEW_SCRIPTING_DIALOGS}
pcbnew_wrap.cxx
${PCBNEW_SCRIPTING_PYTHON_HELPERS}
)
endif()
set( PCBNEW_SCRIPTING_SRCS
${PCBNEW_SCRIPTING_DIALOGS}
pcbnew_wrap.cxx
${PCBNEW_SCRIPTING_PYTHON_HELPERS}
)
if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
set( SWIG_FLAGS
-I${CMAKE_CURRENT_SOURCE_DIR}
-I${CMAKE_SOURCE_DIR}/include
-I${CMAKE_SOURCE_DIR}/scripting
-I${CMAKE_SOURCE_DIR}/common/swig
-I${CMAKE_SOURCE_DIR}/libs/kimath/include
)
if( DEBUG )
set( SWIG_FLAGS ${SWIG_FLAGS} -DDEBUG )
endif()
# collect CFLAGS , and pass them to swig later
get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS )
foreach( d ${DirDefs} )
set( SWIG_FLAGS ${SWIG_FLAGS} -D${d} )
endforeach()
set( SWIG_FLAGS
-I${CMAKE_CURRENT_SOURCE_DIR}
-I${CMAKE_SOURCE_DIR}/include
-I${CMAKE_SOURCE_DIR}/scripting
-I${CMAKE_SOURCE_DIR}/common/swig
-I${CMAKE_SOURCE_DIR}/libs/kimath/include
)
if( DEBUG )
set( SWIG_FLAGS ${SWIG_FLAGS} -DDEBUG )
endif()
# collect CFLAGS , and pass them to swig later
get_directory_property( DirDefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS )
foreach( d ${DirDefs} )
set( SWIG_FLAGS ${SWIG_FLAGS} -D${d} )
endforeach()
if( KICAD_SCRIPTING ) # Generate pcbnew.py and pcbnew_wrap.cxx using swig
# We deliberately do not use the CMake support for swig here,
# i.e. swig_add_footprint()) because we want full control.
# We deliberately do not use the CMake support for swig here,
# i.e. swig_add_footprint()) because we want full control.
# Avoid threading in SWIG (breaks threads in pcbnew)
set( SWIG_OPTS -python -c++ -nothreads )
# Avoid threading in SWIG (breaks threads in pcbnew)
set( SWIG_OPTS -python -c++ -nothreads )
if( KICAD_SCRIPTING_PYTHON3 )
set( SWIG_OPTS ${SWIG_OPTS} -py3 )
endif()
# Use python3-specific features
set( SWIG_OPTS ${SWIG_OPTS} -py3 )
set( SWIG_OPTS ${SWIG_OPTS} -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} )
set( SWIG_OPTS ${SWIG_OPTS} -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} )
if( EXISTS ${CMAKE_CURRENT_BINARY_DIR}/doxygen-xml )
set( SWIG_OPTS ${SWIG_OPTS} -DENABLE_DOCSTRINGS_FROM_DOXYGEN )
set( SWIG_OPTS ${SWIG_OPTS} -I${CMAKE_CURRENT_BINARY_DIR}/docstrings )
endif()
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
DEPENDS pcbcommon
DEPENDS plotcontroller.h
DEPENDS exporters/gendrill_Excellon_writer.h
DEPENDS exporters/export_vrml.h
DEPENDS swig/pcbnew.i
DEPENDS swig/board.i
DEPENDS swig/board_connected_item.i
DEPENDS swig/board_design_settings.i
DEPENDS swig/board_item.i
DEPENDS swig/board_item_container.i
DEPENDS swig/connectivity.i
DEPENDS swig/dimension.i
DEPENDS swig/pcb_shape.i
DEPENDS swig/fp_shape.i
DEPENDS swig/marker_pcb.i
DEPENDS swig/pcb_target.i
DEPENDS swig/pcb_plot_params.i
DEPENDS swig/footprint.i
DEPENDS swig/netinfo.i
DEPENDS swig/pad.i
DEPENDS swig/pcb_text.i
DEPENDS swig/plugins.i
DEPENDS swig/fp_text.i
DEPENDS swig/track.i
DEPENDS swig/units.i
DEPENDS swig/typeinfo.i
DEPENDS swig/zone.i
DEPENDS swig/zone_settings.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/kicad.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/wx.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/ki_exception.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/netclass.i
DEPENDS ${CMAKE_SOURCE_DIR}/scripting/kicadplugins.i
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/docstrings
# Make docstrings.i available if it doesn't exist
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/docstrings/docstrings.i
COMMAND ${SWIG_EXECUTABLE}
${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx swig/pcbnew.i
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_SOURCE_DIR}/scripting/build_tools/fix_swig_imports.py
${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if( EXISTS ${CMAKE_CURRENT_BINARY_DIR}/doxygen-xml )
set( SWIG_OPTS ${SWIG_OPTS} -DENABLE_DOCSTRINGS_FROM_DOXYGEN )
set( SWIG_OPTS ${SWIG_OPTS} -I${CMAKE_CURRENT_BINARY_DIR}/docstrings )
endif()
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
DEPENDS pcbcommon
DEPENDS plotcontroller.h
DEPENDS exporters/gendrill_Excellon_writer.h
DEPENDS exporters/export_vrml.h
DEPENDS swig/pcbnew.i
DEPENDS swig/board.i
DEPENDS swig/board_connected_item.i
DEPENDS swig/board_design_settings.i
DEPENDS swig/board_item.i
DEPENDS swig/board_item_container.i
DEPENDS swig/connectivity.i
DEPENDS swig/dimension.i
DEPENDS swig/pcb_shape.i
DEPENDS swig/fp_shape.i
DEPENDS swig/marker_pcb.i
DEPENDS swig/pcb_target.i
DEPENDS swig/pcb_plot_params.i
DEPENDS swig/footprint.i
DEPENDS swig/netinfo.i
DEPENDS swig/pad.i
DEPENDS swig/pcb_text.i
DEPENDS swig/plugins.i
DEPENDS swig/fp_text.i
DEPENDS swig/track.i
DEPENDS swig/units.i
DEPENDS swig/typeinfo.i
DEPENDS swig/zone.i
DEPENDS swig/zone_settings.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/kicad.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/wx.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/ki_exception.i
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/netclass.i
DEPENDS ${CMAKE_SOURCE_DIR}/scripting/kicadplugins.i
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/docstrings
# Make docstrings.i available if it doesn't exist
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/docstrings/docstrings.i
COMMAND ${SWIG_EXECUTABLE}
${SWIG_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx swig/pcbnew.i
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_SOURCE_DIR}/scripting/build_tools/fix_swig_imports.py
${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if( UNIX AND NOT APPLE )
list( APPEND PCBNEW_EXTRA_LIBS rt )
endif()
@ -523,52 +503,49 @@ endif()
###
if( DOXYGEN_FOUND )
if( KICAD_SCRIPTING )
# create XML files from doxygen parsing
add_custom_target( doxygen-python-xml
${CMAKE_COMMAND} -E remove_directory doxygen-python-xml
COMMAND SOURCES_DIR=${CMAKE_SOURCE_DIR} ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile_xml
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS Doxyfile_xml
COMMENT "building doxygen docs into directory doxygen-python/html"
)
# create XML files from doxygen parsing
add_custom_target( doxygen-python-xml
${CMAKE_COMMAND} -E remove_directory doxygen-python-xml
COMMAND SOURCES_DIR=${CMAKE_SOURCE_DIR} ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile_xml
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS Doxyfile_xml
COMMENT "building doxygen docs into directory doxygen-python/html"
)
# create .i files from XML doxygen parsing, docstrings.i will include all of them
add_custom_target( xml-to-docstrings
COMMAND ${CMAKE_COMMAND} -E remove_directory docstrings
COMMAND ${CMAKE_COMMAND} -E make_directory docstrings
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripting/build_tools/extract_docstrings.py pcbnew.py doxygen-xml/xml docstrings
COMMAND ${CMAKE_COMMAND} -E remove pcbnew.py # force removal so it will be recreated later with the new docstrings
COMMENT "building docstring files"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS pcbnew.py
DEPENDS doxygen-python-xml
)
# create .i files from XML doxygen parsing, docstrings.i will include all of them
add_custom_target( xml-to-docstrings
COMMAND ${CMAKE_COMMAND} -E remove_directory docstrings
COMMAND ${CMAKE_COMMAND} -E make_directory docstrings
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripting/build_tools/extract_docstrings.py pcbnew.py doxygen-xml/xml docstrings
COMMAND ${CMAKE_COMMAND} -E remove pcbnew.py # force removal so it will be recreated later with the new docstrings
COMMENT "building docstring files"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS pcbnew.py
DEPENDS doxygen-python-xml
)
# The sources to give to the Python Doxygen target
set( DOXYGEN_PYTHON_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
${CMAKE_CURRENT_SOURCE_DIR}/python/plugins/FootprintWizardBase.py
${CMAKE_CURRENT_SOURCE_DIR}/python/plugins/PadArray.py )
# The sources to give to the Python Doxygen target
set( DOXYGEN_PYTHON_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
${CMAKE_CURRENT_SOURCE_DIR}/python/plugins/FootprintWizardBase.py
${CMAKE_CURRENT_SOURCE_DIR}/python/plugins/PadArray.py )
# The Doxyfile expects a space-separated list in the env var
string(REPLACE ";" " " DOXYGEN_PYTHON_SOURCES_STR "${DOXYGEN_PYTHON_SOURCES}")
# The Doxyfile expects a space-separated list in the env var
string(REPLACE ";" " " DOXYGEN_PYTHON_SOURCES_STR "${DOXYGEN_PYTHON_SOURCES}")
# Create doxygen-python html
add_custom_target( doxygen-python
${CMAKE_COMMAND} -E remove_directory doxygen-python
COMMAND ${CMAKE_COMMAND} -E env
PYTHON_SOURCES_TO_DOC=${DOXYGEN_PYTHON_SOURCES_STR}
CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile_python
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS Doxyfile_python
DEPENDS xml-to-docstrings
DEPENDS ${DOXYGEN_PYTHON_SOURCES}
COMMENT "building doxygen docs into directory doxygen-python/html"
)
endif()
# Create doxygen-python html
add_custom_target( doxygen-python
${CMAKE_COMMAND} -E remove_directory doxygen-python
COMMAND ${CMAKE_COMMAND} -E env
PYTHON_SOURCES_TO_DOC=${DOXYGEN_PYTHON_SOURCES_STR}
CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile_python
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS Doxyfile_python
DEPENDS xml-to-docstrings
DEPENDS ${DOXYGEN_PYTHON_SOURCES}
COMMENT "building doxygen docs into directory doxygen-python/html"
)
endif()
@ -632,6 +609,7 @@ target_link_libraries( pcbnew
# There's way too much crap coming in from common yet.
common
gal
scripting
${wxWidgets_LIBRARIES}
)
@ -708,6 +686,7 @@ set( PCBNEW_KIFACE_LIBRARIES
kiplatform
common
gal
scripting
dxflib_qcad
tinyspline_lib
idf3
@ -787,103 +766,74 @@ else()
)
endif()
if( KICAD_SCRIPTING )
if( NOT APPLE )
install( FILES ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py DESTINATION ${PYTHON_DEST} )
else()
# put into bundle at build time, it is relocated at install
add_custom_target( ScriptingPcbnewPyCopy ALL
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py" "${PYTHON_DEST}/"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
COMMENT "Copying pcbnew.py into ${PYTHON_DEST}"
)
add_dependencies( ScriptingPcbnewPyCopy ScriptingPythonDirectoryCreation )
endif()
# python plugins
install( DIRECTORY ${PROJECT_SOURCE_DIR}/pcbnew/python/plugins/
DESTINATION ${KICAD_DATA}/scripting/plugins
FILE_PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
)
# python shell
if ( KICAD_SCRIPTING_WXPYTHON )
install( DIRECTORY ${PROJECT_SOURCE_DIR}/pcbnew/python/kicad_pyshell/
DESTINATION ${KICAD_DATA}/scripting/kicad_pyshell
FILE_PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
if( NOT APPLE )
install( FILES ${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py DESTINATION ${PYTHON_DEST} )
else()
# put into bundle at build time, it is relocated at install
add_custom_target( ScriptingPcbnewPyCopy ALL
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/pcbnew/pcbnew.py" "${PYTHON_DEST}/"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/pcbnew.py
COMMENT "Copying pcbnew.py into ${PYTHON_DEST}"
)
endif()
add_dependencies( ScriptingPcbnewPyCopy ScriptingPythonDirectoryCreation )
endif()
# python plugins
install( DIRECTORY ${PROJECT_SOURCE_DIR}/pcbnew/python/plugins/
DESTINATION ${KICAD_DATA}/scripting/plugins
FILE_PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
)
if( KICAD_SCRIPTING_MODULES )
# 1) KICAD_SCRIPTING enables python inside _pcbnew.kiface.
# 2) KICAD_SCRIPTING_MODULES enables python from the OS command line for pcbnew.
# When python is running within _pcbnew.kiface (case 1 above) it uses said
# kiface for the native part of the pcbnew python module. This is a kind of
# circular dependency that works well. When running python from
# the command line (case 2 above) then python needs a native portion of the pcbnew
# python module also, and this is _pcbnew.{so,pyd}. It turns out that the
# kiface file is built adequately to serve the needs of 2) for now if it is
# merely renamed. This is phase 1 of a 2 step plan.
# In phase 2 we will use the _pcbnew.kiface file without renaming, by doctoring
# what the python portion of the pcbnew python module wants to load when run
# from the command line, case 2 above.
# Here is built the _pcbnew.{so,pyd} which is the native part of the pcbnew Python library
# when Python is used from the command line.
# Here is built the _pcbnew.{so,pyd} which is the native part of the pcbnew Python library
# when Python is used from the command line.
if( MINGW OR VCPKG_TOOLCHAIN )
install( FILES ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.pyd DESTINATION ${PYTHON_DEST} )
set( PYMOD_EXT "pyd" )
elseif( APPLE )
# put everything into bundle at build time, it is relocated at install
add_custom_target( ScriptingModulesPcbnewSoCopy ALL
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.so" "${PYTHON_DEST}/"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.so
COMMENT "Copying _pcbnew.so into ${PYTHON_DEST}"
)
add_dependencies( ScriptingModulesPcbnewSoCopy ScriptingPythonDirectoryCreation )
set( PYMOD_EXT "so" )
else() # only linux remains among supported platforms
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.kiface DESTINATION ${PYTHON_DEST} COMPONENT binary RENAME "_pcbnew.so" )
set( PYMOD_EXT "so" )
endif()
if( APPLE )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
DEPENDS pcbnew_kiface
COMMAND ${CMAKE_COMMAND} -E copy ${OSX_BUNDLE_BUILD_KIFACE_DIR}/_pcbnew.kiface _pcbnew.${PYMOD_EXT}
COMMENT "Creating python's pcbnew native module _pcbnew.${PYMOD_EXT} for command line use."
)
add_custom_target(
pcbnew_python_module ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
)
else()
# For phase 1, copy _pcbnew.kiface to the python module.
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
DEPENDS pcbnew_kiface
COMMAND ${CMAKE_COMMAND} -E copy _pcbnew.kiface _pcbnew.${PYMOD_EXT}
COMMENT "Creating python's pcbnew native module _pcbnew.${PYMOD_EXT} for command line use."
)
add_custom_target(
pcbnew_python_module ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
)
endif()
if( MINGW OR VCPKG_TOOLCHAIN )
install( FILES ${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.pyd DESTINATION ${PYTHON_DEST} )
set( PYMOD_EXT "pyd" )
elseif( APPLE )
# put everything into bundle at build time, it is relocated at install
add_custom_target( ScriptingModulesPcbnewSoCopy ALL
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.so" "${PYTHON_DEST}/"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.so
COMMENT "Copying _pcbnew.so into ${PYTHON_DEST}"
)
add_dependencies( ScriptingModulesPcbnewSoCopy ScriptingPythonDirectoryCreation )
set( PYMOD_EXT "so" )
else() # only linux remains among supported platforms
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.kiface DESTINATION ${PYTHON_DEST} COMPONENT binary RENAME "_pcbnew.so" )
set( PYMOD_EXT "so" )
endif()
if( APPLE )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
DEPENDS pcbnew_kiface
COMMAND ${CMAKE_COMMAND} -E copy ${OSX_BUNDLE_BUILD_KIFACE_DIR}/_pcbnew.kiface _pcbnew.${PYMOD_EXT}
COMMENT "Creating python's pcbnew native module _pcbnew.${PYMOD_EXT} for command line use."
)
add_custom_target(
pcbnew_python_module ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
)
else()
# For phase 1, copy _pcbnew.kiface to the python module.
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
DEPENDS pcbnew_kiface
COMMAND ${CMAKE_COMMAND} -E copy _pcbnew.kiface _pcbnew.${PYMOD_EXT}
COMMENT "Creating python's pcbnew native module _pcbnew.${PYMOD_EXT} for command line use."
)
add_custom_target(
pcbnew_python_module ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_pcbnew.${PYMOD_EXT}
)
endif()
if( APPLE )
if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
# If we don't have wxPython, then we must create the site-packages directory
add_custom_target( ScriptingPythonDirectoryCreation ALL
COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_DEST}"
COMMENT "Creating Python library directory ${PYTHON_DEST}"
)
endif()
# If we don't have wxPython, then we must create the site-packages directory
add_custom_target( ScriptingPythonDirectoryCreation ALL
COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_DEST}"
COMMENT "Creating Python library directory ${PYTHON_DEST}"
)
endif()

View File

@ -36,7 +36,7 @@
#include <dialog_footprint_wizard_list.h>
#include <footprint_wizard_frame.h>
#include <python_scripting.h>
#include <swig/pcbnew_scripting.h>
enum FPGeneratorRowNames
{

View File

@ -30,7 +30,7 @@
#include <grid_tricks.h>
#include <widgets/wx_grid.h>
#include <python_scripting.h>
#include <pcbnew_scripting.h>
#define GRID_CELL_MARGIN 4

View File

@ -50,6 +50,7 @@
#include <project/project_file.h>
#include <project/project_local_settings.h>
#include <project/net_settings.h>
#include <python_scripting.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <tool/tool_manager.h>
@ -96,8 +97,8 @@
#include <widgets/panel_selection_filter.h>
#include <kiplatform/app.h>
#include <python_scripting.h>
#include <action_plugin.h>
#include "../scripting/python_scripting.h"
using namespace std::placeholders;
@ -1292,18 +1293,26 @@ void PCB_EDIT_FRAME::UpdateUserInterface()
void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable()
{
wxWindow * pythonPanelFrame = findPythonConsole();
bool pythonPanelShown = true;
KIWAY_PLAYER* frame = Kiway().Player( FRAME_PYTHON, false );
if( pythonPanelFrame == NULL )
pythonPanelFrame = CreatePythonShellWindow( this, pythonConsoleNameId() );
else
pythonPanelShown = ! pythonPanelFrame->IsShown();
if( !frame )
{
frame = Kiway().Player( FRAME_PYTHON, true, this );
if( !frame->IsVisible() )
frame->Show( true );
// On Windows, Raise() does not bring the window on screen, when iconized
if( frame->IsIconized() )
frame->Iconize( false );
frame->Raise();
return;
}
frame->Show( !frame->IsVisible() );
if( pythonPanelFrame )
pythonPanelFrame->Show( pythonPanelShown );
else
wxMessageBox( wxT( "Error: unable to create the Python Console" ) );
}
@ -1558,7 +1567,7 @@ void PCB_EDIT_FRAME::PythonSyncEnvironmentVariables()
// Set the environment variables for python scripts
// note: the string will be encoded UTF8 for python env
for( auto& var : vars )
pcbnewUpdatePythonEnvVar( var.first, var.second.GetValue() );
UpdatePythonEnvVar( var.first, var.second.GetValue() );
// Because the env vars can de modified by the python scripts (rewritten in UTF8),
// regenerate them (in Unicode) for our normal environment
@ -1571,7 +1580,7 @@ void PCB_EDIT_FRAME::PythonSyncProjectName()
{
wxString evValue;
wxGetEnv( PROJECT_VAR_NAME, &evValue );
pcbnewUpdatePythonEnvVar( wxString( PROJECT_VAR_NAME ).ToStdString(), evValue );
UpdatePythonEnvVar( wxString( PROJECT_VAR_NAME ).ToStdString(), evValue );
// Because PROJECT_VAR_NAME can be modified by the python scripts (rewritten in UTF8),
// regenerate it (in Unicode) for our normal environment

View File

@ -28,7 +28,6 @@
* @brief Pcbnew main program.
*/
#include <python_scripting.h>
#include <pcbnew_scripting_helpers.h>
#include <pgm_base.h>
#include <kiface_i.h>
@ -53,6 +52,9 @@
#include <footprint_preview_panel.h>
#include <footprint_info_impl.h>
#include <dialogs/dialog_configure_paths.h>
#include <paths.h>
#include <python_scripting.h>
#include "invoke_pcb_dialog.h"
#include "dialog_global_fp_lib_table_config.h"
#include <wildcards_and_files_ext.h>
@ -208,97 +210,6 @@ PGM_BASE* PgmOrNull()
#endif
static bool scriptingSetup()
{
#if defined( __WINDOWS__ )
// If our python.exe (in kicad/bin) exists, force our kicad python environment
wxString kipython = FindKicadFile( "python.exe" );
// we need only the path:
wxFileName fn( kipython );
kipython = fn.GetPath();
// If our python install is existing inside kicad, use it
// Note: this is useful only when another python version is installed
if( wxDirExists( kipython ) )
{
// clear any PYTHONPATH and PYTHONHOME env var definition: the default
// values work fine inside Kicad:
wxSetEnv( wxT( "PYTHONPATH" ), wxEmptyString );
wxSetEnv( wxT( "PYTHONHOME" ), wxEmptyString );
// Add our python executable path in first position:
wxString ppath;
wxGetEnv( wxT( "PATH" ), &ppath );
kipython << wxT( ";" ) << ppath;
wxSetEnv( wxT( "PATH" ), kipython );
}
#elif defined( __WXMAC__ )
// Add default paths to PYTHONPATH
wxString pypath;
// Bundle scripting folder (<kicad.app>/Contents/SharedSupport/scripting)
pypath += PATHS::GetOSXKicadDataDir() + wxT( "/scripting" );
// $(KICAD_PATH)/scripting/plugins is always added in kicadplugins.i
if( wxGetenv("KICAD_PATH") != NULL )
{
pypath += wxT( ":" ) + wxString( wxGetenv("KICAD_PATH") );
}
// OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR is provided via the build system.
pypath += wxT( ":" ) + Pgm().GetExecutablePath() + wxT( OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR );
// Original content of $PYTHONPATH
if( wxGetenv( wxT( "PYTHONPATH" ) ) != NULL )
{
pypath = wxString( wxGetenv( wxT( "PYTHONPATH" ) ) ) + wxT( ":" ) + pypath;
}
// set $PYTHONPATH
wxSetEnv( "PYTHONPATH", pypath );
wxString pyhome;
pyhome += Pgm().GetExecutablePath() +
wxT( "Contents/Frameworks/Python.framework/Versions/Current" );
// set $PYTHONHOME
wxSetEnv( "PYTHONHOME", pyhome );
#else
wxString pypath;
// PYTHON_DEST is the scripts install dir as determined by the build system.
pypath = Pgm().GetExecutablePath() + wxT( "../" PYTHON_DEST );
if( !wxIsEmpty( wxGetenv( wxT( "PYTHONPATH" ) ) ) )
pypath = wxString( wxGetenv( wxT( "PYTHONPATH" ) ) ) + wxT( ":" ) + pypath;
wxSetEnv( wxT( "PYTHONPATH" ), pypath );
#endif
wxFileName path( PyPluginsPath( true ) + wxT("/") );
// Ensure the user plugin path exists, and create it if not.
// However, if it cannot be created, this is not a fatal error.
if( !path.DirExists() && !path.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
wxLogError( "Warning: could not create user scripting path %s", path.GetPath() );
if( !pcbnewInitPythonScripting( TO_UTF8( PyScriptingPath() ), TO_UTF8( PyScriptingPath( true ) ) ) )
{
wxLogError( "pcbnewInitPythonScripting() failed." );
return false;
}
return true;
}
void PythonPluginsReloadBase()
{
// Reload plugin list: reload Python plugins if they are newer than the already loaded,
@ -371,21 +282,12 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
}
}
scriptingSetup();
return true;
}
void IFACE::OnKifaceEnd()
{
// Restore the thread state and tell Python to cleanup after itself.
// wxPython will do its own cleanup as part of that process.
// This should only be called if python was setup correctly.
if( IsWxPythonLoaded() )
pcbnewFinishPythonScripting();
end_common();
}

View File

@ -1,11 +0,0 @@
* think about documentation, how to do it
* Action plugins:
right click hooks,
toolbar hooks,
menu hooks,
* IO plugins
* better footprint wizard (preview in footprint wizard list)

View File

@ -29,9 +29,9 @@
#include <zone.h>
#include <menus_helpers.h>
#include <pcbnew_settings.h>
#include <python_scripting.h>
#include <tool/action_menu.h>
#include <tool/action_toolbar.h>
#include "../../scripting/python_scripting.h"
PYTHON_ACTION_PLUGIN::PYTHON_ACTION_PLUGIN( PyObject* aAction )
{

View File

@ -30,7 +30,7 @@
#include "pcbnew_footprint_wizards.h"
#include <cstdio>
#include <macros.h>
#include <python_scripting.h>
#include "../../scripting/python_scripting.h"
PYTHON_FOOTPRINT_WIZARD::PYTHON_FOOTPRINT_WIZARD( PyObject* aWizard )
@ -175,17 +175,10 @@ int PYTHON_FOOTPRINT_WIZARD::GetNumParameterPages()
if( result )
{
#if PY_MAJOR_VERSION >= 3
if( !PyLong_Check( result ) )
return -1;
ret = PyLong_AsLong( result );
#else
if( !PyInt_Check( result ) )
return -1;
ret = PyInt_AsLong( result );
#endif
Py_DECREF( result );
}
@ -316,11 +309,7 @@ wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString&
for( int i = 0; i < len; i++ )
{
wxString& str = aValues[i];
#if PY_MAJOR_VERSION >= 3
PyObject* py_str = PyUnicode_FromString( (const char*) str.mb_str() );
#else
PyObject* py_str = PyString_FromString( (const char*) str.mb_str() );
#endif
PyList_SetItem( py_list, i, py_str );
}

View File

@ -0,0 +1,186 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es>
* Copyright (C) 1992-2019 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 python_scripting.cpp
* @brief methods to add scripting capabilities inside pcbnew
*/
#include "../../scripting/python_scripting.h"
#include <cstdlib>
#include <cstring>
#include <Python.h>
#include <sstream>
#include <eda_base_frame.h>
#include <gal/color4d.h>
#include <trace_helpers.h>
#include <kicad_string.h>
#include <paths.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <kiplatform/environment.h>
#include <wx/app.h>
#include <config.h>
/**
* Initialize the python environment and publish the Pcbnew interface inside it.
*
* This initializes all the wxPython interface and returns the python thread control structure
*/
bool pcbnewInitPythonScripting( const char* aStockScriptingPath, const char* aUserScriptingPath )
{
int retv;
char cmd[1024];
// Load pcbnew inside Python and load all the user plugins and package-based plugins
{
PyLOCK lock;
// Load os so that we can modify the environment variables through python
snprintf( cmd, sizeof( cmd ), "import sys, os, traceback\n"
"sys.path.append(\".\")\n"
"import pcbnew\n"
"pcbnew.LoadPlugins(\"%s\", \"%s\")",
aStockScriptingPath, aUserScriptingPath );
retv = PyRun_SimpleString( cmd );
if( retv != 0 )
wxLogError( "Python error %d occurred running command:\n\n`%s`", retv, cmd );
}
return true;
}
/**
* Run a python method from the pcbnew module.
*
* @param aMethodName is the name of the method (like "pcbnew.myfunction" )
* @param aNames will contain the returned string
*/
static void pcbnewRunPythonMethodWithReturnedString( const char* aMethodName, wxString& aNames )
{
aNames.Clear();
PyLOCK lock;
PyErr_Clear();
PyObject* builtins = PyImport_ImportModule( "pcbnew" );
wxASSERT( builtins );
if( !builtins ) // Something is wrong in pcbnew.py module (incorrect version?)
return;
PyObject* globals = PyDict_New();
PyDict_SetItemString( globals, "pcbnew", builtins );
Py_DECREF( builtins );
// Build the python code
char cmd[1024];
snprintf( cmd, sizeof(cmd), "result = %s()", aMethodName );
// Execute the python code and get the returned data
PyObject* localDict = PyDict_New();
PyObject* pobj = PyRun_String( cmd, Py_file_input, globals, localDict);
Py_DECREF( globals );
if( pobj )
{
PyObject* str = PyDict_GetItemString(localDict, "result" );
const char* str_res = NULL;
if(str)
{
PyObject* temp_bytes = PyUnicode_AsEncodedString( str, "UTF-8", "strict" );
if( temp_bytes != NULL )
{
str_res = PyBytes_AS_STRING( temp_bytes );
aNames = FROM_UTF8( str_res );
Py_DECREF( temp_bytes );
}
else
{
wxLogMessage( "cannot encode unicode python string" );
}
}
else
{
aNames = wxString();
}
Py_DECREF( pobj );
}
Py_DECREF( localDict );
if( PyErr_Occurred() )
wxLogMessage( PyErrStringWithTraceback() );
}
void pcbnewGetUnloadableScriptNames( wxString& aNames )
{
pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetUnLoadableWizards", aNames );
}
void pcbnewGetScriptsSearchPaths( wxString& aNames )
{
pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsSearchPaths", aNames );
}
void pcbnewGetWizardsBackTrace( wxString& aTrace )
{
pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsBackTrace", aTrace );
// Filter message before displaying them
// a trace starts by "Traceback" and is followed by 2 useless lines
// for our purpose
wxArrayString traces;
wxStringSplit( aTrace, traces, '\n' );
// Build the filtered message (remove useless lines)
aTrace.Clear();
for( unsigned ii = 0; ii < traces.Count(); ++ii )
{
if( traces[ii].Contains( "Traceback" ) )
{
ii += 2; // Skip this line and next lines which are related to pcbnew.py module
if( !aTrace.IsEmpty() ) // Add separator for the next trace block
aTrace << "\n**********************************\n";
}
else
aTrace += traces[ii] + "\n";
}
}

View File

@ -0,0 +1,57 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2019 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
*/
#ifndef __PYTHON_SCRIPTING_H
#define __PYTHON_SCRIPTING_H
#include <wx/string.h>
/**
* Initialize the Python engine inside pcbnew.
*/
bool pcbnewInitPythonScripting( const char* aStockScriptingPath, const char* aUserScriptingPath );
/**
* Collect the list of python scripts which could not be loaded.
*
* @param aNames is a wxString which will contain the filenames (separated by '\n')
*/
void pcbnewGetUnloadableScriptNames( wxString& aNames );
/**
* Collect the list of paths where python scripts are searched.
*
* @param aNames is a wxString which will contain the paths (separated by '\n')
*/
void pcbnewGetScriptsSearchPaths( wxString& aNames );
/**
* Return the backtrace of errors (if any) when wizard python scripts are loaded.
*
* @param aNames is a wxString which will contain the trace
*/
void pcbnewGetWizardsBackTrace( wxString& aNames );
#endif // __PYTHON_SCRIPTING_H

View File

@ -1,11 +0,0 @@
from __future__ import print_function
import pcbnew
pcb = pcbnew.GetBoard()
for m in pcb.GetFootprints():
print(m.GetPosition())
for p in m.Pads():
print("p=>", p.GetPosition(), p.GetName())
print(p.GetPosition())

View File

@ -1,10 +0,0 @@
from __future__ import print_function
import pcbnew
pcb = pcbnew.GetBoard()
for m in pcb.GetFootprints():
print(m.GetReference(), "(", m.GetValue(), ") at ", m.GetPosition())
for p in m.Pads():
print(" pad", p.GetName(), "at", p.GetPosition())

View File

@ -1,15 +0,0 @@
#
# manual test session for "Tools -> Scripting Console"
# verify that "board-archive.pretty" folder is present
# result should be identical to "File -> Archive -> ..."
#
import os
import pcbnew
board = pcbnew.GetBoard()
board_path = board.GetFileName()
path_tuple = os.path.splitext(board_path)
board_prefix = path_tuple[0]
aStoreInNewLib = True
aLibName = "footprint-export"
aLibPath = board_prefix + "-archive.pretty"
pcbnew.ArchiveModulesOnBoard(aStoreInNewLib,aLibName,aLibPath)

View File

@ -1,13 +0,0 @@
#
# manual test session for "Tools -> Scripting Console"
# verify that "board.dsn" file is created after this session
# result should be identical to "File -> Export -> Specctra DSN"
#
import os
import pcbnew
board = pcbnew.GetBoard()
board_path = board.GetFileName()
path_tuple = os.path.splitext(board_path)
board_prefix = path_tuple[0]
export_path = board_prefix + ".dsn"
pcbnew.ExportSpecctraDSN(export_path)

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