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.

232 lines
6.2 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
  5. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
  7. * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. /**
  27. * @file pad_edition_functions.cpp
  28. */
  29. #include <fctsys.h>
  30. #include <class_drawpanel.h>
  31. #include <confirm.h>
  32. #include <trigo.h>
  33. #include <macros.h>
  34. #include <wxBasePcbFrame.h>
  35. #include <pcbnew.h>
  36. #include <class_board.h>
  37. #include <class_module.h>
  38. #include <class_pad.h>
  39. #include <class_board_design_settings.h>
  40. /* Exports the current pad settings to board design settings.
  41. */
  42. void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad )
  43. {
  44. if( aPad == NULL )
  45. return;
  46. SetMsgPanel( aPad );
  47. D_PAD& masterPad = GetDesignSettings().m_Pad_Master;
  48. masterPad.ImportSettingsFromMaster( *aPad );
  49. }
  50. /* Imports the board design settings to aPad
  51. * - The position, names, and keys are not modifed.
  52. * The parameters are expected to be correct (i.e. settings are valid)
  53. */
  54. void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw )
  55. {
  56. if( aDraw )
  57. {
  58. aPad->SetFlags( DO_NOT_DRAW );
  59. m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
  60. aPad->ClearFlags( DO_NOT_DRAW );
  61. }
  62. const D_PAD& mp = GetDesignSettings().m_Pad_Master;
  63. aPad->ImportSettingsFromMaster( mp );
  64. if( aDraw )
  65. m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
  66. aPad->GetParent()->SetLastEditTime();
  67. OnModify();
  68. }
  69. /** Compute the 'next' pad number for autoincrement
  70. * aPadName is the last pad name used */
  71. static wxString GetNextPadName( wxString aPadName )
  72. {
  73. // Automatically increment the current pad number.
  74. int num = 0;
  75. int ponder = 1;
  76. // Trim and extract the trailing numeric part
  77. while( aPadName.Len()
  78. && aPadName.Last() >= '0'
  79. && aPadName.Last() <= '9' )
  80. {
  81. num += ( aPadName.Last() - '0' ) * ponder;
  82. aPadName.RemoveLast();
  83. ponder *= 10;
  84. }
  85. num++; // Use next number for the new pad
  86. aPadName << num;
  87. return aPadName;
  88. }
  89. /* Add a new pad to aModule.
  90. */
  91. void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
  92. {
  93. m_Pcb->m_Status_Pcb = 0;
  94. aModule->SetLastEditTime();
  95. D_PAD* pad = new D_PAD( aModule );
  96. // Add the new pad to end of the module pad list.
  97. aModule->Pads().PushBack( pad );
  98. // Update the pad properties,
  99. // and keep NETINFO_LIST::ORPHANED as net info
  100. // which is the default when nets cannot be handled.
  101. Import_Pad_Settings( pad, false );
  102. pad->SetPosition( GetCrossHairPosition() );
  103. // Set the relative pad position
  104. // ( pad position for module orient, 0, and relative to the module position)
  105. wxPoint pos0 = pad->GetPosition() - aModule->GetPosition();
  106. RotatePoint( &pos0, -aModule->GetOrientation() );
  107. pad->SetPos0( pos0 );
  108. /* NPTH pads take empty pad number (since they can't be connected),
  109. * other pads get incremented from the last one edited */
  110. wxString padName;
  111. if( pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
  112. {
  113. padName = GetNextPadName( GetDesignSettings()
  114. .m_Pad_Master.GetPadName() );
  115. }
  116. pad->SetPadName( padName );
  117. GetDesignSettings().m_Pad_Master.SetPadName( padName );
  118. aModule->CalculateBoundingBox();
  119. SetMsgPanel( pad );
  120. if( draw )
  121. m_canvas->RefreshDrawingRect( aModule->GetBoundingBox() );
  122. }
  123. void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery )
  124. {
  125. if( aPad == NULL )
  126. return;
  127. MODULE* module = aPad->GetParent();
  128. module->SetLastEditTime();
  129. // aQuery = true to prompt for confirmation, false to delete silently
  130. if( aQuery )
  131. {
  132. wxString msg;
  133. msg.Printf( _( "Delete Pad (footprint %s %s) ?" ),
  134. GetChars( module->GetReference() ),
  135. GetChars( module->GetValue() ) );
  136. if( !IsOK( this, msg ) )
  137. return;
  138. }
  139. // Stores the initial bounding box to refresh the old area
  140. EDA_RECT bbox = module->GetBoundingBox();
  141. m_Pcb->m_Status_Pcb = 0;
  142. GetBoard()->PadDelete( aPad );
  143. // Update the bounding box
  144. module->CalculateBoundingBox();
  145. // Refresh the modified screen area, using the initial bounding box
  146. // which is perhaps larger than the new bounding box
  147. m_canvas->RefreshDrawingRect( bbox );
  148. OnModify();
  149. }
  150. // Rotate selected pad 90 degrees.
  151. void PCB_BASE_FRAME::RotatePad( D_PAD* aPad, wxDC* DC )
  152. {
  153. if( aPad == NULL )
  154. return;
  155. MODULE* module = aPad->GetParent();
  156. module->SetLastEditTime();
  157. OnModify();
  158. if( DC )
  159. module->Draw( m_canvas, DC, GR_XOR );
  160. wxSize sz = aPad->GetSize();
  161. std::swap( sz.x, sz.y );
  162. aPad->SetSize( sz );
  163. sz = aPad->GetDrillSize();
  164. std::swap( sz.x, sz.y );
  165. aPad->SetDrillSize( sz );
  166. wxPoint pt = aPad->GetOffset();
  167. std::swap( pt.x, pt.y );
  168. aPad->SetOffset( pt );
  169. aPad->SetOffset( wxPoint( aPad->GetOffset().x, -aPad->GetOffset().y ) );
  170. sz = aPad->GetDelta();
  171. std::swap( sz.x, sz.y );
  172. sz.x = -sz.x;
  173. aPad->SetDelta( sz );
  174. module->CalculateBoundingBox();
  175. SetMsgPanel( aPad );
  176. if( DC )
  177. module->Draw( m_canvas, DC, GR_OR );
  178. }