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 // the search pane surfaces metadata hits through the reference field
679 if( aSearchData.searchMetadata && parentSymbol->Matches( aSearchData, aAuxData ) )
680 return true;
681
682 wxASSERT( aAuxData );
683
684 // Take sheet path into account which effects the reference field and the unit for
685 // symbols with multiple parts.
686 if( aAuxData )
687 {
688 SCH_SHEET_PATH* sheet = (SCH_SHEET_PATH*) aAuxData;
689 text = parentSymbol->GetRef( sheet );
690
691 if( SCH_ITEM::Matches( text, aSearchData ) )
692 return true;
693
694 if( parentSymbol->GetUnitCount() > 1 )
695 text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( sheet ) );
696 }
697 }
698
699 return SCH_ITEM::Matches( text, aSearchData );
700}
701
702
703void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks, wxStyledTextEvent& aEvent ) const
704{
705 SCH_ITEM* parent = dynamic_cast<SCH_ITEM*>( GetParent() );
706 SCHEMATIC* schematic = parent ? parent->Schematic() : nullptr;
707
708 if( !schematic )
709 return;
710
711 wxStyledTextCtrl* scintilla = aScintillaTricks->Scintilla();
712 int key = aEvent.GetKey();
713
714 wxArrayString autocompleteTokens;
715 int pos = scintilla->GetCurrentPos();
716 int start = scintilla->WordStartPosition( pos, true );
717 wxString partial;
718
719 // Multi-line fields are not allowed. So remove '\n' if entered.
720 if( key == '\n' )
721 {
722 wxString text = scintilla->GetText();
723 int currpos = scintilla->GetCurrentPos();
724 text.Replace( wxS( "\n" ), wxS( "" ) );
725 scintilla->SetText( text );
726 scintilla->GotoPos( currpos - 1 );
727 return;
728 }
729
730 auto textVarRef =
731 [&]( int pt )
732 {
733 return pt >= 2 && scintilla->GetCharAt( pt - 2 ) == '$' && scintilla->GetCharAt( pt - 1 ) == '{';
734 };
735
736 // Check for cross-reference
737 if( start > 1 && scintilla->GetCharAt( start - 1 ) == ':' )
738 {
739 int refStart = scintilla->WordStartPosition( start - 1, true );
740
741 if( textVarRef( refStart ) )
742 {
743 partial = scintilla->GetRange( start, pos );
744
745 wxString ref = scintilla->GetRange( refStart, start - 1 );
746
747 if( ref == wxS( "OP" ) )
748 {
749 // SPICE operating points use ':' syntax for ports
750 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent ) )
751 {
752 NULL_REPORTER devnull;
753 SCH_SHEET_PATH& sheet = schematic->CurrentSheet();
754 wxString variant = schematic->GetCurrentVariant();
755 SIM_LIB_MGR mgr( &schematic->Project() );
756
757 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
758 embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
759
760 if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
761 {
762 embeddedFilesStack.push_back( symbolEmbeddedFiles );
763 symbol->GetLibSymbolRef()->AppendParentEmbeddedFiles( embeddedFilesStack );
764 }
765
766 mgr.SetFilesStack( std::move( embeddedFilesStack ) );
767
768 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true, 0, variant, devnull ).model;
769
770 for( wxString pin : model.GetPinNames() )
771 {
772 if( pin.StartsWith( '<' ) && pin.EndsWith( '>' ) )
773 autocompleteTokens.push_back( pin.Mid( 1, pin.Length() - 2 ) );
774 else
775 autocompleteTokens.push_back( pin );
776 }
777
778 // add the synthetic port for power measurements
779 autocompleteTokens.push_back( wxT( "power" ) );
780 }
781 }
782 else
783 {
785 SCH_SYMBOL* refSymbol = nullptr;
786
787 schematic->Hierarchy().GetSymbols( refs, SYMBOL_FILTER_ALL );
788
789 for( size_t jj = 0; jj < refs.GetCount(); jj++ )
790 {
791 if( refs[jj].GetSymbol()->GetRef( &refs[jj].GetSheetPath(), true ) == ref )
792 {
793 refSymbol = refs[jj].GetSymbol();
794 break;
795 }
796 }
797
798 if( refSymbol )
799 refSymbol->GetContextualTextVars( &autocompleteTokens );
800 }
801 }
802 }
803 else if( textVarRef( start ) )
804 {
805 partial = scintilla->GetTextRange( start, pos );
806
807 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent );
808 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( parent );
809 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( parent );
810
811 if( symbol )
812 {
813 symbol->GetContextualTextVars( &autocompleteTokens );
814
815 if( schematic->CurrentSheet().Last() )
816 schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
817 }
818
819 if( sheet )
820 sheet->GetContextualTextVars( &autocompleteTokens );
821
822 if( label )
823 label->GetContextualTextVars( &autocompleteTokens );
824
825 for( std::pair<wxString, wxString> entry : schematic->Project().GetTextVars() )
826 autocompleteTokens.push_back( entry.first );
827 }
828
829 aScintillaTricks->DoAutocomplete( partial, autocompleteTokens );
830 scintilla->SetFocus();
831}
832
833
835{
836 // See comments in SCH_FIELD::Replace(), below.
838 return false;
839
840 return true;
841}
842
843
845{
846 if( const SYMBOL* parentSymbol = GetParentSymbol() )
847 {
848 if( parentSymbol->IsLocked() )
849 return true;
850 }
851
852 if( const SCH_SHEET* parentSheet = dynamic_cast<const SCH_SHEET*>( m_parent ) )
853 {
854 if( parentSheet->IsLocked() )
855 return true;
856 }
857
858 return SCH_ITEM::IsLocked();
859}
860
861
862bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
863{
864 bool replaceReferences = false;
865
866 try
867 {
868 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
869 replaceReferences = schSearchData.replaceReferences;
870 }
871 catch( const std::bad_cast& )
872 {
873 }
874
875 wxString text;
876 bool isReplaced = false;
877
878 if( m_id == FIELD_T::REFERENCE && m_parent && m_parent->Type() == SCH_SYMBOL_T )
879 {
880 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
881
882 if( !replaceReferences )
883 return false;
884
885 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in refdes." ) );
886
887 text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
888 isReplaced = EDA_ITEM::Replace( aSearchData, text );
889
890 if( isReplaced )
891 parentSymbol->SetRef( (SCH_SHEET_PATH*) aAuxData, text );
892 }
893 else
894 {
895 isReplaced = EDA_TEXT::Replace( aSearchData );
896
897 if( m_id == FIELD_T::SHEET_FILENAME && isReplaced )
898 {
899 // If we allowed this we'd have a bunch of work to do here, including warning
900 // about it not being undoable, checking for recursive hierarchies, reloading
901 // sheets, etc. See DIALOG_SHEET_PROPERTIES::TransferDataFromWindow().
902 }
903 }
904
905 return isReplaced;
906}
907
908
909void SCH_FIELD::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
910{
912
913 if( GetTextAngle().IsVertical() )
914 {
915 switch( horizJustify )
916 {
918 if( aRotateCCW )
920
921 break;
922
924 if( aRotateCCW )
926
927 break;
928
931 break;
932 }
933
935 }
936 else if( GetTextAngle().IsHorizontal() )
937 {
938 switch( horizJustify )
939 {
941 if( !aRotateCCW )
943
944 break;
945
947 if( !aRotateCCW )
949
950 break;
951
954 break;
955 }
956
958 }
959 else
960 {
961 wxFAIL_MSG( wxString::Format( wxT( "SCH_FIELD text angle is not horizontal or vertical: %f" ),
962 GetTextAngle().AsDegrees() ) );
963 }
964
965 VECTOR2I pt = GetPosition();
966 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
967 SetPosition( pt );
968}
969
970
972{
973 int x = GetTextPos().x;
974
975 x -= aCenter;
976 x *= -1;
977 x += aCenter;
978
979 SetTextX( x );
980}
981
982
984{
985 int y = GetTextPos().y;
986
987 y -= aCenter;
988 y *= -1;
989 y += aCenter;
990
991 SetTextY( y );
992}
993
994
995void SCH_FIELD::BeginEdit( const VECTOR2I& aPosition )
996{
997 SetTextPos( aPosition );
998}
999
1000
1001void SCH_FIELD::CalcEdit( const VECTOR2I& aPosition )
1002{
1003 SetTextPos( aPosition );
1004}
1005
1006
1007wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1008{
1009 wxString content = aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() );
1010
1011 if( content.IsEmpty() )
1012 {
1013 return wxString::Format( _( "Field %s (empty)" ), UnescapeString( GetName() ) );
1014 }
1015 else
1016 {
1017 return wxString::Format( _( "Field %s '%s'" ), UnescapeString( GetName() ), content );
1018 }
1019}
1020
1021
1022void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1023{
1024 wxString msg;
1025
1026 aList.emplace_back( _( "Symbol Field" ), UnescapeString( GetName() ) );
1027
1028 // Don't use GetShownText() here; we want to show the user the variable references
1029 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
1030
1031 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1032
1033 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1034
1035 aList.emplace_back( _( "Style" ), GetTextStyleName() );
1036
1037 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1038
1039 switch( GetHorizJustify() )
1040 {
1041 case GR_TEXT_H_ALIGN_LEFT: msg = _( "Left" ); break;
1042 case GR_TEXT_H_ALIGN_CENTER: msg = _( "Center" ); break;
1043 case GR_TEXT_H_ALIGN_RIGHT: msg = _( "Right" ); break;
1045 }
1046
1047 aList.emplace_back( _( "H Justification" ), msg );
1048
1049 switch( GetVertJustify() )
1050 {
1051 case GR_TEXT_V_ALIGN_TOP: msg = _( "Top" ); break;
1052 case GR_TEXT_V_ALIGN_CENTER: msg = _( "Center" ); break;
1053 case GR_TEXT_V_ALIGN_BOTTOM: msg = _( "Bottom" ); break;
1055 }
1056
1057 aList.emplace_back( _( "V Justification" ), msg );
1058}
1059
1060
1062{
1064 return true;
1065
1066 return IsURL( GetShownText( false ) );
1067}
1068
1069
1070void SCH_FIELD::DoHypertextAction( EDA_DRAW_FRAME* aFrame, const VECTOR2I& aMousePos ) const
1071{
1072 constexpr int START_ID = 1;
1073
1074 wxString href;
1075
1077 {
1078 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
1079 SCH_SHEET_PATH* sheet = &label->Schematic()->CurrentSheet();
1080 wxMenu menu;
1081
1082 std::vector<std::pair<wxString, wxString>> pages;
1083
1084 label->GetIntersheetRefs( sheet, &pages );
1085
1086 for( int i = 0; i < (int) pages.size(); ++i )
1087 {
1088 menu.Append( i + START_ID,
1089 wxString::Format( _( "Go to Page %s (%s)" ), pages[i].first, pages[i].second ) );
1090 }
1091
1092 menu.AppendSeparator();
1093 menu.Append( 999 + START_ID, _( "Back to Previous Selected Sheet" ) );
1094
1095 int sel = aFrame->GetPopupMenuSelectionFromUser( menu ) - START_ID;
1096
1097 if( sel >= 0 && sel < (int) pages.size() )
1098 href = wxT( "#" ) + pages[sel].first;
1099 else if( sel == 999 )
1101 }
1102 else if( IsURL( GetShownText( false ) ) || m_name == SIM_LIBRARY::LIBRARY_FIELD )
1103 {
1104 href = GetShownText( false );
1105 }
1106
1107 if( !href.IsEmpty() )
1108 {
1110 navTool->HypertextCommand( href );
1111 }
1112}
1113
1114
1115void SCH_FIELD::SetName( const wxString& aName )
1116{
1117 m_name = aName;
1119
1120 if( m_isGeneratedField )
1121 EDA_TEXT::SetText( aName );
1122}
1123
1124
1125void SCH_FIELD::SetText( const wxString& aText )
1126{
1127 // Don't allow modification of text value of generated fields.
1128 if( m_isGeneratedField )
1129 return;
1130
1131 // Mandatory fields should not have leading or trailing whitespace.
1132 if( IsMandatory() )
1133 EDA_TEXT::SetText( aText.Strip( wxString::both ) );
1134 else
1135 EDA_TEXT::SetText( aText );
1136}
1137
1138
1139void SCH_FIELD::SetText( const wxString& aText, const SCH_SHEET_PATH* aPath, const wxString& aVariantName )
1140{
1141 wxCHECK( m_parent, /* void */ );
1142
1143 if( m_isGeneratedField )
1144 return;
1145
1146 wxString tmp = aText;
1147
1148 if( IsMandatory() )
1149 tmp = aText.Strip( wxString::both ) ;
1150
1151 switch( m_parent->Type() )
1152 {
1153 case SCH_SYMBOL_T:
1154 {
1155 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1156 wxCHECK( symbol, /* void */ );
1157 symbol->SetFieldText( GetName(), aText, aPath, aVariantName );
1158 break;
1159 }
1160
1161 case SCH_SHEET_T:
1162 {
1163 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1164 wxCHECK( sheet, /* void */ );
1165 sheet->SetFieldText( GetName(), aText, aPath, aVariantName );
1166 break;
1167 }
1168
1169 default:
1170 SCH_FIELD::SetText( aText );
1171 break;
1172 }
1173}
1174
1175
1176wxString SCH_FIELD::GetText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1177{
1178 wxString retv;
1179
1180 wxCHECK( aPath && m_parent, retv );
1181
1182 switch( m_parent->Type() )
1183 {
1184 case SCH_SYMBOL_T:
1185 {
1186 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1187 wxCHECK( symbol, retv );
1188 retv = symbol->GetFieldText( GetName(), aPath, aVariantName );
1189 break;
1190 }
1191
1192 case SCH_SHEET_T:
1193 {
1194 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1195 wxCHECK( sheet, retv );
1196 retv = sheet->GetFieldText( GetName(), aPath, aVariantName );
1197 break;
1198 }
1199
1200 default:
1201 retv = GetText();
1202 break;
1203 }
1204
1205 return retv;
1206}
1207
1208
1209wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
1210{
1211 if( m_parent && m_parent->IsType( labelTypes ) )
1212 return SCH_LABEL_BASE::GetDefaultFieldName( m_name, aUseDefaultName );
1213
1214 if( IsMandatory() )
1215 return GetCanonicalFieldName( m_id );
1216 else if( m_name.IsEmpty() && aUseDefaultName )
1218 else
1219 return m_name;
1220}
1221
1222
1224{
1225 if( m_parent && m_parent->IsType( labelTypes ) )
1226 {
1227 // These should be stored in canonical format, but recover translated forms written by
1228 // older versions or by cross-language collaboration via Git.
1230 return wxT( "Netclass" );
1231 }
1232
1233 if( IsMandatory() )
1234 return GetCanonicalFieldName( m_id );
1235
1236 return m_name;
1237}
1238
1239
1241{
1242 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1243 {
1244 switch( m_id )
1245 {
1249 default: return BITMAPS::text;
1250 }
1251 }
1252
1253 return BITMAPS::text;
1254}
1255
1256
1257bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1258{
1259 if( GetShownText( true ).IsEmpty() )
1260 return false;
1261
1262 BOX2I rect = GetBoundingBox();
1263
1264 // Text in symbol editor can have additional chars (ie: reference designators U? or U?A)
1265 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1266 {
1267 SCH_FIELD temp( *this );
1268 temp.SetText( GetFullText() );
1269 rect = temp.GetBoundingBox();
1270 }
1271
1272 rect.Inflate( aAccuracy );
1273
1274 if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1275 {
1276 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1277 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1278 }
1279
1280 return rect.Contains( aPosition );
1281}
1282
1283
1284bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1285{
1286 if( GetShownText( true ).IsEmpty() )
1287 return false;
1288
1289 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1290 return false;
1291
1292 BOX2I rect = aRect;
1293
1294 rect.Inflate( aAccuracy );
1295
1296 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1297 {
1298 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1299 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1300 }
1301
1302 if( aContained )
1303 return rect.Contains( GetBoundingBox() );
1304
1305 return rect.Intersects( GetBoundingBox() );
1306}
1307
1308
1309bool SCH_FIELD::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1310{
1311 if( GetShownText( true ).IsEmpty() )
1312 return false;
1313
1314 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1315 return false;
1316
1317 BOX2I bbox = GetBoundingBox();
1318
1319 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1320 {
1321 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1322 bbox.Offset( label->GetSchematicTextOffset( nullptr ) );
1323 }
1324
1325 return KIGEOM::BoxHitTest( aPoly, bbox, aContained );
1326}
1327
1328
1329void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit, int aBodyStyle,
1330 const VECTOR2I& aOffset, bool aDimmed )
1331{
1332 wxString text;
1333
1334 if( Schematic() )
1335 text = GetShownText( &Schematic()->CurrentSheet(), true, 0, Schematic()->GetCurrentVariant() );
1336 else
1337 text = GetShownText( true );
1338
1339 if( ( !IsVisible() && !IsForceVisible() ) || text.IsEmpty() || aBackground )
1340 return;
1341
1342 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1343 COLOR4D color = renderSettings->GetLayerColor( GetLayer() );
1344 int penWidth = GetEffectiveTextPenWidth( renderSettings->GetDefaultPenWidth() );
1345
1346 COLOR4D bg = renderSettings->GetBackgroundColor();
1347
1348 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1349 bg = COLOR4D::WHITE;
1350
1351 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1352 color = GetTextColor();
1353
1354 if( color.m_text && Schematic() )
1355 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1356
1357 if( aDimmed )
1358 {
1359 color.Desaturate();
1360 color = color.Mix( bg, 0.5f );
1361 }
1362
1363 penWidth = std::max( penWidth, renderSettings->GetMinPenWidth() );
1364
1365 // clamp the pen width to be sure the text is readable
1366 penWidth = std::min( penWidth, std::min( GetTextSize().x, GetTextSize().y ) / 4 );
1367
1368 if( !IsVisible() && !renderSettings->m_ShowHiddenFields )
1369 return;
1370
1371 // Calculate the text orientation, according to the symbol orientation/mirror
1372 EDA_ANGLE orient = GetTextAngle();
1373 VECTOR2I textpos = GetTextPos();
1375 GR_TEXT_V_ALIGN_T vjustify = GetVertJustify();
1376
1377 if( renderSettings->m_Transform.y1 ) // Rotate symbol 90 deg.
1378 {
1379 if( orient.IsHorizontal() )
1380 orient = ANGLE_VERTICAL;
1381 else
1382 orient = ANGLE_HORIZONTAL;
1383 }
1384
1385 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1386 {
1387 /*
1388 * Calculate the text justification, according to the symbol orientation/mirror. This is
1389 * a bit complicated due to cumulative calculations:
1390 * - numerous cases (mirrored or not, rotation)
1391 * - the plotter's Text() function will also recalculate H and V justifications according
1392 * to the text orientation
1393 * - when a symbol is mirrored the text is not, and justifications become a nightmare
1394 *
1395 * So the easier way is to use no justifications (centered text) and use GetBoundingBox
1396 * to know the text coordinate considered as centered.
1397 */
1398 hjustify = GR_TEXT_H_ALIGN_CENTER;
1399 vjustify = GR_TEXT_V_ALIGN_CENTER;
1400 textpos = GetBoundingBox().Centre();
1401 }
1402 else if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1403 {
1404 // Library-symbol exports (CLI/symbol editor) provide an item offset in the same coordinate
1405 // frame as body graphics/pins. Apply the same transform+offset pipeline to field text.
1406 textpos = renderSettings->TransformCoordinate( textpos ) + aOffset;
1407 }
1408 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1409 {
1410 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_parent );
1411 textpos += label->GetSchematicTextOffset( renderSettings );
1412 }
1413 else if( m_parent && m_parent->Type() == SCH_DIRECTIVE_LABEL_T )
1414 {
1415 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( m_parent );
1416 std::shared_ptr<NETCLASS> nc = label->GetEffectiveNetClass();
1417
1418 if( nc && ( nc->GetSchematicColor() != COLOR4D::UNSPECIFIED ) && aPlotter->GetColorMode() )
1419 color = nc->GetSchematicColor();
1420 }
1421
1422 KIFONT::FONT* font = GetDrawFont( renderSettings );
1424 attrs.m_StrokeWidth = penWidth;
1425 attrs.m_Halign = hjustify;
1426 attrs.m_Valign = vjustify;
1427 attrs.m_Angle = orient;
1428 attrs.m_Multiline = false;
1429
1430 aPlotter->PlotText( textpos, color, text, attrs, font, GetFontMetrics() );
1431
1433 {
1434 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( m_parent ) )
1435 {
1436 std::vector<std::pair<wxString, wxString>> pages;
1437 std::vector<wxString> pageHrefs;
1438
1439 label->GetIntersheetRefs( &Schematic()->CurrentSheet(), &pages );
1440
1441 for( const auto& [pageNumber, sheetName] : pages )
1442 pageHrefs.push_back( wxT( "#" ) + pageNumber );
1443
1444 BOX2I bbox = GetBoundingBox();
1445 bbox.Offset( label->GetSchematicTextOffset( renderSettings ) );
1446
1447 aPlotter->HyperlinkMenu( bbox, pageHrefs );
1448 }
1449 }
1450}
1451
1452
1453void SCH_FIELD::SetPosition( const VECTOR2I& aPosition )
1454{
1455 // Actual positions are calculated by the rotation/mirror transform of the parent symbol
1456 // of the field. The inverse transform is used to calculate the position relative to the
1457 // parent symbol.
1458 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1459 {
1460 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1461 VECTOR2I relPos = aPosition - parentSymbol->GetPosition();
1462
1463 relPos = parentSymbol->GetTransform().InverseTransform().TransformCoordinate( relPos );
1464
1465 SetTextPos( relPos + parentSymbol->GetPosition() );
1466 return;
1467 }
1468
1469 SetTextPos( aPosition );
1470}
1471
1472
1474{
1475 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1476 {
1477 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1478 VECTOR2I relativePos = GetTextPos() - parentSymbol->GetPosition();
1479
1480 relativePos = parentSymbol->GetTransform().TransformCoordinate( relativePos );
1481
1482 return relativePos + parentSymbol->GetPosition();
1483 }
1484
1485 return GetTextPos();
1486}
1487
1488
1490{
1491 return m_parent ? m_parent->GetPosition() : VECTOR2I( 0, 0 );
1492}
1493
1494
1501
1502
1503bool SCH_FIELD::operator<( const SCH_ITEM& aItem ) const
1504{
1505 if( Type() != aItem.Type() )
1506 return Type() < aItem.Type();
1507
1508 auto field = static_cast<const SCH_FIELD*>( &aItem );
1509
1510 if( GetId() != field->GetId() )
1511 return GetId() < field->GetId();
1512
1513 if( GetText() != field->GetText() )
1514 return GetText() < field->GetText();
1515
1516 if( GetLibPosition().x != field->GetLibPosition().x )
1517 return GetLibPosition().x < field->GetLibPosition().x;
1518
1519 if( GetLibPosition().y != field->GetLibPosition().y )
1520 return GetLibPosition().y < field->GetLibPosition().y;
1521
1522 return GetName() < field->GetName();
1523}
1524
1525
1526bool SCH_FIELD::operator==( const SCH_ITEM& aOther ) const
1527{
1528 if( Type() != aOther.Type() )
1529 return false;
1530
1531 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1532
1533 return *this == field;
1534}
1535
1536
1537bool SCH_FIELD::operator==( const SCH_FIELD& aOther ) const
1538{
1539 // Identical fields owned by different items are not equal.
1540 if( m_parent || aOther.m_parent )
1541 {
1542 if( !m_parent || !aOther.m_parent )
1543 return false;
1544
1545 if( m_parent->Type() != aOther.m_parent->Type() )
1546 return false;
1547
1548 if( m_parent->m_Uuid != aOther.m_parent->m_Uuid )
1549 return false;
1550 }
1551
1552 if( IsMandatory() != aOther.IsMandatory() )
1553 return false;
1554
1555 if( IsMandatory() )
1556 {
1557 if( GetId() != aOther.GetId() )
1558 return false;
1559 }
1560 else
1561 {
1562 if( GetOrdinal() != aOther.GetOrdinal() )
1563 return false;
1564 }
1565
1566 if( GetPosition() != aOther.GetPosition() )
1567 return false;
1568
1569 if( IsGeneratedField() != aOther.IsGeneratedField() )
1570 return false;
1571
1572 if( IsNameShown() != aOther.IsNameShown() )
1573 return false;
1574
1575 if( CanAutoplace() != aOther.CanAutoplace() )
1576 return false;
1577
1578 return EDA_TEXT::operator==( aOther );
1579}
1580
1581
1582bool SCH_FIELD::HasSameContent( const SCH_FIELD& aOther ) const
1583{
1584 if( GetCanonicalName() != aOther.GetCanonicalName() )
1585 return false;
1586
1587 if( GetPosition() != aOther.GetPosition() )
1588 return false;
1589
1590 if( IsVisible() != aOther.IsVisible() )
1591 return false;
1592
1593 if( IsPrivate() != aOther.IsPrivate() )
1594 return false;
1595
1596 if( IsGeneratedField() != aOther.IsGeneratedField() )
1597 return false;
1598
1599 if( IsNameShown() != aOther.IsNameShown() )
1600 return false;
1601
1602 if( CanAutoplace() != aOther.CanAutoplace() )
1603 return false;
1604
1605 return EDA_TEXT::operator==( aOther );
1606}
1607
1608
1609double SCH_FIELD::Similarity( const SCH_ITEM& aOther ) const
1610{
1611 if( Type() != aOther.Type() )
1612 return 0.0;
1613
1614 if( m_Uuid == aOther.m_Uuid )
1615 return 1.0;
1616
1617 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1618
1619 double similarity = 0.99; // The UUIDs are different, so we start with non-identity
1620
1621 if( GetId() != field.GetId() )
1622 {
1623 // We don't allow swapping of mandatory fields, so these cannot be the same item
1624 if( IsMandatory() || field.IsMandatory() )
1625 return 0.0;
1626 else
1627 similarity *= 0.5;
1628 }
1629
1630 similarity *= SimilarityBase( aOther );
1631
1632 similarity *= EDA_TEXT::Similarity( field );
1633
1634 if( GetPosition() != field.GetPosition() )
1635 similarity *= 0.5;
1636
1637 if( IsGeneratedField() != field.IsGeneratedField() )
1638 similarity *= 0.5;
1639
1640 if( IsNameShown() != field.IsNameShown() )
1641 similarity *= 0.5;
1642
1643 if( CanAutoplace() != field.CanAutoplace() )
1644 similarity *= 0.5;
1645
1646 return similarity;
1647}
1648
1649
1650int SCH_FIELD::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1651{
1652 wxASSERT( aOther.Type() == SCH_FIELD_T );
1653
1654 int compareFlags = aCompareFlags;
1655
1656 // For ERC tests, the field position has no matter, so do not test it
1657 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC )
1659
1660 int retv = SCH_ITEM::compare( aOther, compareFlags );
1661
1662 if( retv )
1663 return retv;
1664
1665 const SCH_FIELD* tmp = static_cast<const SCH_FIELD*>( &aOther );
1666
1667 // Equality test will vary depending whether or not the field is mandatory. Otherwise,
1668 // sorting is done by ordinal.
1669 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1670 {
1671 // Mandatory fields have fixed ordinals and their names can vary due to translated field
1672 // names. Optional fields have fixed names and their ordinals can vary.
1673 if( IsMandatory() )
1674 {
1675 if( m_id != tmp->m_id )
1676 return (int) m_id - (int) tmp->m_id;
1677 }
1678 else
1679 {
1680 retv = m_name.Cmp( tmp->m_name );
1681
1682 if( retv )
1683 return retv;
1684 }
1685 }
1686 else // assume we're sorting
1687 {
1688 if( m_id != tmp->m_id )
1689 return (int) m_id - (int) tmp->m_id;
1690 }
1691
1692 bool ignoreFieldText = false;
1693
1694 if( m_id == FIELD_T::REFERENCE && !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY ) )
1695 ignoreFieldText = true;
1696
1697 if( m_id == FIELD_T::VALUE && ( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1698 ignoreFieldText = true;
1699
1700 if( !ignoreFieldText )
1701 {
1702 retv = GetText().CmpNoCase( tmp->GetText() );
1703
1704 if( retv != 0 )
1705 return retv;
1706 }
1707
1708 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1709 {
1710 if( GetTextPos().x != tmp->GetTextPos().x )
1711 return GetTextPos().x - tmp->GetTextPos().x;
1712
1713 if( GetTextPos().y != tmp->GetTextPos().y )
1714 return GetTextPos().y - tmp->GetTextPos().y;
1715 }
1716
1717 // For ERC tests, the field size has no matter, so do not test it
1718 if( !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1719 {
1720 if( GetTextWidth() != tmp->GetTextWidth() )
1721 return GetTextWidth() - tmp->GetTextWidth();
1722
1723 if( GetTextHeight() != tmp->GetTextHeight() )
1724 return GetTextHeight() - tmp->GetTextHeight();
1725 }
1726
1727 return 0;
1728}
1729
1730
1731wxString SCH_FIELD::getUnescapedText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1732{
1733 // This is the default variant field text for all fields except the reference field.
1734 wxString retv = EDA_TEXT::GetShownText( false );
1735
1736 // Special handling for parent object field instance and variant information.
1737 // Only use the path if it's non-empty; an empty path can't match any instances
1738 if( m_parent && aPath && !aPath->empty() )
1739 {
1740 wxLogTrace( traceSchFieldRendering, " Path is valid and non-empty, parent type=%d", m_parent->Type() );
1741
1742 switch( m_parent->Type() )
1743 {
1744 case SCH_SYMBOL_T:
1745 if( const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( m_parent ) )
1746 {
1747 if( m_id == FIELD_T::REFERENCE )
1748 {
1749 wxLogTrace( traceSchFieldRendering, " Calling GetRef for symbol %s on path %s",
1750 symbol->m_Uuid.AsString(), aPath->Path().AsString() );
1751
1752 retv = symbol->GetRef( aPath, true );
1753
1754 wxLogTrace( traceSchFieldRendering, " GetRef returned: '%s'", retv );
1755 }
1756 else if( !aVariantName.IsEmpty() )
1757 {
1758 // If the variant is not found, fall back to default variant above.
1759 if( std::optional<SCH_SYMBOL_VARIANT> variant = symbol->GetVariant( *aPath, aVariantName ) )
1760 {
1761 // An explicit override wins; otherwise resolve through the alternate
1762 // library symbol so the canvas matches the fields table and netlist.
1763 if( variant->m_Fields.contains( GetName() ) )
1764 {
1765 retv = variant->m_Fields[GetName()];
1766 }
1767 else if( LIB_SYMBOL* altSymbol = symbol->GetVariantLibSymbol( aVariantName, *aPath ) )
1768 {
1769 const SCH_FIELD* altField = altSymbol->GetField( GetName() );
1770
1771 if( altField && !altField->GetText().IsEmpty() )
1772 retv = altField->GetText();
1773 }
1774 }
1775 }
1776 }
1777
1778 break;
1779
1780 case SCH_SHEET_T:
1781 break;
1782
1783 default:
1784 break;
1785 }
1786 }
1787
1788 return retv;
1789}
1790
1791
1792static struct SCH_FIELD_DESC
1793{
1795 {
1796 // These are defined in EDA_TEXT as well but initialization order is
1797 // not defined, so this needs to be conditional. Defining in both
1798 // places leads to duplicate symbols.
1800
1801 if( h_inst.Choices().GetCount() == 0 )
1802 {
1803 h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _HKI( "Left" ) );
1804 h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _HKI( "Center" ) );
1805 h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _HKI( "Right" ) );
1806 }
1807
1809
1810 if( v_inst.Choices().GetCount() == 0 )
1811 {
1812 v_inst.Map( GR_TEXT_V_ALIGN_TOP, _HKI( "Top" ) );
1813 v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _HKI( "Center" ) );
1814 v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _HKI( "Bottom" ) );
1815 }
1816
1823
1824 // Lock state is inherited from parent symbol (no independent locking of child items)
1825 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Locked" ) );
1826
1827 const wxString textProps = _HKI( "Text Properties" );
1828
1829 auto horiz = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_H_ALIGN_T>( _HKI( "Horizontal Justification" ),
1832
1833 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ), horiz, textProps );
1834
1835 auto vert = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_V_ALIGN_T>( _HKI( "Vertical Justification" ),
1838
1839 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ), vert, textProps );
1840
1841 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Show Field Name" ), &SCH_FIELD::SetNameShown,
1843
1844 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Allow Autoplacement" ), &SCH_FIELD::SetCanAutoplace,
1846
1847 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
1848 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
1849 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
1850 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
1851 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
1852
1853
1856 _HKI( "Text Properties" ) );
1857
1858 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
1859
1860 auto isNotGeneratedField = []( INSPECTABLE* aItem ) -> bool
1861 {
1862 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1863 return !field->IsGeneratedField();
1864
1865 return true;
1866 };
1867
1869 isNotGeneratedField );
1870
1871
1872 auto isNonMandatoryField = []( INSPECTABLE* aItem ) -> bool
1873 {
1874 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1875 return !field->IsMandatory();
1876
1877 return false;
1878 };
1879
1880 propMgr.OverrideAvailability( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Private" ),
1881 isNonMandatoryField );
1882 }
1884
1885
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:423
COLOR4D GetSchematicColor(bool aIsForSave=false) const
Definition netclass.h:225
A singleton reporter that reports to nowhere.
Definition reporter.h:250
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:914
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:458
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:455
@ LAYER_SHEETNAME
Definition layer_ids.h:478
@ LAYER_VALUEPART
Definition layer_ids.h:467
@ LAYER_FIELDS
Definition layer_ids.h:468
@ LAYER_SHEETFIELDS
Definition layer_ids.h:480
@ LAYER_REFERENCEPART
Definition layer_ids.h:466
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:470
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:501
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:469
@ LAYER_SHEETFILENAME
Definition layer_ids.h:479
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