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.

302 lines
9.7 KiB

  1. /**
  2. * @file dialog_edit_one_field.cpp
  3. * @brief dialog to editing a field ( not a graphic text) in current component.
  4. */
  5. /*
  6. * This program source code file is part of KiCad, a free EDA CAD application.
  7. *
  8. * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.com
  9. * Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com
  10. * Copyright (C) 2004-2018 KiCad Developers, see change_log.txt for contributors.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version 2
  15. * of the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, you may find one here:
  24. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  25. * or you may search the http://www.gnu.org website for the version 2 license,
  26. * or you may write to the Free Software Foundation, Inc.,
  27. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  28. */
  29. #include <fctsys.h>
  30. #include <common.h>
  31. #include <kiway.h>
  32. #include <confirm.h>
  33. #include <kicad_string.h>
  34. #include <sch_base_frame.h>
  35. #include <sch_component.h>
  36. #include <class_libentry.h>
  37. #include <lib_field.h>
  38. #include <sch_component.h>
  39. #include <template_fieldnames.h>
  40. #include <class_library.h>
  41. #include <sch_validators.h>
  42. #include <dialog_edit_one_field.h>
  43. // These should probably moved into some other file as helpers.
  44. EDA_TEXT_HJUSTIFY_T IntToEdaTextHorizJustify( int aHorizJustify )
  45. {
  46. wxASSERT( aHorizJustify >= GR_TEXT_HJUSTIFY_LEFT && aHorizJustify <= GR_TEXT_HJUSTIFY_RIGHT );
  47. if( aHorizJustify > GR_TEXT_HJUSTIFY_RIGHT )
  48. return GR_TEXT_HJUSTIFY_RIGHT;
  49. if( aHorizJustify < GR_TEXT_HJUSTIFY_LEFT )
  50. return GR_TEXT_HJUSTIFY_LEFT;
  51. return (EDA_TEXT_HJUSTIFY_T) aHorizJustify;
  52. }
  53. EDA_TEXT_VJUSTIFY_T IntToEdaTextVertJustify( int aVertJustify )
  54. {
  55. wxASSERT( aVertJustify >= GR_TEXT_VJUSTIFY_TOP && aVertJustify <= GR_TEXT_VJUSTIFY_BOTTOM );
  56. if( aVertJustify > GR_TEXT_VJUSTIFY_BOTTOM )
  57. return GR_TEXT_VJUSTIFY_BOTTOM;
  58. if( aVertJustify < GR_TEXT_VJUSTIFY_TOP )
  59. return GR_TEXT_VJUSTIFY_TOP;
  60. return (EDA_TEXT_VJUSTIFY_T) aVertJustify;
  61. }
  62. DIALOG_EDIT_ONE_FIELD::DIALOG_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxString& aTitle,
  63. const EDA_TEXT* aTextItem ) :
  64. DIALOG_LIB_EDIT_TEXT_BASE( aParent ),
  65. m_posX( aParent, m_xPosLabel, m_xPosCtrl, m_xPosUnits, true ),
  66. m_posY( aParent, m_yPosLabel, m_yPosCtrl, m_yPosUnits, true ),
  67. m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, true )
  68. {
  69. SetTitle( aTitle );
  70. // The field ID and power status are Initialized in the derived object's ctor.
  71. m_fieldId = VALUE;
  72. m_isPower = false;
  73. m_text = aTextItem->GetText();
  74. m_isItalic = aTextItem->IsItalic();
  75. m_isBold = aTextItem->IsBold();
  76. m_position = aTextItem->GetTextPos();
  77. m_size = aTextItem->GetTextWidth();
  78. m_isVertical = ( aTextItem->GetTextAngle() == TEXT_ANGLE_VERT );
  79. m_verticalJustification = aTextItem->GetVertJustify() + 1;
  80. m_horizontalJustification = aTextItem->GetHorizJustify() + 1;
  81. m_isVisible = aTextItem->IsVisible();
  82. }
  83. void DIALOG_EDIT_ONE_FIELD::init()
  84. {
  85. SetInitialFocus( m_TextValue );
  86. SCH_BASE_FRAME* parent = GetParent();
  87. bool libedit = parent->IsType( FRAME_SCH_LIB_EDITOR );
  88. m_TextValue->SetValidator( SCH_FIELD_VALIDATOR( libedit, m_fieldId, &m_text ) );
  89. // Disable options for graphic text editing which are not needed for fields.
  90. m_CommonConvert->Show( false );
  91. m_CommonUnit->Show( false );
  92. // Show the footprint selection dialog if this is the footprint field.
  93. m_TextValueSelectButton->Show( m_fieldId == FOOTPRINT );
  94. // Value fields of power components cannot be modified. This will grey out
  95. // the text box and display an explanation.
  96. if( m_fieldId == VALUE && m_isPower )
  97. {
  98. m_PowerComponentValues->Show( true );
  99. m_TextValue->Enable( false );
  100. }
  101. else
  102. {
  103. m_PowerComponentValues->Show( false );
  104. m_TextValue->Enable( true );
  105. }
  106. m_sdbSizerButtonsOK->SetDefault();
  107. // Now all widgets have the size fixed, call FinishDialogSettings
  108. FinishDialogSettings();
  109. }
  110. void DIALOG_EDIT_ONE_FIELD::OnTextValueSelectButtonClick( wxCommandEvent& aEvent )
  111. {
  112. // pick a footprint using the footprint picker.
  113. wxString fpid = m_TextValue->GetValue();
  114. KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true );
  115. if( frame->ShowModal( &fpid, this ) )
  116. {
  117. m_TextValue->SetValue( fpid );
  118. }
  119. frame->Destroy();
  120. }
  121. void DIALOG_EDIT_ONE_FIELD::OnSetFocusText( wxFocusEvent& event )
  122. {
  123. if( m_fieldId == REFERENCE )
  124. SelectReferenceNumber( static_cast<wxTextEntry*>( m_TextValue ) );
  125. else
  126. m_TextValue->SetSelection( -1, -1 );
  127. event.Skip();
  128. }
  129. bool DIALOG_EDIT_ONE_FIELD::TransferDataToWindow()
  130. {
  131. m_TextValue->SetValue( m_text );
  132. m_posX.SetValue( m_position.x );
  133. m_posY.SetValue( m_position.y );
  134. m_textSize.SetValue( m_size );
  135. m_orientChoice->SetSelection( m_isVertical ? 1 : 0 );
  136. m_hAlignChoice->SetSelection( m_horizontalJustification );
  137. m_vAlignChoice->SetSelection( m_verticalJustification );
  138. m_visible->SetValue( m_isVisible );
  139. m_italic->SetValue( m_isItalic );
  140. m_bold->SetValue( m_isBold );
  141. return true;
  142. }
  143. bool DIALOG_EDIT_ONE_FIELD::TransferDataFromWindow()
  144. {
  145. m_text = m_TextValue->GetValue();
  146. if( m_fieldId == REFERENCE )
  147. {
  148. // Test if the reference string is valid:
  149. if( !SCH_COMPONENT::IsReferenceStringValid( m_text ) )
  150. {
  151. DisplayError( this, _( "Illegal reference field value!" ) );
  152. return false;
  153. }
  154. }
  155. else if( m_fieldId == VALUE )
  156. {
  157. if( m_text.IsEmpty() )
  158. {
  159. DisplayError( this, _( "Value may not be empty." ) );
  160. return false;
  161. }
  162. }
  163. m_isVertical = m_orientChoice->GetSelection() == 1;
  164. m_position = wxPoint( m_posX.GetValue(), m_posY.GetValue() );
  165. m_size = m_textSize.GetValue();
  166. m_horizontalJustification = m_hAlignChoice->GetSelection();
  167. m_verticalJustification = m_vAlignChoice->GetSelection();
  168. m_isVisible = m_visible->GetValue();
  169. m_isItalic = m_italic->GetValue();
  170. m_isBold = m_bold->GetValue();
  171. return true;
  172. }
  173. void DIALOG_EDIT_ONE_FIELD::updateText( EDA_TEXT* aText )
  174. {
  175. aText->SetTextPos( m_position );
  176. aText->SetTextSize( wxSize( m_size, m_size ) );
  177. aText->SetVisible( m_isVisible );
  178. aText->SetTextAngle( m_isVertical ? TEXT_ANGLE_VERT : TEXT_ANGLE_HORIZ );
  179. aText->SetItalic( m_isItalic );
  180. aText->SetBold( m_isBold );
  181. aText->SetHorizJustify( IntToEdaTextHorizJustify( m_horizontalJustification - 1 ) );
  182. aText->SetVertJustify( IntToEdaTextVertJustify( m_verticalJustification - 1 ) );
  183. }
  184. DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
  185. const wxString& aTitle,
  186. const LIB_FIELD* aField ) :
  187. DIALOG_EDIT_ONE_FIELD( aParent, aTitle, dynamic_cast< const EDA_TEXT* >( aField ) )
  188. {
  189. m_fieldId = aField->GetId();
  190. // When in the library editor, power components can be renamed.
  191. m_isPower = false;
  192. init();
  193. }
  194. DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
  195. const wxString& aTitle,
  196. const SCH_FIELD* aField ) :
  197. DIALOG_EDIT_ONE_FIELD( aParent, aTitle, dynamic_cast< const EDA_TEXT* >( aField ) )
  198. {
  199. m_fieldId = aField->GetId();
  200. const SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent();
  201. wxASSERT_MSG( component && component->Type() == SCH_COMPONENT_T,
  202. wxT( "Invalid schematic field parent item." ) );
  203. // The library symbol may have been removed so using SCH_COMPONENT::GetPartRef() here
  204. // could result in a segfault. If the library symbol is no longer available, the
  205. // schematic fields can still edit so set the power symbol flag to false. This may not
  206. // be entirely accurate if the power library is missing but it's better then a segfault.
  207. const LIB_PART* part = GetParent()->GetLibPart( component->GetLibId(), true );
  208. m_isPower = ( part ) ? part->IsPower() : false;
  209. init();
  210. }
  211. void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aSheetPath )
  212. {
  213. if( aField->GetId() == REFERENCE )
  214. {
  215. wxASSERT( aSheetPath );
  216. SCH_COMPONENT* component = dynamic_cast< SCH_COMPONENT* >( aField->GetParent() );
  217. wxASSERT( component );
  218. if( component )
  219. component->SetRef( aSheetPath, m_text );
  220. }
  221. bool positioningModified = false;
  222. if( aField->GetTextPos() != m_position )
  223. positioningModified = true;
  224. if( ( aField->GetTextAngle() == TEXT_ANGLE_VERT ) != m_isVertical )
  225. positioningModified = true;
  226. if( aField->GetHorizJustify() != IntToEdaTextHorizJustify( m_horizontalJustification - 1 ) )
  227. positioningModified = true;
  228. if( aField->GetVertJustify() != IntToEdaTextVertJustify( m_verticalJustification - 1 ) )
  229. positioningModified = true;
  230. aField->SetText( m_text );
  231. updateText( aField );
  232. if( positioningModified )
  233. {
  234. auto component = static_cast< SCH_COMPONENT* >( aField->GetParent() );
  235. component->ClearFieldsAutoplaced();
  236. }
  237. }