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, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <common.h>
22#include <view/view.h>
23#include <pcb_field.h>
24#include <footprint.h>
26#include <i18n_utility.h>
27#include <pcb_painter.h>
28#include <api/api_utils.h>
29#include <api/board/board_types.pb.h>
30#include <string_utils.h>
31#include <board.h>
32#include <properties/property.h>
34
35
36PCB_FIELD::PCB_FIELD( FOOTPRINT* aParent, FIELD_T aFieldId, const wxString& aName ) :
37 PCB_TEXT( aParent, PCB_FIELD_T ),
38 m_id( aFieldId ),
39 m_ordinal( 0 ),
40 m_name( aName )
41{
42 if( m_id == FIELD_T::USER )
43 m_ordinal = aParent->GetNextFieldOrdinal();
44}
45
46
47PCB_FIELD::PCB_FIELD( const PCB_TEXT& aText, FIELD_T aFieldId, const wxString& aName ) :
48 PCB_TEXT( aText.GetParent(), PCB_FIELD_T ),
49 m_id( aFieldId ),
50 m_ordinal( static_cast<int>( aFieldId ) ),
51 m_name( aName )
52{
53 PCB_TEXT::operator=( aText );
54}
55
56
58 PCB_TEXT( aField.GetParent(), PCB_FIELD_T )
59{
60 *this = aField;
61}
62
63
64void PCB_FIELD::Serialize( kiapi::board::types::Field& field ) const
65{
66 PCB_TEXT::Serialize( *field.mutable_text() );
67
68 field.set_name( GetUntranslatedName().ToStdString() );
69 field.mutable_id()->set_id( (int) GetId() );
70 field.set_visible( IsVisible() );
71 kiapi::common::PackCustomProperties( field.mutable_custom_properties(), *this );
72}
73
74
75void PCB_FIELD::Serialize( google::protobuf::Any &aContainer ) const
76{
77 kiapi::board::types::Field field;
78 Serialize( field );
79 aContainer.PackFrom( field );
80}
81
82
83bool PCB_FIELD::Deserialize( const kiapi::board::types::Field& field )
84{
85 if( field.has_id() )
86 setId( (FIELD_T) field.id().id() );
87
88 // Mandatory fields have a blank Name in the KiCad object
89 if( !IsMandatory() )
90 SetName( wxString( field.name().c_str(), wxConvUTF8 ) );
91
92 if( field.has_text() )
93 {
94 PCB_TEXT::Deserialize( field.text() );
95 }
96
97 SetVisible( field.visible() );
98
99 if( field.text().layer() == kiapi::board::types::BoardLayer::BL_UNKNOWN )
100 SetLayer( F_SilkS );
101
102 kiapi::common::UnpackCustomProperties( field.custom_properties(), *this );
103
104 return true;
105}
106
107
108bool PCB_FIELD::Deserialize( const google::protobuf::Any &aContainer )
109{
110 kiapi::board::types::Field field;
111
112 if( !aContainer.UnpackTo( &field ) )
113 return false;
114
115 return Deserialize( field );
116}
117
118
119wxString PCB_FIELD::GetName( bool aUseDefaultName ) const
120{
121 if( IsMandatory() )
123 else if( m_name.IsEmpty() && aUseDefaultName )
125 else
126 return m_name;
127}
128
129
131{
132 return GetName( true );
133}
134
135
136wxString PCB_FIELD::GetShownText( RESOLUTION_CONTEXT aContext, int aDepth ) const
137{
138 const BOARD* board = GetBoard();
139 return GetShownText( board ? board->GetCurrentVariant() : wxString(), aContext, aDepth );
140}
141
142
143wxString PCB_FIELD::GetShownText( const wxString& aVariantName, RESOLUTION_CONTEXT aContext,
144 int aDepth ) const
145{
146 const FOOTPRINT* parentFootprint = GetParentFootprint();
147 const BOARD* board = GetBoard();
148 wxString text;
149 bool hasVariantOverride = false;
150 bool hasTextVars = HasTextVars();
151
152 if( parentFootprint && board )
153 {
154 if( !aVariantName.IsEmpty() && aVariantName.CmpNoCase( GetDefaultVariantName() ) != 0 )
155 {
156 if( const FOOTPRINT_VARIANT* variant = parentFootprint->GetVariant( aVariantName ) )
157 {
158 if( variant->HasFieldValue( GetName() ) )
159 {
160 text = parentFootprint->GetFieldValueForVariant( aVariantName, GetName() );
161
162 // Variable references in variant values are considered to be in schematic scope,
163 // and are thus resolved before the footprint gets them.
164 hasTextVars = false;
165
166 hasVariantOverride = true;
167 }
168 }
169 }
170 }
171
172 if( !hasVariantOverride )
173 text = GetText();
174
176
177 std::function<bool( wxString* )> resolver =
178 [&]( wxString* token ) -> bool
179 {
180 if( token->IsSameAs( wxT( "LAYER" ) ) )
181 {
182 *token = GetLayerName();
183 return true;
184 }
185
186 if( parentFootprint && parentFootprint->ResolveTextVar( token, aVariantName, aDepth + 1 ) )
187 return true;
188
189 if( board && board->ResolveTextVar( token, aVariantName, aDepth + 1 ) )
190 return true;
191
192 return false;
193 };
194
195 if( hasTextVars && aContext != RAW_VALUE )
196 {
197 text = ResolveTextVars( text, &resolver, aDepth );
198 FinalizeTextVarExpansion( text, aContext );
199 }
200
201 return text;
202}
203
204
206{
207 return m_id == FIELD_T::REFERENCE
208 || m_id == FIELD_T::VALUE
211}
212
213
215{
216 return IsURL( GetShownText( FOR_GUI ) );
217}
218
219
221{
222 if( IsMandatory() )
224 else
225 return _( "User Field" );
226}
227
228
229bool PCB_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
230{
231 if( !IsVisible() && !aSearchData.searchAllFields )
232 return false;
233
234 return PCB_TEXT::Matches( aSearchData, aAuxData );
235}
236
237
238wxString PCB_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
239{
240 wxString content = aFull ? GetShownText( FOR_GUI ) : KIUI::EllipsizeMenuText( GetText() );
241 wxString ref = GetParentFootprint()->GetReference();
242
243 switch( m_id )
244 {
246 return wxString::Format( _( "Reference field of %s" ), ref );
247
248 case FIELD_T::VALUE:
249 return wxString::Format( _( "Value field of %s (%s)" ), ref, content );
250
252 return wxString::Format( _( "Footprint field of %s (%s)" ), ref, content );
253
255 return wxString::Format( _( "Datasheet field of %s (%s)" ), ref, content );
256
257 default:
258 if( GetName().IsEmpty() )
259 return wxString::Format( _( "Field of %s (%s)" ), ref, content );
260 else
261 return wxString::Format( _( "%s field of %s (%s)" ), GetName(), ref, content );
262 }
263}
264
265
266double PCB_FIELD::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
267{
268 if( !aView )
269 return LOD_SHOW;
270
271 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( aView->GetPainter() );
272 KIGFX::PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
273
275 && renderSettings->m_ForceShowFieldsWhenFPSelected )
276 {
277 return LOD_SHOW;
278 }
279
280 // Handle Render tab switches
281 if( IsValue() && !aView->IsLayerVisible( LAYER_FP_VALUES ) )
282 return LOD_HIDE;
283
285 return LOD_HIDE;
286
287 return PCB_TEXT::ViewGetLOD( aLayer, aView );
288}
289
290
292{
293 return new PCB_FIELD( *this );
294}
295
296
297void PCB_FIELD::CopyFrom( const BOARD_ITEM* aOther )
298{
299 wxCHECK( aOther && aOther->Type() == PCB_FIELD_T, /* void */ );
300 *this = *static_cast<const PCB_FIELD*>( aOther );
301}
302
303
305{
306 assert( aImage->Type() == PCB_FIELD_T );
307
308 std::swap( *((PCB_FIELD*) this), *((PCB_FIELD*) aImage) );
309}
310
311
312bool PCB_FIELD::operator==( const BOARD_ITEM& aOther ) const
313{
314 if( aOther.Type() != Type() )
315 return false;
316
317 const PCB_FIELD& other = static_cast<const PCB_FIELD&>( aOther );
318
319 return *this == other;
320}
321
322
323bool PCB_FIELD::operator==( const PCB_FIELD& aOther ) const
324{
325 if( IsMandatory() != aOther.IsMandatory() )
326 return false;
327
328 if( IsMandatory() )
329 {
330 if( m_id != aOther.m_id )
331 return false;
332 }
333 else
334 {
335 if( m_ordinal != aOther.m_ordinal )
336 return false;
337 }
338
339 return m_name == aOther.m_name && EDA_TEXT::operator==( aOther );
340}
341
342
343double PCB_FIELD::Similarity( const BOARD_ITEM& aOther ) const
344{
345 if( m_Uuid == aOther.m_Uuid )
346 return 1.0;
347
348 if( aOther.Type() != Type() )
349 return 0.0;
350
351 const PCB_FIELD& other = static_cast<const PCB_FIELD&>( aOther );
352
353 if( IsMandatory() || other.IsMandatory() )
354 {
355 if( m_id == other.m_id )
356 return 1.0;
357 else
358 return 0.0;
359 }
360
361 if( m_name == other.m_name )
362 return 1.0;
363
364 return EDA_TEXT::Similarity( other );
365}
366
367static struct PCB_FIELD_DESC
368{
370 {
379
380 propMgr.AddProperty( new PROPERTY<PCB_FIELD, wxString>( _HKI( "Name" ),
384
385 // These properties, inherited from EDA_TEXT, have no sense for the board editor
386 propMgr.Mask( TYPE_HASH( PCB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
387 propMgr.Mask( TYPE_HASH( PCB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Color" ) );
388 }
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
friend class BOARD
Definition board_item.h:593
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:374
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:266
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
bool ResolveTextVar(wxString *token, int aDepth) const
Definition board.cpp:687
wxString GetCurrentVariant() const
Definition board.h:529
const KIID m_Uuid
Definition eda_item.h:599
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
bool IsSelected() const
Definition eda_item.h:134
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:84
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
virtual bool IsVisible() const
Definition eda_text.h:226
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:139
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:347
double Similarity(const EDA_TEXT &aOther) const
bool operator==(const EDA_TEXT &aRhs) const
Definition eda_text.h:444
Variant information for a footprint.
Definition footprint.h:228
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.
bool ResolveTextVar(wxString *aToken, int aDepth=0) const
Resolve any references to system tokens supported by the component.
wxString GetFieldValueForVariant(const wxString &aVariantName, const wxString &aFieldName) const
Get a field value for a specific variant.
const wxString & GetReference() const
Definition footprint.h:909
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:84
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
Definition view_item.h:176
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition view_item.h:181
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition view.h:429
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
Definition view.h:227
bool IsMandatory() const
FIELD_T GetId() const
Definition pcb_field.h:123
bool operator==(const PCB_FIELD &aOther) const
wxString GetShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const override
Return the string actually shown after processing of the base text.
PCB_FIELD(FOOTPRINT *aParent, FIELD_T aFieldId, const wxString &aName=wxEmptyString)
Definition pcb_field.cpp:36
void setId(FIELD_T aId)
Definition pcb_field.h:144
wxString GetTextTypeDescription() const override
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
void CopyFrom(const BOARD_ITEM *aOther) override
bool IsReference() const
Definition pcb_field.h:76
bool HasHypertext() const
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition pcb_field.cpp:75
bool IsValue() const
Definition pcb_field.h:77
wxString m_name
Definition pcb_field.h:149
FIELD_T m_id
Field id,.
Definition pcb_field.h:147
int m_ordinal
Sort order for non-mandatory fields.
Definition pcb_field.h:148
void SetName(const wxString &aName)
Definition pcb_field.h:121
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.
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:214
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition pcb_text.cpp:139
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition pcb_text.cpp:257
PCB_TEXT(BOARD_ITEM *parent, KICAD_T idtype=PCB_TEXT_T)
Definition pcb_text.cpp:49
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition pcb_text.cpp:167
PCB_TEXT & operator=(const PCB_TEXT &aOther)
Definition pcb_text.cpp:88
PROPERTY_BASE & SetIsHiddenFromPropertiesManager(bool aHide=true)
Definition property.h:325
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
Definition property.h:339
Provide class metadata.
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.
void FinalizeTextVarExpansion(wxString &aText, RESOLUTION_CONTEXT aContext)
Definition common.cpp:88
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:333
RESOLUTION_CONTEXT
Definition common.h:89
@ FOR_GUI
Definition common.h:91
@ RAW_VALUE
Definition common.h:96
static std::string ToStdString(const wxString &aStr)
#define _(s)
Some functions to handle hotkeys in KiCad.
@ LAYER_FP_REFERENCES
Show footprints references (when texts are visible).
Definition layer_ids.h:262
@ LAYER_FP_VALUES
Show footprints values (when texts are visible).
Definition layer_ids.h:259
@ F_SilkS
Definition layer_ids.h:96
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
#define _HKI(x)
Definition page_info.cpp:40
static struct PCB_FIELD_DESC _PCB_FIELD_DESC
#define TYPE_HASH(x)
Macro to generate unique identifier for a type.
Definition property.h:74
#define NO_SETTER(owner, type)
Macro to define read-only fields (no setter method available)
Definition property.h:895
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
wxString GetDefaultVariantName()
wxString UnescapeString(const wxString &aSource)
bool IsURL(wxString aStr)
Performs a URL sniff-test on a string.
wxString GetUserFieldName(int aFieldNdx, TRANSLATION aTranslation)
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
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".
@ UNTRANSLATED
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:82