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
46static const std::vector<KICAD_T> labelTypes = { SCH_LABEL_LOCATE_ANY_T };
47
48
50 SCH_ITEM( nullptr, SCH_FIELD_T ),
51 EDA_TEXT( schIUScale, wxEmptyString ),
52 m_id( FIELD_T::USER ),
53 m_ordinal( 0 ),
54 m_showName( false ),
55 m_allowAutoPlace( true ),
56 m_isGeneratedField( false ),
57 m_autoAdded( false ),
58 m_showInChooser( true ),
59 m_renderCacheValid( false ),
61{
62}
63
64
65SCH_FIELD::SCH_FIELD( SCH_ITEM* aParent, FIELD_T aFieldId, const wxString& aName ) :
66 SCH_FIELD()
67{
68 m_parent = aParent;
69
70 if( !aName.IsEmpty() )
71 SetName( aName );
72 else
74
75 setId( aFieldId ); // will also set the layer
76 SetVisible( true );
77
78 if( aParent && aParent->Schematic() )
79 {
80 SCHEMATIC_SETTINGS& settings = aParent->Schematic()->Settings();
82 }
83
84 if( aFieldId == FIELD_T::USER && aParent )
85 {
86 if( aParent->Type() == SCH_SYMBOL_T )
87 m_ordinal = static_cast<SCH_SYMBOL*>( aParent )->GetNextFieldOrdinal();
88 else if( aParent->Type() == LIB_SYMBOL_T )
89 m_ordinal = static_cast<LIB_SYMBOL*>( aParent )->GetNextFieldOrdinal();
90 else if( aParent->Type() == SCH_SHEET_T )
91 m_ordinal = static_cast<SCH_SHEET*>( aParent )->GetNextFieldOrdinal();
92 else if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aParent ) )
93 m_ordinal = label->GetNextFieldOrdinal();
94 }
95}
96
97
99 SCH_FIELD( aParent, FIELD_T::USER, wxEmptyString )
100{
101 SCH_ITEM::operator=( *aText );
102 EDA_TEXT::operator=( *aText );
103}
104
105
107 SCH_ITEM( aField ),
108 EDA_TEXT( aField )
109{
110 m_private = aField.m_private;
111 setId( aField.m_id ); // will also set the layer
112 m_ordinal = aField.m_ordinal;
113 m_name = aField.m_name;
114 m_showName = aField.m_showName;
117 m_autoAdded = aField.m_autoAdded;
119
120 m_renderCache.clear();
121
122 for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
123 {
124 if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
125 m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
126 else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
127 m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
128 }
129
132
134}
135
136
138{
139 EDA_TEXT::operator=( aField );
140
141 m_private = aField.m_private;
142 setId( aField.m_id ); // will also set the layer
143 m_ordinal = aField.m_ordinal;
144 m_name = aField.m_name;
145 m_showName = aField.m_showName;
148
149 m_renderCache.clear();
150
151 for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
152 {
153 if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
154 m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
155 else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
156 m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
157 }
158
161
163
164 return *this;
165}
166
167
169{
170 return new SCH_FIELD( *this );
171}
172
173
174void SCH_FIELD::Copy( SCH_FIELD* aTarget ) const
175{
176 *aTarget = *this;
177}
178
179
181{
182 m_id = aId;
184}
185
186
191
192
193wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText, int aDepth,
194 const wxString& aVariantName ) const
195{
196 wxString text = getUnescapedText( aPath, aVariantName );
197
198 if( IsNameShown() && aAllowExtraText )
199 text = GetShownName() << wxS( ": " ) << text;
200
201 if( HasTextVars() )
202 text = ResolveText( text, aPath, aDepth );
203
204 if( m_id == FIELD_T::SHEET_FILENAME && aAllowExtraText && !IsNameShown() )
205 text = _( "File:" ) + wxS( " " ) + text;
206
207 // Convert escape markers back to literals for final display
208 text.Replace( wxT( "<<<ESC_DOLLAR:" ), wxT( "${" ) );
209 text.Replace( wxT( "<<<ESC_AT:" ), wxT( "@{" ) );
210
211 return text;
212}
213
214
215wxString SCH_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
216{
217 if( SCHEMATIC* schematic = Schematic() )
218 {
219 const SCH_SHEET_PATH& currentSheet = schematic->CurrentSheet();
220 wxString variantName = schematic->GetCurrentVariant();
221
222 wxLogTrace( traceSchFieldRendering,
223 "GetShownText (no path arg): field=%s, current sheet path='%s', variant='%s', size=%zu, empty=%d",
224 GetName(), currentSheet.Path().AsString(), variantName, currentSheet.size(),
225 currentSheet.empty() ? 1 : 0 );
226 return GetShownText( &currentSheet, aAllowExtraText, aDepth, variantName );
227 }
228 else
229 {
230 return GetShownText( nullptr, aAllowExtraText, aDepth );
231 }
232}
233
234
235wxString SCH_FIELD::GetFullText( int unit ) const
236{
237 if( GetId() != FIELD_T::REFERENCE )
238 return GetText();
239
240 wxString text = GetText();
241 text << wxT( "?" );
242
243 if( GetParentSymbol() && GetParentSymbol()->IsMultiUnit() )
244 text << LIB_SYMBOL::LetterSubReference( unit, 'A' );
245
246 return text;
247}
248
249
251{
253}
254
255
257{
259
260 if( !font )
261 font = KIFONT::FONT::GetFont( GetDefaultFont( aSettings ), IsBold(), IsItalic() );
262
263 return font;
264}
265
266
272
273
279
280
281std::vector<std::unique_ptr<KIFONT::GLYPH>>*
282SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forPosition, TEXT_ATTRIBUTES& aAttrs ) const
283{
284 KIFONT::FONT* font = GetDrawFont( nullptr );
285
286 if( font->IsOutline() )
287 {
288 KIFONT::OUTLINE_FONT* outlineFont = static_cast<KIFONT::OUTLINE_FONT*>( font );
289
290 if( m_renderCache.empty() || !m_renderCacheValid )
291 {
292 m_renderCache.clear();
293
294 outlineFont->GetLinesAsGlyphs( &m_renderCache, forResolvedText, forPosition, aAttrs, GetFontMetrics() );
295
296 m_renderCachePos = forPosition;
297 m_renderCacheValid = true;
298 }
299
300 if( m_renderCachePos != forPosition )
301 {
302 VECTOR2I delta = forPosition - m_renderCachePos;
303
304 for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache )
305 {
306 if( glyph->IsOutline() )
307 static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
308 else
309 static_cast<KIFONT::STROKE_GLYPH*>( glyph.get() )->Move( delta );
310 }
311
312 m_renderCachePos = forPosition;
313 }
314
315 return &m_renderCache;
316 }
317
318 return nullptr;
319}
320
321
322void SCH_FIELD::ImportValues( const SCH_FIELD& aSource )
323{
324 SetAttributes( aSource );
325 SetVisible( aSource.IsVisible() );
326 SetNameShown( aSource.IsNameShown() );
327 SetCanAutoplace( aSource.CanAutoplace() );
328}
329
330
332{
333 wxCHECK_RET( aItem && aItem->Type() == SCH_FIELD_T, wxT( "Cannot swap with invalid item." ) );
334
335 SCH_FIELD* item = static_cast<SCH_FIELD*>( aItem );
336
337 std::swap( m_showName, item->m_showName );
338 std::swap( m_allowAutoPlace, item->m_allowAutoPlace );
339 std::swap( m_isGeneratedField, item->m_isGeneratedField );
340 SwapText( *item );
341 SwapAttributes( *item );
342
343 std::swap( m_lastResolvedColor, item->m_lastResolvedColor );
344}
345
346
348{
350 {
352 }
353 else
354 {
355 SCH_LABEL_BASE* parentLabel = dynamic_cast<SCH_LABEL_BASE*>( GetParent() );
356
357 if( parentLabel && !parentLabel->IsConnectivityDirty() )
359 else
361 }
362
363 return m_lastResolvedColor;
364}
365
366
367std::vector<int> SCH_FIELD::ViewGetLayers() const
368{
370}
371
372
374{
375 if( m_parent && m_parent->Type() == SCH_LABEL_T )
376 {
377 if( GetCanonicalName() == wxT( "Netclass" ) || GetCanonicalName() == wxT( "Component Class" ) )
378 {
379 return LAYER_NETCLASS_REFS;
380 }
381 }
382
383 switch( m_id )
384 {
386 case FIELD_T::VALUE: return LAYER_VALUEPART;
391 default: return LAYER_FIELDS;
392 }
393}
394
395
397{
398 // Calculate the text orientation according to the symbol orientation.
399 EDA_ANGLE orient = GetTextAngle();
400
401 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
402 {
403 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
404
405 if( parentSymbol && parentSymbol->GetTransform().y1 ) // Rotate symbol 90 degrees.
406 {
407 if( orient.IsHorizontal() )
408 orient = ANGLE_VERTICAL;
409 else
410 orient = ANGLE_HORIZONTAL;
411 }
412 }
413
414 return orient;
415}
416
417
419{
420 BOX2I bbox = GetTextBox( nullptr );
421
422 // Calculate the bounding box position relative to the parent:
423 VECTOR2I origin = GetParentPosition();
424 VECTOR2I pos = GetTextPos() - origin;
425 VECTOR2I begin = bbox.GetOrigin() - origin;
426 VECTOR2I end = bbox.GetEnd() - origin;
427 RotatePoint( begin, pos, GetTextAngle() );
428 RotatePoint( end, pos, GetTextAngle() );
429
430 // Now, apply the symbol transform (mirror/rot)
431 TRANSFORM transform;
432
433 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
434 transform = static_cast<SCH_SYMBOL*>( m_parent )->GetTransform();
435
436 bbox.SetOrigin( transform.TransformCoordinate( begin ) );
437 bbox.SetEnd( transform.TransformCoordinate( end ) );
438
439 bbox.Move( origin );
440 bbox.Normalize();
441
442 return bbox;
443}
444
445
447{
448 VECTOR2I render_center = GetBoundingBox().Centre();
449 VECTOR2I pos = GetPosition();
450
451 switch( GetHorizJustify() )
452 {
454 if( GetDrawRotation().IsVertical() )
455 return render_center.y > pos.y;
456 else
457 return render_center.x < pos.x;
458
460 if( GetDrawRotation().IsVertical() )
461 return render_center.y < pos.y;
462 else
463 return render_center.x > pos.x;
464
465 default:
466 return false;
467 }
468}
469
470
472{
473 GR_TEXT_H_ALIGN_T actualJustify;
474
475 switch( aJustify )
476 {
479 break;
480
483 break;
484
485 default:
486 actualJustify = aJustify;
487 }
488
489 SetHorizJustify( actualJustify );
490}
491
492
502
503
505{
506 VECTOR2I render_center = GetBoundingBox().Centre();
507 VECTOR2I pos = GetPosition();
508
509 switch( GetVertJustify() )
510 {
512 if( GetDrawRotation().IsVertical() )
513 return render_center.x < pos.x;
514 else
515 return render_center.y < pos.y;
516
518 if( GetDrawRotation().IsVertical() )
519 return render_center.x > pos.x;
520 else
521 return render_center.y > pos.y;
522
523 default:
524 return false;
525 }
526}
527
528
530{
531 GR_TEXT_V_ALIGN_T actualJustify;
532
533 switch( aJustify )
534 {
537 break;
538
541 break;
542
543 default:
544 actualJustify = aJustify;
545 }
546
547 SetVertJustify( actualJustify );
548}
549
550
560
561
562bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
563{
564 bool searchHiddenFields = aSearchData.searchAllFields;
565 bool searchAndReplace = aSearchData.searchAndReplace;
566 bool replaceReferences = false;
567
568 try
569 {
570 // downcast
571 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
572 replaceReferences = schSearchData.replaceReferences;
573 }
574 catch( const std::bad_cast& )
575 {
576 }
577
578 wxString text = UnescapeString( GetText() );
579
580 if( !IsVisible() && !searchHiddenFields )
581 return false;
582
583 if( m_id == FIELD_T::REFERENCE )
584 {
585 if( searchAndReplace && !replaceReferences )
586 return false;
587
588 SCH_SYMBOL* parentSymbol = dyn_cast<SCH_SYMBOL*>( m_parent );
589
590 // The parent might be a LIB_SYMBOL, in which case, we don't
591 // have a sheet path to resolve the reference.
592 if( !parentSymbol )
593 return false;
594
595 if( parentSymbol->Matches( aSearchData, aAuxData ) )
596 return true;
597
598 wxASSERT( aAuxData );
599
600 // Take sheet path into account which effects the reference field and the unit for
601 // symbols with multiple parts.
602 if( aAuxData )
603 {
604 SCH_SHEET_PATH* sheet = (SCH_SHEET_PATH*) aAuxData;
605 text = parentSymbol->GetRef( sheet );
606
607 if( SCH_ITEM::Matches( text, aSearchData ) )
608 return true;
609
610 if( parentSymbol->GetUnitCount() > 1 )
611 text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( sheet ) );
612 }
613 }
614
615 return SCH_ITEM::Matches( text, aSearchData );
616}
617
618
619void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks, wxStyledTextEvent& aEvent ) const
620{
621 SCH_ITEM* parent = dynamic_cast<SCH_ITEM*>( GetParent() );
622 SCHEMATIC* schematic = parent ? parent->Schematic() : nullptr;
623
624 if( !schematic )
625 return;
626
627 wxStyledTextCtrl* scintilla = aScintillaTricks->Scintilla();
628 int key = aEvent.GetKey();
629
630 wxArrayString autocompleteTokens;
631 int pos = scintilla->GetCurrentPos();
632 int start = scintilla->WordStartPosition( pos, true );
633 wxString partial;
634
635 // Multi-line fields are not allowed. So remove '\n' if entered.
636 if( key == '\n' )
637 {
638 wxString text = scintilla->GetText();
639 int currpos = scintilla->GetCurrentPos();
640 text.Replace( wxS( "\n" ), wxS( "" ) );
641 scintilla->SetText( text );
642 scintilla->GotoPos( currpos - 1 );
643 return;
644 }
645
646 auto textVarRef =
647 [&]( int pt )
648 {
649 return pt >= 2 && scintilla->GetCharAt( pt - 2 ) == '$' && scintilla->GetCharAt( pt - 1 ) == '{';
650 };
651
652 // Check for cross-reference
653 if( start > 1 && scintilla->GetCharAt( start - 1 ) == ':' )
654 {
655 int refStart = scintilla->WordStartPosition( start - 1, true );
656
657 if( textVarRef( refStart ) )
658 {
659 partial = scintilla->GetRange( start, pos );
660
661 wxString ref = scintilla->GetRange( refStart, start - 1 );
662
663 if( ref == wxS( "OP" ) )
664 {
665 // SPICE operating points use ':' syntax for ports
666 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent ) )
667 {
668 NULL_REPORTER devnull;
669 SCH_SHEET_PATH& sheet = schematic->CurrentSheet();
670 wxString variant = schematic->GetCurrentVariant();
671 SIM_LIB_MGR mgr( &schematic->Project() );
672
673 std::vector<EMBEDDED_FILES*> embeddedFilesStack;
674 embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
675
676 if( EMBEDDED_FILES* symbolEmbeddedFiles = symbol->GetEmbeddedFiles() )
677 {
678 embeddedFilesStack.push_back( symbolEmbeddedFiles );
679 symbol->GetLibSymbolRef()->AppendParentEmbeddedFiles( embeddedFilesStack );
680 }
681
682 mgr.SetFilesStack( std::move( embeddedFilesStack ) );
683
684 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, true, 0, variant, devnull ).model;
685
686 for( wxString pin : model.GetPinNames() )
687 {
688 if( pin.StartsWith( '<' ) && pin.EndsWith( '>' ) )
689 autocompleteTokens.push_back( pin.Mid( 1, pin.Length() - 2 ) );
690 else
691 autocompleteTokens.push_back( pin );
692 }
693
694 // add the synthetic port for power measurements
695 autocompleteTokens.push_back( wxT( "power" ) );
696 }
697 }
698 else
699 {
701 SCH_SYMBOL* refSymbol = nullptr;
702
703 schematic->Hierarchy().GetSymbols( refs );
704
705 for( size_t jj = 0; jj < refs.GetCount(); jj++ )
706 {
707 if( refs[jj].GetSymbol()->GetRef( &refs[jj].GetSheetPath(), true ) == ref )
708 {
709 refSymbol = refs[jj].GetSymbol();
710 break;
711 }
712 }
713
714 if( refSymbol )
715 refSymbol->GetContextualTextVars( &autocompleteTokens );
716 }
717 }
718 }
719 else if( textVarRef( start ) )
720 {
721 partial = scintilla->GetTextRange( start, pos );
722
723 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent );
724 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( parent );
725 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( parent );
726
727 if( symbol )
728 {
729 symbol->GetContextualTextVars( &autocompleteTokens );
730
731 if( schematic->CurrentSheet().Last() )
732 schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
733 }
734
735 if( sheet )
736 sheet->GetContextualTextVars( &autocompleteTokens );
737
738 if( label )
739 label->GetContextualTextVars( &autocompleteTokens );
740
741 for( std::pair<wxString, wxString> entry : schematic->Project().GetTextVars() )
742 autocompleteTokens.push_back( entry.first );
743 }
744
745 aScintillaTricks->DoAutocomplete( partial, autocompleteTokens );
746 scintilla->SetFocus();
747}
748
749
751{
752 // See comments in SCH_FIELD::Replace(), below.
754 return false;
755
756 return true;
757}
758
759
760bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
761{
762 bool replaceReferences = false;
763
764 try
765 {
766 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
767 replaceReferences = schSearchData.replaceReferences;
768 }
769 catch( const std::bad_cast& )
770 {
771 }
772
773 wxString text;
774 bool isReplaced = false;
775
776 if( m_id == FIELD_T::REFERENCE && m_parent && m_parent->Type() == SCH_SYMBOL_T )
777 {
778 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
779
780 if( !replaceReferences )
781 return false;
782
783 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in refdes." ) );
784
785 text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
786 isReplaced = EDA_ITEM::Replace( aSearchData, text );
787
788 if( isReplaced )
789 parentSymbol->SetRef( (SCH_SHEET_PATH*) aAuxData, text );
790 }
791 else
792 {
793 isReplaced = EDA_TEXT::Replace( aSearchData );
794
795 if( m_id == FIELD_T::SHEET_FILENAME && isReplaced )
796 {
797 // If we allowed this we'd have a bunch of work to do here, including warning
798 // about it not being undoable, checking for recursive hierarchies, reloading
799 // sheets, etc. See DIALOG_SHEET_PROPERTIES::TransferDataFromWindow().
800 }
801 }
802
803 return isReplaced;
804}
805
806
807void SCH_FIELD::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
808{
810
811 if( GetTextAngle().IsVertical() )
812 {
813 switch( horizJustify )
814 {
816 if( aRotateCCW )
818
819 break;
820
822 if( aRotateCCW )
824
825 break;
826
829 break;
830 }
831
833 }
834 else if( GetTextAngle().IsHorizontal() )
835 {
836 switch( horizJustify )
837 {
839 if( !aRotateCCW )
841
842 break;
843
845 if( !aRotateCCW )
847
848 break;
849
852 break;
853 }
854
856 }
857 else
858 {
859 wxFAIL_MSG( wxString::Format( wxT( "SCH_FIELD text angle is not horizontal or vertical: %f" ),
860 GetTextAngle().AsDegrees() ) );
861 }
862
863 VECTOR2I pt = GetPosition();
864 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
865 SetPosition( pt );
866}
867
868
870{
871 int x = GetTextPos().x;
872
873 x -= aCenter;
874 x *= -1;
875 x += aCenter;
876
877 SetTextX( x );
878}
879
880
882{
883 int y = GetTextPos().y;
884
885 y -= aCenter;
886 y *= -1;
887 y += aCenter;
888
889 SetTextY( y );
890}
891
892
893void SCH_FIELD::BeginEdit( const VECTOR2I& aPosition )
894{
895 SetTextPos( aPosition );
896}
897
898
899void SCH_FIELD::CalcEdit( const VECTOR2I& aPosition )
900{
901 SetTextPos( aPosition );
902}
903
904
905wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
906{
907 wxString content = aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() );
908
909 if( content.IsEmpty() )
910 {
911 return wxString::Format( _( "Field %s (empty)" ), UnescapeString( GetName() ) );
912 }
913 else
914 {
915 return wxString::Format( _( "Field %s '%s'" ), UnescapeString( GetName() ), content );
916 }
917}
918
919
920void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
921{
922 wxString msg;
923
924 aList.emplace_back( _( "Symbol Field" ), UnescapeString( GetName() ) );
925
926 // Don't use GetShownText() here; we want to show the user the variable references
927 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
928
929 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
930
931 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
932
933 aList.emplace_back( _( "Style" ), GetTextStyleName() );
934
935 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
936
937 switch( GetHorizJustify() )
938 {
939 case GR_TEXT_H_ALIGN_LEFT: msg = _( "Left" ); break;
940 case GR_TEXT_H_ALIGN_CENTER: msg = _( "Center" ); break;
941 case GR_TEXT_H_ALIGN_RIGHT: msg = _( "Right" ); break;
943 }
944
945 aList.emplace_back( _( "H Justification" ), msg );
946
947 switch( GetVertJustify() )
948 {
949 case GR_TEXT_V_ALIGN_TOP: msg = _( "Top" ); break;
950 case GR_TEXT_V_ALIGN_CENTER: msg = _( "Center" ); break;
951 case GR_TEXT_V_ALIGN_BOTTOM: msg = _( "Bottom" ); break;
953 }
954
955 aList.emplace_back( _( "V Justification" ), msg );
956}
957
958
960{
962 return true;
963
965 return true;
966
967 return IsURL( GetShownText( false ) );
968}
969
970
971void SCH_FIELD::DoHypertextAction( EDA_DRAW_FRAME* aFrame, const VECTOR2I& aMousePos ) const
972{
973 constexpr int START_ID = 1;
974
975 wxString href;
976
978 {
979 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
980 SCH_SHEET_PATH* sheet = &label->Schematic()->CurrentSheet();
981 wxMenu menu;
982
983 std::vector<std::pair<wxString, wxString>> pages;
984
985 label->GetIntersheetRefs( sheet, &pages );
986
987 for( int i = 0; i < (int) pages.size(); ++i )
988 {
989 menu.Append( i + START_ID,
990 wxString::Format( _( "Go to Page %s (%s)" ), pages[i].first, pages[i].second ) );
991 }
992
993 menu.AppendSeparator();
994 menu.Append( 999 + START_ID, _( "Back to Previous Selected Sheet" ) );
995
996 int sel = aFrame->GetPopupMenuSelectionFromUser( menu ) - START_ID;
997
998 if( sel >= 0 && sel < (int) pages.size() )
999 href = wxT( "#" ) + pages[sel].first;
1000 else if( sel == 999 )
1002 }
1003 else if( IsURL( GetShownText( false ) ) || m_name == SIM_LIBRARY::LIBRARY_FIELD )
1004 {
1005 href = GetShownText( false );
1006 }
1007
1008 if( !href.IsEmpty() )
1009 {
1011 navTool->HypertextCommand( href );
1012 }
1013}
1014
1015
1016void SCH_FIELD::SetName( const wxString& aName )
1017{
1018 m_name = aName;
1020
1021 if( m_isGeneratedField )
1022 EDA_TEXT::SetText( aName );
1023}
1024
1025
1026void SCH_FIELD::SetText( const wxString& aText )
1027{
1028 // Don't allow modification of text value of generated fields.
1029 if( m_isGeneratedField )
1030 return;
1031
1032 // Mandatory fields should not have leading or trailing whitespace.
1033 if( IsMandatory() )
1034 EDA_TEXT::SetText( aText.Strip( wxString::both ) );
1035 else
1036 EDA_TEXT::SetText( aText );
1037}
1038
1039
1040void SCH_FIELD::SetText( const wxString& aText, const SCH_SHEET_PATH* aPath, const wxString& aVariantName )
1041{
1042 wxCHECK( m_parent, /* void */ );
1043
1044 if( m_isGeneratedField )
1045 return;
1046
1047 wxString tmp = aText;
1048
1049 if( IsMandatory() )
1050 tmp = aText.Strip( wxString::both ) ;
1051
1052 switch( m_parent->Type() )
1053 {
1054 case SCH_SYMBOL_T:
1055 {
1056 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1057 wxCHECK( symbol, /* void */ );
1058 symbol->SetFieldText( GetName(), aText, aPath, aVariantName );
1059 break;
1060 }
1061
1062 case SCH_SHEET_T:
1063 {
1064 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1065 wxCHECK( sheet, /* void */ );
1066 sheet->SetFieldText( GetName(), aText, aPath, aVariantName );
1067 break;
1068 }
1069
1070 default:
1071 SCH_FIELD::SetText( aText );
1072 break;
1073 }
1074}
1075
1076
1077wxString SCH_FIELD::GetText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1078{
1079 wxString retv;
1080
1081 wxCHECK( aPath && m_parent, retv );
1082
1083 switch( m_parent->Type() )
1084 {
1085 case SCH_SYMBOL_T:
1086 {
1087 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
1088 wxCHECK( symbol, retv );
1089 retv = symbol->GetFieldText( GetName(), aPath, aVariantName );
1090 break;
1091 }
1092
1093 case SCH_SHEET_T:
1094 {
1095 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
1096 wxCHECK( sheet, retv );
1097 retv = sheet->GetFieldText( GetName(), aPath, aVariantName );
1098 break;
1099 }
1100
1101 default:
1102 retv = GetText();
1103 break;
1104 }
1105
1106 return retv;
1107}
1108
1109
1110wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
1111{
1112 if( m_parent && m_parent->IsType( labelTypes ) )
1113 return SCH_LABEL_BASE::GetDefaultFieldName( m_name, aUseDefaultName );
1114
1115 if( IsMandatory() )
1116 return GetCanonicalFieldName( m_id );
1117 else if( m_name.IsEmpty() && aUseDefaultName )
1119 else
1120 return m_name;
1121}
1122
1123
1125{
1126 if( m_parent && m_parent->IsType( labelTypes ) )
1127 {
1128 // These should be stored in canonical format, but just in case:
1129 if( m_name == _( "Net Class" ) || m_name == wxT( "Net Class" ) )
1130 return wxT( "Netclass" );
1131 }
1132
1133 if( IsMandatory() )
1134 return GetCanonicalFieldName( m_id );
1135
1136 return m_name;
1137}
1138
1139
1141{
1142 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1143 {
1144 switch( m_id )
1145 {
1149 default: return BITMAPS::text;
1150 }
1151 }
1152
1153 return BITMAPS::text;
1154}
1155
1156
1157bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1158{
1159 if( GetShownText( true ).IsEmpty() )
1160 return false;
1161
1162 BOX2I rect = GetBoundingBox();
1163
1164 // Text in symbol editor can have additional chars (ie: reference designators U? or U?A)
1165 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1166 {
1167 SCH_FIELD temp( *this );
1168 temp.SetText( GetFullText() );
1169 rect = temp.GetBoundingBox();
1170 }
1171
1172 rect.Inflate( aAccuracy );
1173
1174 if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1175 {
1176 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1177 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1178 }
1179
1180 return rect.Contains( aPosition );
1181}
1182
1183
1184bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1185{
1186 if( GetShownText( true ).IsEmpty() )
1187 return false;
1188
1189 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1190 return false;
1191
1192 BOX2I rect = aRect;
1193
1194 rect.Inflate( aAccuracy );
1195
1196 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1197 {
1198 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1199 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1200 }
1201
1202 if( aContained )
1203 return rect.Contains( GetBoundingBox() );
1204
1205 return rect.Intersects( GetBoundingBox() );
1206}
1207
1208
1209bool SCH_FIELD::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1210{
1211 if( GetShownText( true ).IsEmpty() )
1212 return false;
1213
1214 if( m_flags & ( STRUCT_DELETED | SKIP_STRUCT ) )
1215 return false;
1216
1217 BOX2I bbox = GetBoundingBox();
1218
1219 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1220 {
1221 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1222 bbox.Offset( label->GetSchematicTextOffset( nullptr ) );
1223 }
1224
1225 return KIGEOM::BoxHitTest( aPoly, bbox, aContained );
1226}
1227
1228
1229void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit, int aBodyStyle,
1230 const VECTOR2I& aOffset, bool aDimmed )
1231{
1232 wxString text;
1233
1234 if( Schematic() )
1235 text = GetShownText( &Schematic()->CurrentSheet(), true, 0, Schematic()->GetCurrentVariant() );
1236 else
1237 text = GetShownText( true );
1238
1239 if( ( !IsVisible() && !IsForceVisible() ) || text.IsEmpty() || aBackground )
1240 return;
1241
1242 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1243 COLOR4D color = renderSettings->GetLayerColor( GetLayer() );
1244 int penWidth = GetEffectiveTextPenWidth( renderSettings->GetDefaultPenWidth() );
1245
1246 COLOR4D bg = renderSettings->GetBackgroundColor();
1247
1248 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1249 bg = COLOR4D::WHITE;
1250
1251 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1252 color = GetTextColor();
1253
1254 if( color.m_text && Schematic() )
1255 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1256
1257 if( aDimmed )
1258 {
1259 color.Desaturate();
1260 color = color.Mix( bg, 0.5f );
1261 }
1262
1263 penWidth = std::max( penWidth, renderSettings->GetMinPenWidth() );
1264
1265 // clamp the pen width to be sure the text is readable
1266 penWidth = std::min( penWidth, std::min( GetTextSize().x, GetTextSize().y ) / 4 );
1267
1268 if( !IsVisible() && !renderSettings->m_ShowHiddenFields )
1269 return;
1270
1271 // Calculate the text orientation, according to the symbol orientation/mirror
1272 EDA_ANGLE orient = GetTextAngle();
1273 VECTOR2I textpos = GetTextPos();
1275 GR_TEXT_V_ALIGN_T vjustify = GetVertJustify();
1276
1277 if( renderSettings->m_Transform.y1 ) // Rotate symbol 90 deg.
1278 {
1279 if( orient.IsHorizontal() )
1280 orient = ANGLE_VERTICAL;
1281 else
1282 orient = ANGLE_HORIZONTAL;
1283 }
1284
1285 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1286 {
1287 /*
1288 * Calculate the text justification, according to the symbol orientation/mirror. This is
1289 * a bit complicated due to cumulative calculations:
1290 * - numerous cases (mirrored or not, rotation)
1291 * - the plotter's Text() function will also recalculate H and V justifications according
1292 * to the text orientation
1293 * - when a symbol is mirrored the text is not, and justifications become a nightmare
1294 *
1295 * So the easier way is to use no justifications (centered text) and use GetBoundingBox
1296 * to know the text coordinate considered as centered.
1297 */
1298 hjustify = GR_TEXT_H_ALIGN_CENTER;
1299 vjustify = GR_TEXT_V_ALIGN_CENTER;
1300 textpos = GetBoundingBox().Centre();
1301 }
1302 else if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1303 {
1304 // Library-symbol exports (CLI/symbol editor) provide an item offset in the same coordinate
1305 // frame as body graphics/pins. Apply the same transform+offset pipeline to field text.
1306 textpos = renderSettings->TransformCoordinate( textpos ) + aOffset;
1307 }
1308 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1309 {
1310 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_parent );
1311 textpos += label->GetSchematicTextOffset( renderSettings );
1312 }
1313 else if( m_parent && m_parent->Type() == SCH_DIRECTIVE_LABEL_T )
1314 {
1315 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( m_parent );
1316 std::shared_ptr<NETCLASS> nc = label->GetEffectiveNetClass();
1317
1318 if( nc && ( nc->GetSchematicColor() != COLOR4D::UNSPECIFIED ) && aPlotter->GetColorMode() )
1319 color = nc->GetSchematicColor();
1320 }
1321
1322 KIFONT::FONT* font = GetDrawFont( renderSettings );
1324 attrs.m_StrokeWidth = penWidth;
1325 attrs.m_Halign = hjustify;
1326 attrs.m_Valign = vjustify;
1327 attrs.m_Angle = orient;
1328 attrs.m_Multiline = false;
1329
1330 aPlotter->PlotText( textpos, color, text, attrs, font, GetFontMetrics() );
1331
1333 {
1334 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( m_parent ) )
1335 {
1336 std::vector<std::pair<wxString, wxString>> pages;
1337 std::vector<wxString> pageHrefs;
1338
1339 label->GetIntersheetRefs( &Schematic()->CurrentSheet(), &pages );
1340
1341 for( const auto& [pageNumber, sheetName] : pages )
1342 pageHrefs.push_back( wxT( "#" ) + pageNumber );
1343
1344 BOX2I bbox = GetBoundingBox();
1345 bbox.Offset( label->GetSchematicTextOffset( renderSettings ) );
1346
1347 aPlotter->HyperlinkMenu( bbox, pageHrefs );
1348 }
1349 }
1350}
1351
1352
1353void SCH_FIELD::SetPosition( const VECTOR2I& aPosition )
1354{
1355 // Actual positions are calculated by the rotation/mirror transform of the parent symbol
1356 // of the field. The inverse transform is used to calculate the position relative to the
1357 // parent symbol.
1358 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1359 {
1360 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1361 VECTOR2I relPos = aPosition - parentSymbol->GetPosition();
1362
1363 relPos = parentSymbol->GetTransform().InverseTransform().TransformCoordinate( relPos );
1364
1365 SetTextPos( relPos + parentSymbol->GetPosition() );
1366 return;
1367 }
1368
1369 SetTextPos( aPosition );
1370}
1371
1372
1374{
1375 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1376 {
1377 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1378 VECTOR2I relativePos = GetTextPos() - parentSymbol->GetPosition();
1379
1380 relativePos = parentSymbol->GetTransform().TransformCoordinate( relativePos );
1381
1382 return relativePos + parentSymbol->GetPosition();
1383 }
1384
1385 return GetTextPos();
1386}
1387
1388
1390{
1391 return m_parent ? m_parent->GetPosition() : VECTOR2I( 0, 0 );
1392}
1393
1394
1401
1402
1403bool SCH_FIELD::operator<( const SCH_ITEM& aItem ) const
1404{
1405 if( Type() != aItem.Type() )
1406 return Type() < aItem.Type();
1407
1408 auto field = static_cast<const SCH_FIELD*>( &aItem );
1409
1410 if( GetId() != field->GetId() )
1411 return GetId() < field->GetId();
1412
1413 if( GetText() != field->GetText() )
1414 return GetText() < field->GetText();
1415
1416 if( GetLibPosition().x != field->GetLibPosition().x )
1417 return GetLibPosition().x < field->GetLibPosition().x;
1418
1419 if( GetLibPosition().y != field->GetLibPosition().y )
1420 return GetLibPosition().y < field->GetLibPosition().y;
1421
1422 return GetName() < field->GetName();
1423}
1424
1425
1426bool SCH_FIELD::operator==( const SCH_ITEM& aOther ) const
1427{
1428 if( Type() != aOther.Type() )
1429 return false;
1430
1431 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1432
1433 return *this == field;
1434}
1435
1436
1437bool SCH_FIELD::operator==( const SCH_FIELD& aOther ) const
1438{
1439 // Identical fields of different symbols are not equal.
1440 if( !GetParentSymbol() || !aOther.GetParentSymbol()
1441 || GetParentSymbol()->m_Uuid != aOther.GetParentSymbol()->m_Uuid )
1442 {
1443 return false;
1444 }
1445
1446 if( IsMandatory() != aOther.IsMandatory() )
1447 return false;
1448
1449 if( IsMandatory() )
1450 {
1451 if( GetId() != aOther.GetId() )
1452 return false;
1453 }
1454 else
1455 {
1456 if( GetOrdinal() != aOther.GetOrdinal() )
1457 return false;
1458 }
1459
1460 if( GetPosition() != aOther.GetPosition() )
1461 return false;
1462
1463 if( IsGeneratedField() != aOther.IsGeneratedField() )
1464 return false;
1465
1466 if( IsNameShown() != aOther.IsNameShown() )
1467 return false;
1468
1469 if( CanAutoplace() != aOther.CanAutoplace() )
1470 return false;
1471
1472 return EDA_TEXT::operator==( aOther );
1473}
1474
1475
1476double SCH_FIELD::Similarity( const SCH_ITEM& aOther ) const
1477{
1478 if( Type() != aOther.Type() )
1479 return 0.0;
1480
1481 if( m_Uuid == aOther.m_Uuid )
1482 return 1.0;
1483
1484 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1485
1486 double similarity = 0.99; // The UUIDs are different, so we start with non-identity
1487
1488 if( GetId() != field.GetId() )
1489 {
1490 // We don't allow swapping of mandatory fields, so these cannot be the same item
1491 if( IsMandatory() || field.IsMandatory() )
1492 return 0.0;
1493 else
1494 similarity *= 0.5;
1495 }
1496
1497 similarity *= SimilarityBase( aOther );
1498
1499 similarity *= EDA_TEXT::Similarity( field );
1500
1501 if( GetPosition() != field.GetPosition() )
1502 similarity *= 0.5;
1503
1504 if( IsGeneratedField() != field.IsGeneratedField() )
1505 similarity *= 0.5;
1506
1507 if( IsNameShown() != field.IsNameShown() )
1508 similarity *= 0.5;
1509
1510 if( CanAutoplace() != field.CanAutoplace() )
1511 similarity *= 0.5;
1512
1513 return similarity;
1514}
1515
1516
1517int SCH_FIELD::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1518{
1519 wxASSERT( aOther.Type() == SCH_FIELD_T );
1520
1521 int compareFlags = aCompareFlags;
1522
1523 // For ERC tests, the field position has no matter, so do not test it
1524 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC )
1526
1527 int retv = SCH_ITEM::compare( aOther, compareFlags );
1528
1529 if( retv )
1530 return retv;
1531
1532 const SCH_FIELD* tmp = static_cast<const SCH_FIELD*>( &aOther );
1533
1534 // Equality test will vary depending whether or not the field is mandatory. Otherwise,
1535 // sorting is done by ordinal.
1536 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1537 {
1538 // Mandatory fields have fixed ordinals and their names can vary due to translated field
1539 // names. Optional fields have fixed names and their ordinals can vary.
1540 if( IsMandatory() )
1541 {
1542 if( m_id != tmp->m_id )
1543 return (int) m_id - (int) tmp->m_id;
1544 }
1545 else
1546 {
1547 retv = m_name.Cmp( tmp->m_name );
1548
1549 if( retv )
1550 return retv;
1551 }
1552 }
1553 else // assume we're sorting
1554 {
1555 if( m_id != tmp->m_id )
1556 return (int) m_id - (int) tmp->m_id;
1557 }
1558
1559 bool ignoreFieldText = false;
1560
1561 if( m_id == FIELD_T::REFERENCE && !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY ) )
1562 ignoreFieldText = true;
1563
1564 if( m_id == FIELD_T::VALUE && ( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1565 ignoreFieldText = true;
1566
1567 if( !ignoreFieldText )
1568 {
1569 retv = GetText().CmpNoCase( tmp->GetText() );
1570
1571 if( retv != 0 )
1572 return retv;
1573 }
1574
1575 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1576 {
1577 if( GetTextPos().x != tmp->GetTextPos().x )
1578 return GetTextPos().x - tmp->GetTextPos().x;
1579
1580 if( GetTextPos().y != tmp->GetTextPos().y )
1581 return GetTextPos().y - tmp->GetTextPos().y;
1582 }
1583
1584 // For ERC tests, the field size has no matter, so do not test it
1585 if( !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1586 {
1587 if( GetTextWidth() != tmp->GetTextWidth() )
1588 return GetTextWidth() - tmp->GetTextWidth();
1589
1590 if( GetTextHeight() != tmp->GetTextHeight() )
1591 return GetTextHeight() - tmp->GetTextHeight();
1592 }
1593
1594 return 0;
1595}
1596
1597
1598wxString SCH_FIELD::getUnescapedText( const SCH_SHEET_PATH* aPath, const wxString& aVariantName ) const
1599{
1600 // This is the default variant field text for all fields except the reference field.
1601 wxString retv = EDA_TEXT::GetShownText( false );
1602
1603 // Special handling for parent object field instance and variant information.
1604 // Only use the path if it's non-empty; an empty path can't match any instances
1605 if( m_parent && aPath && !aPath->empty() )
1606 {
1607 wxLogTrace( traceSchFieldRendering, " Path is valid and non-empty, parent type=%d", m_parent->Type() );
1608
1609 switch( m_parent->Type() )
1610 {
1611 case SCH_SYMBOL_T:
1612 if( const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( m_parent ) )
1613 {
1614 if( m_id == FIELD_T::REFERENCE )
1615 {
1616 wxLogTrace( traceSchFieldRendering, " Calling GetRef for symbol %s on path %s",
1617 symbol->m_Uuid.AsString(), aPath->Path().AsString() );
1618
1619 retv = symbol->GetRef( aPath, true );
1620
1621 wxLogTrace( traceSchFieldRendering, " GetRef returned: '%s'", retv );
1622 }
1623 else if( !aVariantName.IsEmpty() )
1624 {
1625 // If the variant is not found, fall back to default variant above.
1626 if( std::optional<SCH_SYMBOL_VARIANT> variant = symbol->GetVariant( *aPath, aVariantName ) )
1627 {
1628 // If the field name does not exist in the variant, fall back to the default variant above.
1629 if( variant->m_Fields.contains( GetName() ) )
1630 retv = variant->m_Fields[GetName()];
1631 }
1632 }
1633 }
1634
1635 break;
1636
1637 case SCH_SHEET_T:
1638 break;
1639
1640 default:
1641 break;
1642 }
1643 }
1644
1645 return retv;
1646}
1647
1648
1649static struct SCH_FIELD_DESC
1650{
1652 {
1653 // These are defined in EDA_TEXT as well but initialization order is
1654 // not defined, so this needs to be conditional. Defining in both
1655 // places leads to duplicate symbols.
1657
1658 if( h_inst.Choices().GetCount() == 0 )
1659 {
1660 h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _HKI( "Left" ) );
1661 h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _HKI( "Center" ) );
1662 h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _HKI( "Right" ) );
1663 }
1664
1666
1667 if( v_inst.Choices().GetCount() == 0 )
1668 {
1669 v_inst.Map( GR_TEXT_V_ALIGN_TOP, _HKI( "Top" ) );
1670 v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _HKI( "Center" ) );
1671 v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _HKI( "Bottom" ) );
1672 }
1673
1680
1681 const wxString textProps = _HKI( "Text Properties" );
1682
1683 auto horiz = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_H_ALIGN_T>( _HKI( "Horizontal Justification" ),
1686
1687 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ), horiz, textProps );
1688
1689 auto vert = new PROPERTY_ENUM<SCH_FIELD, GR_TEXT_V_ALIGN_T>( _HKI( "Vertical Justification" ),
1692
1693 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ), vert, textProps );
1694
1695 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Show Field Name" ), &SCH_FIELD::SetNameShown,
1697
1698 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Allow Autoplacement" ), &SCH_FIELD::SetCanAutoplace,
1700
1701 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
1702 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
1703 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
1704 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
1705 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
1706
1707
1710 _HKI( "Text Properties" ) );
1711
1712 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
1713
1714 auto isNotGeneratedField = []( INSPECTABLE* aItem ) -> bool
1715 {
1716 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1717 return !field->IsGeneratedField();
1718
1719 return true;
1720 };
1721
1723 isNotGeneratedField );
1724
1725
1726 auto isNonMandatoryField = []( INSPECTABLE* aItem ) -> bool
1727 {
1728 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1729 return !field->IsMandatory();
1730
1731 return false;
1732 };
1733
1734 propMgr.OverrideAvailability( TYPE_HASH( SCH_FIELD ), TYPE_HASH( SCH_ITEM ), _HKI( "Private" ),
1735 isNonMandatoryField );
1736 }
1738
1739
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
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:527
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:111
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:538
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:412
EDA_ITEM * GetParent() const
Definition eda_item.h:113
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:539
bool IsForceVisible() const
Definition eda_item.h:217
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:80
int GetTextHeight() const
Definition eda_text.h:267
const VECTOR2I & GetTextPos() const
Definition eda_text.h:273
COLOR4D GetTextColor() const
Definition eda_text.h:270
wxString GetTextStyleName() const
bool IsItalic() const
Definition eda_text.h:169
const EDA_ANGLE & GetTextAngle() const
Definition eda_text.h:147
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:546
virtual bool IsVisible() const
Definition eda_text.h:187
void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:590
void SetTextX(int aX)
Definition eda_text.cpp:596
KIFONT::FONT * GetFont() const
Definition eda_text.h:247
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:447
void SetTextY(int aY)
Definition eda_text.cpp:602
EDA_TEXT & operator=(const EDA_TEXT &aItem)
Definition eda_text.cpp:164
int GetTextWidth() const
Definition eda_text.h:264
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:755
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:431
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:200
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition eda_text.cpp:500
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:117
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:400
EDA_TEXT(const EDA_IU_SCALE &aIuScale, const wxString &aText=wxEmptyString)
Definition eda_text.cpp:100
virtual void ClearBoundingBoxCache()
Definition eda_text.cpp:689
double Similarity(const EDA_TEXT &aOther) const
virtual void ClearRenderCache()
Definition eda_text.cpp:683
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:231
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:479
void SwapAttributes(EDA_TEXT &aTradingPartner)
Swap the text attributes of the two involved instances.
Definition eda_text.cpp:466
bool IsBold() const
Definition eda_text.h:184
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:203
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:109
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:284
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:313
void SwapText(EDA_TEXT &aTradingPartner)
Definition eda_text.cpp:459
bool operator==(const EDA_TEXT &aRhs) const
Definition eda_text.h:398
VECTOR2I GetTextSize() const
Definition eda_text.h:261
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:423
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:219
A singleton reporter that reports to nowhere.
Definition reporter.h:216
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
virtual std::map< wxString, wxString > & GetTextVars() const
Definition project.cpp:120
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.
PROPERTY_BASE & ReplaceProperty(PROPERTY_BASE *aProperty, const wxString &aGroup)
Replace an existing 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.
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:88
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:103
wxString GetCurrentVariant() const
Return the current variant being edited.
EMBEDDED_FILES * GetEmbeddedFiles() override
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:187
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:350
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.
std::vector< std::unique_ptr< KIFONT::GLYPH > > m_renderCache
Definition sch_field.h:348
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:167
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:338
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:206
bool m_autoAdded
Was this field automatically added to a LIB_SYMBOL?
Definition sch_field.h:343
double Similarity(const SCH_ITEM &aItem) const override
Return a measure of how likely the other object is to represent the same object.
bool IsGeneratedField() const
Generated fields are fields whose names are variables like ${VAR}.
Definition sch_field.h:215
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:116
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:120
void SetCanAutoplace(bool aCanPlace)
Definition sch_field.h:218
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:340
int m_ordinal
Sort order for non-mandatory fields.
Definition sch_field.h:335
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:334
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.
VECTOR2I GetLibPosition() const
Definition sch_field.h:262
void setId(FIELD_T aId)
int GetOrdinal() const
Definition sch_field.h:122
bool IsEmpty()
Return true if both the name and value of the field are empty.
Definition sch_field.h:159
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) const
bool m_renderCacheValid
Definition sch_field.h:346
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:168
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)
VECTOR2I m_renderCachePos
Definition sch_field.h:347
bool CanAutoplace() const
Definition sch_field.h:217
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:344
void OnScintillaCharAdded(SCINTILLA_TRICKS *aScintillaTricks, wxStyledTextEvent &aEvent) const
wxString m_name
Definition sch_field.h:336
void SetNameShown(bool aShown=true)
Definition sch_field.h:207
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:339
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:80
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.h:727
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:260
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:254
friend class LIB_SYMBOL
Definition sch_item.h:798
@ SKIP_TST_POS
Definition sch_item.h:710
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition sch_item.cpp:509
void SetLayer(SCH_LAYER_ID aLayer)
Definition sch_item.h:342
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition sch_item.h:341
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:703
const wxString & GetDefaultFont(const RENDER_SETTINGS *aSettings) const
Definition sch_item.cpp:751
bool IsConnectivityDirty() const
Definition sch_item.h:588
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:781
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:363
const KIFONT::METRICS & GetFontMetrics() const
Definition sch_item.cpp:764
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:380
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, bool aIncludePowerSymbols=true, 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: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:867
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
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().
wxString GetGeneratedFieldDisplayName(const wxString &aSource)
Returns any variables unexpanded, e.g.
Definition common.cpp:323
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:449
@ LAYER_SHEETNAME
Definition layer_ids.h:472
@ LAYER_VALUEPART
Definition layer_ids.h:461
@ LAYER_FIELDS
Definition layer_ids.h:462
@ LAYER_SHEETFIELDS
Definition layer_ids.h:474
@ LAYER_REFERENCEPART
Definition layer_ids.h:460
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:464
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:495
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:463
@ LAYER_SHEETFILENAME
Definition layer_ids.h:473
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:46
static struct SCH_FIELD_DESC _SCH_FIELD_DESC
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:152
@ SCH_SYMBOL_T
Definition typeinfo.h:176
@ SCH_FIELD_T
Definition typeinfo.h:154
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:175
@ SCH_LABEL_T
Definition typeinfo.h:171
@ SCH_SHEET_T
Definition typeinfo.h:179
@ SCH_LABEL_LOCATE_ANY_T
Definition typeinfo.h:195
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:172
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
Definition typeinfo.h:61
#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:695