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 <sch_render_settings.h>
22#include <scintilla_tricks.h>
23#include <netclass.h>
24#include <wx/log.h>
25#include <wx/menu.h>
26
27#include <advanced_config.h>
28#include <base_units.h>
29#include <common.h> // for ExpandTextVars
30#include <sch_edit_frame.h>
31#include <plotters/plotter.h>
32#include <bitmaps.h>
33#include <kiway.h>
35#include <string_utils.h>
37#include <trace_helpers.h>
38#include <tool/tool_manager.h>
40#include <font/outline_font.h>
41#include "sim/sim_lib_mgr.h"
42#include <properties/property.h>
44#include <google/protobuf/any.pb.h>
45#include <api/api_utils.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 untranslated)
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
146 SetName( GetDefaultFieldName( aFieldId, TRANSLATED ) );
147
148 setId( aFieldId ); // will also set the layer; call only AFTER SetName()
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( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aParent ) )
164 m_ordinal = label->GetNextFieldOrdinal();
165 }
166 else if( aFieldId == FIELD_T::SHEET_USER && aParent )
167 {
168 if( aParent->Type() == SCH_SHEET_T )
169 m_ordinal = static_cast<SCH_SHEET*>( aParent )->GetNextFieldOrdinal();
170 }
171}
172
173
175 SCH_FIELD( aParent, FIELD_T::USER, wxEmptyString )
176{
177 SCH_ITEM::operator=( *aText );
178 EDA_TEXT::operator=( *aText );
179}
180
181
183 SCH_ITEM( aField ),
184 EDA_TEXT( aField )
185{
186 m_private = aField.m_private;
187 m_name = aField.m_name;
188 setId( aField.m_id ); // will also set the layer; call only AFTER setting m_name
189 m_ordinal = aField.m_ordinal;
190 m_showName = aField.m_showName;
193 m_autoAdded = aField.m_autoAdded;
196
197 m_renderCache.reset();
198}
199
200
201void SCH_FIELD::Serialize( kiapi::schematic::types::SchematicField& field, const EDA_IU_SCALE& aScale ) const
202{
203 field.set_name( GetName( false ).ToUTF8() );
204 field.set_visible( IsVisible() );
205 field.set_show_name( IsNameShown() );
206 field.set_allow_auto_place( CanAutoplace() );
207 field.set_is_private( IsPrivate() );
208
209 EDA_TEXT::Serialize( *field.mutable_text(), aScale );
210
211 // Override the position from the above for symbols so that they are in the right reference frame
212 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
213 kiapi::common::PackVector2( *field.mutable_text()->mutable_position(), GetPosition(), aScale );
214
215 kiapi::common::PackCustomProperties( field.mutable_custom_properties(), *this );
216}
217
218
219void SCH_FIELD::Serialize( google::protobuf::Any& aContainer ) const
220{
221 kiapi::schematic::types::SchematicField field;
222 Serialize( field, schIUScale );
223 aContainer.PackFrom( field );
224}
225
226
227bool SCH_FIELD::Deserialize( const kiapi::schematic::types::SchematicField& field, const EDA_IU_SCALE& aScale )
228{
229 SetName( wxString::FromUTF8( field.name() ) );
230 SetVisible( field.visible() );
231 SetNameShown( field.show_name() );
232 SetCanAutoplace( field.allow_auto_place() );
233 SetPrivate( field.is_private() );
234
235 bool result = EDA_TEXT::Deserialize( field.text(), aScale );
236
237 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
238 SetPosition( kiapi::common::UnpackVector2( field.text().position(), aScale ) );
239
240 return result;
241}
242
243
244bool SCH_FIELD::Deserialize( const google::protobuf::Any& aContainer )
245{
246 kiapi::schematic::types::SchematicField field;
247
248 if( !aContainer.UnpackTo( &field ) )
249 return false;
250
251 return Deserialize( field, schIUScale );
252}
253
254
256{
257 EDA_TEXT::operator=( aField );
258
259 m_private = aField.m_private;
260 m_name = aField.m_name;
261 setId( aField.m_id ); // will also set the layer; call only AFTER setting m_name
262 m_ordinal = aField.m_ordinal;
263 m_showName = aField.m_showName;
267
268 m_renderCache.reset();
270
271 return *this;
272}
273
274
276{
277 return new SCH_FIELD( *this );
278}
279
280
281void SCH_FIELD::Copy( SCH_FIELD* aTarget ) const
282{
283 *aTarget = *this;
284}
285
286
288{
289 m_id = aId;
291}
292
293
298
299
301 const wxString& aVariantName, int aDepth ) const
302{
303 bool hasTextVars = HasTextVars();
304 wxString text = getUnescapedText( aPath, aVariantName );
305
306 if( !aVariantName.IsEmpty() )
307 hasTextVars = text.Contains( wxT( "${" ) ) || text.Contains( wxT( "@{" ) );
308
309 if( IsNameShown() && aContext == FOR_CANVAS )
310 text = GetShownName() << wxS( ": " ) << text;
311
312 if( hasTextVars && aContext != RAW_VALUE )
313 {
314 text = ResolveText( text, aPath, aDepth, aVariantName );
315 FinalizeTextVarExpansion( text, aContext );
316 }
317
318 return text;
319}
320
321
322wxString SCH_FIELD::GetShownText( RESOLUTION_CONTEXT aContext, int aDepth ) const
323{
324 if( SCHEMATIC* schematic = Schematic() )
325 {
326 const SCH_SHEET_PATH& currentSheet = schematic->CurrentSheet();
327 wxString variantName = schematic->GetCurrentVariant();
328
329 // Path() builds a KIID_PATH, so keep it off the render path unless the trace is on
330 if( wxLog::IsAllowedTraceMask( traceSchFieldRendering ) )
331 {
332 wxLogTrace( traceSchFieldRendering,
333 "GetShownText (no path arg): field=%s, current sheet path='%s', variant='%s', "
334 "size=%zu, empty=%d",
335 GetName(), currentSheet.Path().AsString(), variantName, currentSheet.size(),
336 currentSheet.empty() ? 1 : 0 );
337 }
338
339 return GetShownText( &currentSheet, aContext, variantName, aDepth );
340 }
341 else
342 {
343 return GetShownText( nullptr, aContext, wxEmptyString, aDepth );
344 }
345}
346
347
348wxString SCH_FIELD::GetFullText( int unit ) const
349{
350 if( GetId() != FIELD_T::REFERENCE )
351 return GetText();
352
353 wxString text = GetText();
354 text << wxT( "?" );
355
356 if( GetParentSymbol() && GetParentSymbol()->IsMultiUnit() )
357 text << GetParentSymbol()->GetUnitDisplayName( unit, false );
358
359 return text;
360}
361
362
364{
366}
367
368
370{
372
373 if( !font )
374 font = KIFONT::FONT::GetFont( GetDefaultFont( aSettings ), IsBold(), IsItalic() );
375
376 return font;
377}
378
379
385
386
392
393
394std::vector<std::unique_ptr<KIFONT::GLYPH>>*
395SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forPosition, TEXT_ATTRIBUTES& aAttrs ) const
396{
397 KIFONT::FONT* font = GetDrawFont( nullptr );
398
399 if( font->IsOutline() )
400 {
401 KIFONT::OUTLINE_FONT* outlineFont = static_cast<KIFONT::OUTLINE_FONT*>( font );
402
403 if( !m_renderCache )
404 m_renderCache = std::make_unique<SCH_FIELD_RENDER_CACHE_DATA>();
405
406 if( m_renderCache->glyphs.empty() )
407 {
408 m_renderCache->glyphs.clear();
409
410 outlineFont->GetLinesAsGlyphs( &m_renderCache->glyphs, forResolvedText, forPosition, aAttrs,
411 GetFontMetrics() );
412
413 m_renderCache->pos = forPosition;
414 }
415
416 if( m_renderCache->pos != forPosition )
417 {
418 VECTOR2I delta = forPosition - m_renderCache->pos;
419
420 for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache->glyphs )
421 {
422 if( glyph->IsOutline() )
423 static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
424 else
425 static_cast<KIFONT::STROKE_GLYPH*>( glyph.get() )->Move( delta );
426 }
427
428 m_renderCache->pos = forPosition;
429 }
430
431 return &m_renderCache->glyphs;
432 }
433
434 return nullptr;
435}
436
437
438void SCH_FIELD::ImportValues( const SCH_FIELD& aSource )
439{
440 SetAttributes( aSource );
441 SetVisible( aSource.IsVisible() );
442 SetNameShown( aSource.IsNameShown() );
443 SetCanAutoplace( aSource.CanAutoplace() );
444}
445
446
448{
449 wxCHECK_RET( aItem && aItem->Type() == SCH_FIELD_T, wxT( "Cannot swap with invalid item." ) );
450
451 SCH_FIELD* item = static_cast<SCH_FIELD*>( aItem );
452
453 std::swap( m_showName, item->m_showName );
454 std::swap( m_allowAutoPlace, item->m_allowAutoPlace );
455 std::swap( m_isGeneratedField, item->m_isGeneratedField );
456 SwapText( *item );
457 SwapAttributes( *item );
458
459 std::swap( m_lastResolvedColor, item->m_lastResolvedColor );
460}
461
462
464{
466 {
468 }
469 else
470 {
471 SCH_LABEL_BASE* parentLabel = dynamic_cast<SCH_LABEL_BASE*>( GetParent() );
472
473 if( parentLabel && !parentLabel->IsConnectivityDirty() )
475 else
477 }
478
479 return m_lastResolvedColor;
480}
481
482
483std::vector<int> SCH_FIELD::ViewGetLayers() const
484{
486}
487
488
490{
491 if( m_parent && m_parent->Type() == SCH_LABEL_T )
492 {
493 if( GetUntranslatedName() == wxT( "Netclass" ) || GetUntranslatedName() == wxT( "Component Class" ) )
494 {
495 return LAYER_NETCLASS_REFS;
496 }
497 }
498
499 switch( m_id )
500 {
502 case FIELD_T::VALUE: return LAYER_VALUEPART;
507 default: return LAYER_FIELDS;
508 }
509}
510
511
513{
514 // Calculate the text orientation according to the symbol orientation.
515 EDA_ANGLE orient = GetTextAngle();
516
517 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
518 {
519 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
520
521 if( parentSymbol && parentSymbol->GetTransform().y1 ) // Rotate symbol 90 degrees.
522 {
523 if( orient.IsHorizontal() )
524 orient = ANGLE_VERTICAL;
525 else
526 orient = ANGLE_HORIZONTAL;
527 }
528 }
529
530 return orient;
531}
532
533
535{
536 BOX2I bbox = GetTextBox( nullptr );
537
538 // Calculate the bounding box position relative to the parent:
539 VECTOR2I origin = GetParentPosition();
540 VECTOR2I pos = GetTextPos() - origin;
541 VECTOR2I begin = bbox.GetOrigin() - origin;
542 VECTOR2I end = bbox.GetEnd() - origin;
543 RotatePoint( begin, pos, GetTextAngle() );
544 RotatePoint( end, pos, GetTextAngle() );
545
546 // Now, apply the symbol transform (mirror/rot)
547 TRANSFORM transform;
548
549 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
550 transform = static_cast<SCH_SYMBOL*>( m_parent )->GetTransform();
551
552 bbox.SetOrigin( transform.TransformCoordinate( begin ) );
553 bbox.SetEnd( transform.TransformCoordinate( end ) );
554
555 bbox.Move( origin );
556 bbox.Normalize();
557
558 return bbox;
559}
560
561
563{
564 VECTOR2I render_center = GetBoundingBox().Centre();
565 VECTOR2I pos = GetPosition();
566
567 switch( GetHorizJustify() )
568 {
570 if( GetDrawRotation().IsVertical() )
571 return render_center.y > pos.y;
572 else
573 return render_center.x < pos.x;
574
576 if( GetDrawRotation().IsVertical() )
577 return render_center.y < pos.y;
578 else
579 return render_center.x > pos.x;
580
581 default:
582 return false;
583 }
584}
585
586
588{
589 // The justification must be stored before asking whether it is flipped, as a center
590 // justification has no side to report.
591 SetHorizJustify( aJustify );
592
594 SetHorizJustify( MapHorizJustify( -aJustify ) );
595}
596
597
607
608
610{
611 VECTOR2I render_center = GetBoundingBox().Centre();
612 VECTOR2I pos = GetPosition();
613
614 switch( GetVertJustify() )
615 {
617 if( GetDrawRotation().IsVertical() )
618 return render_center.x < pos.x;
619 else
620 return render_center.y < pos.y;
621
623 if( GetDrawRotation().IsVertical() )
624 return render_center.x > pos.x;
625 else
626 return render_center.y > pos.y;
627
628 default:
629 return false;
630 }
631}
632
633
635{
636 SetVertJustify( aJustify );
637
639 SetVertJustify( MapVertJustify( -aJustify ) );
640}
641
642
652
653
654bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
655{
656 bool searchHiddenFields = aSearchData.searchAllFields;
657 bool searchAndReplace = aSearchData.searchAndReplace;
658 bool replaceReferences = false;
659
660 try
661 {
662 // downcast
663 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
664 replaceReferences = schSearchData.replaceReferences;
665 }
666 catch( const std::bad_cast& )
667 {
668 }
669
670 wxString text = UnescapeString( GetText() );
671
672 if( !IsVisible() && !searchHiddenFields )
673 return false;
674
675 if( m_id == FIELD_T::REFERENCE )
676 {
677 if( searchAndReplace && !replaceReferences )
678 return false;
679
680 SCH_SYMBOL* parentSymbol = dyn_cast<SCH_SYMBOL*>( m_parent );
681
682 // The parent might be a LIB_SYMBOL, in which case, we don't
683 // have a sheet path to resolve the reference.
684 if( !parentSymbol )
685 return false;
686
687 // the search pane surfaces metadata hits through the reference field
688 if( aSearchData.searchMetadata && parentSymbol->Matches( aSearchData, aAuxData ) )
689 return true;
690
691 wxASSERT( aAuxData );
692
693 // Take sheet path into account which effects the reference field and the unit for
694 // symbols with multiple parts.
695 if( aAuxData )
696 {
697 SCH_SHEET_PATH* sheet = (SCH_SHEET_PATH*) aAuxData;
698 text = parentSymbol->GetRef( sheet );
699
700 if( SCH_ITEM::Matches( text, aSearchData ) )
701 return true;
702
703 if( parentSymbol->GetUnitCount() > 1 )
704 text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( sheet ) );
705 }
706 }
707
708 return SCH_ITEM::Matches( text, aSearchData );
709}
710
711
712void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks, wxStyledTextEvent& aEvent ) const
713{
714 SCH_ITEM* parent = dynamic_cast<SCH_ITEM*>( GetParent() );
715 SCHEMATIC* schematic = parent ? parent->Schematic() : nullptr;
716
717 if( !schematic )
718 return;
719
720 wxStyledTextCtrl* scintilla = aScintillaTricks->Scintilla();
721 int key = aEvent.GetKey();
722
723 wxArrayString autocompleteTokens;
724 int pos = scintilla->GetCurrentPos();
725 int start = scintilla->WordStartPosition( pos, true );
726 wxString partial;
727
728 // Multi-line fields are not allowed. So remove '\n' if entered.
729 if( key == '\n' )
730 {
731 wxString text = scintilla->GetText();
732 int currpos = scintilla->GetCurrentPos();
733 text.Replace( wxS( "\n" ), wxS( "" ) );
734 scintilla->SetText( text );
735 scintilla->GotoPos( currpos - 1 );
736 return;
737 }
738
739 auto textVarRef =
740 [&]( int pt )
741 {
742 return pt >= 2 && scintilla->GetCharAt( pt - 2 ) == '$' && scintilla->GetCharAt( pt - 1 ) == '{';
743 };
744
745 // Check for cross-reference
746 if( start > 1 && scintilla->GetCharAt( start - 1 ) == ':' )
747 {
748 int refStart = scintilla->WordStartPosition( start - 1, true );
749
750 if( textVarRef( refStart ) )
751 {
752 partial = scintilla->GetRange( start, pos );
753
754 wxString ref = scintilla->GetRange( refStart, start - 1 );
755
756 if( ref == wxS( "OP" ) )
757 {
758 // SPICE operating points use ':' syntax for ports
759 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent ) )
760 {
761 NULL_REPORTER devnull;
762 SCH_SHEET_PATH& sheet = schematic->CurrentSheet();
763 wxString variant = schematic->GetCurrentVariant();
764 SIM_LIB_MGR mgr( &schematic->Project() );
765
766 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
767 embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
768
769 if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
770 {
771 embeddedFilesStack.push_back( symbolEmbeddedFiles );
772 symbol->GetLibSymbolRef()->AppendParentEmbeddedFiles( embeddedFilesStack );
773 }
774
775 mgr.SetFilesStack( std::move( embeddedFilesStack ) );
776
777 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true, 0, variant, devnull ).model;
778
779 for( wxString pin : model.GetPinNames() )
780 {
781 if( pin.StartsWith( '<' ) && pin.EndsWith( '>' ) )
782 autocompleteTokens.push_back( pin.Mid( 1, pin.Length() - 2 ) );
783 else
784 autocompleteTokens.push_back( pin );
785 }
786
787 // add the synthetic port for power measurements
788 autocompleteTokens.push_back( wxT( "power" ) );
789 }
790 }
791 else
792 {
794 SCH_SYMBOL* refSymbol = nullptr;
795
796 schematic->Hierarchy().GetSymbols( refs, SYMBOL_FILTER_NON_POWER );
797
798 for( size_t jj = 0; jj < refs.GetCount(); jj++ )
799 {
800 if( refs[jj].GetSymbol()->GetRef( &refs[jj].GetSheetPath(), true ) == ref )
801 {
802 refSymbol = refs[jj].GetSymbol();
803 break;
804 }
805 }
806
807 if( refSymbol )
808 refSymbol->GetContextualTextVars( &autocompleteTokens );
809 }
810 }
811 }
812 else if( textVarRef( start ) )
813 {
814 partial = scintilla->GetTextRange( start, pos );
815
816 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent );
817 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( parent );
818 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( parent );
819
820 if( symbol )
821 {
822 symbol->GetContextualTextVars( &autocompleteTokens );
823
824 if( schematic->CurrentSheet().Last() )
825 schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
826 }
827
828 if( sheet )
829 sheet->GetContextualTextVars( &autocompleteTokens );
830
831 if( label )
832 label->GetContextualTextVars( &autocompleteTokens );
833
834 for( std::pair<wxString, wxString> entry : schematic->Project().GetTextVars() )
835 autocompleteTokens.push_back( entry.first );
836 }
837
838 aScintillaTricks->DoAutocomplete( partial, autocompleteTokens );
839 scintilla->SetFocus();
840}
841
842
844{
845 // See comments in SCH_FIELD::Replace(), below.
847 return false;
848
849 return true;
850}
851
852
854{
855 if( const SYMBOL* parentSymbol = GetParentSymbol() )
856 {
857 if( parentSymbol->IsLocked() )
858 return true;
859 }
860
861 if( const SCH_SHEET* parentSheet = dynamic_cast<const SCH_SHEET*>( m_parent ) )
862 {
863 if( parentSheet->IsLocked() )
864 return true;
865 }
866
867 if( const SCH_LABEL_BASE* parentLabel = dynamic_cast<const SCH_LABEL_BASE*>( m_parent ) )
868 {
869 if( parentLabel->IsLocked() )
870 return true;
871 }
872
873 return SCH_ITEM::IsLocked();
874}
875
876
877bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
878{
880 return false;
881
882 bool replaceReferences = false;
883
884 try
885 {
886 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
887 replaceReferences = schSearchData.replaceReferences;
888 }
889 catch( const std::bad_cast& )
890 {
891 }
892
893 wxString text;
894 bool isReplaced = false;
895
896 if( m_id == FIELD_T::REFERENCE && m_parent && m_parent->Type() == SCH_SYMBOL_T )
897 {
898 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
899
900 if( !replaceReferences )
901 return false;
902
903 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in refdes." ) );
904
905 text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
906 isReplaced = EDA_ITEM::Replace( aSearchData, text );
907
908 if( isReplaced )
909 parentSymbol->SetRef( (SCH_SHEET_PATH*) aAuxData, text );
910 }
911 else
912 {
913 isReplaced = EDA_TEXT::Replace( aSearchData );
914
915 if( m_id == FIELD_T::SHEET_FILENAME && isReplaced )
916 {
917 // If we allowed this we'd have a bunch of work to do here, including warning
918 // about it not being undoable, checking for recursive hierarchies, reloading
919 // sheets, etc. See DIALOG_SHEET_PROPERTIES::TransferDataFromWindow().
920 }
921 }
922
923 return isReplaced;
924}
925
926
927void SCH_FIELD::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
928{
930
931 if( GetTextAngle().IsVertical() )
932 {
933 switch( horizJustify )
934 {
936 if( aRotateCCW )
938
939 break;
940
942 if( aRotateCCW )
944
945 break;
946
949 break;
950 }
951
953 }
954 else if( GetTextAngle().IsHorizontal() )
955 {
956 switch( horizJustify )
957 {
959 if( !aRotateCCW )
961
962 break;
963
965 if( !aRotateCCW )
967
968 break;
969
972 break;
973 }
974
976 }
977 else
978 {
979 wxFAIL_MSG( wxString::Format( wxT( "SCH_FIELD text angle is not horizontal or vertical: %f" ),
980 GetTextAngle().AsDegrees() ) );
981 }
982
983 VECTOR2I pt = GetPosition();
984 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
985 SetPosition( pt );
986}
987
988
990{
991 int x = GetTextPos().x;
992
993 x -= aCenter;
994 x *= -1;
995 x += aCenter;
996
997 SetTextX( x );
998}
999
1000
1002{
1003 int y = GetTextPos().y;
1004
1005 y -= aCenter;
1006 y *= -1;
1007 y += aCenter;
1008
1009 SetTextY( y );
1010}
1011
1012
1013void SCH_FIELD::BeginEdit( const VECTOR2I& aPosition )
1014{
1015 SetTextPos( aPosition );
1016}
1017
1018
1019void SCH_FIELD::CalcEdit( const VECTOR2I& aPosition )
1020{
1021 SetTextPos( aPosition );
1022}
1023
1024
1025wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1026{
1027 wxString content = aFull ? GetShownText( FOR_GUI ) : KIUI::EllipsizeMenuText( GetText() );
1028
1029 if( content.IsEmpty() )
1030 return wxString::Format( _( "Field %s (empty)" ), UnescapeString( GetName() ) );
1031 else
1032 return wxString::Format( _( "Field %s '%s'" ), UnescapeString( GetName() ), content );
1033}
1034
1035
1036void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1037{
1038 wxString msg;
1039
1040 aList.emplace_back( _( "Symbol Field" ), UnescapeString( GetName() ) );
1041
1042 // Don't use GetShownText() here; we want to show the user the variable references
1043 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
1044
1045 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1046
1047 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1048
1049 aList.emplace_back( _( "Style" ), GetTextStyleName() );
1050
1051 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1052
1053 switch( GetHorizJustify() )
1054 {
1055 case GR_TEXT_H_ALIGN_LEFT: msg = _( "Left" ); break;
1056 case GR_TEXT_H_ALIGN_CENTER: msg = _( "Center" ); break;
1057 case GR_TEXT_H_ALIGN_RIGHT: msg = _( "Right" ); break;
1059 }
1060
1061 aList.emplace_back( _( "H Justification" ), msg );
1062
1063 switch( GetVertJustify() )
1064 {
1065 case GR_TEXT_V_ALIGN_TOP: msg = _( "Top" ); break;
1066 case GR_TEXT_V_ALIGN_CENTER: msg = _( "Center" ); break;
1067 case GR_TEXT_V_ALIGN_BOTTOM: msg = _( "Bottom" ); break;
1069 }
1070
1071 aList.emplace_back( _( "V Justification" ), msg );
1072}
1073
1074
1076{
1078 return true;
1079
1080 return IsURL( GetShownText( FOR_GUI ) );
1081}
1082
1083
1084void SCH_FIELD::DoHypertextAction( EDA_DRAW_FRAME* aFrame, const VECTOR2I& aMousePos ) const
1085{
1086 constexpr int START_ID = 1;
1087
1088 wxString href;
1089
1091 {
1092 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
1093 SCH_SHEET_PATH* sheet = &label->Schematic()->CurrentSheet();
1094 wxMenu menu;
1095
1096 std::vector<std::pair<wxString, wxString>> pages;
1097
1098 label->GetIntersheetRefs( sheet, &pages );
1099
1100 for( int i = 0; i < (int) pages.size(); ++i )
1101 {
1102 menu.Append( i + START_ID,
1103 wxString::Format( _( "Go to Page %s (%s)" ), pages[i].first, pages[i].second ) );
1104 }
1105
1106 menu.AppendSeparator();
1107 menu.Append( 999 + START_ID, _( "Back to Previous Selected Sheet" ) );
1108
1109 int sel = aFrame->GetPopupMenuSelectionFromUser( menu ) - START_ID;
1110
1111 if( sel >= 0 && sel < (int) pages.size() )
1112 href = wxT( "#" ) + pages[sel].first;
1113 else if( sel == 999 )
1115 }
1117 {
1118 href = GetShownText( FOR_GUI );
1119 }
1120
1121 if( !href.IsEmpty() )
1122 {
1124 navTool->HypertextCommand( href );
1125 }
1126}
1127
1128
1129void SCH_FIELD::SetName( const wxString& aName )
1130{
1131 const bool generated = ::IsGeneratedField( aName );
1132 const bool changed = m_name != aName || ( generated && EDA_TEXT::GetText() != aName );
1133 m_name = aName;
1134 m_isGeneratedField = generated;
1135
1136 if( m_isGeneratedField )
1137 EDA_TEXT::SetText( aName );
1138
1139 if( changed )
1141}
1142
1143
1144void SCH_FIELD::SetText( const wxString& aText )
1145{
1146 // Don't allow modification of text value of generated fields.
1147 if( m_isGeneratedField )
1148 return;
1149
1150 // Mandatory fields should not have leading or trailing whitespace.
1151 const wxString text = IsMandatory() ? aText.Strip( wxString::both ) : aText;
1152 const bool changed = EDA_TEXT::GetText() != text;
1154
1155 if( changed )
1157}
1158
1159
1160void SCH_FIELD::SetText( const wxString& aText, const SCH_SHEET_PATH* aPath, const wxString& aVariantName )
1161{
1162 wxCHECK( m_parent, /* void */ );
1163
1164 if( m_isGeneratedField )
1165 return;
1166
1167 const wxString text = IsMandatory() ? aText.Strip( wxString::both ) : aText;
1168
1169 // Going through the parent symbol or sheet can handle setting values on variants, but it can't
1170 // handle setting values on fields which haven't yet been added to the parent.
1171 if( !aVariantName.IsEmpty() )
1172 {
1173 switch( m_parent->Type() )
1174 {
1175 case SCH_SYMBOL_T:
1176 {
1177 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1178 wxCHECK( symbol, /* void */ );
1179 symbol->SetFieldText( GetName( false ), text, aPath, aVariantName );
1180 return;
1181 }
1182
1183 case SCH_SHEET_T:
1184 {
1185 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1186 wxCHECK( sheet, /* void */ );
1187 sheet->SetFieldText( GetName( false ), text, aPath, aVariantName );
1188 return;
1189 }
1190
1191 default:
1192 break;
1193 }
1194 }
1195
1197}
1198
1199
1200wxString SCH_FIELD::GetText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1201{
1202 wxCHECK( aPath && m_parent, wxEmptyString );
1203
1204 // Going through the parent symbol or sheet can handle setting values on variants, but it can't
1205 // handle setting values on fields which haven't yet been added to the parent.
1206 if( !aVariantName.IsEmpty() )
1207 {
1208 switch( m_parent->Type() )
1209 {
1210 case SCH_SYMBOL_T:
1211 {
1212 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1213 wxCHECK( symbol, wxEmptyString );
1214 return symbol->GetFieldText( GetName(), aPath, aVariantName );
1215 }
1216
1217 case SCH_SHEET_T:
1218 {
1219 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1220 wxCHECK( sheet, wxEmptyString );
1221 return sheet->GetFieldText( GetName(), aPath, aVariantName );
1222 }
1223
1224 default:
1225 break;
1226 }
1227 }
1228
1229 return SCH_FIELD::GetText();
1230}
1231
1232
1233wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
1234{
1235 if( m_parent && m_parent->IsType( labelTypes ) )
1236 return SCH_LABEL_BASE::GetDefaultFieldName( m_name, aUseDefaultName );
1237
1238 if( IsMandatory() )
1240 else if( m_name.IsEmpty() && aUseDefaultName )
1242 else
1243 return m_name;
1244}
1245
1246
1248{
1249 if( m_parent && m_parent->IsType( labelTypes ) )
1250 {
1251 // These should be stored untranslated, but recover translated forms written by
1252 // older versions or by cross-language collaboration via Git.
1254 return wxT( "Netclass" );
1255 }
1256
1257 if( IsMandatory() )
1259
1260 return m_name;
1261}
1262
1263
1265{
1266 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1267 {
1268 switch( m_id )
1269 {
1273 default: return BITMAPS::text;
1274 }
1275 }
1276
1277 return BITMAPS::text;
1278}
1279
1280
1281bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1282{
1284 return false;
1285
1286 BOX2I rect = GetBoundingBox();
1287
1288 // Text in symbol editor can have additional chars (ie: reference designators U? or U?A)
1289 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1290 {
1291 SCH_FIELD temp( *this );
1292 temp.SetText( GetFullText() );
1293 rect = temp.GetBoundingBox();
1294 }
1295
1296 rect.Inflate( aAccuracy );
1297
1298 if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1299 {
1300 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1301 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1302 }
1303
1304 return rect.Contains( aPosition );
1305}
1306
1307
1308bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1309{
1311 return false;
1312
1313 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1314 return false;
1315
1316 BOX2I rect = aRect;
1317
1318 rect.Inflate( aAccuracy );
1319
1320 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1321 {
1322 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1323 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1324 }
1325
1326 if( aContained )
1327 return rect.Contains( GetBoundingBox() );
1328
1329 return rect.Intersects( GetBoundingBox() );
1330}
1331
1332
1333bool SCH_FIELD::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1334{
1336 return false;
1337
1338 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1339 return false;
1340
1341 BOX2I bbox = GetBoundingBox();
1342
1343 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1344 {
1345 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1346 bbox.Offset( label->GetSchematicTextOffset( nullptr ) );
1347 }
1348
1349 return KIGEOM::BoxHitTest( aPoly, bbox, aContained );
1350}
1351
1352
1353void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit, int aBodyStyle,
1354 const VECTOR2I& aOffset, bool aDimmed )
1355{
1356 wxString text;
1357
1358 if( Schematic() )
1359 text = GetShownText( &Schematic()->CurrentSheet(), FOR_CANVAS, Schematic()->GetCurrentVariant() );
1360 else
1362
1363 if( ( !IsVisible() && !IsForceVisible() ) || text.IsEmpty() || aBackground )
1364 return;
1365
1366 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1367 COLOR4D color = renderSettings->GetLayerColor( GetLayer() );
1368 int penWidth = GetEffectiveTextPenWidth( renderSettings->GetDefaultPenWidth() );
1369
1370 COLOR4D bg = renderSettings->GetBackgroundColor();
1371
1372 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1373 bg = COLOR4D::WHITE;
1374
1375 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1376 color = GetTextColor();
1377
1378 if( color.m_text && Schematic() )
1379 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1380
1381 if( aDimmed )
1382 {
1383 color.Desaturate();
1384 color = color.Mix( bg, 0.5f );
1385 }
1386
1387 penWidth = std::max( penWidth, renderSettings->GetMinPenWidth() );
1388
1389 // clamp the pen width to be sure the text is readable
1390 penWidth = std::min( penWidth, std::min( GetTextSize().x, GetTextSize().y ) / 4 );
1391
1392 if( !IsVisible() && !renderSettings->m_ShowHiddenFields )
1393 return;
1394
1395 // Calculate the text orientation, according to the symbol orientation/mirror
1396 EDA_ANGLE orient = GetTextAngle();
1397 VECTOR2I textpos = GetTextPos();
1399 GR_TEXT_V_ALIGN_T vjustify = GetVertJustify();
1400
1401 if( renderSettings->m_Transform.y1 ) // Rotate symbol 90 deg.
1402 {
1403 if( orient.IsHorizontal() )
1404 orient = ANGLE_VERTICAL;
1405 else
1406 orient = ANGLE_HORIZONTAL;
1407 }
1408
1409 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1410 {
1411 /*
1412 * Calculate the text justification, according to the symbol orientation/mirror. This is
1413 * a bit complicated due to cumulative calculations:
1414 * - numerous cases (mirrored or not, rotation)
1415 * - the plotter's Text() function will also recalculate H and V justifications according
1416 * to the text orientation
1417 * - when a symbol is mirrored the text is not, and justifications become a nightmare
1418 *
1419 * So the easier way is to use no justifications (centered text) and use GetBoundingBox
1420 * to know the text coordinate considered as centered.
1421 */
1422 hjustify = GR_TEXT_H_ALIGN_CENTER;
1423 vjustify = GR_TEXT_V_ALIGN_CENTER;
1424 textpos = GetBoundingBox().Centre();
1425 }
1426 else if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1427 {
1428 // Library-symbol exports (CLI/symbol editor) provide an item offset in the same coordinate
1429 // frame as body graphics/pins. Apply the same transform+offset pipeline to field text.
1430 textpos = renderSettings->TransformCoordinate( textpos ) + aOffset;
1431 }
1432 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1433 {
1434 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_parent );
1435 textpos += label->GetSchematicTextOffset( renderSettings );
1436 }
1437 else if( m_parent && m_parent->Type() == SCH_DIRECTIVE_LABEL_T )
1438 {
1439 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( m_parent );
1440 std::shared_ptr<NETCLASS> nc = label->GetEffectiveNetClass();
1441
1442 if( nc && ( nc->GetSchematicColor() != COLOR4D::UNSPECIFIED ) && aPlotter->GetColorMode() )
1443 color = nc->GetSchematicColor();
1444 }
1445
1446 KIFONT::FONT* font = GetDrawFont( renderSettings );
1448 attrs.m_StrokeWidth = penWidth;
1449 attrs.m_Halign = hjustify;
1450 attrs.m_Valign = vjustify;
1451 attrs.m_Angle = orient;
1452 attrs.m_Multiline = false;
1453
1454 aPlotter->PlotText( textpos, color, text, attrs, font, GetFontMetrics() );
1455
1457 {
1458 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( m_parent ) )
1459 {
1460 std::vector<std::pair<wxString, wxString>> pages;
1461 std::vector<wxString> pageHrefs;
1462
1463 label->GetIntersheetRefs( &Schematic()->CurrentSheet(), &pages );
1464
1465 for( const auto& [pageNumber, sheetName] : pages )
1466 pageHrefs.push_back( wxT( "#" ) + pageNumber );
1467
1468 BOX2I bbox = GetBoundingBox();
1469 bbox.Offset( label->GetSchematicTextOffset( renderSettings ) );
1470
1471 aPlotter->HyperlinkMenu( bbox, pageHrefs );
1472 }
1473 }
1474}
1475
1476
1477void SCH_FIELD::SetPosition( const VECTOR2I& aPosition )
1478{
1479 // Actual positions are calculated by the rotation/mirror transform of the parent symbol
1480 // of the field. The inverse transform is used to calculate the position relative to the
1481 // parent symbol.
1482 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1483 {
1484 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1485 VECTOR2I relPos = aPosition - parentSymbol->GetPosition();
1486
1487 relPos = parentSymbol->GetTransform().InverseTransform().TransformCoordinate( relPos );
1488
1489 SetTextPos( relPos + parentSymbol->GetPosition() );
1490 return;
1491 }
1492
1493 SetTextPos( aPosition );
1494}
1495
1496
1498{
1499 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1500 {
1501 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1502 VECTOR2I relativePos = GetTextPos() - parentSymbol->GetPosition();
1503
1504 relativePos = parentSymbol->GetTransform().TransformCoordinate( relativePos );
1505
1506 return relativePos + parentSymbol->GetPosition();
1507 }
1508
1509 return GetTextPos();
1510}
1511
1512
1514{
1515 return m_parent ? m_parent->GetPosition() : VECTOR2I( 0, 0 );
1516}
1517
1518
1525
1526
1527bool SCH_FIELD::operator<( const SCH_ITEM& aItem ) const
1528{
1529 if( Type() != aItem.Type() )
1530 return Type() < aItem.Type();
1531
1532 auto field = static_cast<const SCH_FIELD*>( &aItem );
1533
1534 if( GetId() != field->GetId() )
1535 return GetId() < field->GetId();
1536
1537 if( GetText() != field->GetText() )
1538 return GetText() < field->GetText();
1539
1540 if( GetLibPosition().x != field->GetLibPosition().x )
1541 return GetLibPosition().x < field->GetLibPosition().x;
1542
1543 if( GetLibPosition().y != field->GetLibPosition().y )
1544 return GetLibPosition().y < field->GetLibPosition().y;
1545
1546 return GetName() < field->GetName();
1547}
1548
1549
1550bool SCH_FIELD::operator==( const SCH_ITEM& aOther ) const
1551{
1552 if( Type() != aOther.Type() )
1553 return false;
1554
1555 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1556
1557 return *this == field;
1558}
1559
1560
1561bool SCH_FIELD::operator==( const SCH_FIELD& aOther ) const
1562{
1563 // Identical fields owned by different items are not equal.
1564 if( m_parent || aOther.m_parent )
1565 {
1566 if( !m_parent || !aOther.m_parent )
1567 return false;
1568
1569 if( m_parent->Type() != aOther.m_parent->Type() )
1570 return false;
1571
1572 if( m_parent->m_Uuid != aOther.m_parent->m_Uuid )
1573 return false;
1574 }
1575
1576 if( IsMandatory() != aOther.IsMandatory() )
1577 return false;
1578
1579 if( IsMandatory() )
1580 {
1581 if( GetId() != aOther.GetId() )
1582 return false;
1583 }
1584 else
1585 {
1586 if( GetOrdinal() != aOther.GetOrdinal() )
1587 return false;
1588 }
1589
1590 if( GetPosition() != aOther.GetPosition() )
1591 return false;
1592
1593 if( IsGeneratedField() != aOther.IsGeneratedField() )
1594 return false;
1595
1596 if( IsNameShown() != aOther.IsNameShown() )
1597 return false;
1598
1599 if( CanAutoplace() != aOther.CanAutoplace() )
1600 return false;
1601
1602 return EDA_TEXT::operator==( aOther );
1603}
1604
1605
1606bool SCH_FIELD::HasSameContent( const SCH_FIELD& aOther ) const
1607{
1608 if( GetUntranslatedName() != aOther.GetUntranslatedName() )
1609 return false;
1610
1611 if( GetPosition() != aOther.GetPosition() )
1612 return false;
1613
1614 if( IsVisible() != aOther.IsVisible() )
1615 return false;
1616
1617 if( IsPrivate() != aOther.IsPrivate() )
1618 return false;
1619
1620 if( IsGeneratedField() != aOther.IsGeneratedField() )
1621 return false;
1622
1623 if( IsNameShown() != aOther.IsNameShown() )
1624 return false;
1625
1626 if( CanAutoplace() != aOther.CanAutoplace() )
1627 return false;
1628
1629 return EDA_TEXT::operator==( aOther );
1630}
1631
1632
1633double SCH_FIELD::Similarity( const SCH_ITEM& aOther ) const
1634{
1635 if( Type() != aOther.Type() )
1636 return 0.0;
1637
1638 if( m_Uuid == aOther.m_Uuid )
1639 return 1.0;
1640
1641 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1642
1643 double similarity = 0.99; // The UUIDs are different, so we start with non-identity
1644
1645 if( GetId() != field.GetId() )
1646 {
1647 // We don't allow swapping of mandatory fields, so these cannot be the same item
1648 if( IsMandatory() || field.IsMandatory() )
1649 return 0.0;
1650 else
1651 similarity *= 0.5;
1652 }
1653
1654 similarity *= SimilarityBase( aOther );
1655
1656 similarity *= EDA_TEXT::Similarity( field );
1657
1658 if( GetPosition() != field.GetPosition() )
1659 similarity *= 0.5;
1660
1661 if( IsGeneratedField() != field.IsGeneratedField() )
1662 similarity *= 0.5;
1663
1664 if( IsNameShown() != field.IsNameShown() )
1665 similarity *= 0.5;
1666
1667 if( CanAutoplace() != field.CanAutoplace() )
1668 similarity *= 0.5;
1669
1670 return similarity;
1671}
1672
1673
1674int SCH_FIELD::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1675{
1676 wxASSERT( aOther.Type() == SCH_FIELD_T );
1677
1678 int retv = SCH_ITEM::compare( aOther, aCompareFlags );
1679
1680 if( retv )
1681 return retv;
1682
1683 const SCH_FIELD* tmp = static_cast<const SCH_FIELD*>( &aOther );
1684
1685 // If we're not testing the UUID then we're looking for an equivalence test
1686 if( !( aCompareFlags & COMPARE_FLAGS::UUID ) )
1687 {
1688 // Mandatory fields have fixed ordinals and their names can vary due to translated field
1689 // names. Optional fields have fixed names and their ordinals can vary.
1690 if( IsMandatory() )
1691 {
1692 if( m_id != tmp->m_id )
1693 return (int) m_id - (int) tmp->m_id;
1694 }
1695 else
1696 {
1697 retv = m_name.Cmp( tmp->m_name );
1698
1699 if( retv )
1700 return retv;
1701 }
1702 }
1703 else // assume we're sorting for stable file order
1704 {
1705 if( m_id != tmp->m_id )
1706 return (int) m_id - (int) tmp->m_id;
1707 }
1708
1709 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::FIELD_TEXT )
1710 {
1711 retv = GetText().CmpNoCase( tmp->GetText() );
1712
1713 if( retv != 0 )
1714 return retv;
1715 }
1716
1717 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::FIELD_POSITIONS )
1718 {
1719 if( GetTextPos().x != tmp->GetTextPos().x )
1720 return GetTextPos().x - tmp->GetTextPos().x;
1721
1722 if( GetTextPos().y != tmp->GetTextPos().y )
1723 return GetTextPos().y - tmp->GetTextPos().y;
1724 }
1725
1726 if( aCompareFlags & COMPARE_FLAGS::FIELD_SIZE_AND_STYLE )
1727 {
1728 retv = GetAttributes().Compare( tmp->GetAttributes() );
1729
1730 if( retv )
1731 return retv;
1732 }
1733
1734 return 0;
1735}
1736
1737
1738wxString SCH_FIELD::getUnescapedText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1739{
1740 // This is the default variant field text for all fields except the reference field.
1741 wxString retv = EDA_TEXT::GetShownText( INTERNAL );
1742
1743 // Special handling for parent object field instance and variant information.
1744 // Only use the path if it's non-empty; an empty path can't match any instances
1745 if( m_parent && aPath && !aPath->empty() )
1746 {
1747 const bool trace = wxLog::IsAllowedTraceMask( traceSchFieldRendering );
1748
1749 if( trace )
1750 wxLogTrace( traceSchFieldRendering, " Path is valid and non-empty, parent type=%d", m_parent->Type() );
1751
1752 switch( m_parent->Type() )
1753 {
1754 case SCH_SYMBOL_T:
1755 if( const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( m_parent ) )
1756 {
1757 if( m_id == FIELD_T::REFERENCE )
1758 {
1759 if( trace )
1760 {
1761 wxLogTrace( traceSchFieldRendering, " Calling GetRef for symbol %s on path %s",
1762 symbol->m_Uuid.AsString(), aPath->Path().AsString() );
1763 }
1764
1765 retv = symbol->GetRef( aPath, true );
1766
1767 if( trace )
1768 wxLogTrace( traceSchFieldRendering, " GetRef returned: '%s'", retv );
1769 }
1770 else if( !aVariantName.IsEmpty() )
1771 {
1772 // If the variant is not found, fall back to default variant above.
1773 if( std::optional<SCH_SYMBOL_VARIANT> variant = symbol->GetVariant( *aPath, aVariantName ) )
1774 {
1775 // An explicit override wins; otherwise resolve through the alternate
1776 // library symbol so the canvas matches the fields table and netlist.
1777 if( variant->m_Fields.contains( GetName() ) )
1778 {
1779 retv = variant->m_Fields[GetName()];
1780 }
1781 else if( LIB_SYMBOL* altSymbol = symbol->GetVariantLibSymbol( aVariantName, *aPath ) )
1782 {
1783 const SCH_FIELD* altField = altSymbol->GetField( GetName() );
1784
1785 if( altField && !altField->GetText().IsEmpty() )
1786 retv = altField->GetText();
1787 }
1788 }
1789 }
1790 }
1791
1792 break;
1793
1794 case SCH_SHEET_T:
1795 if( const SCH_SHEET* sheet = static_cast<const SCH_SHEET*>( m_parent ) )
1796 {
1797 if( !aVariantName.IsEmpty() )
1798 {
1799 const SCH_SHEET_INSTANCE* instance = sheet->GetInstance( aPath->Path() );
1800
1801 if( instance
1802 && instance->m_Variants.contains( aVariantName )
1803 && instance->m_Variants.at( aVariantName ).m_Fields.contains( GetName() ) )
1804 {
1805 return instance->m_Variants.at( aVariantName ).m_Fields.at( GetName() );
1806 }
1807 }
1808 }
1809
1810 break;
1811
1812 default:
1813 break;
1814 }
1815 }
1816
1817 return retv;
1818}
1819
1820
1821static struct SCH_FIELD_DESC
1822{
1824 {
1825 // These are defined in EDA_TEXT as well but initialization order is
1826 // not defined, so this needs to be conditional. Defining in both
1827 // places leads to duplicate symbols.
1829
1830 if( h_inst.Choices().GetCount() == 0 )
1831 {
1832 h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _HKI( "Left" ) );
1833 h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _HKI( "Center" ) );
1834 h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _HKI( "Right" ) );
1835 }
1836
1838
1839 if( v_inst.Choices().GetCount() == 0 )
1840 {
1841 v_inst.Map( GR_TEXT_V_ALIGN_TOP, _HKI( "Top" ) );
1842 v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _HKI( "Center" ) );
1843 v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _HKI( "Bottom" ) );
1844 }
1845
1852
1853 // Lock state is inherited from parent symbol (no independent locking of child items)
1854 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Locked" ) );
1855
1856 // Library fields are written at symbol scope rather than inside a unit body, so a
1857 // per-unit or per-body-style assignment is silently dropped by the next save
1858 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Unit" ) );
1859 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Body Style" ) );
1860
1861 const wxString textProps = _HKI( "Text Properties" );
1862
1863 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ),
1864 new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_H_ALIGN_T>( _HKI( "Horizontal Justification" ),
1866 textProps );
1867
1868 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ),
1869 new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_V_ALIGN_T>( _HKI( "Vertical Justification" ),
1871 textProps );
1872
1873 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Show Field Name" ),
1875
1876 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Allow Autoplacement" ),
1878
1879 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
1880 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
1881 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
1882 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
1883 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
1884
1885
1886 propMgr.AddProperty( new PROPERTY<SCH_FIELD, int>( _HKI( "Text Size" ),
1888 _HKI( "Text Properties" ) );
1889
1890 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
1891
1893 []( INSPECTABLE* aItem ) -> bool
1894 {
1895 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1896 return !field->IsGeneratedField();
1897
1898 return true;
1899 } );
1900
1901
1902 propMgr.OverrideAvailability( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Private" ),
1903 []( INSPECTABLE* aItem ) -> bool
1904 {
1905 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1906 return !field->IsMandatory();
1907
1908 return false;
1909 } );
1910 }
1912
1913
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
BITMAPS
A list of all bitmap identifiers.
@ edit_comp_value
@ edit_comp_footprint
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:553
constexpr const Vec GetEnd() const
Definition box2.h:209
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:234
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition box2.h:143
constexpr Vec Centre() const
Definition box2.h:94
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:165
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition box2.h:135
constexpr const Vec & GetOrigin() const
Definition box2.h:207
constexpr void SetEnd(coord_type x, coord_type y)
Definition box2.h:294
constexpr void Offset(coord_type dx, coord_type dy)
Definition box2.h:256
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:308
static const COLOR4D WHITE
Definition color4d.h:403
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:400
bool IsHorizontal() const
Definition eda_angle.h:141
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:599
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:608
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:484
EDA_ITEM * GetParent() const
Definition eda_item.h:112
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:609
bool IsForceVisible() const
Definition eda_item.h:233
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:396
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:84
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition eda_text.cpp:170
virtual VECTOR2I GetTextSize() const
Definition eda_text.h:301
COLOR4D GetTextColor() const
Definition eda_text.h:310
wxString GetTextStyleName() const
virtual VECTOR2I GetTextPos() const
Definition eda_text.h:313
bool IsItalic() const
Definition eda_text.h:200
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:512
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
virtual bool IsVisible() const
Definition eda_text.h:226
virtual void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:556
virtual void SetTextX(int aX)
Definition eda_text.cpp:563
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition eda_text.cpp:200
KIFONT::FONT * GetFont() const
Definition eda_text.h:286
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:394
virtual void SetTextY(int aY)
Definition eda_text.cpp:569
EDA_TEXT & operator=(const EDA_TEXT &aItem)
Definition eda_text.cpp:140
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:754
virtual wxString GetShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:128
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:378
virtual int GetTextWidth() const
Definition eda_text.h:304
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:239
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition eda_text.cpp:450
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:139
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:347
EDA_TEXT(const EDA_IU_SCALE &aIuScale, const wxString &aText=wxEmptyString)
Definition eda_text.cpp:98
virtual void ClearBoundingBoxCache()
Definition eda_text.cpp:675
double Similarity(const EDA_TEXT &aOther) const
static GR_TEXT_H_ALIGN_T MapHorizJustify(int aHorizJustify)
Definition eda_text.cpp:70
virtual void ClearRenderCache()
Definition eda_text.cpp:669
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:178
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:270
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:427
void SwapAttributes(EDA_TEXT &aTradingPartner)
Swap the text attributes of the two involved instances.
Definition eda_text.cpp:414
bool IsBold() const
Definition eda_text.h:215
static GR_TEXT_V_ALIGN_T MapVertJustify(int aVertJustify)
Definition eda_text.cpp:84
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:242
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:236
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:268
void SwapText(EDA_TEXT &aTradingPartner)
Definition eda_text.cpp:406
bool operator==(const EDA_TEXT &aRhs) const
Definition eda_text.h:444
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:370
static ENUM_MAP< T > & Instance()
Definition property.h:783
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:39
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
Implement 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:397
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:530
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition color4d.h:293
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:236
A singleton reporter that reports to nowhere.
Definition reporter.h:267
Base plotter engine class.
Definition plotter.h:136
bool GetColorMode() const
Definition plotter.h:164
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:617
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition plotter.h:521
virtual std::map< wxString, wxString > & GetTextVars() const
Definition project.cpp:126
Provide class metadata.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void 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:149
SCHEMATIC_SETTINGS & Settings() const
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition schematic.h:171
wxString GetCurrentVariant() const
Return the current variant being edited.
EMBEDDED_FILES * GetEmbeddedFiles() override
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:304
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:379
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:190
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:369
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:229
bool m_autoAdded
Was this field automatically added to a LIB_SYMBOL?
Definition sch_field.h:374
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:377
bool IsGeneratedField() const
Generated fields are fields whose names are variables like ${VAR}.
Definition sch_field.h:238
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:139
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:143
void SetCanAutoplace(bool aCanPlace)
Definition sch_field.h:241
int GetPenWidth() const override
bool m_isGeneratedField
If the field name is a variable name (e.g.
Definition sch_field.h:371
int m_ordinal
Sort order for non-mandatory fields.
Definition sch_field.h:366
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.
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
bool operator<(const SCH_ITEM &aItem) const override
FIELD_T m_id
Field id,.
Definition sch_field.h:365
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:287
void setId(FIELD_T aId)
int GetOrdinal() const
Definition sch_field.h:145
bool IsEmpty()
Return true if both the name and value of the field are empty.
Definition sch_field.h:182
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:191
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
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:240
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:375
void OnScintillaCharAdded(SCINTILLA_TRICKS *aScintillaTricks, wxStyledTextEvent &aEvent) const
wxString m_name
Definition sch_field.h:367
void SetNameShown(bool aShown=true)
Definition sch_field.h:230
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:370
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:170
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition sch_item.cpp:91
const wxString & GetDefaultFont(const KIGFX::RENDER_SETTINGS *aSettings) const
Definition sch_item.cpp:999
void invalidateConnectivity(KICAD_T aChangedType=TYPE_NOT_INIT)
Bump the parent screen's connectivity revision when this item, or the item owning it as a child,...
Definition sch_item.cpp:323
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.cpp:46
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:350
void SetPrivate(bool aPrivate)
Definition sch_item.h:258
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:302
virtual wxString GetUnitDisplayName(int aUnit, bool aLabel) const
Definition sch_item.cpp:225
bool IsLocked() const override
Definition sch_item.cpp:179
friend class LIB_SYMBOL
Definition sch_item.h:817
@ FIELD_SIZE_AND_STYLE
Definition sch_item.h:752
@ FIELD_TEXT
Definition sch_item.h:750
@ FIELD_POSITIONS
Definition sch_item.h:753
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition sch_item.cpp:733
bool IsPrivate() const
Definition sch_item.h:259
void SetLayer(SCH_LAYER_ID aLayer)
Definition sch_item.h:354
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition sch_item.h:353
bool IsConnectivityDirty() const
Definition sch_item.h:630
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:65
bool m_private
Definition sch_item.h:841
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:464
virtual int compare(const SCH_ITEM &aOther, int aCompareFlags=~COMPARE_FLAGS::UNIT) const
Provide the draw object specific comparison called by the == and < operators.
Definition sch_item.cpp:935
const KIFONT::METRICS & GetFontMetrics() const
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:398
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.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
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.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
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:895
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, std::span< const wxString > aPins, REPORTER &aReporter)
void SetFilesStack(std::vector< EMBEDDED_FILES * > aFilesStack)
Definition sim_lib_mgr.h:45
A base class for LIB_SYMBOL and SCH_SYMBOL.
Definition symbol.h:60
const TRANSFORM & GetTransform() const
Definition symbol.h:247
EDA_ORIENTATION m_Angle
int Compare(const TEXT_ATTRIBUTES &aRhs) const
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
T * GetTool()
Return the tool of given type or nullptr if there is no such tool registered.
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().
void FinalizeTextVarExpansion(wxString &aText, RESOLUTION_CONTEXT aContext)
Definition common.cpp:88
wxString GetGeneratedFieldDisplayName(const wxString &aSource)
Returns any variables unexpanded, e.g.
Definition common.cpp:481
RESOLUTION_CONTEXT
Definition common.h:89
@ FOR_GUI
Definition common.h:91
@ FOR_CANVAS
Definition common.h:90
@ RAW_VALUE
Definition common.h:96
@ INTERNAL
Definition common.h:94
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:450
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:445
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:444
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:453
#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:471
@ LAYER_SHEETNAME
Definition layer_ids.h:494
@ LAYER_VALUEPART
Definition layer_ids.h:483
@ LAYER_FIELDS
Definition layer_ids.h:484
@ LAYER_SHEETFIELDS
Definition layer_ids.h:496
@ LAYER_REFERENCEPART
Definition layer_ids.h:482
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:486
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:517
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:485
@ LAYER_SHEETFILENAME
Definition layer_ids.h:495
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.
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
#define _HKI(x)
Definition page_info.cpp:40
static GR_TEXT_H_ALIGN_T horizJustify(const char *horizontal)
#define TYPE_HASH(x)
Macro to generate unique identifier for a type.
Definition property.h:74
#define DECLARE_ENUM_TO_WXANY(type)
Definition property.h:851
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
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_NON_POWER
wxString UnescapeString(const wxString &aSource)
bool IsURL(wxString aStr)
Performs a URL sniff-test on a string.
A simple container for sheet instance information.
std::map< wxString, SCH_SHEET_VARIANT > m_Variants
A list of sheet variants.
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ 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".
@ UNTRANSLATED
@ TRANSLATED
KIBIS_MODEL * model
KIBIS_PIN * pin
VECTOR2I end
wxString result
Test unit parsing edge cases and error handling.
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:227
@ LIB_SYMBOL_T
Definition typeinfo.h:144
@ SCH_SYMBOL_T
Definition typeinfo.h:168
@ SCH_FIELD_T
Definition typeinfo.h:146
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:167
@ SCH_LABEL_T
Definition typeinfo.h:163
@ SCH_SHEET_T
Definition typeinfo.h:171
@ SCH_LABEL_LOCATE_ANY_T
Definition typeinfo.h:187
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:164
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
Definition typeinfo.h:55
#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:708