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