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.

273 lines
6.6 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /*
  25. * This is a program launcher for a single KIFACE DSO. It only mimics a KIWAY,
  26. * not actually implements one, since only a single DSO is supported by it.
  27. *
  28. * It is compiled multiple times, once for each standalone program and as such
  29. * gets different compiler command line supplied #defines from CMake.
  30. */
  31. #include <typeinfo>
  32. #include <macros.h>
  33. #include <wx/filename.h>
  34. #include <wx/stdpaths.h>
  35. #include <wx/snglinst.h>
  36. #include <wx/html/htmlwin.h>
  37. #include <pgm_base.h>
  38. #include <kiface_base.h>
  39. #include <kiway.h>
  40. #include <pgm_base.h>
  41. #include <kiway_player.h>
  42. #include <confirm.h>
  43. #include <settings/settings_manager.h>
  44. #include <qa_utils/utility_registry.h>
  45. static struct IFACE : public KIFACE_BASE
  46. {
  47. // Of course all are overloads, implementations of the KIFACE.
  48. IFACE( const char* aName, KIWAY::FACE_T aType ) :
  49. KIFACE_BASE( aName, aType )
  50. {}
  51. bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) override
  52. {
  53. return true;
  54. }
  55. void OnKifaceEnd() override {}
  56. wxWindow* CreateKiWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway,
  57. int aCtlBits = 0 ) override
  58. {
  59. assert( false );
  60. return nullptr;
  61. }
  62. /**
  63. * Return a pointer to the requested object.
  64. *
  65. * The safest way to use this is to retrieve a pointer to a static instance of an interface,
  66. * similar to how the KIFACE interface is exported. But if you know what you are doing
  67. * use it to retrieve anything you want.
  68. *
  69. * @param aDataId identifies which object you want the address of.
  70. * @return the requested object which must be cast into the know type.
  71. */
  72. void* IfaceOrAddress( int aDataId ) override
  73. {
  74. return nullptr;
  75. }
  76. }
  77. kiface( "pcb_test_frame", KIWAY::FACE_PCB );
  78. KIWAY Kiway( &Pgm(), KFCTL_STANDALONE );
  79. static struct PGM_TEST_FRAME : public PGM_BASE
  80. {
  81. bool OnPgmInit();
  82. void OnPgmExit()
  83. {
  84. printf("Destroy\n");
  85. Kiway.OnKiwayEnd();
  86. // Destroy everything in PGM_BASE, especially wxSingleInstanceCheckerImpl
  87. // earlier than wxApp and earlier than static destruction would.
  88. PGM_BASE::Destroy();
  89. }
  90. void MacOpenFile( const wxString& aFileName ) override
  91. {
  92. wxFileName filename( aFileName );
  93. if( filename.FileExists() )
  94. {
  95. #if 0
  96. // this pulls in EDA_DRAW_FRAME type info, which we don't want in
  97. // the single_top link image.
  98. KIWAY_PLAYER* frame = dynamic_cast<KIWAY_PLAYER*>( App().GetTopWindow() );
  99. #else
  100. KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow();
  101. #endif
  102. if( frame )
  103. frame->OpenProjectFiles( std::vector<wxString>( 1, aFileName ) );
  104. }
  105. }
  106. }
  107. program;
  108. PGM_BASE& Pgm()
  109. {
  110. return program;
  111. }
  112. // Similar to PGM_BASE& Pgm(), but return nullptr when a *.ki_face
  113. // is run from a python script, mot from a Kicad application
  114. PGM_BASE* PgmOrNull()
  115. {
  116. return &program;
  117. }
  118. KIFACE_BASE& Kiface()
  119. {
  120. return kiface;
  121. }
  122. /**
  123. * Implement a bare naked wxApp (so that we don't become dependent on functionality in a wxApp
  124. * derivative that we cannot deliver under wxPython).
  125. */
  126. struct APP_TEST : public wxApp
  127. {
  128. APP_TEST()
  129. {}
  130. bool OnInit() override
  131. {
  132. try
  133. {
  134. if( !program.OnPgmInit() )
  135. {
  136. program.OnPgmExit();
  137. return false;
  138. }
  139. KI_TEST::COMBINED_UTILITY c_util;
  140. auto app = wxApp::GetInstance();
  141. auto ret = c_util.HandleCommandLine( app->argc, app->argv );
  142. if( ret != KI_TEST::RET_CODES::OK)
  143. return false;
  144. return true;
  145. }
  146. catch( const std::exception& e )
  147. {
  148. wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
  149. FROM_UTF8( typeid(e).name() ), FROM_UTF8( e.what() ) );
  150. }
  151. catch( const IO_ERROR& ioe )
  152. {
  153. wxLogError( ioe.What() );
  154. }
  155. catch(...)
  156. {
  157. wxLogError( wxT( "Unhandled exception of unknown type" ) );
  158. }
  159. program.OnPgmExit();
  160. return false;
  161. }
  162. int OnExit() override
  163. {
  164. program.OnPgmExit();
  165. return wxApp::OnExit();
  166. }
  167. int OnRun() override
  168. {
  169. int ret = -1;
  170. try
  171. {
  172. ret = wxApp::OnRun();
  173. }
  174. catch( const std::exception& e )
  175. {
  176. wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
  177. FROM_UTF8( typeid(e).name() ),
  178. FROM_UTF8( e.what() ) );
  179. }
  180. catch( const IO_ERROR& ioe )
  181. {
  182. wxLogError( ioe.What() );
  183. }
  184. catch(...)
  185. {
  186. wxLogError( wxT( "Unhandled exception of unknown type" ) );
  187. }
  188. program.OnPgmExit();
  189. return ret;
  190. }
  191. };
  192. bool PGM_TEST_FRAME::OnPgmInit()
  193. {
  194. return true;
  195. }
  196. void SetTopFrame ( wxFrame* aFrame )
  197. {
  198. Pgm().App().SetTopWindow( aFrame ); // wxApp gets a face.
  199. aFrame->Show();
  200. }
  201. IMPLEMENT_APP_NO_MAIN(APP_TEST);
  202. #ifndef TEST_APP_NO_MAIN
  203. int main( int argc, char** argv )
  204. {
  205. wxInitialize( argc, argv );
  206. #ifdef TEST_APP_GUI
  207. Pgm().InitPgm( false, true );
  208. #else
  209. Pgm().InitPgm( true, true );
  210. #endif
  211. auto ret = wxEntry( argc, argv );
  212. // This causes some glib warnings on GTK3 (http://trac.wxwidgets.org/ticket/18274)
  213. // but without it, Valgrind notices a lot of leaks from WX
  214. wxUninitialize();
  215. return ret;
  216. }
  217. #endif