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.

500 lines
16 KiB

14 years ago
14 years ago
17 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
  5. * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. /**
  26. * @file moduleframe.cpp
  27. * @brief Footprint (module) editor main window.
  28. */
  29. #include <fctsys.h>
  30. #include <appl_wxstruct.h>
  31. #include <class_drawpanel.h>
  32. #include <confirm.h>
  33. #include <wxPcbStruct.h>
  34. #include <dialog_helpers.h>
  35. #include <3d_viewer.h>
  36. #include <pcbcommon.h>
  37. #include <class_board.h>
  38. #include <class_module.h>
  39. #include <pcbnew.h>
  40. #include <protos.h>
  41. #include <pcbnew_id.h>
  42. #include <hotkeys.h>
  43. #include <module_editor_frame.h>
  44. static PCB_SCREEN* s_screenModule; // the PCB_SCREEN used by the footprint editor
  45. wxString FOOTPRINT_EDIT_FRAME::m_CurrentLib = wxEmptyString;
  46. BOARD* FOOTPRINT_EDIT_FRAME::s_Pcb;
  47. BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
  48. EVT_MENU_RANGE( ID_POPUP_PCB_ITEM_SELECTION_START, ID_POPUP_PCB_ITEM_SELECTION_END,
  49. PCB_BASE_FRAME::ProcessItemSelection )
  50. EVT_CLOSE( FOOTPRINT_EDIT_FRAME::OnCloseWindow )
  51. EVT_MENU( wxID_EXIT, FOOTPRINT_EDIT_FRAME::CloseModuleEditor )
  52. EVT_SIZE( FOOTPRINT_EDIT_FRAME::OnSize )
  53. EVT_COMBOBOX( ID_ON_ZOOM_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectZoom )
  54. EVT_COMBOBOX( ID_ON_GRID_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectGrid )
  55. EVT_TOOL( ID_MODEDIT_SELECT_CURRENT_LIB, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  56. EVT_TOOL( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  57. EVT_TOOL( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  58. EVT_TOOL( ID_MODEDIT_NEW_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  59. EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  60. EVT_TOOL( ID_MODEDIT_IMPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  61. EVT_TOOL( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  62. EVT_TOOL( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
  63. FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  64. EVT_TOOL( ID_MODEDIT_SHEET_SET, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  65. EVT_TOOL( wxID_PRINT, FOOTPRINT_EDIT_FRAME::ToPrinter )
  66. EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  67. EVT_TOOL( ID_MODEDIT_CHECK, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  68. EVT_TOOL( ID_MODEDIT_PAD_SETTINGS, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  69. EVT_TOOL( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard )
  70. EVT_TOOL( ID_MODEDIT_INSERT_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  71. EVT_TOOL( ID_MODEDIT_UPDATE_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  72. EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  73. EVT_TOOL( wxID_UNDO, FOOTPRINT_EDIT_FRAME::GetComponentFromUndoList )
  74. EVT_TOOL( wxID_REDO, FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList )
  75. // Vertical tool bar button click event handler.
  76. EVT_TOOL( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
  77. EVT_TOOL_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
  78. FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
  79. // Options Toolbar
  80. EVT_TOOL( ID_TB_OPTIONS_SHOW_PADS_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
  81. EVT_TOOL( ID_TB_OPTIONS_SHOW_VIAS_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
  82. EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
  83. EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
  84. // popup commands
  85. EVT_MENU_RANGE( ID_POPUP_PCB_START_RANGE, ID_POPUP_PCB_END_RANGE,
  86. FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  87. EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
  88. FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  89. // Module transformations
  90. EVT_MENU( ID_MODEDIT_MODULE_ROTATE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  91. EVT_MENU( ID_MODEDIT_MODULE_MIRROR, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  92. EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  93. EVT_MENU( ID_PCB_PAD_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  94. EVT_MENU( ID_PCB_USER_GRID_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
  95. // Menu 3D Frame
  96. EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, FOOTPRINT_EDIT_FRAME::Show3D_Frame )
  97. EVT_UPDATE_UI( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected )
  98. EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
  99. EVT_UPDATE_UI( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
  100. FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
  101. EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected )
  102. EVT_UPDATE_UI( ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
  103. FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard )
  104. EVT_UPDATE_UI( ID_MODEDIT_INSERT_MODULE_IN_BOARD,
  105. FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard )
  106. EVT_UPDATE_UI( ID_MODEDIT_UPDATE_MODULE_IN_BOARD,
  107. FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard )
  108. EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
  109. EVT_UPDATE_UI_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
  110. FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
  111. END_EVENT_TABLE()
  112. FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( PCB_EDIT_FRAME* aParent,
  113. const wxString& title,
  114. const wxPoint& pos,
  115. const wxSize& size,
  116. long style ) :
  117. PCB_BASE_FRAME( aParent, MODULE_EDITOR_FRAME, wxEmptyString, pos, size, style )
  118. {
  119. m_FrameName = wxT( "ModEditFrame" );
  120. m_showBorderAndTitleBlock = false; // true to show the frame references
  121. m_showAxis = true; // true to show X and Y axis on screen
  122. m_showGridAxis = true; // show the grid origin axis
  123. m_HotkeysZoomAndGridList = g_Module_Editor_Hokeys_Descr;
  124. // Give an icon
  125. wxIcon icon;
  126. icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) );
  127. SetIcon( icon );
  128. UpdateTitle();
  129. if( !s_Pcb )
  130. s_Pcb = new BOARD();
  131. SetBoard( s_Pcb );
  132. if( !s_screenModule )
  133. s_screenModule = new PCB_SCREEN( GetPageSettings().GetSizeIU() );
  134. SetScreen( s_screenModule );
  135. GetScreen()->SetCurItem( NULL );
  136. LoadSettings();
  137. GetScreen()->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );
  138. GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
  139. SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
  140. ReCreateMenuBar();
  141. ReCreateHToolbar();
  142. ReCreateAuxiliaryToolbar();
  143. ReCreateVToolbar();
  144. ReCreateOptToolbar();
  145. if( m_canvas )
  146. m_canvas->SetEnableBlockCommands( true );
  147. m_auimgr.SetManagedWindow( this );
  148. EDA_PANEINFO horiz;
  149. horiz.HorizontalToolbarPane();
  150. EDA_PANEINFO vert;
  151. vert.VerticalToolbarPane();
  152. EDA_PANEINFO mesg_pane;
  153. mesg_pane.MessageToolbarPane();
  154. m_auimgr.AddPane( m_mainToolBar,
  155. wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top(). Row( 0 ) );
  156. m_auimgr.AddPane( m_auxiliaryToolBar,
  157. wxAuiPaneInfo( horiz ).Name( wxT( "m_auxiliaryToolBar" ) ).Top().Row( 1 ) );
  158. m_auimgr.AddPane( m_drawToolBar,
  159. wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right() );
  160. m_auimgr.AddPane( m_optionsToolBar,
  161. wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ). Left() );
  162. m_auimgr.AddPane( m_canvas,
  163. wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
  164. m_auimgr.AddPane( m_messagePanel,
  165. wxAuiPaneInfo( mesg_pane ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
  166. m_auimgr.Update();
  167. }
  168. FOOTPRINT_EDIT_FRAME::~FOOTPRINT_EDIT_FRAME()
  169. {
  170. // When user reopens the Footprint editor, user would like to find the last edited item.
  171. // Do not delete PCB_SCREEN (by the destructor of EDA_DRAW_FRAME)
  172. SetScreen( NULL );
  173. PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent();
  174. frame->m_ModuleEditFrame = NULL;
  175. // Do not allow PCB_BASE_FRAME::~PCB_BASE_FRAME()
  176. // to delete our precious BOARD, which is also in static FOOTPRINT_EDIT_FRAME::s_Pcb.
  177. // That function, PCB_BASE_FRAME::~PCB_BASE_FRAME(), runs immediately next
  178. // as we return from here.
  179. m_Pcb = 0;
  180. }
  181. BOARD_DESIGN_SETTINGS& FOOTPRINT_EDIT_FRAME::GetDesignSettings() const
  182. {
  183. // get the BOARD_DESIGN_SETTINGS from the parent editor, not our BOARD.
  184. PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent();
  185. wxASSERT( parentFrame );
  186. return parentFrame->GetDesignSettings();
  187. }
  188. void FOOTPRINT_EDIT_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings )
  189. {
  190. // set the BOARD_DESIGN_SETTINGS int parent editor, not our BOARD.
  191. PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent();
  192. wxASSERT( parentFrame );
  193. parentFrame->SetDesignSettings( aSettings );
  194. }
  195. void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
  196. {
  197. if( GetScreen()->IsModify() )
  198. {
  199. if( !IsOK( this, _( "Module Editor: Module modified! Continue?" ) ) )
  200. {
  201. Event.Veto(); return;
  202. }
  203. }
  204. SaveSettings();
  205. Destroy();
  206. }
  207. void FOOTPRINT_EDIT_FRAME::CloseModuleEditor( wxCommandEvent& Event )
  208. {
  209. Close();
  210. }
  211. void FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar( wxUpdateUIEvent& aEvent )
  212. {
  213. aEvent.Enable( GetBoard()->m_Modules != NULL );
  214. if( aEvent.GetEventObject() == m_drawToolBar )
  215. aEvent.Check( GetToolId() == aEvent.GetId() );
  216. }
  217. void FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected( wxUpdateUIEvent& aEvent )
  218. {
  219. aEvent.Enable( m_CurrentLib != wxEmptyString );
  220. }
  221. void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
  222. {
  223. aEvent.Enable( GetBoard()->m_Modules != NULL );
  224. }
  225. void FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent )
  226. {
  227. aEvent.Enable( ( m_CurrentLib != wxEmptyString ) && ( GetBoard()->m_Modules != NULL ) );
  228. }
  229. void FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent )
  230. {
  231. PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent();
  232. aEvent.Enable( frame->GetBoard()->m_Modules != NULL );
  233. }
  234. void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent )
  235. {
  236. PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent();
  237. MODULE* module_in_edit = GetBoard()->m_Modules;
  238. bool canInsert = ( module_in_edit && !module_in_edit->m_Link );
  239. // If the source was deleted, the module can inserted but not updated in the board.
  240. if( module_in_edit && module_in_edit->m_Link ) // this is not a new module
  241. {
  242. BOARD* mainpcb = frame->GetBoard();
  243. MODULE* source_module = mainpcb->m_Modules;
  244. // search if the source module was not deleted:
  245. for( ; source_module != NULL; source_module = source_module->Next() )
  246. {
  247. if( module_in_edit->m_Link == source_module->GetTimeStamp() )
  248. break;
  249. }
  250. canInsert = ( source_module == NULL );
  251. }
  252. aEvent.Enable( canInsert );
  253. }
  254. void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent )
  255. {
  256. PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent();
  257. MODULE* module_in_edit = GetBoard()->m_Modules;
  258. bool canReplace = ( module_in_edit && module_in_edit->m_Link );
  259. if( module_in_edit && module_in_edit->m_Link ) // this is not a new module
  260. {
  261. BOARD* mainpcb = frame->GetBoard();
  262. MODULE* source_module = mainpcb->m_Modules;
  263. // search if the source module was not deleted:
  264. for( ; source_module != NULL; source_module = source_module->Next() )
  265. {
  266. if( module_in_edit->m_Link == source_module->GetTimeStamp() )
  267. break;
  268. }
  269. canReplace = ( source_module != NULL );
  270. }
  271. aEvent.Enable( canReplace );
  272. }
  273. void FOOTPRINT_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event )
  274. {
  275. if( m_Draw3DFrame )
  276. {
  277. // Raising the window does not show the window on Windows if iconized.
  278. // This should work on any platform.
  279. if( m_Draw3DFrame->IsIconized() )
  280. m_Draw3DFrame->Iconize( false );
  281. m_Draw3DFrame->Raise();
  282. // Raising the window does not set the focus on Linux. This should work on any platform.
  283. if( wxWindow::FindFocus() != m_Draw3DFrame )
  284. m_Draw3DFrame->SetFocus();
  285. return;
  286. }
  287. m_Draw3DFrame = new EDA_3D_FRAME( this, _( "3D Viewer" ) );
  288. m_Draw3DFrame->Show( true );
  289. }
  290. void FOOTPRINT_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
  291. {
  292. wxRealPoint gridSize;
  293. wxPoint oldpos;
  294. wxPoint pos = aPosition;
  295. pos = GetScreen()->GetNearestGridPosition( aPosition );
  296. oldpos = GetScreen()->GetCrossHairPosition();
  297. gridSize = GetScreen()->GetGridSize();
  298. switch( aHotKey )
  299. {
  300. case WXK_NUMPAD8:
  301. case WXK_UP:
  302. pos.y -= wxRound( gridSize.y );
  303. m_canvas->MoveCursor( pos );
  304. break;
  305. case WXK_NUMPAD2:
  306. case WXK_DOWN:
  307. pos.y += wxRound( gridSize.y );
  308. m_canvas->MoveCursor( pos );
  309. break;
  310. case WXK_NUMPAD4:
  311. case WXK_LEFT:
  312. pos.x -= wxRound( gridSize.x );
  313. m_canvas->MoveCursor( pos );
  314. break;
  315. case WXK_NUMPAD6:
  316. case WXK_RIGHT:
  317. pos.x += wxRound( gridSize.x );
  318. m_canvas->MoveCursor( pos );
  319. break;
  320. default:
  321. break;
  322. }
  323. GetScreen()->SetCrossHairPosition( pos );
  324. if( oldpos != GetScreen()->GetCrossHairPosition() )
  325. {
  326. pos = GetScreen()->GetCrossHairPosition();
  327. GetScreen()->SetCrossHairPosition( oldpos );
  328. m_canvas->CrossHairOff( aDC );
  329. GetScreen()->SetCrossHairPosition( pos );
  330. m_canvas->CrossHairOn( aDC );
  331. if( m_canvas->IsMouseCaptured() )
  332. {
  333. #ifdef USE_WX_OVERLAY
  334. wxDCOverlay oDC( m_overlay, (wxWindowDC*)aDC );
  335. oDC.Clear();
  336. m_canvas->CallMouseCapture( aDC, aPosition, false );
  337. #else
  338. m_canvas->CallMouseCapture( aDC, aPosition, true );
  339. #endif
  340. }
  341. #ifdef USE_WX_OVERLAY
  342. else
  343. {
  344. m_overlay.Reset();
  345. }
  346. #endif
  347. }
  348. if( aHotKey )
  349. {
  350. OnHotKey( aDC, aHotKey, aPosition );
  351. }
  352. UpdateStatusBar();
  353. }
  354. void FOOTPRINT_EDIT_FRAME::OnModify()
  355. {
  356. PCB_BASE_FRAME::OnModify();
  357. if( m_Draw3DFrame )
  358. m_Draw3DFrame->ReloadRequest();
  359. }
  360. void FOOTPRINT_EDIT_FRAME::UpdateTitle()
  361. {
  362. wxString title = _( "Module Editor " );
  363. if( m_CurrentLib.IsEmpty() )
  364. {
  365. title += _( "(no active library)" );
  366. }
  367. else
  368. {
  369. wxFileName fileName = wxFileName( wxEmptyString, m_CurrentLib, ModuleFileExtension );
  370. fileName = wxGetApp().FindLibraryPath( fileName );
  371. if( !fileName.IsOk() || !fileName.FileExists() )
  372. {
  373. title += _( "(no active library)" );
  374. }
  375. else
  376. {
  377. title = _( "Module Editor (active library: " ) + fileName.GetFullPath() + wxT( ")" );
  378. if( !fileName.IsFileWritable() )
  379. title += _( " [Read Only]" );
  380. }
  381. }
  382. SetTitle( title );
  383. }