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.

298 lines
7.5 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2018 CERN
  5. * Copyright (C) 2019 KiCad Developers, see change_log.txt for contributors.
  6. * @author Jon Evans <jon@craftyjon.com>
  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 along
  19. * with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <lib_pin.h>
  22. #include <sch_component.h>
  23. #include <sch_pin.h>
  24. #include <sch_sheet_path.h>
  25. #include <sch_edit_frame.h>
  26. SCH_PIN::SCH_PIN( LIB_PIN* aLibPin, SCH_COMPONENT* aParentSymbol ) :
  27. SCH_ITEM( aParentSymbol, SCH_PIN_T )
  28. {
  29. m_alt = wxEmptyString;
  30. m_number = aLibPin->GetNumber();
  31. m_libPin = aLibPin;
  32. SetPosition( aLibPin->GetPosition() );
  33. m_isDangling = true;
  34. }
  35. /**
  36. * Create a proxy pin from an alternate pin designation.
  37. * The LIB_PIN data will be filled in when the pin is resolved (see SCH_COMPONENT::UpdatePins).
  38. */
  39. SCH_PIN::SCH_PIN( SCH_COMPONENT* aParentSymbol, const wxString& aNumber, const wxString& aAlt ) :
  40. SCH_ITEM( aParentSymbol, SCH_PIN_T )
  41. {
  42. m_alt = aAlt;
  43. m_number = aNumber;
  44. m_libPin = nullptr;
  45. m_isDangling = true;
  46. }
  47. SCH_PIN::SCH_PIN( const SCH_PIN& aPin ) :
  48. SCH_ITEM( aPin )
  49. {
  50. m_alt = aPin.m_alt;
  51. m_number = aPin.m_number;
  52. m_libPin = aPin.m_libPin;
  53. m_position = aPin.m_position;
  54. m_isDangling = aPin.m_isDangling;
  55. }
  56. SCH_PIN& SCH_PIN::operator=( const SCH_PIN& aPin )
  57. {
  58. SCH_ITEM::operator=( aPin );
  59. m_alt = aPin.m_alt;
  60. m_number = aPin.m_number;
  61. m_libPin = aPin.m_libPin;
  62. m_position = aPin.m_position;
  63. m_isDangling = aPin.m_isDangling;
  64. return *this;
  65. }
  66. wxString SCH_PIN::GetName() const
  67. {
  68. if( !m_alt.IsEmpty() )
  69. return m_alt;
  70. return m_libPin->GetName();
  71. }
  72. ELECTRICAL_PINTYPE SCH_PIN::GetType() const
  73. {
  74. if( !m_alt.IsEmpty() )
  75. return m_libPin->GetAlt( m_alt ).m_Type;
  76. return m_libPin->GetType();
  77. }
  78. GRAPHIC_PINSHAPE SCH_PIN::GetShape() const
  79. {
  80. if( !m_alt.IsEmpty() )
  81. return m_libPin->GetAlt( m_alt ).m_Shape;
  82. return m_libPin->GetShape();
  83. }
  84. int SCH_PIN::GetOrientation() const
  85. {
  86. return m_libPin->GetOrientation();
  87. }
  88. int SCH_PIN::GetLength() const
  89. {
  90. return m_libPin->GetLength();
  91. }
  92. bool SCH_PIN::Matches( wxFindReplaceData& aSearchData, void* aAuxDat )
  93. {
  94. if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS ) )
  95. return false;
  96. return EDA_ITEM::Matches( GetName(), aSearchData )
  97. || EDA_ITEM::Matches( GetNumber(), aSearchData );
  98. }
  99. bool SCH_PIN::Replace( wxFindReplaceData& aSearchData, void* aAuxData )
  100. {
  101. bool isReplaced = false;
  102. /* TODO: waiting on a way to override pins in the schematic...
  103. isReplaced |= EDA_ITEM::Replace( aSearchData, m_name );
  104. isReplaced |= EDA_ITEM::Replace( aSearchData, m_number );
  105. */
  106. return isReplaced;
  107. }
  108. SCH_COMPONENT* SCH_PIN::GetParentSymbol() const
  109. {
  110. return static_cast<SCH_COMPONENT*>( GetParent() );
  111. }
  112. wxString SCH_PIN::GetSelectMenuText( EDA_UNITS aUnits ) const
  113. {
  114. return wxString::Format( "%s %s",
  115. GetParentSymbol()->GetSelectMenuText( aUnits ),
  116. m_libPin->GetSelectMenuText( aUnits ) );
  117. }
  118. void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList )
  119. {
  120. wxString msg;
  121. aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Pin" ) ) );
  122. if( m_libPin->GetUnit() == 0 )
  123. msg = _( "All" );
  124. else
  125. msg.Printf( wxT( "%d" ), m_libPin->GetUnit() );
  126. aList.push_back( MSG_PANEL_ITEM( _( "Unit" ), msg ) );
  127. if( m_libPin->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
  128. msg = _( "no" );
  129. else if( m_libPin->GetConvert() == LIB_ITEM::LIB_CONVERT::DEMORGAN )
  130. msg = _( "yes" );
  131. else
  132. msg = wxT( "?" );
  133. aList.push_back( MSG_PANEL_ITEM( _( "Converted" ), msg ) );
  134. aList.push_back( MSG_PANEL_ITEM( _( "Name" ), GetName() ) );
  135. aList.push_back( MSG_PANEL_ITEM( _( "Number" ), msg ) );
  136. aList.push_back( MSG_PANEL_ITEM( _( "Type" ), ElectricalPinTypeGetText( GetType() ) ) );
  137. msg = PinShapeGetText( GetShape() );
  138. aList.push_back( MSG_PANEL_ITEM( _( "Style" ), msg ) );
  139. msg = IsVisible() ? _( "Yes" ) : _( "No" );
  140. aList.push_back( MSG_PANEL_ITEM( _( "Visible" ), msg ) );
  141. // Display pin length
  142. msg = StringFromValue( aFrame->GetUserUnits(), GetLength() );
  143. aList.push_back( MSG_PANEL_ITEM( _( "Length" ), msg ) );
  144. msg = PinOrientationName( (unsigned) PinOrientationIndex( GetOrientation() ) );
  145. aList.push_back( MSG_PANEL_ITEM( _( "Orientation" ), msg ) );
  146. msg = MessageTextFromValue( aFrame->GetUserUnits(), m_position.x );
  147. aList.emplace_back( _( "Pos X" ), msg );
  148. msg = MessageTextFromValue( aFrame->GetUserUnits(), m_position.y );
  149. aList.emplace_back( _( "Pos Y" ), msg );
  150. SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
  151. SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
  152. SCH_COMPONENT* symbol = GetParentSymbol();
  153. aList.emplace_back( symbol->GetRef( currentSheet ), symbol->GetValue( currentSheet, true ) );
  154. #if defined(DEBUG)
  155. SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
  156. if( !frame )
  157. return;
  158. SCH_CONNECTION* conn = Connection();
  159. if( conn )
  160. conn->AppendInfoToMsgPanel( aList );
  161. #endif
  162. }
  163. void SCH_PIN::ClearDefaultNetName( const SCH_SHEET_PATH* aPath )
  164. {
  165. std::lock_guard<std::recursive_mutex> lock( m_netmap_mutex );
  166. if( aPath )
  167. m_net_name_map.erase( *aPath );
  168. else
  169. m_net_name_map.clear();
  170. }
  171. wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH& aPath )
  172. {
  173. if( m_libPin->IsPowerConnection() )
  174. return m_libPin->GetName();
  175. std::lock_guard<std::recursive_mutex> lock( m_netmap_mutex );
  176. if( m_net_name_map.count( aPath ) > 0 )
  177. return m_net_name_map.at( aPath );
  178. wxString name = "Net-(";
  179. name << GetParentSymbol()->GetRef( &aPath );
  180. bool annotated = true;
  181. // Add timestamp for uninitialized symbols
  182. if( name.Last() == '?' )
  183. {
  184. name << GetParentSymbol()->m_Uuid.AsString();
  185. annotated = false;
  186. }
  187. name << "-Pad" << m_libPin->GetNumber() << ")";
  188. if( annotated )
  189. m_net_name_map[ aPath ] = name;
  190. return name;
  191. }
  192. wxPoint SCH_PIN::GetTransformedPosition() const
  193. {
  194. TRANSFORM t = GetParentSymbol()->GetTransform();
  195. return t.TransformCoordinate( GetLocalPosition() ) + GetParentSymbol()->GetPosition();
  196. }
  197. const EDA_RECT SCH_PIN::GetBoundingBox() const
  198. {
  199. TRANSFORM t = GetParentSymbol()->GetTransform();
  200. EDA_RECT r = m_libPin->GetBoundingBox();
  201. r.RevertYAxis();
  202. r = t.TransformCoordinate( r );
  203. r.Offset( GetParentSymbol()->GetPosition() );
  204. return r;
  205. }
  206. bool SCH_PIN::HitTest( const wxPoint& aPosition, int aAccuracy ) const
  207. {
  208. EDA_RECT rect = GetBoundingBox();
  209. return rect.Inflate( aAccuracy ).Contains( aPosition );
  210. }
  211. bool SCH_PIN::ConnectionPropagatesTo( const EDA_ITEM* aItem ) const
  212. {
  213. // Reciprocal checking is done in CONNECTION_GRAPH anyway
  214. return !( m_libPin->GetType() == ELECTRICAL_PINTYPE::PT_NC );
  215. }