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