KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
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 <wx/log.h>
22#include <wx/menu.h>
23
24#include <advanced_config.h>
25#include <base_units.h>
26#include <common.h> // for ExpandTextVars
27#include <sch_edit_frame.h>
28#include <plotters/plotter.h>
29#include <bitmaps.h>
30#include <kiway.h>
32#include <string_utils.h>
34#include <trace_helpers.h>
35#include <tool/tool_manager.h>
37#include <font/outline_font.h>
38#include "sim/sim_lib_mgr.h"
39#include <properties/property.h>
41#include <google/protobuf/any.pb.h>
42#include <api/schematic/schematic_types.pb.h>
43
44static const std::vector<KICAD_T> labelTypes = { SCH_LABEL_LOCATE_ANY_T };
45
46
56static const std::vector<wxString>& GetKnownNetclassFieldTranslations()
57{
58 static const std::vector<wxString> translations = {
59 wxString::FromUTF8( "Net Class" ),
60 wxString::FromUTF8( "صنف الشبكة" ), // ar
61 wxString::FromUTF8( "Верига Клас" ), // bg
62 wxString::FromUTF8( "Classe de xarxa" ), // ca
63 wxString::FromUTF8( "Třídy spojů" ), // cs
64 wxString::FromUTF8( "Netklasse" ), // da, nl
65 wxString::FromUTF8( "Netzklasse" ), // de
66 wxString::FromUTF8( "Κλάση Δικτύου" ), // el
67 wxString::FromUTF8( "Clase de red" ), // es, es_MX
68 wxString::FromUTF8( "Ühendusniidiklass" ), // et
69 wxString::FromUTF8( "Verkkoluokka" ), // fi
70 wxString::FromUTF8( "Classe d'Equipot" ), // fr
71 wxString::FromUTF8( "מחלקת רשת" ), // he
72 wxString::FromUTF8( "नेट क्लास" ), // hi
73 wxString::FromUTF8( "Hálózatosztály" ), // hu
74 wxString::FromUTF8( "Kelas Net" ), // id
75 wxString::FromUTF8( "Netclass" ), // it, ro (same as canonical)
76 wxString::FromUTF8( "ネットクラス" ), // ja
77 wxString::FromUTF8( "ქსელის კლასი" ), // ka
78 wxString::FromUTF8( "네트 클래스" ), // ko
79 wxString::FromUTF8( "Grandinių klasė" ), // lt
80 wxString::FromUTF8( "Tīklu klase" ), // lv
81 wxString::FromUTF8( "Nettklasse" ), // no
82 wxString::FromUTF8( "Klasy sieci" ), // pl
83 wxString::FromUTF8( "Classes da rede" ), // pt_BR
84 wxString::FromUTF8( "Classe de Rede" ), // pt
85 wxString::FromUTF8( "Класс цепей" ), // ru
86 wxString::FromUTF8( "Triedy spojov" ), // sk
87 wxString::FromUTF8( "Razred vozlišča" ), // sl
88 wxString::FromUTF8( "Класа везе" ), // sr
89 wxString::FromUTF8( "Nätklass" ), // sv
90 wxString::FromUTF8( "நிகர வகுப்பு" ), // ta
91 wxString::FromUTF8( "నెట్ క్లాస్" ), // te
92 wxString::FromUTF8( "เน็ตคลาส" ), // th
93 wxString::FromUTF8( "Ağ Sınıfı" ), // tr
94 wxString::FromUTF8( "Клас зв'язків" ), // uk
95 wxString::FromUTF8( "Lớp mạng" ), // vi
96 wxString::FromUTF8( "网络类" ), // zh_CN
97 wxString::FromUTF8( "網路類" ) // zh_TW
98 };
99
100 return translations;
101}
102
103
104bool SCH_FIELD::IsNetclassLabelFieldName( const wxString& aName )
105{
106 if( aName == wxT( "Netclass" ) )
107 return true;
108
109 for( const wxString& candidate : GetKnownNetclassFieldTranslations() )
110 {
111 if( aName == candidate )
112 return true;
113 }
114
115 return false;
116}
117
118
120 SCH_ITEM( nullptr, SCH_FIELD_T ),
121 EDA_TEXT( schIUScale, wxEmptyString ),
122 m_id( FIELD_T::USER ),
123 m_ordinal( 0 ),
124 m_showName( false ),
125 m_allowAutoPlace( true ),
126 m_isGeneratedField( false ),
127 m_autoAdded( false ),
128 m_showInChooser( true ),
130{
131}
132
133
134SCH_FIELD::SCH_FIELD( SCH_ITEM* aParent, FIELD_T aFieldId, const wxString& aName ) :
135 SCH_FIELD()
136{
137 m_parent = aParent;
138
139 if( !aName.IsEmpty() )
140 SetName( aName );
141 else
143
144 setId( aFieldId ); // will also set the layer
145 SetVisible( true );
146
147 if( aParent && aParent->Schematic() )
148 {
149 SCHEMATIC_SETTINGS& settings = aParent->Schematic()->Settings();
151 }
152
153 if( aFieldId == FIELD_T::USER && aParent )
154 {
155 if( aParent->Type() == SCH_SYMBOL_T )
156 m_ordinal = static_cast<SCH_SYMBOL*>( aParent )->GetNextFieldOrdinal();
157 else if( aParent->Type() == LIB_SYMBOL_T )
158 m_ordinal = static_cast<LIB_SYMBOL*>( aParent )->GetNextFieldOrdinal();
159 else if( aParent->Type() == SCH_SHEET_T )
160 m_ordinal = static_cast<SCH_SHEET*>( aParent )->GetNextFieldOrdinal();
161 else if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aParent ) )
162 m_ordinal = label->GetNextFieldOrdinal();
163 }
164}
165
166
168 SCH_FIELD( aParent, FIELD_T::USER, wxEmptyString )
169{
170 SCH_ITEM::operator=( *aText );
171 EDA_TEXT::operator=( *aText );
172}
173
174
176 SCH_ITEM( aField ),
177 EDA_TEXT( aField )
178{
179 m_private = aField.m_private;
180 setId( aField.m_id ); // will also set the layer
181 m_ordinal = aField.m_ordinal;
182 m_name = aField.m_name;
183 m_showName = aField.m_showName;
186 m_autoAdded = aField.m_autoAdded;
189
190 m_renderCache.reset();
191}
192
193
194void SCH_FIELD::Serialize( google::protobuf::Any& aContainer ) const
195{
196 kiapi::schematic::types::SchematicField field;
197
198 field.set_name( GetName( false ).ToUTF8() );
199 field.set_visible( IsVisible() );
200 field.set_show_name( IsNameShown() );
201 field.set_allow_auto_place( CanAutoplace() );
202
203 google::protobuf::Any any;
205 any.UnpackTo( field.mutable_text() );
206
207 aContainer.PackFrom( field );
208}
209
210
211bool SCH_FIELD::Deserialize( const google::protobuf::Any& aContainer )
212{
213 kiapi::schematic::types::SchematicField field;
214
215 if( !aContainer.UnpackTo( &field ) )
216 return false;
217
218 SetName( wxString::FromUTF8( field.name() ) );
219 SetVisible( field.visible() );
220 SetNameShown( field.show_name() );
221 SetCanAutoplace( field.allow_auto_place() );
222
223 google::protobuf::Any any;
224 any.PackFrom( field.text() );
226}
227
228
230{
231 EDA_TEXT::operator=( aField );
232
233 m_private = aField.m_private;
234 setId( aField.m_id ); // will also set the layer
235 m_ordinal = aField.m_ordinal;
236 m_name = aField.m_name;
237 m_showName = aField.m_showName;
241
242 m_renderCache.reset();
243
244 return *this;
245}
246
247
249{
250 return new SCH_FIELD( *this );
251}
252
253
254void SCH_FIELD::Copy( SCH_FIELD* aTarget ) const
255{
256 *aTarget = *this;
257}
258
259
261{
262 m_id = aId;
264}
265
266
271
272
273wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText, int aDepth,
274 const wxString& aVariantName ) const
275{
276 wxString text = getUnescapedText( aPath, aVariantName );
277
278 if( IsNameShown() && aAllowExtraText )
279 text = GetShownName() << wxS( ": " ) << text;
280
281 if( HasTextVars() )
282 text = ResolveText( text, aPath, aDepth );
283
284 if( m_id == FIELD_T::SHEET_FILENAME && aAllowExtraText && !IsNameShown() )
285 text = _( "File:" ) + wxS( " " ) + text;
286
287 // Convert escape markers back to literals for final display
288 text.Replace( wxT( "<<<ESC_DOLLAR:" ), wxT( "${" ) );
289 text.Replace( wxT( "<<<ESC_AT:" ), wxT( "@{" ) );
290
291 return text;
292}
293
294
295wxString SCH_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
296{
297 if( SCHEMATIC* schematic = Schematic() )
298 {
299 const SCH_SHEET_PATH& currentSheet = schematic->CurrentSheet();
300 wxString variantName = schematic->GetCurrentVariant();
301
302 wxLogTrace( traceSchFieldRendering,
303 "GetShownText (no path arg): field=%s, current sheet path='%s', variant='%s', size=%zu, empty=%d",
304 GetName(), currentSheet.Path().AsString(), variantName, currentSheet.size(),
305 currentSheet.empty() ? 1 : 0 );
306 return GetShownText( &currentSheet, aAllowExtraText, aDepth, variantName );
307 }
308 else
309 {
310 return GetShownText( nullptr, aAllowExtraText, aDepth );
311 }
312}
313
314
315wxString SCH_FIELD::GetFullText( int unit ) const
316{
317 if( GetId() != FIELD_T::REFERENCE )
318 return GetText();
319
320 wxString text = GetText();
321 text << wxT( "?" );
322
323 if( GetParentSymbol() && GetParentSymbol()->IsMultiUnit() )
324 text << GetParentSymbol()->GetUnitDisplayName( unit, false );
325
326 return text;
327}
328
329
331{
333}
334
335
337{
339
340 if( !font )
341 font = KIFONT::FONT::GetFont( GetDefaultFont( aSettings ), IsBold(), IsItalic() );
342
343 return font;
344}
345
346
352
353
359
360
361std::vector<std::unique_ptr<KIFONT::GLYPH>>*
362SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forPosition, TEXT_ATTRIBUTES& aAttrs ) const
363{
364 KIFONT::FONT* font = GetDrawFont( nullptr );
365
366 if( font->IsOutline() )
367 {
368 KIFONT::OUTLINE_FONT* outlineFont = static_cast<KIFONT::OUTLINE_FONT*>( font );
369
370 if( !m_renderCache )
371 m_renderCache = std::make_unique<SCH_FIELD_RENDER_CACHE_DATA>();
372
373 if( m_renderCache->glyphs.empty() )
374 {
375 m_renderCache->glyphs.clear();
376
377 outlineFont->GetLinesAsGlyphs( &m_renderCache->glyphs, forResolvedText, forPosition, aAttrs,
378 GetFontMetrics() );
379
380 m_renderCache->pos = forPosition;
381 }
382
383 if( m_renderCache->pos != forPosition )
384 {
385 VECTOR2I delta = forPosition - m_renderCache->pos;
386
387 for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache->glyphs )
388 {
389 if( glyph->IsOutline() )
390 static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
391 else
392 static_cast<KIFONT::STROKE_GLYPH*>( glyph.get() )->Move( delta );
393 }
394
395 m_renderCache->pos = forPosition;
396 }
397
398 return &m_renderCache->glyphs;
399 }
400
401 return nullptr;
402}
403
404
405void SCH_FIELD::ImportValues( const SCH_FIELD& aSource )
406{
407 SetAttributes( aSource );
408 SetVisible( aSource.IsVisible() );
409 SetNameShown( aSource.IsNameShown() );
410 SetCanAutoplace( aSource.CanAutoplace() );
411}
412
413
415{
416 wxCHECK_RET( aItem && aItem->Type() == SCH_FIELD_T, wxT( "Cannot swap with invalid item." ) );
417
418 SCH_FIELD* item = static_cast<SCH_FIELD*>( aItem );
419
420 std::swap( m_showName, item->m_showName );
421 std::swap( m_allowAutoPlace, item->m_allowAutoPlace );
422 std::swap( m_isGeneratedField, item->m_isGeneratedField );
423 SwapText( *item );
424 SwapAttributes( *item );
425
426 std::swap( m_lastResolvedColor, item->m_lastResolvedColor );
427}
428
429
431{
433 {
435 }
436 else
437 {
438 SCH_LABEL_BASE* parentLabel = dynamic_cast<SCH_LABEL_BASE*>( GetParent() );
439
440 if( parentLabel && !parentLabel->IsConnectivityDirty() )
442 else
444 }
445
446 return m_lastResolvedColor;
447}
448
449
450std::vector<int> SCH_FIELD::ViewGetLayers() const
451{
453}
454
455
457{
458 if( m_parent && m_parent->Type() == SCH_LABEL_T )
459 {
460 if( GetCanonicalName() == wxT( "Netclass" ) || GetCanonicalName() == wxT( "Component Class" ) )
461 {
462 return LAYER_NETCLASS_REFS;
463 }
464 }
465
466 switch( m_id )
467 {
469 case FIELD_T::VALUE: return LAYER_VALUEPART;
474 default: return LAYER_FIELDS;
475 }
476}
477
478
480{
481 // Calculate the text orientation according to the symbol orientation.
482 EDA_ANGLE orient = GetTextAngle();
483
484 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
485 {
486 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
487
488 if( parentSymbol && parentSymbol->GetTransform().y1 ) // Rotate symbol 90 degrees.
489 {
490 if( orient.IsHorizontal() )
491 orient = ANGLE_VERTICAL;
492 else
493 orient = ANGLE_HORIZONTAL;
494 }
495 }
496
497 return orient;
498}
499
500
502{
503 BOX2I bbox = GetTextBox( nullptr );
504
505 // Calculate the bounding box position relative to the parent:
506 VECTOR2I origin = GetParentPosition();
507 VECTOR2I pos = GetTextPos() - origin;
508 VECTOR2I begin = bbox.GetOrigin() - origin;
509 VECTOR2I end = bbox.GetEnd() - origin;
510 RotatePoint( begin, pos, GetTextAngle() );
511 RotatePoint( end, pos, GetTextAngle() );
512
513 // Now, apply the symbol transform (mirror/rot)
514 TRANSFORM transform;
515
516 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
517 transform = static_cast<SCH_SYMBOL*>( m_parent )->GetTransform();
518
519 bbox.SetOrigin( transform.TransformCoordinate( begin ) );
520 bbox.SetEnd( transform.TransformCoordinate( end ) );
521
522 bbox.Move( origin );
523 bbox.Normalize();
524
525 return bbox;
526}
527
528
530{
531 VECTOR2I render_center = GetBoundingBox().Centre();
532 VECTOR2I pos = GetPosition();
533
534 switch( GetHorizJustify() )
535 {
537 if( GetDrawRotation().IsVertical() )
538 return render_center.y > pos.y;
539 else
540 return render_center.x < pos.x;
541
543 if( GetDrawRotation().IsVertical() )
544 return render_center.y < pos.y;
545 else
546 return render_center.x > pos.x;
547
548 default:
549 return false;
550 }
551}
552
553
555{
556 GR_TEXT_H_ALIGN_T actualJustify;
557
558 switch( aJustify )
559 {
562 break;
563
566 break;
567
568 default:
569 actualJustify = aJustify;
570 }
571
572 SetHorizJustify( actualJustify );
573}
574
575
585
586
588{
589 VECTOR2I render_center = GetBoundingBox().Centre();
590 VECTOR2I pos = GetPosition();
591
592 switch( GetVertJustify() )
593 {
595 if( GetDrawRotation().IsVertical() )
596 return render_center.x < pos.x;
597 else
598 return render_center.y < pos.y;
599
601 if( GetDrawRotation().IsVertical() )
602 return render_center.x > pos.x;
603 else
604 return render_center.y > pos.y;
605
606 default:
607 return false;
608 }
609}
610
611
613{
614 GR_TEXT_V_ALIGN_T actualJustify;
615
616 switch( aJustify )
617 {
620 break;
621
624 break;
625
626 default:
627 actualJustify = aJustify;
628 }
629
630 SetVertJustify( actualJustify );
631}
632
633
643
644
645bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
646{
647 bool searchHiddenFields = aSearchData.searchAllFields;
648 bool searchAndReplace = aSearchData.searchAndReplace;
649 bool replaceReferences = false;
650
651 try
652 {
653 // downcast
654 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
655 replaceReferences = schSearchData.replaceReferences;
656 }
657 catch( const std::bad_cast& )
658 {
659 }
660
661 wxString text = UnescapeString( GetText() );
662
663 if( !IsVisible() && !searchHiddenFields )
664 return false;
665
666 if( m_id == FIELD_T::REFERENCE )
667 {
668 if( searchAndReplace && !replaceReferences )
669 return false;
670
671 SCH_SYMBOL* parentSymbol = dyn_cast<SCH_SYMBOL*>( m_parent );
672
673 // The parent might be a LIB_SYMBOL, in which case, we don't
674 // have a sheet path to resolve the reference.
675 if( !parentSymbol )
676 return false;
677
678 if( parentSymbol->Matches( aSearchData, aAuxData ) )
679 return true;
680
681 wxASSERT( aAuxData );
682
683 // Take sheet path into account which effects the reference field and the unit for
684 // symbols with multiple parts.
685 if( aAuxData )
686 {
687 SCH_SHEET_PATH* sheet = (SCH_SHEET_PATH*) aAuxData;
688 text = parentSymbol->GetRef( sheet );
689
690 if( SCH_ITEM::Matches( text, aSearchData ) )
691 return true;
692
693 if( parentSymbol->GetUnitCount() > 1 )
694 text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( sheet ) );
695 }
696 }
697
698 return SCH_ITEM::Matches( text, aSearchData );
699}
700
701
702void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks, wxStyledTextEvent& aEvent ) const
703{
704 SCH_ITEM* parent = dynamic_cast<SCH_ITEM*>( GetParent() );
705 SCHEMATIC* schematic = parent ? parent->Schematic() : nullptr;
706
707 if( !schematic )
708 return;
709
710 wxStyledTextCtrl* scintilla = aScintillaTricks->Scintilla();
711 int key = aEvent.GetKey();
712
713 wxArrayString autocompleteTokens;
714 int pos = scintilla->GetCurrentPos();
715 int start = scintilla->WordStartPosition( pos, true );
716 wxString partial;
717
718 // Multi-line fields are not allowed. So remove '\n' if entered.
719 if( key == '\n' )
720 {
721 wxString text = scintilla->GetText();
722 int currpos = scintilla->GetCurrentPos();
723 text.Replace( wxS( "\n" ), wxS( "" ) );
724 scintilla->SetText( text );
725 scintilla->GotoPos( currpos - 1 );
726 return;
727 }
728
729 auto textVarRef =
730 [&]( int pt )
731 {
732 return pt >= 2 && scintilla->GetCharAt( pt - 2 ) == '$' && scintilla->GetCharAt( pt - 1 ) == '{';
733 };
734
735 // Check for cross-reference
736 if( start > 1 && scintilla->GetCharAt( start - 1 ) == ':' )
737 {
738 int refStart = scintilla->WordStartPosition( start - 1, true );
739
740 if( textVarRef( refStart ) )
741 {
742 partial = scintilla->GetRange( start, pos );
743
744 wxString ref = scintilla->GetRange( refStart, start - 1 );
745
746 if( ref == wxS( "OP" ) )
747 {
748 // SPICE operating points use ':' syntax for ports
749 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent ) )
750 {
751 NULL_REPORTER devnull;
752 SCH_SHEET_PATH& sheet = schematic->CurrentSheet();
753 wxString variant = schematic->GetCurrentVariant();
754 SIM_LIB_MGR mgr( &schematic->Project() );
755
756 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
757 embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
758
759 if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
760 {
761 embeddedFilesStack.push_back( symbolEmbeddedFiles );
762 symbol->GetLibSymbolRef()->AppendParentEmbeddedFiles( embeddedFilesStack );
763 }
764
765 mgr.SetFilesStack( std::move( embeddedFilesStack ) );
766
767 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true, 0, variant, devnull ).model;
768
769 for( wxString pin : model.GetPinNames() )
770 {
771 if( pin.StartsWith( '<' ) && pin.EndsWith( '>' ) )
772 autocompleteTokens.push_back( pin.Mid( 1, pin.Length() - 2 ) );
773 else
774 autocompleteTokens.push_back( pin );
775 }
776
777 // add the synthetic port for power measurements
778 autocompleteTokens.push_back( wxT( "power" ) );
779 }
780 }
781 else
782 {
784 SCH_SYMBOL* refSymbol = nullptr;
785
786 schematic->Hierarchy().GetSymbols( refs, SYMBOL_FILTER_ALL );
787
788 for( size_t jj = 0; jj < refs.GetCount(); jj++ )
789 {
790 if( refs[jj].GetSymbol()->GetRef( &refs[jj].GetSheetPath(), true ) == ref )
791 {
792 refSymbol = refs[jj].GetSymbol();
793 break;
794 }
795 }
796
797 if( refSymbol )
798 refSymbol->GetContextualTextVars( &autocompleteTokens );
799 }
800 }
801 }
802 else if( textVarRef( start ) )
803 {
804 partial = scintilla->GetTextRange( start, pos );
805
806 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent );
807 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( parent );
808 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( parent );
809
810 if( symbol )
811 {
812 symbol->GetContextualTextVars( &autocompleteTokens );
813
814 if( schematic->CurrentSheet().Last() )
815 schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
816 }
817
818 if( sheet )
819 sheet->GetContextualTextVars( &autocompleteTokens );
820
821 if( label )
822 label->GetContextualTextVars( &autocompleteTokens );
823
824 for( std::pair<wxString, wxString> entry : schematic->Project().GetTextVars() )
825 autocompleteTokens.push_back( entry.first );
826 }
827
828 aScintillaTricks->DoAutocomplete( partial, autocompleteTokens );
829 scintilla->SetFocus();
830}
831
832
834{
835 // See comments in SCH_FIELD::Replace(), below.
837 return false;
838
839 return true;
840}
841
842
844{
845 if( const SYMBOL* parentSymbol = GetParentSymbol() )
846 {
847 if( parentSymbol->IsLocked() )
848 return true;
849 }
850
851 if( const SCH_SHEET* parentSheet = dynamic_cast<const SCH_SHEET*>( m_parent ) )
852 {
853 if( parentSheet->IsLocked() )
854 return true;
855 }
856
857 return SCH_ITEM::IsLocked();
858}
859
860
861bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
862{
863 bool replaceReferences = false;
864
865 try
866 {
867 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
868 replaceReferences = schSearchData.replaceReferences;
869 }
870 catch( const std::bad_cast& )
871 {
872 }
873
874 wxString text;
875 bool isReplaced = false;
876
877 if( m_id == FIELD_T::REFERENCE && m_parent && m_parent->Type() == SCH_SYMBOL_T )
878 {
879 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
880
881 if( !replaceReferences )
882 return false;
883
884 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in refdes." ) );
885
886 text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
887 isReplaced = EDA_ITEM::Replace( aSearchData, text );
888
889 if( isReplaced )
890 parentSymbol->SetRef( (SCH_SHEET_PATH*) aAuxData, text );
891 }
892 else
893 {
894 isReplaced = EDA_TEXT::Replace( aSearchData );
895
896 if( m_id == FIELD_T::SHEET_FILENAME && isReplaced )
897 {
898 // If we allowed this we'd have a bunch of work to do here, including warning
899 // about it not being undoable, checking for recursive hierarchies, reloading
900 // sheets, etc. See DIALOG_SHEET_PROPERTIES::TransferDataFromWindow().
901 }
902 }
903
904 return isReplaced;
905}
906
907
908void SCH_FIELD::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
909{
911
912 if( GetTextAngle().IsVertical() )
913 {
914 switch( horizJustify )
915 {
917 if( aRotateCCW )
919
920 break;
921
923 if( aRotateCCW )
925
926 break;
927
930 break;
931 }
932
934 }
935 else if( GetTextAngle().IsHorizontal() )
936 {
937 switch( horizJustify )
938 {
940 if( !aRotateCCW )
942
943 break;
944
946 if( !aRotateCCW )
948
949 break;
950
953 break;
954 }
955
957 }
958 else
959 {
960 wxFAIL_MSG( wxString::Format( wxT( "SCH_FIELD text angle is not horizontal or vertical: %f" ),
961 GetTextAngle().AsDegrees() ) );
962 }
963
964 VECTOR2I pt = GetPosition();
965 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
966 SetPosition( pt );
967}
968
969
971{
972 int x = GetTextPos().x;
973
974 x -= aCenter;
975 x *= -1;
976 x += aCenter;
977
978 SetTextX( x );
979}
980
981
983{
984 int y = GetTextPos().y;
985
986 y -= aCenter;
987 y *= -1;
988 y += aCenter;
989
990 SetTextY( y );
991}
992
993
994void SCH_FIELD::BeginEdit( const VECTOR2I& aPosition )
995{
996 SetTextPos( aPosition );
997}
998
999
1000void SCH_FIELD::CalcEdit( const VECTOR2I& aPosition )
1001{
1002 SetTextPos( aPosition );
1003}
1004
1005
1006wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1007{
1008 wxString content = aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() );
1009
1010 if( content.IsEmpty() )
1011 {
1012 return wxString::Format( _( "Field %s (empty)" ), UnescapeString( GetName() ) );
1013 }
1014 else
1015 {
1016 return wxString::Format( _( "Field %s '%s'" ), UnescapeString( GetName() ), content );
1017 }
1018}
1019
1020
1021void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1022{
1023 wxString msg;
1024
1025 aList.emplace_back( _( "Symbol Field" ), UnescapeString( GetName() ) );
1026
1027 // Don't use GetShownText() here; we want to show the user the variable references
1028 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
1029
1030 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1031
1032 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1033
1034 aList.emplace_back( _( "Style" ), GetTextStyleName() );
1035
1036 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1037
1038 switch( GetHorizJustify() )
1039 {
1040 case GR_TEXT_H_ALIGN_LEFT: msg = _( "Left" ); break;
1041 case GR_TEXT_H_ALIGN_CENTER: msg = _( "Center" ); break;
1042 case GR_TEXT_H_ALIGN_RIGHT: msg = _( "Right" ); break;
1044 }
1045
1046 aList.emplace_back( _( "H Justification" ), msg );
1047
1048 switch( GetVertJustify() )
1049 {
1050 case GR_TEXT_V_ALIGN_TOP: msg = _( "Top" ); break;
1051 case GR_TEXT_V_ALIGN_CENTER: msg = _( "Center" ); break;
1052 case GR_TEXT_V_ALIGN_BOTTOM: msg = _( "Bottom" ); break;
1054 }
1055
1056 aList.emplace_back( _( "V Justification" ), msg );
1057}
1058
1059
1061{
1063 return true;
1064
1066 return true;
1067
1068 return IsURL( GetShownText( false ) );
1069}
1070
1071
1072void SCH_FIELD::DoHypertextAction( EDA_DRAW_FRAME* aFrame, const VECTOR2I& aMousePos ) const
1073{
1074 constexpr int START_ID = 1;
1075
1076 wxString href;
1077
1079 {
1080 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
1081 SCH_SHEET_PATH* sheet = &label->Schematic()->CurrentSheet();
1082 wxMenu menu;
1083
1084 std::vector<std::pair<wxString, wxString>> pages;
1085
1086 label->GetIntersheetRefs( sheet, &pages );
1087
1088 for( int i = 0; i < (int) pages.size(); ++i )
1089 {
1090 menu.Append( i + START_ID,
1091 wxString::Format( _( "Go to Page %s (%s)" ), pages[i].first, pages[i].second ) );
1092 }
1093
1094 menu.AppendSeparator();
1095 menu.Append( 999 + START_ID, _( "Back to Previous Selected Sheet" ) );
1096
1097 int sel = aFrame->GetPopupMenuSelectionFromUser( menu ) - START_ID;
1098
1099 if( sel >= 0 && sel < (int) pages.size() )
1100 href = wxT( "#" ) + pages[sel].first;
1101 else if( sel == 999 )
1103 }
1104 else if( IsURL( GetShownText( false ) ) || m_name == SIM_LIBRARY::LIBRARY_FIELD )
1105 {
1106 href = GetShownText( false );
1107 }
1108
1109 if( !href.IsEmpty() )
1110 {
1112 navTool->HypertextCommand( href );
1113 }
1114}
1115
1116
1117void SCH_FIELD::SetName( const wxString& aName )
1118{
1119 m_name = aName;
1121
1122 if( m_isGeneratedField )
1123 EDA_TEXT::SetText( aName );
1124}
1125
1126
1127void SCH_FIELD::SetText( const wxString& aText )
1128{
1129 // Don't allow modification of text value of generated fields.
1130 if( m_isGeneratedField )
1131 return;
1132
1133 // Mandatory fields should not have leading or trailing whitespace.
1134 if( IsMandatory() )
1135 EDA_TEXT::SetText( aText.Strip( wxString::both ) );
1136 else
1137 EDA_TEXT::SetText( aText );
1138}
1139
1140
1141void SCH_FIELD::SetText( const wxString& aText, const SCH_SHEET_PATH* aPath, const wxString& aVariantName )
1142{
1143 wxCHECK( m_parent, /* void */ );
1144
1145 if( m_isGeneratedField )
1146 return;
1147
1148 wxString tmp = aText;
1149
1150 if( IsMandatory() )
1151 tmp = aText.Strip( wxString::both ) ;
1152
1153 switch( m_parent->Type() )
1154 {
1155 case SCH_SYMBOL_T:
1156 {
1157 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1158 wxCHECK( symbol, /* void */ );
1159 symbol->SetFieldText( GetName(), aText, aPath, aVariantName );
1160 break;
1161 }
1162
1163 case SCH_SHEET_T:
1164 {
1165 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1166 wxCHECK( sheet, /* void */ );
1167 sheet->SetFieldText( GetName(), aText, aPath, aVariantName );
1168 break;
1169 }
1170
1171 default:
1172 SCH_FIELD::SetText( aText );
1173 break;
1174 }
1175}
1176
1177
1178wxString SCH_FIELD::GetText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1179{
1180 wxString retv;
1181
1182 wxCHECK( aPath && m_parent, retv );
1183
1184 switch( m_parent->Type() )
1185 {
1186 case SCH_SYMBOL_T:
1187 {
1188 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1189 wxCHECK( symbol, retv );
1190 retv = symbol->GetFieldText( GetName(), aPath, aVariantName );
1191 break;
1192 }
1193
1194 case SCH_SHEET_T:
1195 {
1196 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1197 wxCHECK( sheet, retv );
1198 retv = sheet->GetFieldText( GetName(), aPath, aVariantName );
1199 break;
1200 }
1201
1202 default:
1203 retv = GetText();
1204 break;
1205 }
1206
1207 return retv;
1208}
1209
1210
1211wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
1212{
1213 if( m_parent && m_parent->IsType( labelTypes ) )
1214 return SCH_LABEL_BASE::GetDefaultFieldName( m_name, aUseDefaultName );
1215
1216 if( IsMandatory() )
1217 return GetCanonicalFieldName( m_id );
1218 else if( m_name.IsEmpty() && aUseDefaultName )
1220 else
1221 return m_name;
1222}
1223
1224
1226{
1227 if( m_parent && m_parent->IsType( labelTypes ) )
1228 {
1229 // These should be stored in canonical format, but recover translated forms written by
1230 // older versions or by cross-language collaboration via Git.
1232 return wxT( "Netclass" );
1233 }
1234
1235 if( IsMandatory() )
1236 return GetCanonicalFieldName( m_id );
1237
1238 return m_name;
1239}
1240
1241
1243{
1244 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1245 {
1246 switch( m_id )
1247 {
1251 default: return BITMAPS::text;
1252 }
1253 }
1254
1255 return BITMAPS::text;
1256}
1257
1258
1259bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1260{
1261 if( GetShownText( true ).IsEmpty() )
1262 return false;
1263
1264 BOX2I rect = GetBoundingBox();
1265
1266 // Text in symbol editor can have additional chars (ie: reference designators U? or U?A)
1267 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1268 {
1269 SCH_FIELD temp( *this );
1270 temp.SetText( GetFullText() );
1271 rect = temp.GetBoundingBox();
1272 }
1273
1274 rect.Inflate( aAccuracy );
1275
1276 if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1277 {
1278 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1279 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1280 }
1281
1282 return rect.Contains( aPosition );
1283}
1284
1285
1286bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1287{
1288 if( GetShownText( true ).IsEmpty() )
1289 return false;
1290
1291 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1292 return false;
1293
1294 BOX2I rect = aRect;
1295
1296 rect.Inflate( aAccuracy );
1297
1298 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1299 {
1300 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1301 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1302 }
1303
1304 if( aContained )
1305 return rect.Contains( GetBoundingBox() );
1306
1307 return rect.Intersects( GetBoundingBox() );
1308}
1309
1310
1311bool SCH_FIELD::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1312{
1313 if( GetShownText( true ).IsEmpty() )
1314 return false;
1315
1316 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1317 return false;
1318
1319 BOX2I bbox = GetBoundingBox();
1320
1321 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1322 {
1323 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1324 bbox.Offset( label->GetSchematicTextOffset( nullptr ) );
1325 }
1326
1327 return KIGEOM::BoxHitTest( aPoly, bbox, aContained );
1328}
1329
1330
1331void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit, int aBodyStyle,
1332 const VECTOR2I& aOffset, bool aDimmed )
1333{
1334 wxString text;
1335
1336 if( Schematic() )
1337 text = GetShownText( &Schematic()->CurrentSheet(), true, 0, Schematic()->GetCurrentVariant() );
1338 else
1339 text = GetShownText( true );
1340
1341 if( ( !IsVisible() && !IsForceVisible() ) || text.IsEmpty() || aBackground )
1342 return;
1343
1344 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1345 COLOR4D color = renderSettings->GetLayerColor( GetLayer() );
1346 int penWidth = GetEffectiveTextPenWidth( renderSettings->GetDefaultPenWidth() );
1347
1348 COLOR4D bg = renderSettings->GetBackgroundColor();
1349
1350 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1351 bg = COLOR4D::WHITE;
1352
1353 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1354 color = GetTextColor();
1355
1356 if( color.m_text && Schematic() )
1357 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1358
1359 if( aDimmed )
1360 {
1361 color.Desaturate();
1362 color = color.Mix( bg, 0.5f );
1363 }
1364
1365 penWidth = std::max( penWidth, renderSettings->GetMinPenWidth() );
1366
1367 // clamp the pen width to be sure the text is readable
1368 penWidth = std::min( penWidth, std::min( GetTextSize().x, GetTextSize().y ) / 4 );
1369
1370 if( !IsVisible() && !renderSettings->m_ShowHiddenFields )
1371 return;
1372
1373 // Calculate the text orientation, according to the symbol orientation/mirror
1374 EDA_ANGLE orient = GetTextAngle();
1375 VECTOR2I textpos = GetTextPos();
1377 GR_TEXT_V_ALIGN_T vjustify = GetVertJustify();
1378
1379 if( renderSettings->m_Transform.y1 ) // Rotate symbol 90 deg.
1380 {
1381 if( orient.IsHorizontal() )
1382 orient = ANGLE_VERTICAL;
1383 else
1384 orient = ANGLE_HORIZONTAL;
1385 }
1386
1387 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1388 {
1389 /*
1390 * Calculate the text justification, according to the symbol orientation/mirror. This is
1391 * a bit complicated due to cumulative calculations:
1392 * - numerous cases (mirrored or not, rotation)
1393 * - the plotter's Text() function will also recalculate H and V justifications according
1394 * to the text orientation
1395 * - when a symbol is mirrored the text is not, and justifications become a nightmare
1396 *
1397 * So the easier way is to use no justifications (centered text) and use GetBoundingBox
1398 * to know the text coordinate considered as centered.
1399 */
1400 hjustify = GR_TEXT_H_ALIGN_CENTER;
1401 vjustify = GR_TEXT_V_ALIGN_CENTER;
1402 textpos = GetBoundingBox().Centre();
1403 }
1404 else if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1405 {
1406 // Library-symbol exports (CLI/symbol editor) provide an item offset in the same coordinate
1407 // frame as body graphics/pins. Apply the same transform+offset pipeline to field text.
1408 textpos = renderSettings->TransformCoordinate( textpos ) + aOffset;
1409 }
1410 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1411 {
1412 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_parent );
1413 textpos += label->GetSchematicTextOffset( renderSettings );
1414 }
1415 else if( m_parent && m_parent->Type() == SCH_DIRECTIVE_LABEL_T )
1416 {
1417 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( m_parent );
1418 std::shared_ptr<NETCLASS> nc = label->GetEffectiveNetClass();
1419
1420 if( nc && ( nc->GetSchematicColor() != COLOR4D::UNSPECIFIED ) && aPlotter->GetColorMode() )
1421 color = nc->GetSchematicColor();
1422 }
1423
1424 KIFONT::FONT* font = GetDrawFont( renderSettings );
1426 attrs.m_StrokeWidth = penWidth;
1427 attrs.m_Halign = hjustify;
1428 attrs.m_Valign = vjustify;
1429 attrs.m_Angle = orient;
1430 attrs.m_Multiline = false;
1431
1432 aPlotter->PlotText( textpos, color, text, attrs, font, GetFontMetrics() );
1433
1435 {
1436 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( m_parent ) )
1437 {
1438 std::vector<std::pair<wxString, wxString>> pages;
1439 std::vector<wxString> pageHrefs;
1440
1441 label->GetIntersheetRefs( &Schematic()->CurrentSheet(), &pages );
1442
1443 for( const auto& [pageNumber, sheetName] : pages )
1444 pageHrefs.push_back( wxT( "#" ) + pageNumber );
1445
1446 BOX2I bbox = GetBoundingBox();
1447 bbox.Offset( label->GetSchematicTextOffset( renderSettings ) );
1448
1449 aPlotter->HyperlinkMenu( bbox, pageHrefs );
1450 }
1451 }
1452}
1453
1454
1455void SCH_FIELD::SetPosition( const VECTOR2I& aPosition )
1456{
1457 // Actual positions are calculated by the rotation/mirror transform of the parent symbol
1458 // of the field. The inverse transform is used to calculate the position relative to the
1459 // parent symbol.
1460 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1461 {
1462 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1463 VECTOR2I relPos = aPosition - parentSymbol->GetPosition();
1464
1465 relPos = parentSymbol->GetTransform().InverseTransform().TransformCoordinate( relPos );
1466
1467 SetTextPos( relPos + parentSymbol->GetPosition() );
1468 return;
1469 }
1470
1471 SetTextPos( aPosition );
1472}
1473
1474
1476{
1477 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1478 {
1479 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1480 VECTOR2I relativePos = GetTextPos() - parentSymbol->GetPosition();
1481
1482 relativePos = parentSymbol->GetTransform().TransformCoordinate( relativePos );
1483
1484 return relativePos + parentSymbol->GetPosition();
1485 }
1486
1487 return GetTextPos();
1488}
1489
1490
1492{
1493 return m_parent ? m_parent->GetPosition() : VECTOR2I( 0, 0 );
1494}
1495
1496
1503
1504
1505bool SCH_FIELD::operator<( const SCH_ITEM& aItem ) const
1506{
1507 if( Type() != aItem.Type() )
1508 return Type() < aItem.Type();
1509
1510 auto field = static_cast<const SCH_FIELD*>( &aItem );
1511
1512 if( GetId() != field->GetId() )
1513 return GetId() < field->GetId();
1514
1515 if( GetText() != field->GetText() )
1516 return GetText() < field->GetText();
1517
1518 if( GetLibPosition().x != field->GetLibPosition().x )
1519 return GetLibPosition().x < field->GetLibPosition().x;
1520
1521 if( GetLibPosition().y != field->GetLibPosition().y )
1522 return GetLibPosition().y < field->GetLibPosition().y;
1523
1524 return GetName() < field->GetName();
1525}
1526
1527
1528bool SCH_FIELD::operator==( const SCH_ITEM& aOther ) const
1529{
1530 if( Type() != aOther.Type() )
1531 return false;
1532
1533 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1534
1535 return *this == field;
1536}
1537
1538
1539bool SCH_FIELD::operator==( const SCH_FIELD& aOther ) const
1540{
1541 // Identical fields owned by different items are not equal.
1542 if( m_parent || aOther.m_parent )
1543 {
1544 if( !m_parent || !aOther.m_parent )
1545 return false;
1546
1547 if( m_parent->Type() != aOther.m_parent->Type() )
1548 return false;
1549
1550 if( m_parent->m_Uuid != aOther.m_parent->m_Uuid )
1551 return false;
1552 }
1553
1554 if( IsMandatory() != aOther.IsMandatory() )
1555 return false;
1556
1557 if( IsMandatory() )
1558 {
1559 if( GetId() != aOther.GetId() )
1560 return false;
1561 }
1562 else
1563 {
1564 if( GetOrdinal() != aOther.GetOrdinal() )
1565 return false;
1566 }
1567
1568 if( GetPosition() != aOther.GetPosition() )
1569 return false;
1570
1571 if( IsGeneratedField() != aOther.IsGeneratedField() )
1572 return false;
1573
1574 if( IsNameShown() != aOther.IsNameShown() )
1575 return false;
1576
1577 if( CanAutoplace() != aOther.CanAutoplace() )
1578 return false;
1579
1580 return EDA_TEXT::operator==( aOther );
1581}
1582
1583
1584bool SCH_FIELD::HasSameContent( const SCH_FIELD& aOther ) const
1585{
1586 if( GetCanonicalName() != aOther.GetCanonicalName() )
1587 return false;
1588
1589 if( GetPosition() != aOther.GetPosition() )
1590 return false;
1591
1592 if( IsVisible() != aOther.IsVisible() )
1593 return false;
1594
1595 if( IsPrivate() != aOther.IsPrivate() )
1596 return false;
1597
1598 if( IsGeneratedField() != aOther.IsGeneratedField() )
1599 return false;
1600
1601 if( IsNameShown() != aOther.IsNameShown() )
1602 return false;
1603
1604 if( CanAutoplace() != aOther.CanAutoplace() )
1605 return false;
1606
1607 return EDA_TEXT::operator==( aOther );
1608}
1609
1610
1611double SCH_FIELD::Similarity( const SCH_ITEM& aOther ) const
1612{
1613 if( Type() != aOther.Type() )
1614 return 0.0;
1615
1616 if( m_Uuid == aOther.m_Uuid )
1617 return 1.0;
1618
1619 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1620
1621 double similarity = 0.99; // The UUIDs are different, so we start with non-identity
1622
1623 if( GetId() != field.GetId() )
1624 {
1625 // We don't allow swapping of mandatory fields, so these cannot be the same item
1626 if( IsMandatory() || field.IsMandatory() )
1627 return 0.0;
1628 else
1629 similarity *= 0.5;
1630 }
1631
1632 similarity *= SimilarityBase( aOther );
1633
1634 similarity *= EDA_TEXT::Similarity( field );
1635
1636 if( GetPosition() != field.GetPosition() )
1637 similarity *= 0.5;
1638
1639 if( IsGeneratedField() != field.IsGeneratedField() )
1640 similarity *= 0.5;
1641
1642 if( IsNameShown() != field.IsNameShown() )
1643 similarity *= 0.5;
1644
1645 if( CanAutoplace() != field.CanAutoplace() )
1646 similarity *= 0.5;
1647
1648 return similarity;
1649}
1650
1651
1652int SCH_FIELD::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1653{
1654 wxASSERT( aOther.Type() == SCH_FIELD_T );
1655
1656 int compareFlags = aCompareFlags;
1657
1658 // For ERC tests, the field position has no matter, so do not test it
1659 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC )
1661
1662 int retv = SCH_ITEM::compare( aOther, compareFlags );
1663
1664 if( retv )
1665 return retv;
1666
1667 const SCH_FIELD* tmp = static_cast<const SCH_FIELD*>( &aOther );
1668
1669 // Equality test will vary depending whether or not the field is mandatory. Otherwise,
1670 // sorting is done by ordinal.
1671 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1672 {
1673 // Mandatory fields have fixed ordinals and their names can vary due to translated field
1674 // names. Optional fields have fixed names and their ordinals can vary.
1675 if( IsMandatory() )
1676 {
1677 if( m_id != tmp->m_id )
1678 return (int) m_id - (int) tmp->m_id;
1679 }
1680 else
1681 {
1682 retv = m_name.Cmp( tmp->m_name );
1683
1684 if( retv )
1685 return retv;
1686 }
1687 }
1688 else // assume we're sorting
1689 {
1690 if( m_id != tmp->m_id )
1691 return (int) m_id - (int) tmp->m_id;
1692 }
1693
1694 bool ignoreFieldText = false;
1695
1696 if( m_id == FIELD_T::REFERENCE && !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY ) )
1697 ignoreFieldText = true;
1698
1699 if( m_id == FIELD_T::VALUE && ( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1700 ignoreFieldText = true;
1701
1702 if( !ignoreFieldText )
1703 {
1704 retv = GetText().CmpNoCase( tmp->GetText() );
1705
1706 if( retv != 0 )
1707 return retv;
1708 }
1709
1710 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1711 {
1712 if( GetTextPos().x != tmp->GetTextPos().x )
1713 return GetTextPos().x - tmp->GetTextPos().x;
1714
1715 if( GetTextPos().y != tmp->GetTextPos().y )
1716 return GetTextPos().y - tmp->GetTextPos().y;
1717 }
1718
1719 // For ERC tests, the field size has no matter, so do not test it
1720 if( !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1721 {
1722 if( GetTextWidth() != tmp->GetTextWidth() )
1723 return GetTextWidth() - tmp->GetTextWidth();
1724
1725 if( GetTextHeight() != tmp->GetTextHeight() )
1726 return GetTextHeight() - tmp->GetTextHeight();
1727 }
1728
1729 return 0;
1730}
1731
1732
1733wxString SCH_FIELD::getUnescapedText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1734{
1735 // This is the default variant field text for all fields except the reference field.
1736 wxString retv = EDA_TEXT::GetShownText( false );
1737
1738 // Special handling for parent object field instance and variant information.
1739 // Only use the path if it's non-empty; an empty path can't match any instances
1740 if( m_parent && aPath && !aPath->empty() )
1741 {
1742 wxLogTrace( traceSchFieldRendering, " Path is valid and non-empty, parent type=%d", m_parent->Type() );
1743
1744 switch( m_parent->Type() )
1745 {
1746 case SCH_SYMBOL_T:
1747 if( const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( m_parent ) )
1748 {
1749 if( m_id == FIELD_T::REFERENCE )
1750 {
1751 wxLogTrace( traceSchFieldRendering, " Calling GetRef for symbol %s on path %s",
1752 symbol->m_Uuid.AsString(), aPath->Path().AsString() );
1753
1754 retv = symbol->GetRef( aPath, true );
1755
1756 wxLogTrace( traceSchFieldRendering, " GetRef returned: '%s'", retv );
1757 }
1758 else if( !aVariantName.IsEmpty() )
1759 {
1760 // If the variant is not found, fall back to default variant above.
1761 if( std::optional<SCH_SYMBOL_VARIANT> variant = symbol->GetVariant( *aPath, aVariantName ) )
1762 {
1763 // If the field name does not exist in the variant, fall back to the default variant above.
1764 if( variant->m_Fields.contains( GetName() ) )
1765 retv = variant->m_Fields[GetName()];
1766 }
1767 }
1768 }
1769
1770 break;
1771
1772 case SCH_SHEET_T:
1773 break;
1774
1775 default:
1776 break;
1777 }
1778 }
1779
1780 return retv;
1781}
1782
1783
1784static struct SCH_FIELD_DESC
1785{
1787 {
1788 // These are defined in EDA_TEXT as well but initialization order is
1789 // not defined, so this needs to be conditional. Defining in both
1790 // places leads to duplicate symbols.
1792
1793 if( h_inst.Choices().GetCount() == 0 )
1794 {
1795 h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _HKI( "Left" ) );
1796 h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _HKI( "Center" ) );
1797 h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _HKI( "Right" ) );
1798 }
1799
1801
1802 if( v_inst.Choices().GetCount() == 0 )
1803 {
1804 v_inst.Map( GR_TEXT_V_ALIGN_TOP, _HKI( "Top" ) );
1805 v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _HKI( "Center" ) );
1806 v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _HKI( "Bottom" ) );
1807 }
1808
1815
1816 // Lock state is inherited from parent symbol (no independent locking of child items)
1817 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Locked" ) );
1818
1819 const wxString textProps = _HKI( "Text Properties" );
1820
1821 auto horiz = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_H_ALIGN_T>( _HKI( "Horizontal Justification" ),
1824
1825 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ), horiz, textProps );
1826
1827 auto vert = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_V_ALIGN_T>( _HKI( "Vertical Justification" ),
1830
1831 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ), vert, textProps );
1832
1833 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Show Field Name" ), &SCH_FIELD::SetNameShown,
1835
1836 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Allow Autoplacement" ), &SCH_FIELD::SetCanAutoplace,
1838
1839 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
1840 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
1841 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
1842 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
1843 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
1844
1845
1848 _HKI( "Text Properties" ) );
1849
1850 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
1851
1852 auto isNotGeneratedField = []( INSPECTABLE* aItem ) -> bool
1853 {
1854 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1855 return !field->IsGeneratedField();
1856
1857 return true;
1858 };
1859
1861 isNotGeneratedField );
1862
1863
1864 auto isNonMandatoryField = []( INSPECTABLE* aItem ) -> bool
1865 {
1866 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1867 return !field->IsMandatory();
1868
1869 return false;
1870 };
1871
1872 propMgr.OverrideAvailability( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Private" ),
1873 isNonMandatoryField );
1874 }
1876
1877
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
BITMAPS
A list of all bitmap identifiers.
@ edit_comp_value
@ edit_comp_footprint
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:554
constexpr const Vec GetEnd() const
Definition box2.h:208
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:233
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition box2.h:142
constexpr Vec Centre() const
Definition box2.h:93
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:164
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition box2.h:134
constexpr const Vec & GetOrigin() const
Definition box2.h:206
constexpr void SetEnd(coord_type x, coord_type y)
Definition box2.h:293
constexpr void Offset(coord_type dx, coord_type dy)
Definition box2.h:255
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:307
static const COLOR4D WHITE
Definition color4d.h:401
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
bool IsHorizontal() const
Definition eda_angle.h:142
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:531
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:542
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:416
EDA_ITEM * GetParent() const
Definition eda_item.h:110
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:543
bool IsForceVisible() const
Definition eda_item.h:221
static bool Replace(const EDA_SEARCH_DATA &aSearchData, wxString &aText)
Perform a text replace on aText using the find and replace criteria in aSearchData on items that supp...
Definition eda_item.cpp:261
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:37
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:89
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition eda_text.cpp:165
virtual VECTOR2I GetTextSize() const
Definition eda_text.h:282
COLOR4D GetTextColor() const
Definition eda_text.h:291
wxString GetTextStyleName() const
virtual VECTOR2I GetTextPos() const
Definition eda_text.h:294
bool IsItalic() const
Definition eda_text.h:190
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:532
virtual bool IsVisible() const
Definition eda_text.h:208
virtual void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:576
virtual void SetTextX(int aX)
Definition eda_text.cpp:583
virtual int GetTextHeight() const
Definition eda_text.h:288
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition eda_text.cpp:208
KIFONT::FONT * GetFont() const
Definition eda_text.h:268
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:428
virtual void SetTextY(int aY)
Definition eda_text.cpp:589
EDA_TEXT & operator=(const EDA_TEXT &aItem)
Definition eda_text.cpp:138
BOX2I GetTextBox(const RENDER_SETTINGS *aSettings, int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition eda_text.cpp:773
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:412
virtual int GetTextWidth() const
Definition eda_text.h:285
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:221
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition eda_text.cpp:482
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:129
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:381
EDA_TEXT(const EDA_IU_SCALE &aIuScale, const wxString &aText=wxEmptyString)
Definition eda_text.cpp:98
virtual void ClearBoundingBoxCache()
Definition eda_text.cpp:695
double Similarity(const EDA_TEXT &aOther) const
virtual void ClearRenderCache()
Definition eda_text.cpp:689
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:168
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:252
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:461
void SwapAttributes(EDA_TEXT &aTradingPartner)
Swap the text attributes of the two involved instances.
Definition eda_text.cpp:448
bool IsBold() const
Definition eda_text.h:205
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:224
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:121
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:265
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:294
void SwapText(EDA_TEXT &aTradingPartner)
Definition eda_text.cpp:440
bool operator==(const EDA_TEXT &aRhs) const
Definition eda_text.h:419
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:404
static ENUM_MAP< T > & Instance()
Definition property.h:721
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:38
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:94
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition font.cpp:143
virtual bool IsOutline() const
Definition font.h:102
Class OUTLINE_FONT implements outline font drawing.
void GetLinesAsGlyphs(std::vector< std::unique_ptr< GLYPH > > *aGlyphs, const wxString &aText, const VECTOR2I &aPosition, const TEXT_ATTRIBUTES &aAttrs, const METRICS &aFontMetrics) const
void Move(const VECTOR2I &aOffset)
Definition glyph.cpp:114
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
std::shared_ptr< wxString > m_text
Definition color4d.h:395
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:528
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition color4d.h:292
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxString AsString() const
Definition kiid.cpp:393
COLOR4D GetSchematicColor(bool aIsForSave=false) const
Definition netclass.h:225
A singleton reporter that reports to nowhere.
Definition reporter.h:214
Base plotter engine class.
Definition plotter.h:133
bool GetColorMode() const
Definition plotter.h:161
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont=nullptr, const KIFONT::METRICS &aFontMetrics=KIFONT::METRICS::Default(), void *aData=nullptr)
Definition plotter.cpp:712
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition plotter.h:514
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 OverrideAvailability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override availability functor for a base class property of a given derived class.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
void OverrideWriteability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override writeability functor for a base class property of a given derived class.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
Definition schematic.h:90
SCHEMATIC_SETTINGS & Settings() const
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:189
void ClearRenderCache() override
int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const override
Provide the draw object specific comparison called by the == and < operators.
COLOR4D m_lastResolvedColor
Definition sch_field.h:368
GR_TEXT_V_ALIGN_T GetEffectiveVertJustify() const
bool IsMandatory() const
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
bool HasSameContent(const SCH_FIELD &aOther) const
Test if this field has the same name, content and presentation as another field, ignoring the owning ...
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
wxString GetFullText(int unit=1) const
Return the text of a field.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
bool IsLocked() const override
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
VECTOR2I GetPosition() const override
void SetEffectiveHorizJustify(GR_TEXT_H_ALIGN_T)
int GetSchTextSize() const
Definition sch_field.h:179
bool Replace(const EDA_SEARCH_DATA &aSearchData, void *aAuxData=nullptr) override
Perform a text replace using the find and replace criteria in aSearchData on items that support text ...
bool m_showName
Render the field name in addition to its value.
Definition sch_field.h:358
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
bool IsNameShown() const
Definition sch_field.h:218
bool m_autoAdded
Was this field automatically added to a LIB_SYMBOL?
Definition sch_field.h:363
double Similarity(const SCH_ITEM &aItem) const override
Return a measure of how likely the other object is to represent the same object.
std::unique_ptr< SCH_FIELD_RENDER_CACHE_DATA > m_renderCache
Definition sch_field.h:366
bool IsGeneratedField() const
Generated fields are fields whose names are variables like ${VAR}.
Definition sch_field.h:227
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
SCH_LAYER_ID GetDefaultLayer() const
bool HasHypertext() const override
Indicates that the item has at least one hypertext action.
bool IsHorizJustifyFlipped() const
Return whether the field will be rendered with the horizontal justification inverted due to rotation ...
bool IsVertJustifyFlipped() const
EDA_ANGLE GetDrawRotation() const override
Adjusters to allow EDA_TEXT to draw/print/etc.
void SetEffectiveVertJustify(GR_TEXT_V_ALIGN_T)
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
FIELD_T GetId() const
Definition sch_field.h:132
void SetCanAutoplace(bool aCanPlace)
Definition sch_field.h:230
int GetPenWidth() const override
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
bool m_isGeneratedField
If the field name is a variable name (e.g.
Definition sch_field.h:360
int m_ordinal
Sort order for non-mandatory fields.
Definition sch_field.h:355
COLOR4D GetFieldColor() const
wxString getUnescapedText(const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
bool operator==(const SCH_ITEM &aItem) const override
SCH_FIELD & operator=(const SCH_FIELD &aField)
void ImportValues(const SCH_FIELD &aSource)
Copy parameters from a SCH_FIELD source.
bool operator<(const SCH_ITEM &aItem) const override
FIELD_T m_id
Field id,.
Definition sch_field.h:354
void DoHypertextAction(EDA_DRAW_FRAME *aFrame, const VECTOR2I &aMousePos) const override
wxString GetShownName() const
Get the field's name as displayed on the schematic or in the symbol fields table.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
VECTOR2I GetLibPosition() const
Definition sch_field.h:276
void setId(FIELD_T aId)
int GetOrdinal() const
Definition sch_field.h:134
bool IsEmpty()
Return true if both the name and value of the field are empty.
Definition sch_field.h:171
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) const
KIFONT::FONT * GetDrawFont(const RENDER_SETTINGS *aSettings) const override
void BeginEdit(const VECTOR2I &aStartPoint) override
Begin drawing a symbol library draw item at aPosition.
bool IsReplaceable() const override
Override this method in any derived object that supports test find and replace.
void SetSchTextSize(int aSize)
Definition sch_field.h:180
GR_TEXT_H_ALIGN_T GetEffectiveHorizJustify() const
std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
void SetPosition(const VECTOR2I &aPosition) override
void SetName(const wxString &aName)
bool CanAutoplace() const
Definition sch_field.h:229
std::vector< std::unique_ptr< KIFONT::GLYPH > > * GetRenderCache(const wxString &forResolvedText, const VECTOR2I &forPosition, TEXT_ATTRIBUTES &aAttrs) const
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
void ClearCaches() override
void SetText(const wxString &aText) override
VECTOR2I GetParentPosition() const
bool m_showInChooser
This field is available as a data column for the chooser.
Definition sch_field.h:364
void OnScintillaCharAdded(SCINTILLA_TRICKS *aScintillaTricks, wxStyledTextEvent &aEvent) const
wxString m_name
Definition sch_field.h:356
void SetNameShown(bool aShown=true)
Definition sch_field.h:219
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
static bool IsNetclassLabelFieldName(const wxString &aName)
Test whether aName is one of the known translations of the directive-label net class field name (used...
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
void Copy(SCH_FIELD *aTarget) const
Copy parameters of this field to another field.
bool m_allowAutoPlace
This field can be autoplaced.
Definition sch_field.h:359
VECTOR2I GetSchematicTextOffset(const RENDER_SETTINGS *aSettings) const override
This offset depends on the orientation, the type of text, and the area required to draw the associate...
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition sch_item.cpp:78
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.h:724
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:274
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:268
virtual wxString GetUnitDisplayName(int aUnit, bool aLabel) const
Definition sch_item.cpp:191
bool IsLocked() const override
Definition sch_item.cpp:148
friend class LIB_SYMBOL
Definition sch_item.h:797
@ SKIP_TST_POS
Definition sch_item.h:707
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition sch_item.cpp:523
bool IsPrivate() const
Definition sch_item.h:248
void SetLayer(SCH_LAYER_ID aLayer)
Definition sch_item.h:339
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition sch_item.h:338
virtual int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const
Provide the draw object specific comparison called by the == and < operators.
Definition sch_item.cpp:720
const wxString & GetDefaultFont(const RENDER_SETTINGS *aSettings) const
Definition sch_item.cpp:768
bool IsConnectivityDirty() const
Definition sch_item.h:585
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:52
bool m_private
Definition sch_item.h:778
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:377
const KIFONT::METRICS & GetFontMetrics() const
Definition sch_item.cpp:781
double SimilarityBase(const SCH_ITEM &aItem) const
Calculate the boilerplate similarity for all LIB_ITEMs without preventing the use above of a pure vir...
Definition sch_item.h:377
void GetIntersheetRefs(const SCH_SHEET_PATH *aPath, std::vector< std::pair< wxString, wxString > > *pages)
Build an array of { pageNumber, pageName } pairs.
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this label.
Handle actions specific to the schematic editor.
static wxString g_BackLink
void HypertextCommand(const wxString &aHref)
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
const KIGFX::COLOR4D & GetBackgroundColor() const override
Return current background color settings.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool empty() const
Forwarded method from std::vector.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
size_t size() const
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
wxString GetFieldText(const wxString &aFieldName, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
void SetFieldText(const wxString &aFieldName, const wxString &aFieldText, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString)
Schematic symbol object.
Definition sch_symbol.h:69
wxString SubReference(int aUnit, bool aAddSeparator=true) const
void SetFieldText(const wxString &aFieldName, const wxString &aFieldText, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString)
wxString GetFieldText(const wxString &aFieldName, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
VECTOR2I GetPosition() const override
Definition sch_symbol.h:885
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
int GetUnitCount() const override
Return the number of units per package of the symbol.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
wxStyledTextCtrl * Scintilla() const
void DoAutocomplete(const wxString &aPartial, const wxArrayString &aTokens)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
static constexpr auto LIBRARY_FIELD
Definition sim_library.h:31
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
void SetFilesStack(std::vector< EMBEDDED_FILES * > aFilesStack)
Definition sim_lib_mgr.h:44
A base class for LIB_SYMBOL and SCH_SYMBOL.
Definition symbol.h:59
const TRANSFORM & GetTransform() const
Definition symbol.h:243
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
for transforming drawing coordinates for a wxDC device context.
Definition transform.h:42
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition transform.cpp:55
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition transform.cpp:40
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
A type-safe container of any type.
Definition ki_any.h:92
wxString GetGeneratedFieldDisplayName(const wxString &aSource)
Returns any variables unexpanded, e.g.
Definition common.cpp:444
The common library.
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:408
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:407
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:416
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
a few functions useful in geometry calculations.
const wxChar *const traceSchFieldRendering
Flag to enable debug output of schematic field rendering and positioning.
@ USER
The main config directory (e.g. ~/.config/kicad/)
SCH_LAYER_ID
Eeschema drawing layers.
Definition layer_ids.h:447
@ LAYER_SHEETNAME
Definition layer_ids.h:470
@ LAYER_VALUEPART
Definition layer_ids.h:459
@ LAYER_FIELDS
Definition layer_ids.h:460
@ LAYER_SHEETFIELDS
Definition layer_ids.h:472
@ LAYER_REFERENCEPART
Definition layer_ids.h:458
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:462
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:493
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:461
@ LAYER_SHEETFILENAME
Definition layer_ids.h:471
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
KICOMMON_API wxString EllipsizeStatusText(wxWindow *aWindow, const wxString &aString)
Ellipsize text (at the end) to be no more than 1/3 of the window width.
#define _HKI(x)
Definition page_info.cpp:40
static GR_TEXT_H_ALIGN_T horizJustify(const char *horizontal)
#define TYPE_HASH(x)
Definition property.h:74
#define DECLARE_ENUM_TO_WXANY(type)
Definition property.h:789
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
static const std::vector< wxString > & GetKnownNetclassFieldTranslations()
Translations of "Net Class" extracted from KiCad's .po catalogs.
Definition sch_field.cpp:56
static const std::vector< KICAD_T > labelTypes
Definition sch_field.cpp:44
static struct SCH_FIELD_DESC _SCH_FIELD_DESC
@ SYMBOL_FILTER_ALL
wxString UnescapeString(const wxString &aSource)
bool IsURL(wxString aStr)
Performs a URL sniff-test on a string.
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
#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.
@ INTERSHEET_REFS
Global label cross-reference page numbers.
@ 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)
KIBIS_MODEL * model
KIBIS_PIN * pin
VECTOR2I end
int delta
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
wxLogTrace helper definitions.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
@ LIB_SYMBOL_T
Definition typeinfo.h:145
@ SCH_SYMBOL_T
Definition typeinfo.h:169
@ SCH_FIELD_T
Definition typeinfo.h:147
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:168
@ SCH_LABEL_T
Definition typeinfo.h:164
@ SCH_SHEET_T
Definition typeinfo.h:172
@ SCH_LABEL_LOCATE_ANY_T
Definition typeinfo.h:188
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:165
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
Definition typeinfo.h:56
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition ui_common.h:46
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683