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.

329 lines
8.7 KiB

16 years ago
16 years ago
16 years ago
15 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
14 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
  5. * Copyright (C) 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 automove.cpp
  27. * @brief Routines for automatic displacement and rotation of modules.
  28. */
  29. #include <algorithm>
  30. #include "fctsys.h"
  31. #include "class_drawpanel.h"
  32. #include "confirm.h"
  33. #include "kicad_string.h"
  34. #include "pcbnew.h"
  35. #include "wxPcbStruct.h"
  36. #include "kicad_device_context.h"
  37. #include "autorout.h"
  38. #include "cell.h"
  39. #include "pcbnew_id.h"
  40. #include "class_board.h"
  41. #include "class_module.h"
  42. typedef enum {
  43. FIXE_MODULE,
  44. FREE_MODULE,
  45. FIXE_ALL_MODULES,
  46. FREE_ALL_MODULES
  47. } SelectFixeFct;
  48. static bool sortModulesbySize( MODULE* ref, MODULE* compare );
  49. wxString ModulesMaskSelection = wxT( "*" );
  50. /* Called on events (popup menus) relative to automove and autoplace footprints
  51. */
  52. void PCB_EDIT_FRAME::AutoPlace( wxCommandEvent& event )
  53. {
  54. int id = event.GetId();
  55. if( m_mainToolBar == NULL )
  56. return;
  57. INSTALL_UNBUFFERED_DC( dc, m_canvas );
  58. switch( id )
  59. {
  60. case ID_POPUP_PCB_AUTOROUTE_SELECT_LAYERS:
  61. return;
  62. case ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE:
  63. LockModule( (MODULE*) GetScreen()->GetCurItem(), true );
  64. return;
  65. case ID_POPUP_PCB_AUTOPLACE_FREE_MODULE:
  66. LockModule( (MODULE*) GetScreen()->GetCurItem(), false );
  67. return;
  68. case ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES:
  69. LockModule( NULL, false );
  70. return;
  71. case ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES:
  72. LockModule( NULL, true );
  73. return;
  74. case ID_POPUP_CANCEL_CURRENT_COMMAND:
  75. if( m_canvas->IsMouseCaptured() )
  76. {
  77. m_canvas->CallEndMouseCapture( &dc );
  78. }
  79. break;
  80. default: // Abort a current command (if any)
  81. m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
  82. break;
  83. }
  84. /* Erase ratsnest if needed */
  85. if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) )
  86. DrawGeneralRatsnest( &dc );
  87. GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
  88. switch( id )
  89. {
  90. case ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE:
  91. AutoPlaceModule( (MODULE*) GetScreen()->GetCurItem(), PLACE_1_MODULE, &dc );
  92. break;
  93. case ID_POPUP_PCB_AUTOPLACE_ALL_MODULES:
  94. AutoPlaceModule( NULL, PLACE_ALL, &dc );
  95. break;
  96. case ID_POPUP_PCB_AUTOPLACE_NEW_MODULES:
  97. AutoPlaceModule( NULL, PLACE_OUT_OF_BOARD, &dc );
  98. break;
  99. case ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE:
  100. AutoPlaceModule( NULL, PLACE_INCREMENTAL, &dc );
  101. break;
  102. case ID_POPUP_PCB_AUTOMOVE_ALL_MODULES:
  103. AutoMoveModulesOnPcb( false );
  104. break;
  105. case ID_POPUP_PCB_AUTOMOVE_NEW_MODULES:
  106. AutoMoveModulesOnPcb( true );
  107. break;
  108. case ID_POPUP_PCB_AUTOROUTE_ALL_MODULES:
  109. Autoroute( &dc, ROUTE_ALL );
  110. break;
  111. case ID_POPUP_PCB_AUTOROUTE_MODULE:
  112. Autoroute( &dc, ROUTE_MODULE );
  113. break;
  114. case ID_POPUP_PCB_AUTOROUTE_PAD:
  115. Autoroute( &dc, ROUTE_PAD );
  116. break;
  117. case ID_POPUP_PCB_AUTOROUTE_NET:
  118. Autoroute( &dc, ROUTE_NET );
  119. break;
  120. case ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED:
  121. Reset_Noroutable( &dc );
  122. break;
  123. default:
  124. wxMessageBox( wxT( "AutoPlace command error" ) );
  125. break;
  126. }
  127. GetBoard()->m_Status_Pcb &= ~DO_NOT_SHOW_GENERAL_RASTNEST;
  128. Compile_Ratsnest( &dc, true );
  129. }
  130. /* Function to move components in a rectangular area format 4 / 3,
  131. * starting from the mouse cursor
  132. * The components with the FIXED status set are not moved
  133. */
  134. void PCB_EDIT_FRAME::AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb )
  135. {
  136. std::vector <MODULE*> moduleList;
  137. wxPoint start, current;
  138. int Ymax_size, Xsize_allowed;
  139. int pas_grille = (int) GetScreen()->GetGridSize().x;
  140. double surface;
  141. // Undo: init list
  142. PICKED_ITEMS_LIST newList;
  143. newList.m_Status = UR_CHANGED;
  144. ITEM_PICKER picker( NULL, UR_CHANGED );
  145. if( GetBoard()->m_Modules == NULL )
  146. {
  147. DisplayError( this, _( "No modules found!" ) );
  148. return;
  149. }
  150. /* Confirmation */
  151. if( !IsOK( this, _( "Move modules?" ) ) )
  152. return;
  153. EDA_RECT bbbox = GetBoard()->ComputeBoundingBox( true );
  154. bool edgesExist = ( bbbox.GetWidth() || bbbox.GetHeight() );
  155. // no edges exist
  156. if( PlaceModulesHorsPcb && !edgesExist )
  157. {
  158. DisplayError( this,
  159. _( "Could not automatically place modules. No board outlines detected." ) );
  160. return;
  161. }
  162. // Build sorted footprints list (sort by decreasing size )
  163. MODULE* Module = GetBoard()->m_Modules;
  164. for( ; Module != NULL; Module = Module->Next() )
  165. {
  166. Module->CalculateBoundingBox();
  167. moduleList.push_back(Module);
  168. }
  169. sort( moduleList.begin(), moduleList.end(), sortModulesbySize );
  170. /* to move modules outside the board, the cursor is placed below
  171. * the current board, to avoid placing components in board area.
  172. */
  173. if( PlaceModulesHorsPcb && edgesExist )
  174. {
  175. if( GetScreen()->GetCrossHairPosition().y < (bbbox.GetBottom() + 2000) )
  176. {
  177. wxPoint pos = GetScreen()->GetCrossHairPosition();
  178. pos.y = bbbox.GetBottom() + 2000;
  179. GetScreen()->SetCrossHairPosition( pos );
  180. }
  181. }
  182. /* calculate the area needed by footprints */
  183. surface = 0.0;
  184. for( unsigned ii = 0; ii < moduleList.size(); ii++ )
  185. {
  186. Module = moduleList[ii];
  187. if( PlaceModulesHorsPcb && edgesExist )
  188. {
  189. if( bbbox.Contains( Module->m_Pos ) )
  190. continue;
  191. }
  192. surface += Module->m_Surface;
  193. }
  194. Xsize_allowed = (int) ( sqrt( surface ) * 4.0 / 3.0 );
  195. start = current = GetScreen()->GetCrossHairPosition();
  196. Ymax_size = 0;
  197. for( unsigned ii = 0; ii < moduleList.size(); ii++ )
  198. {
  199. Module = moduleList[ii];
  200. if( Module->IsLocked() )
  201. continue;
  202. if( PlaceModulesHorsPcb && edgesExist )
  203. {
  204. if( bbbox.Contains( Module->m_Pos ) )
  205. continue;
  206. }
  207. // Undo: add copy of old Module to undo
  208. picker.m_Link = Module->Clone();
  209. picker.m_PickedItemType = Module->Type();
  210. if( current.x > (Xsize_allowed + start.x) )
  211. {
  212. current.x = start.x;
  213. current.y += Ymax_size + pas_grille;
  214. Ymax_size = 0;
  215. }
  216. GetScreen()->SetCrossHairPosition( current + Module->m_Pos -
  217. Module->m_BoundaryBox.GetPosition() );
  218. Ymax_size = max( Ymax_size, Module->m_BoundaryBox.GetHeight() );
  219. PlaceModule( Module, NULL, true );
  220. // Undo: add new Module to undo
  221. picker.m_PickedItem = Module;
  222. newList.PushItem( picker );
  223. current.x += Module->m_BoundaryBox.GetWidth() + pas_grille;
  224. }
  225. // Undo: commit
  226. if( newList.GetCount() )
  227. SaveCopyInUndoList( newList, UR_CHANGED );
  228. m_canvas->Refresh();
  229. }
  230. /* Set or reset (true or false) Lock attribute of aModule or all modules if aModule == NULL
  231. */
  232. void PCB_EDIT_FRAME::LockModule( MODULE* aModule, bool aLocked )
  233. {
  234. if( aModule )
  235. {
  236. aModule->SetLocked( aLocked );
  237. aModule->DisplayInfo( this );
  238. OnModify();
  239. }
  240. else
  241. {
  242. aModule = GetBoard()->m_Modules;
  243. for( ; aModule != NULL; aModule = aModule->Next() )
  244. {
  245. if( WildCompareString( ModulesMaskSelection, aModule->m_Reference->m_Text ) )
  246. {
  247. aModule->SetLocked( aLocked );
  248. OnModify();
  249. }
  250. }
  251. }
  252. }
  253. static bool sortModulesbySize( MODULE* ref, MODULE* compare )
  254. {
  255. return compare->m_Surface < ref->m_Surface;
  256. }