KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_field.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 Mike Williams, [email protected]
5 * Copyright The 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#include <common.h>
26#include <view/view.h>
27#include <pcb_field.h>
28#include <footprint.h>
30#include <i18n_utility.h>
31#include <pcb_painter.h>
32#include <api/board/board_types.pb.h>
33#include <string_utils.h>
34#include <board.h>
35#include <properties/property.h>
37
38
39PCB_FIELD::PCB_FIELD( FOOTPRINT* aParent, FIELD_T aFieldId, const wxString& aName ) :
40 PCB_TEXT( aParent, PCB_FIELD_T ),
41 m_id( aFieldId ),
42 m_ordinal( 0 ),
43 m_name( aName )
44{
45 if( m_id == FIELD_T::USER )
46 m_ordinal = aParent->GetNextFieldOrdinal();
47}
48
49
50PCB_FIELD::PCB_FIELD( const PCB_TEXT& aText, FIELD_T aFieldId, const wxString& aName ) :
51 PCB_TEXT( aText.GetParent(), PCB_FIELD_T ),
52 m_id( aFieldId ),
53 m_ordinal( static_cast<int>( aFieldId ) ),
54 m_name( aName )
55{
56 // Copy the text properties from the PCB_TEXT
57 SetText( aText.GetText() );
58 SetVisible( aText.IsVisible() );
59 SetLayer( aText.GetLayer() );
60 SetPosition( aText.GetPosition() );
62}
63
64
65void PCB_FIELD::Serialize( google::protobuf::Any &aContainer ) const
66{
67 kiapi::board::types::Field field;
68
69 google::protobuf::Any anyText;
70 PCB_TEXT::Serialize( anyText );
71 anyText.UnpackTo( field.mutable_text() );
72
73 field.set_name( GetCanonicalName().ToStdString() );
74 field.mutable_id()->set_id( (int) GetId() );
75 field.set_visible( IsVisible() );
76
77 aContainer.PackFrom( field );
78}
79
80
81bool PCB_FIELD::Deserialize( const google::protobuf::Any &aContainer )
82{
83 kiapi::board::types::Field field;
84
85 if( !aContainer.UnpackTo( &field ) )
86 return false;
87
88 if( field.has_id() )
89 setId( (FIELD_T) field.id().id() );
90
91 // Mandatory fields have a blank Name in the KiCad object
92 if( !IsMandatory() )
93 SetName( wxString( field.name().c_str(), wxConvUTF8 ) );
94
95 if( field.has_text() )
96 {
97 google::protobuf::Any anyText;
98 anyText.PackFrom( field.text() );
99 PCB_TEXT::Deserialize( anyText );
100 }
101
102 SetVisible( field.visible() );
103
104 if( field.text().layer() == kiapi::board::types::BoardLayer::BL_UNKNOWN )
105 SetLayer( F_SilkS );
106
107 return true;
108}
109
110
111wxString PCB_FIELD::GetName( bool aUseDefaultName ) const
112{
113 if( IsMandatory() )
114 return GetCanonicalFieldName( m_id );
115 else if( m_name.IsEmpty() && aUseDefaultName )
117 else
118 return m_name;
119}
120
121
123{
124 return GetName( true );
125}
126
127
128wxString PCB_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
129{
130 wxUnusedVar( aAllowExtraText );
131
132 const FOOTPRINT* parentFootprint = GetParentFootprint();
133 const BOARD* board = GetBoard();
134 wxString text;
135 bool hasVariantOverride = false;
136
137 if( parentFootprint && board )
138 {
139 const wxString& variantName = board->GetCurrentVariant();
140
141 if( !variantName.IsEmpty() && variantName.CmpNoCase( GetDefaultVariantName() ) != 0 )
142 {
143 if( const FOOTPRINT_VARIANT* variant = parentFootprint->GetVariant( variantName ) )
144 {
145 if( variant->HasFieldValue( GetName() ) )
146 {
147 text = parentFootprint->GetFieldValueForVariant( variantName, GetName() );
148 hasVariantOverride = true;
149 }
150 }
151 }
152 }
153
154 if( !hasVariantOverride )
155 text = GetText();
156
158
159 std::function<bool( wxString* )> resolver = [&]( wxString* token ) -> bool
160 {
161 if( token->IsSameAs( wxT( "LAYER" ) ) )
162 {
163 *token = GetLayerName();
164 return true;
165 }
166
167 if( parentFootprint && parentFootprint->ResolveTextVar( token, aDepth + 1 ) )
168 return true;
169
170 if( board && board->ResolveTextVar( token, aDepth + 1 ) )
171 return true;
172
173 return false;
174 };
175
176 if( text.Contains( wxT( "${" ) ) || text.Contains( wxT( "@{" ) ) )
177 text = ResolveTextVars( text, &resolver, aDepth );
178
179 text.Replace( wxT( "<<<ESC_DOLLAR:" ), wxT( "${" ) );
180 text.Replace( wxT( "<<<ESC_AT:" ), wxT( "@{" ) );
181
182 return text;
183}
184
185
187{
188 return m_id == FIELD_T::REFERENCE
189 || m_id == FIELD_T::VALUE
192}
193
194
196{
197 return IsURL( GetShownText( false ) );
198}
199
200
202{
203 if( IsMandatory() )
204 return GetCanonicalFieldName( m_id );
205 else
206 return _( "User Field" );
207}
208
209
210bool PCB_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
211{
212 if( !IsVisible() && !aSearchData.searchAllFields )
213 return false;
214
215 return PCB_TEXT::Matches( aSearchData, aAuxData );
216}
217
218
219wxString PCB_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
220{
221 wxString content = aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() );
222 wxString ref = GetParentFootprint()->GetReference();
223
224 switch( m_id )
225 {
227 return wxString::Format( _( "Reference field of %s" ), ref );
228
229 case FIELD_T::VALUE:
230 return wxString::Format( _( "Value field of %s (%s)" ), ref, content );
231
233 return wxString::Format( _( "Footprint field of %s (%s)" ), ref, content );
234
236 return wxString::Format( _( "Datasheet field of %s (%s)" ), ref, content );
237
238 default:
239 if( GetName().IsEmpty() )
240 return wxString::Format( _( "Field of %s (%s)" ), ref, content );
241 else
242 return wxString::Format( _( "%s field of %s (%s)" ), GetName(), ref, content );
243 }
244}
245
246
247double PCB_FIELD::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
248{
249 if( !aView )
250 return LOD_SHOW;
251
252 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( aView->GetPainter() );
253 KIGFX::PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
254
256 && renderSettings->m_ForceShowFieldsWhenFPSelected )
257 {
258 return LOD_SHOW;
259 }
260
261 // Handle Render tab switches
262 if( IsValue() && !aView->IsLayerVisible( LAYER_FP_VALUES ) )
263 return LOD_HIDE;
264
266 return LOD_HIDE;
267
268 return PCB_TEXT::ViewGetLOD( aLayer, aView );
269}
270
271
273{
274 return new PCB_FIELD( *this );
275}
276
277
279{
280 assert( aImage->Type() == PCB_FIELD_T );
281
282 std::swap( *((PCB_FIELD*) this), *((PCB_FIELD*) aImage) );
283}
284
285
286bool PCB_FIELD::operator==( const BOARD_ITEM& aOther ) const
287{
288 if( aOther.Type() != Type() )
289 return false;
290
291 const PCB_FIELD& other = static_cast<const PCB_FIELD&>( aOther );
292
293 return *this == other;
294}
295
296
297bool PCB_FIELD::operator==( const PCB_FIELD& aOther ) const
298{
299 if( IsMandatory() != aOther.IsMandatory() )
300 return false;
301
302 if( IsMandatory() )
303 {
304 if( m_id != aOther.m_id )
305 return false;
306 }
307 else
308 {
309 if( m_ordinal != aOther.m_ordinal )
310 return false;
311 }
312
313 return m_name == aOther.m_name && EDA_TEXT::operator==( aOther );
314}
315
316
317double PCB_FIELD::Similarity( const BOARD_ITEM& aOther ) const
318{
319 if( m_Uuid == aOther.m_Uuid )
320 return 1.0;
321
322 if( aOther.Type() != Type() )
323 return 0.0;
324
325 const PCB_FIELD& other = static_cast<const PCB_FIELD&>( aOther );
326
327 if( IsMandatory() || other.IsMandatory() )
328 {
329 if( m_id == other.m_id )
330 return 1.0;
331 else
332 return 0.0;
333 }
334
335 if( m_name == other.m_name )
336 return 1.0;
337
338 return EDA_TEXT::Similarity( other );
339}
340
341static struct PCB_FIELD_DESC
342{
344 {
353
354 propMgr.AddProperty( new PROPERTY<PCB_FIELD, wxString>( _HKI( "Name" ),
358
359 // These properties, inherited from EDA_TEXT, have no sense for the board editor
360 propMgr.Mask( TYPE_HASH( PCB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
361 propMgr.Mask( TYPE_HASH( PCB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Color" ) );
362 }
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:86
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:237
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:285
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
BOARD_ITEM_CONTAINER * GetParent() const
Definition board_item.h:215
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
bool ResolveTextVar(wxString *token, int aDepth) const
Definition board.cpp:501
wxString GetCurrentVariant() const
Definition board.h:404
const KIID m_Uuid
Definition eda_item.h:522
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:111
bool IsSelected() const
Definition eda_item.h:128
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:41
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:80
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:98
virtual bool IsVisible() const
Definition eda_text.h:187
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:447
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:400
double Similarity(const EDA_TEXT &aOther) const
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:231
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:284
bool operator==(const EDA_TEXT &aRhs) const
Definition eda_text.h:398
Variant information for a footprint.
Definition footprint.h:146
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
int GetNextFieldOrdinal() const
Return the next ordinal for a user field for this footprint.
const FOOTPRINT_VARIANT * GetVariant(const wxString &aVariantName) const
Get a variant by name.
wxString GetFieldValueForVariant(const wxString &aVariantName, const wxString &aFieldName) const
Get a field value for a specific variant.
const wxString & GetReference() const
Definition footprint.h:751
Contains methods for drawing PCB-specific items.
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition pcb_painter.h:82
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
Definition view_item.h:180
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition view_item.h:185
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:67
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition view.h:423
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:221
bool IsMandatory() const
FIELD_T GetId() const
Definition pcb_field.h:112
bool operator==(const PCB_FIELD &aOther) const
PCB_FIELD(FOOTPRINT *aParent, FIELD_T aFieldId, const wxString &aName=wxEmptyString)
Definition pcb_field.cpp:39
void setId(FIELD_T aId)
Definition pcb_field.h:133
wxString GetTextTypeDescription() const override
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
bool IsReference() const
Definition pcb_field.h:68
bool HasHypertext() const
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition pcb_field.cpp:65
bool IsValue() const
Definition pcb_field.h:69
wxString m_name
Definition pcb_field.h:138
FIELD_T m_id
Field id,.
Definition pcb_field.h:136
int m_ordinal
Sort order for non-mandatory fields.
Definition pcb_field.h:137
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
void SetName(const wxString &aName)
Definition pcb_field.h:110
void swapData(BOARD_ITEM *aImage) override
double Similarity(const BOARD_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition pcb_field.cpp:81
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition pcb_text.cpp:178
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition pcb_text.cpp:94
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition pcb_text.cpp:221
virtual VECTOR2I GetPosition() const override
Definition pcb_text.h:82
PCB_TEXT(BOARD_ITEM *parent, KICAD_T idtype=PCB_TEXT_T)
Definition pcb_text.cpp:53
virtual void SetPosition(const VECTOR2I &aPos) override
Definition pcb_text.h:84
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition pcb_text.cpp:117
PROPERTY_BASE & SetIsHiddenFromPropertiesManager(bool aHide=true)
Definition property.h:319
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
Definition property.h:333
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
wxString ResolveTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aResolver, int &aDepth)
Multi-pass text variable expansion and math expression evaluation.
Definition common.cpp:296
The common library.
#define _(s)
static FILENAME_RESOLVER * resolver
Some functions to handle hotkeys in KiCad.
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
Definition layer_ids.h:266
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
Definition layer_ids.h:263
@ F_SilkS
Definition layer_ids.h:100
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
#define _HKI(x)
Definition page_info.cpp:44
static struct PCB_FIELD_DESC _PCB_FIELD_DESC
#define TYPE_HASH(x)
Definition property.h:74
#define NO_SETTER(owner, type)
Definition property.h:828
#define REGISTER_TYPE(x)
wxString GetDefaultVariantName()
wxString UnescapeString(const wxString &aSource)
bool IsURL(wxString aStr)
Performs a URL sniff-test on a string.
wxString GetUserFieldName(int aFieldNdx, bool aTranslateForHI)
#define DO_TRANSLATE
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:90