KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_field.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <wx/log.h>
26#include <wx/menu.h>
27
28#include <advanced_config.h>
29#include <base_units.h>
30#include <common.h> // for ExpandTextVars
31#include <sch_edit_frame.h>
32#include <plotters/plotter.h>
33#include <bitmaps.h>
34#include <kiway.h>
36#include <string_utils.h>
38#include <trace_helpers.h>
39#include <tool/tool_manager.h>
41#include <font/outline_font.h>
42#include "sim/sim_lib_mgr.h"
43#include <properties/property.h>
45#include <google/protobuf/any.pb.h>
46#include <api/schematic/schematic_types.pb.h>
47
48static const std::vector<KICAD_T> labelTypes = { SCH_LABEL_LOCATE_ANY_T };
49
50
52 SCH_ITEM( nullptr, SCH_FIELD_T ),
53 EDA_TEXT( schIUScale, wxEmptyString ),
54 m_id( FIELD_T::USER ),
55 m_ordinal( 0 ),
56 m_showName( false ),
57 m_allowAutoPlace( true ),
58 m_isGeneratedField( false ),
59 m_autoAdded( false ),
60 m_showInChooser( true ),
62{
63}
64
65
66SCH_FIELD::SCH_FIELD( SCH_ITEM* aParent, FIELD_T aFieldId, const wxString& aName ) :
67 SCH_FIELD()
68{
69 m_parent = aParent;
70
71 if( !aName.IsEmpty() )
72 SetName( aName );
73 else
75
76 setId( aFieldId ); // will also set the layer
77 SetVisible( true );
78
79 if( aParent && aParent->Schematic() )
80 {
81 SCHEMATIC_SETTINGS& settings = aParent->Schematic()->Settings();
83 }
84
85 if( aFieldId == FIELD_T::USER && aParent )
86 {
87 if( aParent->Type() == SCH_SYMBOL_T )
88 m_ordinal = static_cast<SCH_SYMBOL*>( aParent )->GetNextFieldOrdinal();
89 else if( aParent->Type() == LIB_SYMBOL_T )
90 m_ordinal = static_cast<LIB_SYMBOL*>( aParent )->GetNextFieldOrdinal();
91 else if( aParent->Type() == SCH_SHEET_T )
92 m_ordinal = static_cast<SCH_SHEET*>( aParent )->GetNextFieldOrdinal();
93 else if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aParent ) )
94 m_ordinal = label->GetNextFieldOrdinal();
95 }
96}
97
98
100 SCH_FIELD( aParent, FIELD_T::USER, wxEmptyString )
101{
102 SCH_ITEM::operator=( *aText );
103 EDA_TEXT::operator=( *aText );
104}
105
106
108 SCH_ITEM( aField ),
109 EDA_TEXT( aField )
110{
111 m_private = aField.m_private;
112 setId( aField.m_id ); // will also set the layer
113 m_ordinal = aField.m_ordinal;
114 m_name = aField.m_name;
115 m_showName = aField.m_showName;
118 m_autoAdded = aField.m_autoAdded;
121
122 m_renderCache.reset();
123}
124
125
126void SCH_FIELD::Serialize( google::protobuf::Any& aContainer ) const
127{
128 kiapi::schematic::types::SchematicField field;
129
130 field.set_name( GetName( false ).ToUTF8() );
131 field.set_visible( IsVisible() );
132 field.set_show_name( IsNameShown() );
133 field.set_allow_auto_place( CanAutoplace() );
134
135 google::protobuf::Any any;
137 any.UnpackTo( field.mutable_text() );
138
139 aContainer.PackFrom( field );
140}
141
142
143bool SCH_FIELD::Deserialize( const google::protobuf::Any& aContainer )
144{
145 kiapi::schematic::types::SchematicField field;
146
147 if( !aContainer.UnpackTo( &field ) )
148 return false;
149
150 SetName( wxString::FromUTF8( field.name() ) );
151 SetVisible( field.visible() );
152 SetNameShown( field.show_name() );
153 SetCanAutoplace( field.allow_auto_place() );
154
155 google::protobuf::Any any;
156 any.PackFrom( field.text() );
158}
159
160
162{
163 EDA_TEXT::operator=( aField );
164
165 m_private = aField.m_private;
166 setId( aField.m_id ); // will also set the layer
167 m_ordinal = aField.m_ordinal;
168 m_name = aField.m_name;
169 m_showName = aField.m_showName;
173
174 m_renderCache.reset();
175
176 return *this;
177}
178
179
181{
182 return new SCH_FIELD( *this );
183}
184
185
186void SCH_FIELD::Copy( SCH_FIELD* aTarget ) const
187{
188 *aTarget = *this;
189}
190
191
193{
194 m_id = aId;
196}
197
198
203
204
205wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText, int aDepth,
206 const wxString& aVariantName ) const
207{
208 wxString text = getUnescapedText( aPath, aVariantName );
209
210 if( IsNameShown() && aAllowExtraText )
211 text = GetShownName() << wxS( ": " ) << text;
212
213 if( HasTextVars() )
214 text = ResolveText( text, aPath, aDepth );
215
216 if( m_id == FIELD_T::SHEET_FILENAME && aAllowExtraText && !IsNameShown() )
217 text = _( "File:" ) + wxS( " " ) + text;
218
219 // Convert escape markers back to literals for final display
220 text.Replace( wxT( "<<<ESC_DOLLAR:" ), wxT( "${" ) );
221 text.Replace( wxT( "<<<ESC_AT:" ), wxT( "@{" ) );
222
223 return text;
224}
225
226
227wxString SCH_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
228{
229 if( SCHEMATIC* schematic = Schematic() )
230 {
231 const SCH_SHEET_PATH& currentSheet = schematic->CurrentSheet();
232 wxString variantName = schematic->GetCurrentVariant();
233
234 wxLogTrace( traceSchFieldRendering,
235 "GetShownText (no path arg): field=%s, current sheet path='%s', variant='%s', size=%zu, empty=%d",
236 GetName(), currentSheet.Path().AsString(), variantName, currentSheet.size(),
237 currentSheet.empty() ? 1 : 0 );
238 return GetShownText( &currentSheet, aAllowExtraText, aDepth, variantName );
239 }
240 else
241 {
242 return GetShownText( nullptr, aAllowExtraText, aDepth );
243 }
244}
245
246
247wxString SCH_FIELD::GetFullText( int unit ) const
248{
249 if( GetId() != FIELD_T::REFERENCE )
250 return GetText();
251
252 wxString text = GetText();
253 text << wxT( "?" );
254
255 if( GetParentSymbol() && GetParentSymbol()->IsMultiUnit() )
256 text << LIB_SYMBOL::LetterSubReference( unit, 'A' );
257
258 return text;
259}
260
261
263{
265}
266
267
269{
271
272 if( !font )
273 font = KIFONT::FONT::GetFont( GetDefaultFont( aSettings ), IsBold(), IsItalic() );
274
275 return font;
276}
277
278
284
285
291
292
293std::vector<std::unique_ptr<KIFONT::GLYPH>>*
294SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forPosition, TEXT_ATTRIBUTES& aAttrs ) const
295{
296 KIFONT::FONT* font = GetDrawFont( nullptr );
297
298 if( font->IsOutline() )
299 {
300 KIFONT::OUTLINE_FONT* outlineFont = static_cast<KIFONT::OUTLINE_FONT*>( font );
301
302 if( !m_renderCache )
303 m_renderCache = std::make_unique<SCH_FIELD_RENDER_CACHE_DATA>();
304
305 if( m_renderCache->glyphs.empty() )
306 {
307 m_renderCache->glyphs.clear();
308
309 outlineFont->GetLinesAsGlyphs( &m_renderCache->glyphs, forResolvedText, forPosition, aAttrs,
310 GetFontMetrics() );
311
312 m_renderCache->pos = forPosition;
313 }
314
315 if( m_renderCache->pos != forPosition )
316 {
317 VECTOR2I delta = forPosition - m_renderCache->pos;
318
319 for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache->glyphs )
320 {
321 if( glyph->IsOutline() )
322 static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
323 else
324 static_cast<KIFONT::STROKE_GLYPH*>( glyph.get() )->Move( delta );
325 }
326
327 m_renderCache->pos = forPosition;
328 }
329
330 return &m_renderCache->glyphs;
331 }
332
333 return nullptr;
334}
335
336
337void SCH_FIELD::ImportValues( const SCH_FIELD& aSource )
338{
339 SetAttributes( aSource );
340 SetVisible( aSource.IsVisible() );
341 SetNameShown( aSource.IsNameShown() );
342 SetCanAutoplace( aSource.CanAutoplace() );
343}
344
345
347{
348 wxCHECK_RET( aItem && aItem->Type() == SCH_FIELD_T, wxT( "Cannot swap with invalid item." ) );
349
350 SCH_FIELD* item = static_cast<SCH_FIELD*>( aItem );
351
352 std::swap( m_showName, item->m_showName );
353 std::swap( m_allowAutoPlace, item->m_allowAutoPlace );
354 std::swap( m_isGeneratedField, item->m_isGeneratedField );
355 SwapText( *item );
356 SwapAttributes( *item );
357
358 std::swap( m_lastResolvedColor, item->m_lastResolvedColor );
359}
360
361
363{
365 {
367 }
368 else
369 {
370 SCH_LABEL_BASE* parentLabel = dynamic_cast<SCH_LABEL_BASE*>( GetParent() );
371
372 if( parentLabel && !parentLabel->IsConnectivityDirty() )
374 else
376 }
377
378 return m_lastResolvedColor;
379}
380
381
382std::vector<int> SCH_FIELD::ViewGetLayers() const
383{
385}
386
387
389{
390 if( m_parent && m_parent->Type() == SCH_LABEL_T )
391 {
392 if( GetCanonicalName() == wxT( "Netclass" ) || GetCanonicalName() == wxT( "Component Class" ) )
393 {
394 return LAYER_NETCLASS_REFS;
395 }
396 }
397
398 switch( m_id )
399 {
401 case FIELD_T::VALUE: return LAYER_VALUEPART;
406 default: return LAYER_FIELDS;
407 }
408}
409
410
412{
413 // Calculate the text orientation according to the symbol orientation.
414 EDA_ANGLE orient = GetTextAngle();
415
416 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
417 {
418 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
419
420 if( parentSymbol && parentSymbol->GetTransform().y1 ) // Rotate symbol 90 degrees.
421 {
422 if( orient.IsHorizontal() )
423 orient = ANGLE_VERTICAL;
424 else
425 orient = ANGLE_HORIZONTAL;
426 }
427 }
428
429 return orient;
430}
431
432
434{
435 BOX2I bbox = GetTextBox( nullptr );
436
437 // Calculate the bounding box position relative to the parent:
438 VECTOR2I origin = GetParentPosition();
439 VECTOR2I pos = GetTextPos() - origin;
440 VECTOR2I begin = bbox.GetOrigin() - origin;
441 VECTOR2I end = bbox.GetEnd() - origin;
442 RotatePoint( begin, pos, GetTextAngle() );
443 RotatePoint( end, pos, GetTextAngle() );
444
445 // Now, apply the symbol transform (mirror/rot)
446 TRANSFORM transform;
447
448 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
449 transform = static_cast<SCH_SYMBOL*>( m_parent )->GetTransform();
450
451 bbox.SetOrigin( transform.TransformCoordinate( begin ) );
452 bbox.SetEnd( transform.TransformCoordinate( end ) );
453
454 bbox.Move( origin );
455 bbox.Normalize();
456
457 return bbox;
458}
459
460
462{
463 VECTOR2I render_center = GetBoundingBox().Centre();
464 VECTOR2I pos = GetPosition();
465
466 switch( GetHorizJustify() )
467 {
469 if( GetDrawRotation().IsVertical() )
470 return render_center.y > pos.y;
471 else
472 return render_center.x < pos.x;
473
475 if( GetDrawRotation().IsVertical() )
476 return render_center.y < pos.y;
477 else
478 return render_center.x > pos.x;
479
480 default:
481 return false;
482 }
483}
484
485
487{
488 GR_TEXT_H_ALIGN_T actualJustify;
489
490 switch( aJustify )
491 {
494 break;
495
498 break;
499
500 default:
501 actualJustify = aJustify;
502 }
503
504 SetHorizJustify( actualJustify );
505}
506
507
517
518
520{
521 VECTOR2I render_center = GetBoundingBox().Centre();
522 VECTOR2I pos = GetPosition();
523
524 switch( GetVertJustify() )
525 {
527 if( GetDrawRotation().IsVertical() )
528 return render_center.x < pos.x;
529 else
530 return render_center.y < pos.y;
531
533 if( GetDrawRotation().IsVertical() )
534 return render_center.x > pos.x;
535 else
536 return render_center.y > pos.y;
537
538 default:
539 return false;
540 }
541}
542
543
545{
546 GR_TEXT_V_ALIGN_T actualJustify;
547
548 switch( aJustify )
549 {
552 break;
553
556 break;
557
558 default:
559 actualJustify = aJustify;
560 }
561
562 SetVertJustify( actualJustify );
563}
564
565
575
576
577bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
578{
579 bool searchHiddenFields = aSearchData.searchAllFields;
580 bool searchAndReplace = aSearchData.searchAndReplace;
581 bool replaceReferences = false;
582
583 try
584 {
585 // downcast
586 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
587 replaceReferences = schSearchData.replaceReferences;
588 }
589 catch( const std::bad_cast& )
590 {
591 }
592
593 wxString text = UnescapeString( GetText() );
594
595 if( !IsVisible() && !searchHiddenFields )
596 return false;
597
598 if( m_id == FIELD_T::REFERENCE )
599 {
600 if( searchAndReplace && !replaceReferences )
601 return false;
602
603 SCH_SYMBOL* parentSymbol = dyn_cast<SCH_SYMBOL*>( m_parent );
604
605 // The parent might be a LIB_SYMBOL, in which case, we don't
606 // have a sheet path to resolve the reference.
607 if( !parentSymbol )
608 return false;
609
610 if( parentSymbol->Matches( aSearchData, aAuxData ) )
611 return true;
612
613 wxASSERT( aAuxData );
614
615 // Take sheet path into account which effects the reference field and the unit for
616 // symbols with multiple parts.
617 if( aAuxData )
618 {
619 SCH_SHEET_PATH* sheet = (SCH_SHEET_PATH*) aAuxData;
620 text = parentSymbol->GetRef( sheet );
621
622 if( SCH_ITEM::Matches( text, aSearchData ) )
623 return true;
624
625 if( parentSymbol->GetUnitCount() > 1 )
626 text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( sheet ) );
627 }
628 }
629
630 return SCH_ITEM::Matches( text, aSearchData );
631}
632
633
634void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks, wxStyledTextEvent& aEvent ) const
635{
636 SCH_ITEM* parent = dynamic_cast<SCH_ITEM*>( GetParent() );
637 SCHEMATIC* schematic = parent ? parent->Schematic() : nullptr;
638
639 if( !schematic )
640 return;
641
642 wxStyledTextCtrl* scintilla = aScintillaTricks->Scintilla();
643 int key = aEvent.GetKey();
644
645 wxArrayString autocompleteTokens;
646 int pos = scintilla->GetCurrentPos();
647 int start = scintilla->WordStartPosition( pos, true );
648 wxString partial;
649
650 // Multi-line fields are not allowed. So remove '\n' if entered.
651 if( key == '\n' )
652 {
653 wxString text = scintilla->GetText();
654 int currpos = scintilla->GetCurrentPos();
655 text.Replace( wxS( "\n" ), wxS( "" ) );
656 scintilla->SetText( text );
657 scintilla->GotoPos( currpos - 1 );
658 return;
659 }
660
661 auto textVarRef =
662 [&]( int pt )
663 {
664 return pt >= 2 && scintilla->GetCharAt( pt - 2 ) == '$' && scintilla->GetCharAt( pt - 1 ) == '{';
665 };
666
667 // Check for cross-reference
668 if( start > 1 && scintilla->GetCharAt( start - 1 ) == ':' )
669 {
670 int refStart = scintilla->WordStartPosition( start - 1, true );
671
672 if( textVarRef( refStart ) )
673 {
674 partial = scintilla->GetRange( start, pos );
675
676 wxString ref = scintilla->GetRange( refStart, start - 1 );
677
678 if( ref == wxS( "OP" ) )
679 {
680 // SPICE operating points use ':' syntax for ports
681 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent ) )
682 {
683 NULL_REPORTER devnull;
684 SCH_SHEET_PATH& sheet = schematic->CurrentSheet();
685 wxString variant = schematic->GetCurrentVariant();
686 SIM_LIB_MGR mgr( &schematic->Project() );
687
688 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
689 embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
690
691 if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
692 {
693 embeddedFilesStack.push_back( symbolEmbeddedFiles );
694 symbol->GetLibSymbolRef()->AppendParentEmbeddedFiles( embeddedFilesStack );
695 }
696
697 mgr.SetFilesStack( std::move( embeddedFilesStack ) );
698
699 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true, 0, variant, devnull ).model;
700
701 for( wxString pin : model.GetPinNames() )
702 {
703 if( pin.StartsWith( '<' ) && pin.EndsWith( '>' ) )
704 autocompleteTokens.push_back( pin.Mid( 1, pin.Length() - 2 ) );
705 else
706 autocompleteTokens.push_back( pin );
707 }
708
709 // add the synthetic port for power measurements
710 autocompleteTokens.push_back( wxT( "power" ) );
711 }
712 }
713 else
714 {
716 SCH_SYMBOL* refSymbol = nullptr;
717
718 schematic->Hierarchy().GetSymbols( refs, SYMBOL_FILTER_ALL );
719
720 for( size_t jj = 0; jj < refs.GetCount(); jj++ )
721 {
722 if( refs[jj].GetSymbol()->GetRef( &refs[jj].GetSheetPath(), true ) == ref )
723 {
724 refSymbol = refs[jj].GetSymbol();
725 break;
726 }
727 }
728
729 if( refSymbol )
730 refSymbol->GetContextualTextVars( &autocompleteTokens );
731 }
732 }
733 }
734 else if( textVarRef( start ) )
735 {
736 partial = scintilla->GetTextRange( start, pos );
737
738 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent );
739 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( parent );
740 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( parent );
741
742 if( symbol )
743 {
744 symbol->GetContextualTextVars( &autocompleteTokens );
745
746 if( schematic->CurrentSheet().Last() )
747 schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
748 }
749
750 if( sheet )
751 sheet->GetContextualTextVars( &autocompleteTokens );
752
753 if( label )
754 label->GetContextualTextVars( &autocompleteTokens );
755
756 for( std::pair<wxString, wxString> entry : schematic->Project().GetTextVars() )
757 autocompleteTokens.push_back( entry.first );
758 }
759
760 aScintillaTricks->DoAutocomplete( partial, autocompleteTokens );
761 scintilla->SetFocus();
762}
763
764
766{
767 // See comments in SCH_FIELD::Replace(), below.
769 return false;
770
771 return true;
772}
773
774
776{
777 if( const SYMBOL* parentSymbol = GetParentSymbol() )
778 {
779 if( parentSymbol->IsLocked() )
780 return true;
781 }
782
783 if( const SCH_SHEET* parentSheet = dynamic_cast<const SCH_SHEET*>( m_parent ) )
784 {
785 if( parentSheet->IsLocked() )
786 return true;
787 }
788
789 return SCH_ITEM::IsLocked();
790}
791
792
793bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
794{
795 bool replaceReferences = false;
796
797 try
798 {
799 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
800 replaceReferences = schSearchData.replaceReferences;
801 }
802 catch( const std::bad_cast& )
803 {
804 }
805
806 wxString text;
807 bool isReplaced = false;
808
809 if( m_id == FIELD_T::REFERENCE && m_parent && m_parent->Type() == SCH_SYMBOL_T )
810 {
811 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
812
813 if( !replaceReferences )
814 return false;
815
816 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in refdes." ) );
817
818 text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
819 isReplaced = EDA_ITEM::Replace( aSearchData, text );
820
821 if( isReplaced )
822 parentSymbol->SetRef( (SCH_SHEET_PATH*) aAuxData, text );
823 }
824 else
825 {
826 isReplaced = EDA_TEXT::Replace( aSearchData );
827
828 if( m_id == FIELD_T::SHEET_FILENAME && isReplaced )
829 {
830 // If we allowed this we'd have a bunch of work to do here, including warning
831 // about it not being undoable, checking for recursive hierarchies, reloading
832 // sheets, etc. See DIALOG_SHEET_PROPERTIES::TransferDataFromWindow().
833 }
834 }
835
836 return isReplaced;
837}
838
839
840void SCH_FIELD::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
841{
843
844 if( GetTextAngle().IsVertical() )
845 {
846 switch( horizJustify )
847 {
849 if( aRotateCCW )
851
852 break;
853
855 if( aRotateCCW )
857
858 break;
859
862 break;
863 }
864
866 }
867 else if( GetTextAngle().IsHorizontal() )
868 {
869 switch( horizJustify )
870 {
872 if( !aRotateCCW )
874
875 break;
876
878 if( !aRotateCCW )
880
881 break;
882
885 break;
886 }
887
889 }
890 else
891 {
892 wxFAIL_MSG( wxString::Format( wxT( "SCH_FIELD text angle is not horizontal or vertical: %f" ),
893 GetTextAngle().AsDegrees() ) );
894 }
895
896 VECTOR2I pt = GetPosition();
897 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
898 SetPosition( pt );
899}
900
901
903{
904 int x = GetTextPos().x;
905
906 x -= aCenter;
907 x *= -1;
908 x += aCenter;
909
910 SetTextX( x );
911}
912
913
915{
916 int y = GetTextPos().y;
917
918 y -= aCenter;
919 y *= -1;
920 y += aCenter;
921
922 SetTextY( y );
923}
924
925
926void SCH_FIELD::BeginEdit( const VECTOR2I& aPosition )
927{
928 SetTextPos( aPosition );
929}
930
931
932void SCH_FIELD::CalcEdit( const VECTOR2I& aPosition )
933{
934 SetTextPos( aPosition );
935}
936
937
938wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
939{
940 wxString content = aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() );
941
942 if( content.IsEmpty() )
943 {
944 return wxString::Format( _( "Field %s (empty)" ), UnescapeString( GetName() ) );
945 }
946 else
947 {
948 return wxString::Format( _( "Field %s '%s'" ), UnescapeString( GetName() ), content );
949 }
950}
951
952
953void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
954{
955 wxString msg;
956
957 aList.emplace_back( _( "Symbol Field" ), UnescapeString( GetName() ) );
958
959 // Don't use GetShownText() here; we want to show the user the variable references
960 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
961
962 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
963
964 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
965
966 aList.emplace_back( _( "Style" ), GetTextStyleName() );
967
968 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
969
970 switch( GetHorizJustify() )
971 {
972 case GR_TEXT_H_ALIGN_LEFT: msg = _( "Left" ); break;
973 case GR_TEXT_H_ALIGN_CENTER: msg = _( "Center" ); break;
974 case GR_TEXT_H_ALIGN_RIGHT: msg = _( "Right" ); break;
976 }
977
978 aList.emplace_back( _( "H Justification" ), msg );
979
980 switch( GetVertJustify() )
981 {
982 case GR_TEXT_V_ALIGN_TOP: msg = _( "Top" ); break;
983 case GR_TEXT_V_ALIGN_CENTER: msg = _( "Center" ); break;
984 case GR_TEXT_V_ALIGN_BOTTOM: msg = _( "Bottom" ); break;
986 }
987
988 aList.emplace_back( _( "V Justification" ), msg );
989}
990
991
993{
995 return true;
996
998 return true;
999
1000 return IsURL( GetShownText( false ) );
1001}
1002
1003
1004void SCH_FIELD::DoHypertextAction( EDA_DRAW_FRAME* aFrame, const VECTOR2I& aMousePos ) const
1005{
1006 constexpr int START_ID = 1;
1007
1008 wxString href;
1009
1011 {
1012 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
1013 SCH_SHEET_PATH* sheet = &label->Schematic()->CurrentSheet();
1014 wxMenu menu;
1015
1016 std::vector<std::pair<wxString, wxString>> pages;
1017
1018 label->GetIntersheetRefs( sheet, &pages );
1019
1020 for( int i = 0; i < (int) pages.size(); ++i )
1021 {
1022 menu.Append( i + START_ID,
1023 wxString::Format( _( "Go to Page %s (%s)" ), pages[i].first, pages[i].second ) );
1024 }
1025
1026 menu.AppendSeparator();
1027 menu.Append( 999 + START_ID, _( "Back to Previous Selected Sheet" ) );
1028
1029 int sel = aFrame->GetPopupMenuSelectionFromUser( menu ) - START_ID;
1030
1031 if( sel >= 0 && sel < (int) pages.size() )
1032 href = wxT( "#" ) + pages[sel].first;
1033 else if( sel == 999 )
1035 }
1036 else if( IsURL( GetShownText( false ) ) || m_name == SIM_LIBRARY::LIBRARY_FIELD )
1037 {
1038 href = GetShownText( false );
1039 }
1040
1041 if( !href.IsEmpty() )
1042 {
1044 navTool->HypertextCommand( href );
1045 }
1046}
1047
1048
1049void SCH_FIELD::SetName( const wxString& aName )
1050{
1051 m_name = aName;
1053
1054 if( m_isGeneratedField )
1055 EDA_TEXT::SetText( aName );
1056}
1057
1058
1059void SCH_FIELD::SetText( const wxString& aText )
1060{
1061 // Don't allow modification of text value of generated fields.
1062 if( m_isGeneratedField )
1063 return;
1064
1065 // Mandatory fields should not have leading or trailing whitespace.
1066 if( IsMandatory() )
1067 EDA_TEXT::SetText( aText.Strip( wxString::both ) );
1068 else
1069 EDA_TEXT::SetText( aText );
1070}
1071
1072
1073void SCH_FIELD::SetText( const wxString& aText, const SCH_SHEET_PATH* aPath, const wxString& aVariantName )
1074{
1075 wxCHECK( m_parent, /* void */ );
1076
1077 if( m_isGeneratedField )
1078 return;
1079
1080 wxString tmp = aText;
1081
1082 if( IsMandatory() )
1083 tmp = aText.Strip( wxString::both ) ;
1084
1085 switch( m_parent->Type() )
1086 {
1087 case SCH_SYMBOL_T:
1088 {
1089 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1090 wxCHECK( symbol, /* void */ );
1091 symbol->SetFieldText( GetName(), aText, aPath, aVariantName );
1092 break;
1093 }
1094
1095 case SCH_SHEET_T:
1096 {
1097 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1098 wxCHECK( sheet, /* void */ );
1099 sheet->SetFieldText( GetName(), aText, aPath, aVariantName );
1100 break;
1101 }
1102
1103 default:
1104 SCH_FIELD::SetText( aText );
1105 break;
1106 }
1107}
1108
1109
1110wxString SCH_FIELD::GetText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1111{
1112 wxString retv;
1113
1114 wxCHECK( aPath && m_parent, retv );
1115
1116 switch( m_parent->Type() )
1117 {
1118 case SCH_SYMBOL_T:
1119 {
1120 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1121 wxCHECK( symbol, retv );
1122 retv = symbol->GetFieldText( GetName(), aPath, aVariantName );
1123 break;
1124 }
1125
1126 case SCH_SHEET_T:
1127 {
1128 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1129 wxCHECK( sheet, retv );
1130 retv = sheet->GetFieldText( GetName(), aPath, aVariantName );
1131 break;
1132 }
1133
1134 default:
1135 retv = GetText();
1136 break;
1137 }
1138
1139 return retv;
1140}
1141
1142
1143wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
1144{
1145 if( m_parent && m_parent->IsType( labelTypes ) )
1146 return SCH_LABEL_BASE::GetDefaultFieldName( m_name, aUseDefaultName );
1147
1148 if( IsMandatory() )
1149 return GetCanonicalFieldName( m_id );
1150 else if( m_name.IsEmpty() && aUseDefaultName )
1152 else
1153 return m_name;
1154}
1155
1156
1158{
1159 if( m_parent && m_parent->IsType( labelTypes ) )
1160 {
1161 // These should be stored in canonical format, but just in case:
1162 if( m_name == _( "Net Class" ) || m_name == wxT( "Net Class" ) )
1163 return wxT( "Netclass" );
1164 }
1165
1166 if( IsMandatory() )
1167 return GetCanonicalFieldName( m_id );
1168
1169 return m_name;
1170}
1171
1172
1174{
1175 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1176 {
1177 switch( m_id )
1178 {
1182 default: return BITMAPS::text;
1183 }
1184 }
1185
1186 return BITMAPS::text;
1187}
1188
1189
1190bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1191{
1192 if( GetShownText( true ).IsEmpty() )
1193 return false;
1194
1195 BOX2I rect = GetBoundingBox();
1196
1197 // Text in symbol editor can have additional chars (ie: reference designators U? or U?A)
1198 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1199 {
1200 SCH_FIELD temp( *this );
1201 temp.SetText( GetFullText() );
1202 rect = temp.GetBoundingBox();
1203 }
1204
1205 rect.Inflate( aAccuracy );
1206
1207 if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1208 {
1209 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1210 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1211 }
1212
1213 return rect.Contains( aPosition );
1214}
1215
1216
1217bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1218{
1219 if( GetShownText( true ).IsEmpty() )
1220 return false;
1221
1222 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1223 return false;
1224
1225 BOX2I rect = aRect;
1226
1227 rect.Inflate( aAccuracy );
1228
1229 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1230 {
1231 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1232 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1233 }
1234
1235 if( aContained )
1236 return rect.Contains( GetBoundingBox() );
1237
1238 return rect.Intersects( GetBoundingBox() );
1239}
1240
1241
1242bool SCH_FIELD::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1243{
1244 if( GetShownText( true ).IsEmpty() )
1245 return false;
1246
1247 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1248 return false;
1249
1250 BOX2I bbox = GetBoundingBox();
1251
1252 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1253 {
1254 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1255 bbox.Offset( label->GetSchematicTextOffset( nullptr ) );
1256 }
1257
1258 return KIGEOM::BoxHitTest( aPoly, bbox, aContained );
1259}
1260
1261
1262void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit, int aBodyStyle,
1263 const VECTOR2I& aOffset, bool aDimmed )
1264{
1265 wxString text;
1266
1267 if( Schematic() )
1268 text = GetShownText( &Schematic()->CurrentSheet(), true, 0, Schematic()->GetCurrentVariant() );
1269 else
1270 text = GetShownText( true );
1271
1272 if( ( !IsVisible() && !IsForceVisible() ) || text.IsEmpty() || aBackground )
1273 return;
1274
1275 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1276 COLOR4D color = renderSettings->GetLayerColor( GetLayer() );
1277 int penWidth = GetEffectiveTextPenWidth( renderSettings->GetDefaultPenWidth() );
1278
1279 COLOR4D bg = renderSettings->GetBackgroundColor();
1280
1281 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1282 bg = COLOR4D::WHITE;
1283
1284 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1285 color = GetTextColor();
1286
1287 if( color.m_text && Schematic() )
1288 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1289
1290 if( aDimmed )
1291 {
1292 color.Desaturate();
1293 color = color.Mix( bg, 0.5f );
1294 }
1295
1296 penWidth = std::max( penWidth, renderSettings->GetMinPenWidth() );
1297
1298 // clamp the pen width to be sure the text is readable
1299 penWidth = std::min( penWidth, std::min( GetTextSize().x, GetTextSize().y ) / 4 );
1300
1301 if( !IsVisible() && !renderSettings->m_ShowHiddenFields )
1302 return;
1303
1304 // Calculate the text orientation, according to the symbol orientation/mirror
1305 EDA_ANGLE orient = GetTextAngle();
1306 VECTOR2I textpos = GetTextPos();
1308 GR_TEXT_V_ALIGN_T vjustify = GetVertJustify();
1309
1310 if( renderSettings->m_Transform.y1 ) // Rotate symbol 90 deg.
1311 {
1312 if( orient.IsHorizontal() )
1313 orient = ANGLE_VERTICAL;
1314 else
1315 orient = ANGLE_HORIZONTAL;
1316 }
1317
1318 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1319 {
1320 /*
1321 * Calculate the text justification, according to the symbol orientation/mirror. This is
1322 * a bit complicated due to cumulative calculations:
1323 * - numerous cases (mirrored or not, rotation)
1324 * - the plotter's Text() function will also recalculate H and V justifications according
1325 * to the text orientation
1326 * - when a symbol is mirrored the text is not, and justifications become a nightmare
1327 *
1328 * So the easier way is to use no justifications (centered text) and use GetBoundingBox
1329 * to know the text coordinate considered as centered.
1330 */
1331 hjustify = GR_TEXT_H_ALIGN_CENTER;
1332 vjustify = GR_TEXT_V_ALIGN_CENTER;
1333 textpos = GetBoundingBox().Centre();
1334 }
1335 else if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1336 {
1337 // Library-symbol exports (CLI/symbol editor) provide an item offset in the same coordinate
1338 // frame as body graphics/pins. Apply the same transform+offset pipeline to field text.
1339 textpos = renderSettings->TransformCoordinate( textpos ) + aOffset;
1340 }
1341 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1342 {
1343 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_parent );
1344 textpos += label->GetSchematicTextOffset( renderSettings );
1345 }
1346 else if( m_parent && m_parent->Type() == SCH_DIRECTIVE_LABEL_T )
1347 {
1348 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( m_parent );
1349 std::shared_ptr<NETCLASS> nc = label->GetEffectiveNetClass();
1350
1351 if( nc && ( nc->GetSchematicColor() != COLOR4D::UNSPECIFIED ) && aPlotter->GetColorMode() )
1352 color = nc->GetSchematicColor();
1353 }
1354
1355 KIFONT::FONT* font = GetDrawFont( renderSettings );
1357 attrs.m_StrokeWidth = penWidth;
1358 attrs.m_Halign = hjustify;
1359 attrs.m_Valign = vjustify;
1360 attrs.m_Angle = orient;
1361 attrs.m_Multiline = false;
1362
1363 aPlotter->PlotText( textpos, color, text, attrs, font, GetFontMetrics() );
1364
1366 {
1367 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( m_parent ) )
1368 {
1369 std::vector<std::pair<wxString, wxString>> pages;
1370 std::vector<wxString> pageHrefs;
1371
1372 label->GetIntersheetRefs( &Schematic()->CurrentSheet(), &pages );
1373
1374 for( const auto& [pageNumber, sheetName] : pages )
1375 pageHrefs.push_back( wxT( "#" ) + pageNumber );
1376
1377 BOX2I bbox = GetBoundingBox();
1378 bbox.Offset( label->GetSchematicTextOffset( renderSettings ) );
1379
1380 aPlotter->HyperlinkMenu( bbox, pageHrefs );
1381 }
1382 }
1383}
1384
1385
1386void SCH_FIELD::SetPosition( const VECTOR2I& aPosition )
1387{
1388 // Actual positions are calculated by the rotation/mirror transform of the parent symbol
1389 // of the field. The inverse transform is used to calculate the position relative to the
1390 // parent symbol.
1391 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1392 {
1393 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1394 VECTOR2I relPos = aPosition - parentSymbol->GetPosition();
1395
1396 relPos = parentSymbol->GetTransform().InverseTransform().TransformCoordinate( relPos );
1397
1398 SetTextPos( relPos + parentSymbol->GetPosition() );
1399 return;
1400 }
1401
1402 SetTextPos( aPosition );
1403}
1404
1405
1407{
1408 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1409 {
1410 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1411 VECTOR2I relativePos = GetTextPos() - parentSymbol->GetPosition();
1412
1413 relativePos = parentSymbol->GetTransform().TransformCoordinate( relativePos );
1414
1415 return relativePos + parentSymbol->GetPosition();
1416 }
1417
1418 return GetTextPos();
1419}
1420
1421
1423{
1424 return m_parent ? m_parent->GetPosition() : VECTOR2I( 0, 0 );
1425}
1426
1427
1434
1435
1436bool SCH_FIELD::operator<( const SCH_ITEM& aItem ) const
1437{
1438 if( Type() != aItem.Type() )
1439 return Type() < aItem.Type();
1440
1441 auto field = static_cast<const SCH_FIELD*>( &aItem );
1442
1443 if( GetId() != field->GetId() )
1444 return GetId() < field->GetId();
1445
1446 if( GetText() != field->GetText() )
1447 return GetText() < field->GetText();
1448
1449 if( GetLibPosition().x != field->GetLibPosition().x )
1450 return GetLibPosition().x < field->GetLibPosition().x;
1451
1452 if( GetLibPosition().y != field->GetLibPosition().y )
1453 return GetLibPosition().y < field->GetLibPosition().y;
1454
1455 return GetName() < field->GetName();
1456}
1457
1458
1459bool SCH_FIELD::operator==( const SCH_ITEM& aOther ) const
1460{
1461 if( Type() != aOther.Type() )
1462 return false;
1463
1464 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1465
1466 return *this == field;
1467}
1468
1469
1470bool SCH_FIELD::operator==( const SCH_FIELD& aOther ) const
1471{
1472 // Identical fields owned by different items are not equal.
1473 if( m_parent || aOther.m_parent )
1474 {
1475 if( !m_parent || !aOther.m_parent )
1476 return false;
1477
1478 if( m_parent->Type() != aOther.m_parent->Type() )
1479 return false;
1480
1481 if( m_parent->m_Uuid != aOther.m_parent->m_Uuid )
1482 return false;
1483 }
1484
1485 if( IsMandatory() != aOther.IsMandatory() )
1486 return false;
1487
1488 if( IsMandatory() )
1489 {
1490 if( GetId() != aOther.GetId() )
1491 return false;
1492 }
1493 else
1494 {
1495 if( GetOrdinal() != aOther.GetOrdinal() )
1496 return false;
1497 }
1498
1499 if( GetPosition() != aOther.GetPosition() )
1500 return false;
1501
1502 if( IsGeneratedField() != aOther.IsGeneratedField() )
1503 return false;
1504
1505 if( IsNameShown() != aOther.IsNameShown() )
1506 return false;
1507
1508 if( CanAutoplace() != aOther.CanAutoplace() )
1509 return false;
1510
1511 return EDA_TEXT::operator==( aOther );
1512}
1513
1514
1515double SCH_FIELD::Similarity( const SCH_ITEM& aOther ) const
1516{
1517 if( Type() != aOther.Type() )
1518 return 0.0;
1519
1520 if( m_Uuid == aOther.m_Uuid )
1521 return 1.0;
1522
1523 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1524
1525 double similarity = 0.99; // The UUIDs are different, so we start with non-identity
1526
1527 if( GetId() != field.GetId() )
1528 {
1529 // We don't allow swapping of mandatory fields, so these cannot be the same item
1530 if( IsMandatory() || field.IsMandatory() )
1531 return 0.0;
1532 else
1533 similarity *= 0.5;
1534 }
1535
1536 similarity *= SimilarityBase( aOther );
1537
1538 similarity *= EDA_TEXT::Similarity( field );
1539
1540 if( GetPosition() != field.GetPosition() )
1541 similarity *= 0.5;
1542
1543 if( IsGeneratedField() != field.IsGeneratedField() )
1544 similarity *= 0.5;
1545
1546 if( IsNameShown() != field.IsNameShown() )
1547 similarity *= 0.5;
1548
1549 if( CanAutoplace() != field.CanAutoplace() )
1550 similarity *= 0.5;
1551
1552 return similarity;
1553}
1554
1555
1556int SCH_FIELD::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1557{
1558 wxASSERT( aOther.Type() == SCH_FIELD_T );
1559
1560 int compareFlags = aCompareFlags;
1561
1562 // For ERC tests, the field position has no matter, so do not test it
1563 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC )
1565
1566 int retv = SCH_ITEM::compare( aOther, compareFlags );
1567
1568 if( retv )
1569 return retv;
1570
1571 const SCH_FIELD* tmp = static_cast<const SCH_FIELD*>( &aOther );
1572
1573 // Equality test will vary depending whether or not the field is mandatory. Otherwise,
1574 // sorting is done by ordinal.
1575 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1576 {
1577 // Mandatory fields have fixed ordinals and their names can vary due to translated field
1578 // names. Optional fields have fixed names and their ordinals can vary.
1579 if( IsMandatory() )
1580 {
1581 if( m_id != tmp->m_id )
1582 return (int) m_id - (int) tmp->m_id;
1583 }
1584 else
1585 {
1586 retv = m_name.Cmp( tmp->m_name );
1587
1588 if( retv )
1589 return retv;
1590 }
1591 }
1592 else // assume we're sorting
1593 {
1594 if( m_id != tmp->m_id )
1595 return (int) m_id - (int) tmp->m_id;
1596 }
1597
1598 bool ignoreFieldText = false;
1599
1600 if( m_id == FIELD_T::REFERENCE && !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY ) )
1601 ignoreFieldText = true;
1602
1603 if( m_id == FIELD_T::VALUE && ( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1604 ignoreFieldText = true;
1605
1606 if( !ignoreFieldText )
1607 {
1608 retv = GetText().CmpNoCase( tmp->GetText() );
1609
1610 if( retv != 0 )
1611 return retv;
1612 }
1613
1614 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1615 {
1616 if( GetTextPos().x != tmp->GetTextPos().x )
1617 return GetTextPos().x - tmp->GetTextPos().x;
1618
1619 if( GetTextPos().y != tmp->GetTextPos().y )
1620 return GetTextPos().y - tmp->GetTextPos().y;
1621 }
1622
1623 // For ERC tests, the field size has no matter, so do not test it
1624 if( !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1625 {
1626 if( GetTextWidth() != tmp->GetTextWidth() )
1627 return GetTextWidth() - tmp->GetTextWidth();
1628
1629 if( GetTextHeight() != tmp->GetTextHeight() )
1630 return GetTextHeight() - tmp->GetTextHeight();
1631 }
1632
1633 return 0;
1634}
1635
1636
1637wxString SCH_FIELD::getUnescapedText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1638{
1639 // This is the default variant field text for all fields except the reference field.
1640 wxString retv = EDA_TEXT::GetShownText( false );
1641
1642 // Special handling for parent object field instance and variant information.
1643 // Only use the path if it's non-empty; an empty path can't match any instances
1644 if( m_parent && aPath && !aPath->empty() )
1645 {
1646 wxLogTrace( traceSchFieldRendering, " Path is valid and non-empty, parent type=%d", m_parent->Type() );
1647
1648 switch( m_parent->Type() )
1649 {
1650 case SCH_SYMBOL_T:
1651 if( const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( m_parent ) )
1652 {
1653 if( m_id == FIELD_T::REFERENCE )
1654 {
1655 wxLogTrace( traceSchFieldRendering, " Calling GetRef for symbol %s on path %s",
1656 symbol->m_Uuid.AsString(), aPath->Path().AsString() );
1657
1658 retv = symbol->GetRef( aPath, true );
1659
1660 wxLogTrace( traceSchFieldRendering, " GetRef returned: '%s'", retv );
1661 }
1662 else if( !aVariantName.IsEmpty() )
1663 {
1664 // If the variant is not found, fall back to default variant above.
1665 if( std::optional<SCH_SYMBOL_VARIANT> variant = symbol->GetVariant( *aPath, aVariantName ) )
1666 {
1667 // If the field name does not exist in the variant, fall back to the default variant above.
1668 if( variant->m_Fields.contains( GetName() ) )
1669 retv = variant->m_Fields[GetName()];
1670 }
1671 }
1672 }
1673
1674 break;
1675
1676 case SCH_SHEET_T:
1677 break;
1678
1679 default:
1680 break;
1681 }
1682 }
1683
1684 return retv;
1685}
1686
1687
1688static struct SCH_FIELD_DESC
1689{
1691 {
1692 // These are defined in EDA_TEXT as well but initialization order is
1693 // not defined, so this needs to be conditional. Defining in both
1694 // places leads to duplicate symbols.
1696
1697 if( h_inst.Choices().GetCount() == 0 )
1698 {
1699 h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _HKI( "Left" ) );
1700 h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _HKI( "Center" ) );
1701 h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _HKI( "Right" ) );
1702 }
1703
1705
1706 if( v_inst.Choices().GetCount() == 0 )
1707 {
1708 v_inst.Map( GR_TEXT_V_ALIGN_TOP, _HKI( "Top" ) );
1709 v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _HKI( "Center" ) );
1710 v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _HKI( "Bottom" ) );
1711 }
1712
1719
1720 // Lock state is inherited from parent symbol (no independent locking of child items)
1721 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Locked" ) );
1722
1723 const wxString textProps = _HKI( "Text Properties" );
1724
1725 auto horiz = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_H_ALIGN_T>( _HKI( "Horizontal Justification" ),
1728
1729 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ), horiz, textProps );
1730
1731 auto vert = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_V_ALIGN_T>( _HKI( "Vertical Justification" ),
1734
1735 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ), vert, textProps );
1736
1737 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Show Field Name" ), &SCH_FIELD::SetNameShown,
1739
1740 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Allow Autoplacement" ), &SCH_FIELD::SetCanAutoplace,
1742
1743 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
1744 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
1745 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
1746 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
1747 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
1748
1749
1752 _HKI( "Text Properties" ) );
1753
1754 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
1755
1756 auto isNotGeneratedField = []( INSPECTABLE* aItem ) -> bool
1757 {
1758 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1759 return !field->IsGeneratedField();
1760
1761 return true;
1762 };
1763
1765 isNotGeneratedField );
1766
1767
1768 auto isNonMandatoryField = []( INSPECTABLE* aItem ) -> bool
1769 {
1770 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1771 return !field->IsMandatory();
1772
1773 return false;
1774 };
1775
1776 propMgr.OverrideAvailability( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Private" ),
1777 isNonMandatoryField );
1778 }
1780
1781
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:127
BITMAPS
A list of all bitmap identifiers.
@ edit_comp_value
@ edit_comp_footprint
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:558
constexpr const Vec GetEnd() const
Definition box2.h:212
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:237
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition box2.h:146
constexpr Vec Centre() const
Definition box2.h:97
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:168
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition box2.h:138
constexpr const Vec & GetOrigin() const
Definition box2.h:210
constexpr void SetEnd(coord_type x, coord_type y)
Definition box2.h:297
constexpr void Offset(coord_type dx, coord_type dy)
Definition box2.h:259
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:311
static const COLOR4D WHITE
Definition color4d.h:405
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:402
bool IsHorizontal() const
Definition eda_angle.h:142
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:528
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:112
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:539
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:413
EDA_ITEM * GetParent() const
Definition eda_item.h:114
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:540
bool IsForceVisible() const
Definition eda_item.h:218
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:246
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:41
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:93
int GetTextHeight() const
Definition eda_text.h:292
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition eda_text.cpp:169
const VECTOR2I & GetTextPos() const
Definition eda_text.h:298
COLOR4D GetTextColor() const
Definition eda_text.h:295
wxString GetTextStyleName() const
bool IsItalic() const
Definition eda_text.h:194
const EDA_ANGLE & GetTextAngle() const
Definition eda_text.h:172
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:532
virtual bool IsVisible() const
Definition eda_text.h:212
void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:576
void SetTextX(int aX)
Definition eda_text.cpp:582
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition eda_text.cpp:212
KIFONT::FONT * GetFont() const
Definition eda_text.h:272
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:432
void SetTextY(int aY)
Definition eda_text.cpp:588
EDA_TEXT & operator=(const EDA_TEXT &aItem)
Definition eda_text.cpp:142
int GetTextWidth() const
Definition eda_text.h:289
BOX2I GetTextBox(const RENDER_SETTINGS *aSettings, int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition eda_text.cpp:771
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:416
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:225
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition eda_text.cpp:486
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:133
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:385
EDA_TEXT(const EDA_IU_SCALE &aIuScale, const wxString &aText=wxEmptyString)
Definition eda_text.cpp:102
virtual void ClearBoundingBoxCache()
Definition eda_text.cpp:694
double Similarity(const EDA_TEXT &aOther) const
virtual void ClearRenderCache()
Definition eda_text.cpp:688
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:256
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:465
void SwapAttributes(EDA_TEXT &aTradingPartner)
Swap the text attributes of the two involved instances.
Definition eda_text.cpp:452
bool IsBold() const
Definition eda_text.h:209
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:228
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:125
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:269
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:298
void SwapText(EDA_TEXT &aTradingPartner)
Definition eda_text.cpp:444
bool operator==(const EDA_TEXT &aRhs) const
Definition eda_text.h:423
VECTOR2I GetTextSize() const
Definition eda_text.h:286
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:408
static ENUM_MAP< T > & Instance()
Definition property.h:721
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:38
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:98
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition font.cpp:147
virtual bool IsOutline() const
Definition font.h:106
Class OUTLINE_FONT implements outline font drawing.
void GetLinesAsGlyphs(std::vector< std::unique_ptr< GLYPH > > *aGlyphs, const wxString &aText, const VECTOR2I &aPosition, const TEXT_ATTRIBUTES &aAttrs, const METRICS &aFontMetrics) const
void Move(const VECTOR2I &aOffset)
Definition glyph.cpp:114
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
std::shared_ptr< wxString > m_text
Definition color4d.h:399
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:532
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition color4d.h:296
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxString AsString() const
Definition kiid.cpp:365
static wxString LetterSubReference(int aUnit, wxChar aInitialLetter)
COLOR4D GetSchematicColor(bool aIsForSave=false) const
Definition netclass.h:216
A singleton reporter that reports to nowhere.
Definition reporter.h:218
Base plotter engine class.
Definition plotter.h: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:696
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
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void OverrideAvailability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override availability functor for a base class property of a given derived class.
PROPERTY_BASE & ReplaceProperty(size_t aBase, const wxString &aName, PROPERTY_BASE *aNew, const wxString &aGroup=wxEmptyString)
Replace an existing property for a specific type.
void OverrideWriteability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override writeability functor for a base class property of a given derived class.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
Definition schematic.h:89
SCHEMATIC_SETTINGS & Settings() const
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:188
void ClearRenderCache() override
int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const override
Provide the draw object specific comparison called by the == and < operators.
COLOR4D m_lastResolvedColor
Definition sch_field.h:360
GR_TEXT_V_ALIGN_T GetEffectiveVertJustify() const
bool IsMandatory() const
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
wxString GetFullText(int unit=1) const
Return the text of a field.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
bool IsLocked() const override
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
VECTOR2I GetPosition() const override
void SetEffectiveHorizJustify(GR_TEXT_H_ALIGN_T)
int GetSchTextSize() const
Definition sch_field.h:177
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:350
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:216
bool m_autoAdded
Was this field automatically added to a LIB_SYMBOL?
Definition sch_field.h:355
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:358
bool IsGeneratedField() const
Generated fields are fields whose names are variables like ${VAR}.
Definition sch_field.h:225
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:126
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:130
void SetCanAutoplace(bool aCanPlace)
Definition sch_field.h:228
int GetPenWidth() const override
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
bool m_isGeneratedField
If the field name is a variable name (e.g.
Definition sch_field.h:352
int m_ordinal
Sort order for non-mandatory fields.
Definition sch_field.h:347
COLOR4D GetFieldColor() const
wxString getUnescapedText(const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
bool operator==(const SCH_ITEM &aItem) const override
SCH_FIELD & operator=(const SCH_FIELD &aField)
void ImportValues(const SCH_FIELD &aSource)
Copy parameters from a SCH_FIELD source.
bool operator<(const SCH_ITEM &aItem) const override
FIELD_T m_id
Field id,.
Definition sch_field.h:346
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:274
void setId(FIELD_T aId)
int GetOrdinal() const
Definition sch_field.h:132
bool IsEmpty()
Return true if both the name and value of the field are empty.
Definition sch_field.h:169
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) const
KIFONT::FONT * GetDrawFont(const RENDER_SETTINGS *aSettings) const override
void BeginEdit(const VECTOR2I &aStartPoint) override
Begin drawing a symbol library draw item at aPosition.
bool IsReplaceable() const override
Override this method in any derived object that supports test find and replace.
void SetSchTextSize(int aSize)
Definition sch_field.h:178
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:227
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:356
void OnScintillaCharAdded(SCINTILLA_TRICKS *aScintillaTricks, wxStyledTextEvent &aEvent) const
wxString m_name
Definition sch_field.h:348
void SetNameShown(bool aShown=true)
Definition sch_field.h:217
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
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:351
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:168
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition sch_item.cpp:82
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.h:730
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:278
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:272
bool IsLocked() const override
Definition sch_item.cpp:152
friend class LIB_SYMBOL
Definition sch_item.h:803
@ SKIP_TST_POS
Definition sch_item.h:713
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition sch_item.cpp:527
void SetLayer(SCH_LAYER_ID aLayer)
Definition sch_item.h:345
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition sch_item.h:344
virtual int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const
Provide the draw object specific comparison called by the == and < operators.
Definition sch_item.cpp:722
const wxString & GetDefaultFont(const RENDER_SETTINGS *aSettings) const
Definition sch_item.cpp:770
bool IsConnectivityDirty() const
Definition sch_item.h:591
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:56
bool m_private
Definition sch_item.h:784
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:381
const KIFONT::METRICS & GetFontMetrics() const
Definition sch_item.cpp:783
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:383
void GetIntersheetRefs(const SCH_SHEET_PATH *aPath, std::vector< std::pair< wxString, wxString > > *pages)
Build an array of { pageNumber, pageName } pairs.
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this label.
Handle actions specific to the schematic editor.
static wxString g_BackLink
void HypertextCommand(const wxString &aHref)
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
const KIGFX::COLOR4D & GetBackgroundColor() const override
Return current background color settings.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool empty() const
Forwarded method from std::vector.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
size_t size() const
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
wxString GetFieldText(const wxString &aFieldName, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
void SetFieldText(const wxString &aFieldName, const wxString &aFieldText, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString)
Schematic symbol object.
Definition sch_symbol.h:76
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:871
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
int GetUnitCount() const override
Return the number of units per package of the symbol.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
wxStyledTextCtrl * Scintilla() const
void DoAutocomplete(const wxString &aPartial, const wxArrayString &aTokens)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
static constexpr auto LIBRARY_FIELD
Definition sim_library.h:35
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
void SetFilesStack(std::vector< EMBEDDED_FILES * > aFilesStack)
Definition sim_lib_mgr.h:48
A base class for LIB_SYMBOL and SCH_SYMBOL.
Definition symbol.h:63
const TRANSFORM & GetTransform() const
Definition symbol.h:247
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
for transforming drawing coordinates for a wxDC device context.
Definition transform.h:46
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition transform.cpp:59
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition transform.cpp:44
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
A type-safe container of any type.
Definition ki_any.h:93
wxString GetGeneratedFieldDisplayName(const wxString &aSource)
Returns any variables unexpanded, e.g.
Definition common.cpp:448
The common library.
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:408
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:407
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:416
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
a few functions useful in geometry calculations.
const wxChar *const traceSchFieldRendering
Flag to enable debug output of schematic field rendering and positioning.
@ USER
The main config directory (e.g. ~/.config/kicad/)
SCH_LAYER_ID
Eeschema drawing layers.
Definition layer_ids.h:451
@ LAYER_SHEETNAME
Definition layer_ids.h:474
@ LAYER_VALUEPART
Definition layer_ids.h:463
@ LAYER_FIELDS
Definition layer_ids.h:464
@ LAYER_SHEETFIELDS
Definition layer_ids.h:476
@ LAYER_REFERENCEPART
Definition layer_ids.h:462
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:466
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:497
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:465
@ LAYER_SHEETFILENAME
Definition layer_ids.h:475
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
KICOMMON_API wxString EllipsizeStatusText(wxWindow *aWindow, const wxString &aString)
Ellipsize text (at the end) to be no more than 1/3 of the window width.
#define _HKI(x)
Definition page_info.cpp:44
static GR_TEXT_H_ALIGN_T horizJustify(const char *horizontal)
#define TYPE_HASH(x)
Definition property.h:74
#define DECLARE_ENUM_TO_WXANY(type)
Definition property.h:787
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
static const std::vector< KICAD_T > labelTypes
Definition sch_field.cpp:48
static struct SCH_FIELD_DESC _SCH_FIELD_DESC
@ SYMBOL_FILTER_ALL
wxString UnescapeString(const wxString &aSource)
bool IsURL(wxString aStr)
Performs a URL sniff-test on a string.
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
#define DO_TRANSLATE
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ INTERSHEET_REFS
Global label cross-reference page numbers.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
KIBIS_MODEL * model
KIBIS_PIN * pin
VECTOR2I end
int delta
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
wxLogTrace helper definitions.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:229
@ LIB_SYMBOL_T
Definition typeinfo.h:149
@ SCH_SYMBOL_T
Definition typeinfo.h:173
@ SCH_FIELD_T
Definition typeinfo.h:151
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:172
@ SCH_LABEL_T
Definition typeinfo.h:168
@ SCH_SHEET_T
Definition typeinfo.h:176
@ SCH_LABEL_LOCATE_ANY_T
Definition typeinfo.h:192
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:169
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
Definition typeinfo.h:60
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition ui_common.h:46
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687