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.

217 lines
6.8 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 2014 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. * @file append_board_to_current.cpp
  26. * @brief append a board to the currently edited board.
  27. */
  28. #include <fctsys.h>
  29. #include <confirm.h>
  30. #include <properties.h>
  31. #include <pcb_edit_frame.h>
  32. #include <pcbnew.h>
  33. #include <io_mgr.h>
  34. #include <class_module.h>
  35. #include <class_zone.h>
  36. #include <class_board.h>
  37. #include <pcb_draw_panel_gal.h>
  38. // Defined in files.cpp:
  39. extern IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl );
  40. bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl )
  41. {
  42. IO_MGR::PCB_FILE_T pluginType = plugin_type( aFullFileName, aCtl );
  43. PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
  44. // keep trace of existing items, in order to know what are the new items
  45. // (for undo command for instance)
  46. // Tracks are inserted, not append, so mark existing tracks to know what are
  47. // the new tracks
  48. for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
  49. track->SetFlags( FLAG0 );
  50. // Other items are append to the item list, so keep trace to the
  51. // last existing item is enough
  52. MODULE* module = GetBoard()->m_Modules.GetLast();
  53. BOARD_ITEM* drawing = GetBoard()->DrawingsList().GetLast();
  54. int zonescount = GetBoard()->GetAreaCount();
  55. // Keep also the count of copper layers, because we can happen boards
  56. // with different copper layers counts,
  57. // and the enabled layers
  58. int initialCopperLayerCount = GetBoard()->GetCopperLayerCount();
  59. LSET initialEnabledLayers = GetBoard()->GetEnabledLayers();
  60. try
  61. {
  62. PROPERTIES props;
  63. char xbuf[30];
  64. char ybuf[30];
  65. // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet.
  66. sprintf( xbuf, "%d", GetPageSizeIU().x );
  67. sprintf( ybuf, "%d", GetPageSizeIU().y );
  68. props["page_width"] = xbuf;
  69. props["page_height"] = ybuf;
  70. GetDesignSettings().m_NetClasses.Clear();
  71. pi->Load( aFullFileName, GetBoard(), &props );
  72. }
  73. catch( const IO_ERROR& ioe )
  74. {
  75. for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
  76. {
  77. track->ClearFlags( FLAG0 );
  78. }
  79. DisplayErrorMessage( this, _( "Error loading board in AppendBoardFile" ), ioe.What() );
  80. return false;
  81. }
  82. // Now prepare a block move command to place the new items, and
  83. // prepare the undo command.
  84. BLOCK_SELECTOR& blockmove = GetScreen()->m_BlockLocate;
  85. HandleBlockBegin( NULL, BLOCK_PRESELECT_MOVE, wxPoint( 0, 0) );
  86. PICKED_ITEMS_LIST& blockitemsList = blockmove.GetItems();
  87. PICKED_ITEMS_LIST undoListPicker;
  88. ITEM_PICKER picker( NULL, UR_NEW );
  89. EDA_RECT bbox; // the new items bounding box, for block move
  90. bool bboxInit = true; // true until the bounding box is initialized
  91. for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
  92. {
  93. if( track->GetFlags() & FLAG0 )
  94. {
  95. track->ClearFlags( FLAG0 );
  96. continue;
  97. }
  98. track->SetFlags( IS_MOVED );
  99. picker.SetItem( track );
  100. undoListPicker.PushItem( picker );
  101. blockitemsList.PushItem( picker );
  102. if( bboxInit )
  103. bbox = track->GetBoundingBox();
  104. else
  105. bbox.Merge( track->GetBoundingBox() );
  106. bboxInit = false;
  107. }
  108. if( module )
  109. module = module->Next();
  110. else
  111. module = GetBoard()->m_Modules;
  112. for( ; module; module = module->Next() )
  113. {
  114. module->SetFlags( IS_MOVED );
  115. picker.SetItem( module );
  116. undoListPicker.PushItem( picker );
  117. blockitemsList.PushItem( picker );
  118. if( bboxInit )
  119. bbox = module->GetBoundingBox();
  120. else
  121. bbox.Merge( module->GetBoundingBox() );
  122. bboxInit = false;
  123. }
  124. if( drawing )
  125. drawing = drawing->Next();
  126. else
  127. drawing = GetBoard()->DrawingsList();
  128. for( ; drawing; drawing = drawing->Next() )
  129. {
  130. drawing->SetFlags( IS_MOVED );
  131. picker.SetItem( drawing );
  132. undoListPicker.PushItem( picker );
  133. blockitemsList.PushItem( picker );
  134. if( bboxInit )
  135. bbox = drawing->GetBoundingBox();
  136. else
  137. bbox.Merge( drawing->GetBoundingBox() );
  138. bboxInit = false;
  139. }
  140. for( ZONE_CONTAINER* zone = GetBoard()->GetArea( zonescount ); zone;
  141. zone = GetBoard()->GetArea( zonescount ) )
  142. {
  143. zone->SetFlags( IS_MOVED );
  144. picker.SetItem( zone );
  145. undoListPicker.PushItem( picker );
  146. blockitemsList.PushItem( picker );
  147. zonescount++;
  148. if( bboxInit )
  149. bbox = zone->GetBoundingBox();
  150. else
  151. bbox.Merge( zone->GetBoundingBox() );
  152. bboxInit = false;
  153. }
  154. SaveCopyInUndoList( undoListPicker, UR_NEW );
  155. // we should not ask PLUGINs to do these items:
  156. int copperLayerCount = GetBoard()->GetCopperLayerCount();
  157. if( copperLayerCount > initialCopperLayerCount )
  158. GetBoard()->SetCopperLayerCount( copperLayerCount );
  159. // Enable all used layers, and make them visible:
  160. LSET enabledLayers = GetBoard()->GetEnabledLayers();
  161. enabledLayers |= initialEnabledLayers;
  162. GetBoard()->SetEnabledLayers( enabledLayers );
  163. GetBoard()->SetVisibleLayers( enabledLayers );
  164. onBoardLoaded();
  165. if( IsGalCanvasActive() )
  166. static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( GetBoard() );
  167. GetBoard()->BuildListOfNets();
  168. GetBoard()->SynchronizeNetsAndNetClasses();
  169. // Finish block move command:
  170. wxPoint cpos = GetNearestGridPosition( bbox.Centre() );
  171. blockmove.SetOrigin( bbox.GetOrigin() );
  172. blockmove.SetSize( bbox.GetSize() );
  173. blockmove.SetLastCursorPosition( cpos );
  174. HandleBlockEnd( NULL );
  175. return true;
  176. }