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