You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.3 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2021 KiCad Developers, see AUTHORS.TXT for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 3
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/gpl-3.0.html
  19. * or you may search the http://www.gnu.org website for the version 3 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <frame_type.h>
  24. #include <kipython_frame.h>
  25. #include <kiway_player.h>
  26. #include <python_scripting.h>
  27. #include <pybind11/embed.h>
  28. #include <sstream>
  29. #include <pybind11/embed.h>
  30. void KIPYTHON_FRAME::SetupPythonEditor()
  31. {
  32. using namespace pybind11::literals;
  33. // As always, first grab the GIL
  34. PyLOCK lock;
  35. // Make sure the kicad_pyshell module is in the path
  36. wxString sysPath = SCRIPTING::PyScriptingPath( SCRIPTING::PATH_TYPE::STOCK );
  37. auto locals = pybind11::dict( "stock_path"_a = sysPath.ToStdString() );
  38. pybind11::exec( R"(
  39. import sys
  40. sys.path.append( stock_path )
  41. )", pybind11::globals(), locals );
  42. // passing window ids instead of pointers is because wxPython is not
  43. // exposing the needed c++ apis to make that possible.
  44. std::stringstream pcbnew_pyshell_one_step;
  45. pcbnew_pyshell_one_step << "import kicad_pyshell\n";
  46. pcbnew_pyshell_one_step << "newshell = kicad_pyshell.makePcbnewShellWindow( " << GetId() << " )\n";
  47. // Execute the code to make the makeWindow function we defined above
  48. PyRun_SimpleString( pcbnew_pyshell_one_step.str().c_str() );
  49. /// For unknown reasons, some mac builds don't automatically layout the Python window until resized
  50. /// so force the fit here
  51. Layout();
  52. Fit();
  53. }
  54. void KIPYTHON_FRAME::redirectStdio()
  55. {
  56. // This is a helpful little tidbit to help debugging and such. It
  57. // redirects Python's stdout and stderr to a window that will popup
  58. // only on demand when something is printed, like a traceback.
  59. PyLOCK lock;
  60. using namespace pybind11::literals;
  61. int id = GetId();
  62. auto locals = pybind11::dict( "parent_id"_a= id );
  63. pybind11::exec( R"(
  64. import sys
  65. import wx
  66. output = wx.PyOnDemandOutputWindow()
  67. sys.stderr = output
  68. parent = wx.Window.FindWindowById( parent_id )
  69. output.SetParent( parent )
  70. )", pybind11::globals(), locals );
  71. }
  72. KIPYTHON_FRAME::KIPYTHON_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
  73. KIWAY_PLAYER( aKiway, aParent, FRAME_PYTHON, wxT( "KiPython" ), wxDefaultPosition,
  74. wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, wxT( "KiPython" ),
  75. unityScale )
  76. {
  77. CallAfter( [this]()
  78. {
  79. SetupPythonEditor();
  80. } );
  81. redirectStdio();
  82. }
  83. KIPYTHON_FRAME::~KIPYTHON_FRAME()
  84. {
  85. }