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