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>
35#include <symbol_library.h>
37#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
47SCH_FIELD::SCH_FIELD( const VECTOR2I& aPos, int aFieldId, SCH_ITEM* aParent,
48 const wxString& aName ) :
49 SCH_ITEM( aParent, SCH_FIELD_T ),
50 EDA_TEXT( schIUScale, wxEmptyString ),
51 m_id( 0 ),
52 m_showName( false ),
53 m_allowAutoPlace( true ),
54 m_isNamedVariable( false ),
55 m_autoAdded( false ),
56 m_showInChooser( true ),
57 m_renderCacheValid( false ),
58 m_lastResolvedColor( COLOR4D::UNSPECIFIED )
59{
60 if( !aName.IsEmpty() )
61 SetName( aName );
62 else if( aParent && aParent->Type() == SCH_SYMBOL_T )
64 else if( aParent && aParent->Type() == SCH_SHEET_T )
66
67 SetTextPos( aPos );
68 SetId( aFieldId ); // will also set the layer
69 SetVisible( true );
70}
71
72
73SCH_FIELD::SCH_FIELD( SCH_ITEM* aParent, int aFieldId, const wxString& aName ) :
74 SCH_FIELD( VECTOR2I(), aFieldId, aParent, aName )
75{
76}
77
78
80 SCH_FIELD( VECTOR2I(), INVALID_FIELD, nullptr, wxEmptyString )
81{
82 SCH_ITEM::operator=( *aText );
83 EDA_TEXT::operator=( *aText );
84}
85
86
88 SCH_ITEM( aField ),
89 EDA_TEXT( aField )
90{
91 m_private = aField.m_private;
92 m_id = aField.m_id;
93 m_name = aField.m_name;
94 m_showName = aField.m_showName;
97 m_autoAdded = aField.m_autoAdded;
99
100 m_renderCache.clear();
101
102 for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
103 {
104 if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
105 m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
106 else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
107 m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
108 }
109
112
114}
115
116
118{
119 EDA_TEXT::operator=( aField );
120
121 m_private = aField.m_private;
122 m_id = aField.m_id;
123 m_name = aField.m_name;
124 m_showName = aField.m_showName;
127
128 m_renderCache.clear();
129
130 for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
131 {
132 if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
133 m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
134 else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
135 m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
136 }
137
140
142
143 return *this;
144}
145
146
148{
149 return new SCH_FIELD( *this );
150}
151
152
153void SCH_FIELD::Copy( SCH_FIELD* aTarget ) const
154{
155 *aTarget = *this;
156}
157
158
159void SCH_FIELD::SetId( int aId )
160{
161 m_id = aId;
162
163 if( m_parent && m_parent->Type() == SCH_SHEET_T )
164 {
165 switch( m_id )
166 {
167 case SHEETNAME: SetLayer( LAYER_SHEETNAME ); break;
169 default: SetLayer( LAYER_SHEETFIELDS ); break;
170 }
171 }
172 else if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
173 {
174 switch( m_id )
175 {
177 case VALUE_FIELD: SetLayer( LAYER_VALUEPART ); break;
178 default: SetLayer( LAYER_FIELDS ); break;
179 }
180 }
181 else if( m_parent && m_parent->IsType( labelTypes ) )
182 {
183 // We can't use defined IDs for labels because there can be multiple net class
184 // assignments.
185
186 if( GetCanonicalName() == wxT( "Netclass" )
187 || GetCanonicalName() == wxT( "Component Class" ) )
188 {
190 }
191 else if( GetCanonicalName() == wxT( "Intersheetrefs" ) )
192 {
194 }
195 else
196 {
198 }
199 }
200}
201
202
204{
206}
207
208
209wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText,
210 int aDepth ) const
211{
212 std::function<bool( wxString* )> libSymbolResolver =
213 [&]( wxString* token ) -> bool
214 {
215 LIB_SYMBOL* symbol = static_cast<LIB_SYMBOL*>( m_parent );
216 return symbol->ResolveTextVar( token, aDepth + 1 );
217 };
218
219 std::function<bool( wxString* )> symbolResolver =
220 [&]( wxString* token ) -> bool
221 {
222 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( m_parent );
223 return symbol->ResolveTextVar( aPath, token, aDepth + 1 );
224 };
225
226 std::function<bool( wxString* )> schematicResolver =
227 [&]( wxString* token ) -> bool
228 {
229 if( !aPath )
230 return false;
231
232 if( SCHEMATIC* schematic = Schematic() )
233 return schematic->ResolveTextVar( aPath, token, aDepth + 1 );
234
235 return false;
236 };
237
238 std::function<bool( wxString* )> sheetResolver =
239 [&]( wxString* token ) -> bool
240 {
241 if( !aPath )
242 return false;
243
244 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
245
246 SCHEMATIC* schematic = Schematic();
247 SCH_SHEET_PATH path = *aPath;
248 path.push_back( sheet );
249
250 bool retval = sheet->ResolveTextVar( &path, token, aDepth + 1 );
251
252 if( schematic )
253 retval |= schematic->ResolveTextVar( &path, token, aDepth + 1 );
254
255 return retval;
256 };
257
258 std::function<bool( wxString* )> labelResolver =
259 [&]( wxString* token ) -> bool
260 {
261 if( !aPath )
262 return false;
263
264 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
265 return label->ResolveTextVar( aPath, token, aDepth + 1 );
266 };
267
268 wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
269
270 if( IsNameShown() && aAllowExtraText )
271 text = GetShownName() << wxS( ": " ) << text;
272
273 if( text == wxS( "~" ) ) // Legacy placeholder for empty string
274 text = wxS( "" );
275
276 // The iteration here it to allow for nested variables in the
277 // text strings (e.g. ${${VAR}}). Although the symbols and sheets
278 // and labels recurse, text that is none of those types such as text
279 // boxes and labels do not. This only loops if there is still a
280 // variable to resolve.
281 for( int ii = aDepth;
282 ii < ADVANCED_CFG::GetCfg().m_ResolveTextRecursionDepth && text.Contains( wxT( "${" ) );
283 ++ii )
284 {
285 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
286 text = ExpandTextVars( text, &libSymbolResolver );
287 else if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
288 text = ExpandTextVars( text, &symbolResolver );
289 else if( m_parent && m_parent->Type() == SCH_SHEET_T )
290 text = ExpandTextVars( text, &sheetResolver );
291 else if( m_parent && m_parent->IsType( labelTypes ) )
292 text = ExpandTextVars( text, &labelResolver );
293 else if( Schematic() )
294 {
296 text = ExpandTextVars( text, &schematicResolver );
297 }
298 }
299
300 // WARNING: the IDs of FIELDS and SHEETS overlap, so one must check *both* the
301 // id and the parent's type.
302
303 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
304 {
305 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
306
307 if( m_id == REFERENCE_FIELD && aPath )
308 {
309 // For more than one part per package, we must add the part selection
310 // A, B, ... or 1, 2, .. to the reference.
311 if( parentSymbol->GetUnitCount() > 1 )
312 text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( aPath ) );
313 }
314 }
315 else if( m_parent && m_parent->Type() == SCH_SHEET_T )
316 {
317 if( m_id == SHEETFILENAME && aAllowExtraText && !IsNameShown() )
318 text = _( "File:" ) + wxS( " " ) + text;
319 }
320
321 return text;
322}
323
324
325wxString SCH_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
326{
327 if( SCHEMATIC* schematic = Schematic() )
328 return GetShownText( &schematic->CurrentSheet(), aAllowExtraText, aDepth );
329 else
330 return GetShownText( nullptr, aAllowExtraText, aDepth );
331}
332
333
334wxString SCH_FIELD::GetFullText( int unit ) const
335{
336 if( GetId() != REFERENCE_FIELD )
337 return GetText();
338
339 wxString text = GetText();
340 text << wxT( "?" );
341
342 if( GetParentSymbol() && GetParentSymbol()->IsMulti() )
343 text << LIB_SYMBOL::LetterSubReference( unit, 'A' );
344
345 return text;
346}
347
348
350{
352}
353
354
356{
358
359 if( !font )
361
362 return font;
363}
364
365
367{
370}
371
372
374{
376 m_renderCacheValid = false;
377}
378
379
380std::vector<std::unique_ptr<KIFONT::GLYPH>>*
381SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forPosition,
382 TEXT_ATTRIBUTES& aAttrs ) const
383{
384 KIFONT::FONT* font = GetFont();
385
386 if( !font )
388
389 if( font->IsOutline() )
390 {
391 KIFONT::OUTLINE_FONT* outlineFont = static_cast<KIFONT::OUTLINE_FONT*>( font );
392
393 if( m_renderCache.empty() || !m_renderCacheValid )
394 {
395 m_renderCache.clear();
396
397 outlineFont->GetLinesAsGlyphs( &m_renderCache, forResolvedText, forPosition, aAttrs,
398 GetFontMetrics() );
399
400 m_renderCachePos = forPosition;
401 m_renderCacheValid = true;
402 }
403
404 if( m_renderCachePos != forPosition )
405 {
406 VECTOR2I delta = forPosition - m_renderCachePos;
407
408 for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache )
409 {
410 if( glyph->IsOutline() )
411 static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
412 else
413 static_cast<KIFONT::STROKE_GLYPH*>( glyph.get() )->Move( delta );
414 }
415
416 m_renderCachePos = forPosition;
417 }
418
419 return &m_renderCache;
420 }
421
422 return nullptr;
423}
424
425
426void SCH_FIELD::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
427 const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
428{
429 wxString text;
430
431 if( Schematic() )
432 text = GetShownText( &Schematic()->CurrentSheet(), true );
433 else
434 text = GetShownText( true );
435
436 if( ( !IsVisible() && !IsForceVisible() ) || text.IsEmpty() )
437 return;
438
439 wxDC* DC = aSettings->GetPrintDC();
441 bool blackAndWhiteMode = GetGRForceBlackPenState();
442 int penWidth = GetEffectiveTextPenWidth( aSettings->GetDefaultPenWidth() );
443
444 COLOR4D bg = aSettings->GetBackgroundColor();
445
446 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
447 bg = COLOR4D::WHITE;
448
449 if( IsForceVisible() )
450 bg = aSettings->GetLayerColor( LAYER_HIDDEN );
451
452 if( !blackAndWhiteMode && GetTextColor() != COLOR4D::UNSPECIFIED )
454
455 if( aDimmed )
456 {
457 color.Desaturate( );
458 color = color.Mix( bg, 0.5f );
459 }
460
461 // Calculate the text orientation according to the symbol orientation.
462 EDA_ANGLE orient = GetTextAngle();
463 VECTOR2I textpos = GetTextPos();
466 KIFONT::FONT* font = GetFont();
467
468 if( !font )
469 font = KIFONT::FONT::GetFont( aSettings->GetDefaultFont(), IsBold(), IsItalic() );
470
471 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
472 {
473 textpos = aSettings->TransformCoordinate( GetTextPos() ) + aOffset;
474 }
475 else if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
476 {
477 /*
478 * Calculate the text justification, according to the symbol orientation/mirror.
479 * This is a bit complicated due to cumulative calculations:
480 * - numerous cases (mirrored or not, rotation)
481 * - the GRText function will also recalculate H and V justifications according to the
482 * text orientation.
483 * - when symbol is mirrored, the text is not mirrored and justifications are complicated
484 * to calculate so the easier way is to use no justifications (centered text) and use
485 * GetBoundingBox to know the text coordinate considered as centered
486 */
487 hjustify = GR_TEXT_H_ALIGN_CENTER;
488 vjustify = GR_TEXT_V_ALIGN_CENTER;
489 textpos = GetBoundingBox().Centre() + aOffset;
490
491 if( aSettings->m_Transform.y1 ) // Rotate symbol 90 degrees.
492 {
493 if( orient == ANGLE_HORIZONTAL )
494 orient = ANGLE_VERTICAL;
495 else
496 orient = ANGLE_HORIZONTAL;
497 }
498 }
499 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
500 {
501 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
502 textpos += label->GetSchematicTextOffset( aSettings );
503 }
504
505 GRPrintText( DC, textpos, color, text, orient, GetTextSize(), hjustify, vjustify, penWidth,
506 IsItalic(), IsBold(), font, GetFontMetrics() );
507}
508
509
510void SCH_FIELD::ImportValues( const SCH_FIELD& aSource )
511{
512 SetAttributes( aSource );
513 SetVisible( aSource.IsVisible() );
514 SetNameShown( aSource.IsNameShown() );
515 SetCanAutoplace( aSource.CanAutoplace() );
516}
517
518
520{
521 wxCHECK_RET( aItem && aItem->Type() == SCH_FIELD_T, wxT( "Cannot swap with invalid item." ) );
522
523 SCH_ITEM::SwapFlags( aItem );
524
525 SCH_FIELD* item = static_cast<SCH_FIELD*>( aItem );
526
527 std::swap( m_layer, item->m_layer );
528 std::swap( m_showName, item->m_showName );
529 std::swap( m_allowAutoPlace, item->m_allowAutoPlace );
530 std::swap( m_isNamedVariable, item->m_isNamedVariable );
531 std::swap( m_private, item->m_private );
532 SwapText( *item );
533 SwapAttributes( *item );
534
535 std::swap( m_lastResolvedColor, item->m_lastResolvedColor );
536}
537
538
540{
541 if( GetTextColor() != COLOR4D::UNSPECIFIED )
542 {
544 }
545 else
546 {
547 SCH_LABEL_BASE* parentLabel = dynamic_cast<SCH_LABEL_BASE*>( GetParent() );
548
549 if( parentLabel && !parentLabel->IsConnectivityDirty() )
550 m_lastResolvedColor = parentLabel->GetEffectiveNetClass()->GetSchematicColor();
551 else
553 }
554
555 return m_lastResolvedColor;
556}
557
558
559std::vector<int> SCH_FIELD::ViewGetLayers() const
560{
562}
563
564
566{
567 if( m_parent && ( m_parent->Type() == LIB_SYMBOL_T || m_parent->Type() == SCH_SYMBOL_T ) )
568 {
569 if( m_id == REFERENCE_FIELD )
570 return LAYER_REFERENCEPART;
571 else if( m_id == VALUE_FIELD )
572 return LAYER_VALUEPART;
573 }
574 else if( m_parent && m_parent->Type() == SCH_SHEET_T )
575 {
576 if( m_id == SHEETNAME )
577 return LAYER_SHEETNAME;
578 else if( m_id == SHEETFILENAME )
579 return LAYER_SHEETFILENAME;
580 else
581 return LAYER_SHEETFIELDS;
582 }
583 else if( m_parent && m_parent->Type() == SCH_LABEL_T )
584 {
585 if( GetCanonicalName() == wxT( "Netclass" ) )
586 return LAYER_NETCLASS_REFS;
587 }
588
589 return LAYER_FIELDS;
590}
591
592
594{
595 // Calculate the text orientation according to the symbol orientation.
596 EDA_ANGLE orient = GetTextAngle();
597
598 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
599 {
600 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
601
602 if( parentSymbol && parentSymbol->GetTransform().y1 ) // Rotate symbol 90 degrees.
603 {
604 if( orient.IsHorizontal() )
605 orient = ANGLE_VERTICAL;
606 else
607 orient = ANGLE_HORIZONTAL;
608 }
609 }
610
611 return orient;
612}
613
614
616{
617 BOX2I bbox = GetTextBox();
618
619 // Calculate the bounding box position relative to the parent:
620 VECTOR2I origin = GetParentPosition();
621 VECTOR2I pos = GetTextPos() - origin;
622 VECTOR2I begin = bbox.GetOrigin() - origin;
623 VECTOR2I end = bbox.GetEnd() - origin;
624 RotatePoint( begin, pos, GetTextAngle() );
625 RotatePoint( end, pos, GetTextAngle() );
626
627 // Now, apply the symbol transform (mirror/rot)
628 TRANSFORM transform;
629
630 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
631 transform = static_cast<SCH_SYMBOL*>( m_parent )->GetTransform();
632
633 bbox.SetOrigin( transform.TransformCoordinate( begin ) );
634 bbox.SetEnd( transform.TransformCoordinate( end ) );
635
636 bbox.Move( origin );
637 bbox.Normalize();
638
639 return bbox;
640}
641
642
644{
645 VECTOR2I render_center = GetBoundingBox().Centre();
646 VECTOR2I pos = GetPosition();
647
648 switch( GetHorizJustify() )
649 {
651 if( GetDrawRotation().IsVertical() )
652 return render_center.y > pos.y;
653 else
654 return render_center.x < pos.x;
656 if( GetDrawRotation().IsVertical() )
657 return render_center.y < pos.y;
658 else
659 return render_center.x > pos.x;
660 default:
661 return false;
662 }
663}
664
665
667{
668 GR_TEXT_H_ALIGN_T actualJustify;
669
670 switch( aJustify )
671 {
674 break;
677 break;
678 default:
679 actualJustify = aJustify;
680 }
681
682 SetHorizJustify( actualJustify );
683}
684
685
687{
688 switch( GetHorizJustify() )
689 {
694 default:
696 }
697}
698
699
701{
702 VECTOR2I render_center = GetBoundingBox().Centre();
703 VECTOR2I pos = GetPosition();
704
705 switch( GetVertJustify() )
706 {
708 if( GetDrawRotation().IsVertical() )
709 return render_center.x < pos.x;
710 else
711 return render_center.y < pos.y;
713 if( GetDrawRotation().IsVertical() )
714 return render_center.x > pos.x;
715 else
716 return render_center.y > pos.y;
717 default:
718 return false;
719 }
720}
721
722
724{
725 GR_TEXT_V_ALIGN_T actualJustify;
726
727 switch( aJustify )
728 {
731 break;
734 break;
735 default:
736 actualJustify = aJustify;
737 }
738
739 SetVertJustify( actualJustify );
740}
741
742
744{
745 switch( GetVertJustify() )
746 {
751 default:
753 }
754}
755
756
757bool SCH_FIELD::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
758{
759 bool searchHiddenFields = false;
760 bool searchAndReplace = false;
761 bool replaceReferences = false;
762
763 try
764 {
765 // downcast
766 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
767 searchHiddenFields = schSearchData.searchAllFields;
768 searchAndReplace = schSearchData.searchAndReplace;
769 replaceReferences = schSearchData.replaceReferences;
770 }
771 catch( const std::bad_cast& )
772 {
773 }
774
775 wxString text = UnescapeString( GetText() );
776
777 if( !IsVisible() && !searchHiddenFields )
778 return false;
779
781 {
782 if( searchAndReplace && !replaceReferences )
783 return false;
784
785 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
786 wxASSERT( aAuxData );
787
788 // Take sheet path into account which effects the reference field and the unit for
789 // symbols with multiple parts.
790 if( aAuxData )
791 {
792 SCH_SHEET_PATH* sheet = (SCH_SHEET_PATH*) aAuxData;
793 text = parentSymbol->GetRef( sheet );
794
795 if( SCH_ITEM::Matches( text, aSearchData ) )
796 return true;
797
798 if( parentSymbol->GetUnitCount() > 1 )
799 text << parentSymbol->SubReference( parentSymbol->GetUnitSelection( sheet ) );
800 }
801 }
802
803 return SCH_ITEM::Matches( text, aSearchData );
804}
805
806
808 wxStyledTextEvent &aEvent ) const
809{
810 SCH_ITEM* parent = dynamic_cast<SCH_ITEM*>( GetParent() );
811 SCHEMATIC* schematic = parent ? parent->Schematic() : nullptr;
812
813 if( !schematic )
814 return;
815
816 wxStyledTextCtrl* scintilla = aScintillaTricks->Scintilla();
817 int key = aEvent.GetKey();
818
819 wxArrayString autocompleteTokens;
820 int pos = scintilla->GetCurrentPos();
821 int start = scintilla->WordStartPosition( pos, true );
822 wxString partial;
823
824 // Multi-line fields are not allowed. So remove '\n' if entered.
825 if( key == '\n' )
826 {
827 wxString text = scintilla->GetText();
828 int currpos = scintilla->GetCurrentPos();
829 text.Replace( wxS( "\n" ), wxS( "" ) );
830 scintilla->SetText( text );
831 scintilla->GotoPos( currpos-1 );
832 return;
833 }
834
835 auto textVarRef =
836 [&]( int pt )
837 {
838 return pt >= 2
839 && scintilla->GetCharAt( pt - 2 ) == '$'
840 && scintilla->GetCharAt( pt - 1 ) == '{';
841 };
842
843 // Check for cross-reference
844 if( start > 1 && scintilla->GetCharAt( start - 1 ) == ':' )
845 {
846 int refStart = scintilla->WordStartPosition( start - 1, true );
847
848 if( textVarRef( refStart ) )
849 {
850 partial = scintilla->GetRange( start, pos );
851
852 wxString ref = scintilla->GetRange( refStart, start - 1 );
853
854 if( ref == wxS( "OP" ) )
855 {
856 // SPICE operating points use ':' syntax for ports
857 if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent ) )
858 {
859 NULL_REPORTER devnull;
860 SCH_SHEET_PATH& sheet = schematic->CurrentSheet();
861 SIM_LIB_MGR mgr( &schematic->Prj() );
862 SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, devnull ).model;
863
864 for( wxString pin : model.GetPinNames() )
865 {
866 if( pin.StartsWith( '<' ) && pin.EndsWith( '>' ) )
867 autocompleteTokens.push_back( pin.Mid( 1, pin.Length() - 2 ) );
868 else
869 autocompleteTokens.push_back( pin );
870 }
871 }
872 }
873 else
874 {
876 SCH_SYMBOL* refSymbol = nullptr;
877
878 schematic->Hierarchy().GetSymbols( refs );
879
880 for( size_t jj = 0; jj < refs.GetCount(); jj++ )
881 {
882 if( refs[ jj ].GetSymbol()->GetRef( &refs[ jj ].GetSheetPath(), true ) == ref )
883 {
884 refSymbol = refs[ jj ].GetSymbol();
885 break;
886 }
887 }
888
889 if( refSymbol )
890 refSymbol->GetContextualTextVars( &autocompleteTokens );
891 }
892 }
893 }
894 else if( textVarRef( start ) )
895 {
896 partial = scintilla->GetTextRange( start, pos );
897
898 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( parent );
899 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( parent );
900 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( parent );
901
902 if( symbol )
903 {
904 symbol->GetContextualTextVars( &autocompleteTokens );
905
906 if( schematic->CurrentSheet().Last() )
907 schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
908 }
909
910 if( sheet )
911 sheet->GetContextualTextVars( &autocompleteTokens );
912
913 if( label )
914 label->GetContextualTextVars( &autocompleteTokens );
915
916 for( std::pair<wxString, wxString> entry : schematic->Prj().GetTextVars() )
917 autocompleteTokens.push_back( entry.first );
918 }
919
920 aScintillaTricks->DoAutocomplete( partial, autocompleteTokens );
921 scintilla->SetFocus();
922}
923
924
926{
927 if( m_parent && m_parent->Type() == SCH_SHEET_T )
928 {
929 // See comments in SCH_FIELD::Replace(), below.
930 if( m_id == SHEETFILENAME )
931 return false;
932 }
933 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
934 {
935 if( m_id == 0 /* IntersheetRefs */ )
936 return false;
937 }
938
939 return true;
940}
941
942
943bool SCH_FIELD::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
944{
945 bool replaceReferences = false;
946
947 try
948 {
949 const SCH_SEARCH_DATA& schSearchData = dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
950 replaceReferences = schSearchData.replaceReferences;
951 }
952 catch( const std::bad_cast& )
953 {
954 }
955
956 wxString text;
957 bool isReplaced = false;
958
959 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
960 {
961 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
962
963 switch( m_id )
964 {
965 case REFERENCE_FIELD:
966 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in refdes." ) );
967
968 if( !replaceReferences )
969 return false;
970
971 text = parentSymbol->GetRef( (SCH_SHEET_PATH*) aAuxData );
972 isReplaced = EDA_ITEM::Replace( aSearchData, text );
973
974 if( isReplaced )
975 parentSymbol->SetRef( (SCH_SHEET_PATH*) aAuxData, text );
976
977 break;
978
979 case VALUE_FIELD:
980 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in value field." ) );
981
982 text = parentSymbol->GetField( VALUE_FIELD )->GetText();
983 isReplaced = EDA_ITEM::Replace( aSearchData, text );
984
985 if( isReplaced )
986 parentSymbol->SetValueFieldText( text );
987
988 break;
989
990 case FOOTPRINT_FIELD:
991 wxCHECK_MSG( aAuxData, false, wxT( "Need sheetpath to replace in footprint field." ) );
992
993 text = parentSymbol->GetField( FOOTPRINT_FIELD )->GetText();
994 isReplaced = EDA_ITEM::Replace( aSearchData, text );
995
996 if( isReplaced )
997 parentSymbol->SetFootprintFieldText( text );
998
999 break;
1000
1001 default:
1002 isReplaced = EDA_TEXT::Replace( aSearchData );
1003 }
1004 }
1005 else if( m_parent && m_parent->Type() == SCH_SHEET_T )
1006 {
1007 isReplaced = EDA_TEXT::Replace( aSearchData );
1008
1009 if( m_id == SHEETFILENAME && isReplaced )
1010 {
1011 // If we allowed this we'd have a bunch of work to do here, including warning
1012 // about it not being undoable, checking for recursive hierarchies, reloading
1013 // sheets, etc. See DIALOG_SHEET_PROPERTIES::TransferDataFromWindow().
1014 }
1015 }
1016 else
1017 {
1018 isReplaced = EDA_TEXT::Replace( aSearchData );
1019 }
1020
1021 return isReplaced;
1022}
1023
1024
1025void SCH_FIELD::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
1026{
1028
1029 if( GetTextAngle().IsVertical() )
1030 {
1031 switch( horizJustify )
1032 {
1034 if( aRotateCCW )
1036
1037 break;
1039 if( aRotateCCW )
1041 break;
1044 }
1045
1047 }
1048 else if( GetTextAngle().IsHorizontal() )
1049 {
1050 switch( horizJustify )
1051 {
1053 if( !aRotateCCW )
1055 break;
1057 if( !aRotateCCW )
1059 break;
1062 }
1063
1065 }
1066 else
1067 {
1068 wxASSERT_MSG(
1069 false,
1070 wxString::Format( wxT( "SCH_FIELD text angle is not horizontal or vertical: %d" ),
1071 GetTextAngle().AsDegrees() ) );
1072 }
1073
1074 VECTOR2I pt = GetPosition();
1075 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
1076 SetPosition( pt );
1077}
1078
1079
1081{
1082 int x = GetTextPos().x;
1083
1084 x -= aCenter;
1085 x *= -1;
1086 x += aCenter;
1087
1088 SetTextX( x );
1089}
1090
1091
1093{
1094 int y = GetTextPos().y;
1095
1096 y -= aCenter;
1097 y *= -1;
1098 y += aCenter;
1099
1100 SetTextY( y );
1101}
1102
1103
1104void SCH_FIELD::BeginEdit( const VECTOR2I& aPosition )
1105{
1106 SetTextPos( aPosition );
1107}
1108
1109
1110void SCH_FIELD::CalcEdit( const VECTOR2I& aPosition )
1111{
1112 SetTextPos( aPosition );
1113}
1114
1115
1116wxString SCH_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1117{
1118 return wxString::Format( _( "Field %s '%s'" ),
1120 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
1121}
1122
1123
1124void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1125{
1126 wxString msg;
1127
1128 aList.emplace_back( _( "Symbol Field" ), UnescapeString( GetName() ) );
1129
1130 // Don't use GetShownText() here; we want to show the user the variable references
1131 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
1132
1133 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1134
1135 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1136
1137 aList.emplace_back( _( "Style" ), GetTextStyleName() );
1138
1139 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1140
1141 switch ( GetHorizJustify() )
1142 {
1143 case GR_TEXT_H_ALIGN_LEFT: msg = _( "Left" ); break;
1144 case GR_TEXT_H_ALIGN_CENTER: msg = _( "Center" ); break;
1145 case GR_TEXT_H_ALIGN_RIGHT: msg = _( "Right" ); break;
1147 }
1148
1149 aList.emplace_back( _( "H Justification" ), msg );
1150
1151 switch ( GetVertJustify() )
1152 {
1153 case GR_TEXT_V_ALIGN_TOP: msg = _( "Top" ); break;
1154 case GR_TEXT_V_ALIGN_CENTER: msg = _( "Center" ); break;
1155 case GR_TEXT_V_ALIGN_BOTTOM: msg = _( "Bottom" ); break;
1157 }
1158
1159 aList.emplace_back( _( "V Justification" ), msg );
1160}
1161
1162
1164{
1165 constexpr int START_ID = 1;
1166
1167 if( IsHypertext() )
1168 {
1169 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
1170 SCH_SHEET_PATH* sheet = &label->Schematic()->CurrentSheet();
1171 wxMenu menu;
1172 wxString href;
1173
1174 std::vector<std::pair<wxString, wxString>> pages;
1175
1176 label->GetIntersheetRefs( sheet, &pages );
1177
1178 for( int i = 0; i < (int) pages.size(); ++i )
1179 {
1180 menu.Append( i + START_ID, wxString::Format( _( "Go to Page %s (%s)" ),
1181 pages[i].first,
1182 pages[i].second ) );
1183 }
1184
1185 menu.AppendSeparator();
1186 menu.Append( 999 + START_ID, _( "Back to Previous Selected Sheet" ) );
1187
1188 int sel = aFrame->GetPopupMenuSelectionFromUser( menu ) - START_ID;
1189
1190 if( sel >= 0 && sel < (int) pages.size() )
1191 href = wxT( "#" ) + pages[ sel ].first;
1192 else if( sel == 999 )
1194
1195 if( !href.IsEmpty() )
1196 {
1198 navTool->HypertextCommand( href );
1199 }
1200 }
1201}
1202
1203
1204void SCH_FIELD::SetName( const wxString& aName )
1205{
1206 m_name = aName;
1207 m_isNamedVariable = m_name.StartsWith( wxT( "${" ) );
1208
1209 if( m_isNamedVariable )
1210 EDA_TEXT::SetText( aName );
1211}
1212
1213
1214void SCH_FIELD::SetText( const wxString& aText )
1215{
1216 // Don't allow modification of text value when using named variables
1217 // as field name.
1218 if( m_isNamedVariable )
1219 return;
1220
1221 // Mandatory fields should not have leading or trailing whitespace.
1222 if( IsMandatory() )
1223 EDA_TEXT::SetText( aText.Strip( wxString::both ) );
1224 else
1225 EDA_TEXT::SetText( aText );
1226}
1227
1228
1229wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
1230{
1231 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1232 {
1233 if( IsMandatory() )
1234 return GetCanonicalFieldName( m_id );
1235 else if( m_name.IsEmpty() && aUseDefaultName )
1237 }
1238 else if( m_parent && m_parent->Type() == SCH_SHEET_T )
1239 {
1240 if( IsMandatory() )
1242 else if( m_name.IsEmpty() && aUseDefaultName )
1244 }
1245 else if( m_parent && m_parent->IsType( labelTypes ) )
1246 {
1247 return SCH_LABEL_BASE::GetDefaultFieldName( m_name, aUseDefaultName );
1248 }
1249
1250 return m_name;
1251}
1252
1253
1255{
1256 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1257 {
1258 if( IsMandatory() )
1259 return GetCanonicalFieldName( m_id );
1260 }
1261 else if( m_parent && m_parent->Type() == SCH_SHEET_T )
1262 {
1263 if( IsMandatory() )
1265 }
1266 else if( m_parent && m_parent->IsType( labelTypes ) )
1267 {
1268 // These should be stored in canonical format, but just in case:
1269 if( m_name == _( "Net Class" ) || m_name == wxT( "Net Class" ) )
1270 {
1271 return wxT( "Netclass" );
1272 }
1273 else if( m_name == _( "Sheet References" )
1274 || m_name == wxT( "Sheet References" )
1275 || m_name == wxT( "Intersheet References" ) )
1276 {
1277 return wxT( "Intersheetrefs" );
1278 }
1279 }
1280
1281 return m_name;
1282}
1283
1284
1286{
1287 if( m_parent && ( m_parent->Type() == SCH_SYMBOL_T || m_parent->Type() == LIB_SYMBOL_T ) )
1288 {
1289 switch( m_id )
1290 {
1291 case REFERENCE_FIELD: return BITMAPS::edit_comp_ref;
1292 case VALUE_FIELD: return BITMAPS::edit_comp_value;
1293 case FOOTPRINT_FIELD: return BITMAPS::edit_comp_footprint;
1294 default: return BITMAPS::text;
1295 }
1296 }
1297
1298 return BITMAPS::text;
1299}
1300
1301
1302bool SCH_FIELD::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1303{
1304 if( GetShownText( true ).IsEmpty() )
1305 return false;
1306
1307 BOX2I rect = GetBoundingBox();
1308
1309 // Text in symbol editor can have additional chars (ie: reference designators U? or U?A)
1310 if( m_parent && m_parent->Type() == LIB_SYMBOL_T )
1311 {
1312 SCH_FIELD temp( *this );
1313 temp.SetText( GetFullText() );
1314 rect = temp.GetBoundingBox();
1315 }
1316
1317 rect.Inflate( aAccuracy );
1318
1320 {
1321 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1322 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1323 }
1324
1325 return rect.Contains( aPosition );
1326}
1327
1328
1329bool SCH_FIELD::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1330{
1331 if( GetShownText( true ).IsEmpty() )
1332 return false;
1333
1335 return false;
1336
1337 BOX2I rect = aRect;
1338
1339 rect.Inflate( aAccuracy );
1340
1341 if( GetParent() && GetParent()->Type() == SCH_GLOBAL_LABEL_T )
1342 {
1343 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( GetParent() );
1344 rect.Offset( label->GetSchematicTextOffset( nullptr ) );
1345 }
1346
1347 if( aContained )
1348 return rect.Contains( GetBoundingBox() );
1349
1350 return rect.Intersects( GetBoundingBox() );
1351}
1352
1353
1354void SCH_FIELD::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
1355 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1356{
1357 wxString text;
1358
1359 if( Schematic() )
1360 text = GetShownText( &Schematic()->CurrentSheet(), true );
1361 else
1362 text = GetShownText( true );
1363
1364 if( ( !IsVisible() && !IsForceVisible() ) || text.IsEmpty() || aBackground )
1365 return;
1366
1367 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1368 COLOR4D color = renderSettings->GetLayerColor( GetLayer() );
1369 int penWidth = GetEffectiveTextPenWidth( renderSettings->GetDefaultPenWidth() );
1370
1371 COLOR4D bg = renderSettings->GetBackgroundColor();;
1372
1373 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1374 bg = COLOR4D::WHITE;
1375
1376 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1377 color = GetTextColor();
1378
1379 if( aDimmed )
1380 {
1381 color.Desaturate( );
1382 color = color.Mix( bg, 0.5f );
1383 }
1384
1385 penWidth = std::max( penWidth, renderSettings->GetMinPenWidth() );
1386
1387 // clamp the pen width to be sure the text is readable
1388 penWidth = std::min( penWidth, std::min( GetTextSize().x, GetTextSize().y ) / 4 );
1389
1390 if( !IsVisible() && !renderSettings->m_ShowHiddenFields )
1391 return;
1392
1393 // Calculate the text orientation, according to the symbol orientation/mirror
1394 EDA_ANGLE orient = GetTextAngle();
1395 VECTOR2I textpos = GetTextPos();
1397 GR_TEXT_V_ALIGN_T vjustify = GetVertJustify();
1398
1399 if( renderSettings->m_Transform.y1 ) // Rotate symbol 90 deg.
1400 {
1401 if( orient.IsHorizontal() )
1402 orient = ANGLE_VERTICAL;
1403 else
1404 orient = ANGLE_HORIZONTAL;
1405 }
1406
1407 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1408 {
1409 /*
1410 * Calculate the text justification, according to the symbol orientation/mirror. This is
1411 * a bit complicated due to cumulative calculations:
1412 * - numerous cases (mirrored or not, rotation)
1413 * - the plotter's Text() function will also recalculate H and V justifications according
1414 * to the text orientation
1415 * - when a symbol is mirrored the text is not, and justifications become a nightmare
1416 *
1417 * So the easier way is to use no justifications (centered text) and use GetBoundingBox
1418 * to know the text coordinate considered as centered.
1419 */
1420 hjustify = GR_TEXT_H_ALIGN_CENTER;
1421 vjustify = GR_TEXT_V_ALIGN_CENTER;
1422 textpos = GetBoundingBox().Centre();
1423 }
1424 else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
1425 {
1426 SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_parent );
1427 textpos += label->GetSchematicTextOffset( renderSettings );
1428 }
1429
1430 KIFONT::FONT* font = GetFont();
1431
1432 if( !font )
1433 font = KIFONT::FONT::GetFont( renderSettings->GetDefaultFont(), IsBold(), IsItalic() );
1434
1436 attrs.m_StrokeWidth = penWidth;
1437 attrs.m_Halign = hjustify;
1438 attrs.m_Valign = vjustify;
1439 attrs.m_Angle = orient;
1440 attrs.m_Multiline = false;
1441
1442 aPlotter->PlotText( textpos, color, text, attrs, font, GetFontMetrics() );
1443
1444 if( IsHypertext() && Schematic() )
1445 {
1446 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( m_parent );
1447 std::vector<std::pair<wxString, wxString>> pages;
1448 std::vector<wxString> pageHrefs;
1449 BOX2I bbox = GetBoundingBox();
1450
1451 wxCHECK( label, /* void */ );
1452
1453 label->GetIntersheetRefs( &Schematic()->CurrentSheet(), &pages );
1454
1455 for( const auto& [ pageNumber, sheetName ] : pages )
1456 pageHrefs.push_back( wxT( "#" ) + pageNumber );
1457
1458 bbox.Offset( label->GetSchematicTextOffset( renderSettings ) );
1459
1460 aPlotter->HyperlinkMenu( bbox, pageHrefs );
1461 }
1462}
1463
1464
1465void SCH_FIELD::SetPosition( const VECTOR2I& aPosition )
1466{
1467 // Actual positions are calculated by the rotation/mirror transform of the parent symbol
1468 // of the field. The inverse transform is used to calculate the position relative to the
1469 // parent symbol.
1470 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1471 {
1472 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1473 VECTOR2I relPos = aPosition - parentSymbol->GetPosition();
1474
1475 relPos = parentSymbol->GetTransform().InverseTransform().TransformCoordinate( relPos );
1476
1477 SetTextPos( relPos + parentSymbol->GetPosition() );
1478 return;
1479 }
1480
1481 SetTextPos( aPosition );
1482}
1483
1484
1486{
1487 if( m_parent && m_parent->Type() == SCH_SYMBOL_T )
1488 {
1489 SCH_SYMBOL* parentSymbol = static_cast<SCH_SYMBOL*>( m_parent );
1490 VECTOR2I relativePos = GetTextPos() - parentSymbol->GetPosition();
1491
1492 relativePos = parentSymbol->GetTransform().TransformCoordinate( relativePos );
1493
1494 return relativePos + parentSymbol->GetPosition();
1495 }
1496
1497 return GetTextPos();
1498}
1499
1500
1502{
1503 return m_parent ? m_parent->GetPosition() : VECTOR2I( 0, 0 );
1504}
1505
1506
1508{
1509 if( !m_parent )
1510 return false;
1511
1512 switch( m_parent->Type() )
1513 {
1514 case SCH_SHEET_T:
1515 return m_id == SHEETNAME
1516 || m_id == SHEETFILENAME;
1517
1518 case SCH_SYMBOL_T:
1519 case LIB_SYMBOL_T:
1520 return m_id == REFERENCE_FIELD
1521 || m_id == VALUE_FIELD
1522 || m_id == FOOTPRINT_FIELD
1523 || m_id == DATASHEET_FIELD
1524 || m_id == DESCRIPTION_FIELD;
1525
1526 case SCH_GLOBAL_LABEL_T:
1527 return m_id == INTERSHEET_REFS;
1528
1529 default:
1530 return false;
1531 }
1532}
1533
1534
1535bool SCH_FIELD::operator<( const SCH_ITEM& aItem ) const
1536{
1537 if( Type() != aItem.Type() )
1538 return Type() < aItem.Type();
1539
1540 auto field = static_cast<const SCH_FIELD*>( &aItem );
1541
1542 if( GetId() != field->GetId() )
1543 return GetId() < field->GetId();
1544
1545 if( GetText() != field->GetText() )
1546 return GetText() < field->GetText();
1547
1548 if( GetLibPosition().x != field->GetLibPosition().x )
1549 return GetLibPosition().x < field->GetLibPosition().x;
1550
1551 if( GetLibPosition().y != field->GetLibPosition().y )
1552 return GetLibPosition().y < field->GetLibPosition().y;
1553
1554 return GetName() < field->GetName();
1555}
1556
1557
1558bool SCH_FIELD::operator==(const SCH_ITEM& aOther) const
1559{
1560 if( Type() != aOther.Type() )
1561 return false;
1562
1563 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1564
1565 return *this == field;
1566}
1567
1568
1569bool SCH_FIELD::operator==( const SCH_FIELD& aOther ) const
1570{
1571 // Identical fields of different symbols are not equal.
1572 if( !GetParentSymbol() || !aOther.GetParentSymbol()
1573 || GetParentSymbol()->m_Uuid != aOther.GetParentSymbol()->m_Uuid )
1574 {
1575 return false;
1576 }
1577
1578 if( GetId() != aOther.GetId() )
1579 return false;
1580
1581 if( GetPosition() != aOther.GetPosition() )
1582 return false;
1583
1584 if( IsNamedVariable() != aOther.IsNamedVariable() )
1585 return false;
1586
1587 if( IsNameShown() != aOther.IsNameShown() )
1588 return false;
1589
1590 if( CanAutoplace() != aOther.CanAutoplace() )
1591 return false;
1592
1593 return EDA_TEXT::operator==( aOther );
1594}
1595
1596
1597double SCH_FIELD::Similarity( const SCH_ITEM& aOther ) const
1598{
1599 if( Type() != aOther.Type() )
1600 return 0.0;
1601
1602 if( m_Uuid == aOther.m_Uuid )
1603 return 1.0;
1604
1605 const SCH_FIELD& field = static_cast<const SCH_FIELD&>( aOther );
1606
1607 double similarity = 0.99; // The UUIDs are different, so we start with non-identity
1608
1609 if( GetId() != field.GetId() )
1610 {
1611 // We don't allow swapping of mandatory fields, so these cannot be the same item
1612 if( IsMandatory() || field.IsMandatory() )
1613 return 0.0;
1614 else
1615 similarity *= 0.5;
1616 }
1617
1618 similarity *= SimilarityBase( aOther );
1619
1620 similarity *= EDA_TEXT::Similarity( field );
1621
1622 if( GetPosition() != field.GetPosition() )
1623 similarity *= 0.5;
1624
1625 if( IsNamedVariable() != field.IsNamedVariable() )
1626 similarity *= 0.5;
1627
1628 if( IsNameShown() != field.IsNameShown() )
1629 similarity *= 0.5;
1630
1631 if( CanAutoplace() != field.CanAutoplace() )
1632 similarity *= 0.5;
1633
1634 return similarity;
1635}
1636
1637
1638int SCH_FIELD::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1639{
1640 wxASSERT( aOther.Type() == SCH_FIELD_T );
1641
1642 int compareFlags = aCompareFlags;
1643
1644 // For ERC tests, the field position has no matter, so do not test it
1645 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC )
1647
1648 int retv = SCH_ITEM::compare( aOther, compareFlags );
1649
1650 if( retv )
1651 return retv;
1652
1653 const SCH_FIELD* tmp = static_cast<const SCH_FIELD*>( &aOther );
1654
1655 // Equality test will vary depending whether or not the field is mandatory. Otherwise,
1656 // sorting is done by ordinal.
1657 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1658 {
1659 // Mandatory fields have fixed ordinals and their names can vary due to translated field
1660 // names. Optional fields have fixed names and their ordinals can vary.
1661 if( IsMandatory() )
1662 {
1663 if( m_id != tmp->m_id )
1664 return m_id - tmp->m_id;
1665 }
1666 else
1667 {
1668 retv = m_name.Cmp( tmp->m_name );
1669
1670 if( retv )
1671 return retv;
1672 }
1673 }
1674 else // assume we're sorting
1675 {
1676 if( m_id != tmp->m_id )
1677 return m_id - tmp->m_id;
1678 }
1679
1680 bool ignoreFieldText = false;
1681
1682 if( m_id == REFERENCE_FIELD && !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY ) )
1683 ignoreFieldText = true;
1684
1685 if( m_id == VALUE_FIELD && ( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1686 ignoreFieldText = true;
1687
1688 if( !ignoreFieldText )
1689 {
1690 retv = GetText().CmpNoCase( tmp->GetText() );
1691
1692 if( retv != 0 )
1693 return retv;
1694 }
1695
1696 if( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::EQUALITY )
1697 {
1698 if( GetTextPos().x != tmp->GetTextPos().x )
1699 return GetTextPos().x - tmp->GetTextPos().x;
1700
1701 if( GetTextPos().y != tmp->GetTextPos().y )
1702 return GetTextPos().y - tmp->GetTextPos().y;
1703 }
1704
1705 // For ERC tests, the field size has no matter, so do not test it
1706 if( !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::ERC ) )
1707 {
1708 if( GetTextWidth() != tmp->GetTextWidth() )
1709 return GetTextWidth() - tmp->GetTextWidth();
1710
1711 if( GetTextHeight() != tmp->GetTextHeight() )
1712 return GetTextHeight() - tmp->GetTextHeight();
1713 }
1714
1715 return 0;
1716}
1717
1718
1719static struct SCH_FIELD_DESC
1720{
1722 {
1723 // These are defined in EDA_TEXT as well but initialization order is
1724 // not defined, so this needs to be conditional. Defining in both
1725 // places leads to duplicate symbols.
1727
1728 if( h_inst.Choices().GetCount() == 0)
1729 {
1730 h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _( "Left" ) );
1731 h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _( "Center" ) );
1732 h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _( "Right" ) );
1733 }
1734
1736
1737 if( v_inst.Choices().GetCount() == 0)
1738 {
1739 v_inst.Map( GR_TEXT_V_ALIGN_TOP, _( "Top" ) );
1740 v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _( "Center" ) );
1741 v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _( "Bottom" ) );
1742 }
1743
1750
1751 const wxString textProps = _HKI( "Text Properties" );
1752
1754 _HKI( "Horizontal Justification" ), &SCH_FIELD::SetEffectiveHorizJustify,
1756
1757 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ), horiz,
1758 textProps );
1759
1761 _HKI( "Vertical Justification" ), &SCH_FIELD::SetEffectiveVertJustify,
1763
1764 propMgr.ReplaceProperty( TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ), vert,
1765 textProps );
1766
1767 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Show Field Name" ),
1769
1770 propMgr.AddProperty( new PROPERTY<SCH_FIELD, bool>( _HKI( "Allow Autoplacement" ),
1772
1773 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
1774 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
1775 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Mirrored" ) );
1776 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
1777 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
1778
1779
1780 propMgr.AddProperty( new PROPERTY<SCH_FIELD, int>( _HKI( "Text Size" ),
1781 &SCH_FIELD::SetSchTextSize, &SCH_FIELD::GetSchTextSize, PROPERTY_DISPLAY::PT_SIZE ),
1782 _HKI( "Text Properties" ) );
1783
1784 propMgr.Mask( TYPE_HASH( SCH_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
1785
1786 auto isNotNamedVariable =
1787 []( INSPECTABLE* aItem ) -> bool
1788 {
1789 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1790 return !field->IsNamedVariable();
1791
1792 return true;
1793 };
1794
1796 isNotNamedVariable );
1797
1798
1799 auto isNonMandatoryField =
1800 []( INSPECTABLE* aItem ) -> bool
1801 {
1802 if( SCH_FIELD* field = dynamic_cast<SCH_FIELD*>( aItem ) )
1803 return !field->IsMandatory();
1804
1805 return false;
1806 };
1807
1809 _HKI( "Private" ), isNonMandatoryField );
1810 }
1812
1813
int color
Definition: DXF_plotter.cpp:60
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
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
bool IsHorizontal() const
Definition: eda_angle.h:138
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:242
const KIID m_Uuid
Definition: eda_item.h:488
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:499
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:376
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
Definition: eda_item.h:174
EDA_ITEM * GetParent() const
Definition: eda_item.h:103
EDA_ITEM * m_parent
Linked list: Link (parent struct).
Definition: eda_item.h:500
bool IsForceVisible() const
Definition: eda_item.h:193
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:189
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:254
const VECTOR2I & GetTextPos() const
Definition: eda_text.h:260
COLOR4D GetTextColor() const
Definition: eda_text.h:257
wxString GetTextStyleName() const
Definition: eda_text.cpp:965
bool IsItalic() const
Definition: eda_text.h:156
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
virtual bool IsVisible() const
Definition: eda_text.h:174
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:571
void SetTextX(int aX)
Definition: eda_text.cpp:577
KIFONT::FONT * GetFont() const
Definition: eda_text.h:234
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition: eda_text.cpp:426
BOX2I GetTextBox(int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition: eda_text.cpp:723
void SetTextY(int aY)
Definition: eda_text.cpp:583
EDA_TEXT & operator=(const EDA_TEXT &aItem)
Definition: eda_text.cpp:154
int GetTextWidth() const
Definition: eda_text.h:251
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:410
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:187
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition: eda_text.cpp:479
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:379
virtual void ClearBoundingBoxCache()
Definition: eda_text.cpp:657
double Similarity(const EDA_TEXT &aOther) const
Definition: eda_text.cpp:1279
virtual void ClearRenderCache()
Definition: eda_text.cpp:651
const TEXT_ATTRIBUTES & GetAttributes() const
Definition: eda_text.h:218
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition: eda_text.cpp:458
void SwapAttributes(EDA_TEXT &aTradingPartner)
Swap the text attributes of the two involved instances.
Definition: eda_text.cpp:445
bool IsBold() const
Definition: eda_text.h:171
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:190
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:270
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:292
void SwapText(EDA_TEXT &aTradingPartner)
Definition: eda_text.cpp:438
bool operator==(const EDA_TEXT &aRhs) const
Definition: eda_text.h:382
VECTOR2I GetTextSize() const
Definition: eda_text.h:248
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:402
static ENUM_MAP< T > & Instance()
Definition: property.h:680
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.
Definition: outline_font.h:53
void GetLinesAsGlyphs(std::vector< std::unique_ptr< GLYPH > > *aGlyphs, const wxString &aText, const VECTOR2I &aPosition, const TEXT_ATTRIBUTES &aAttrs, const METRICS &aFontMetrics) const
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
int GetDefaultPenWidth() const
const wxString & GetDefaultFont() const
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
Define a library symbol object.
Definition: lib_symbol.h:84
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
Definition: lib_symbol.cpp:500
static wxString LetterSubReference(int aUnit, int aFirstId)
Definition: lib_symbol.cpp:481
A singleton reporter that reports to nowhere.
Definition: reporter.h:203
Base plotter engine class.
Definition: plotter.h:105
bool GetColorMode() const
Definition: plotter.h:133
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:754
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:467
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:95
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
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()
Definition: property_mgr.h:87
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.
Holds all the data relating to one schematic.
Definition: schematic.h:83
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:162
SCH_SHEET_LIST Hierarchy() const override
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:224
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
Definition: schematic.cpp:263
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:98
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:53
void ClearRenderCache() override
Definition: sch_field.cpp:373
int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const override
Provide the draw object specific comparison called by the == and < operators.
Definition: sch_field.cpp:1638
COLOR4D m_lastResolvedColor
Definition: sch_field.h:362
GR_TEXT_V_ALIGN_T GetEffectiveVertJustify() const
Definition: sch_field.cpp:743
bool IsMandatory() const
Definition: sch_field.cpp:1507
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: sch_field.cpp:1116
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_field.cpp:1025
wxString GetFullText(int unit=1) const
Return the text of a field.
Definition: sch_field.cpp:334
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_field.cpp:615
std::vector< std::unique_ptr< KIFONT::GLYPH > > m_renderCache
Definition: sch_field.h:360
VECTOR2I GetPosition() const override
Definition: sch_field.cpp:1485
void SetEffectiveHorizJustify(GR_TEXT_H_ALIGN_T)
Definition: sch_field.cpp:666
int GetSchTextSize() const
Definition: sch_field.h:182
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 ...
Definition: sch_field.cpp:943
bool m_showName
Render the field name in addition to its value.
Definition: sch_field.h:350
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
Definition: sch_field.cpp:1354
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_field.cpp:147
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_field.cpp:1285
bool IsNameShown() const
Definition: sch_field.h:219
bool IsHypertext() const override
Allow items to support hypertext actions when hovered/clicked.
Definition: sch_field.h:105
bool m_autoAdded
Was this field automatically added to a LIB_SYMBOL?
Definition: sch_field.h:355
double Similarity(const SCH_ITEM &aItem) const override
Return a measure of how likely the other object is to represent the same object.
Definition: sch_field.cpp:1597
void Print(const SCH_RENDER_SETTINGS *aSettings, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aForceNoFill, bool aDimmed) override
Print an item.
Definition: sch_field.cpp:426
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_field.cpp:1302
SCH_LAYER_ID GetDefaultLayer() const
Definition: sch_field.cpp:565
bool IsHorizJustifyFlipped() const
Return whether the field will be rendered with the horizontal justification inverted due to rotation ...
Definition: sch_field.cpp:643
bool IsVertJustifyFlipped() const
Definition: sch_field.cpp:700
EDA_ANGLE GetDrawRotation() const override
Adjusters to allow EDA_TEXT to draw/print/etc.
Definition: sch_field.cpp:593
void SetEffectiveVertJustify(GR_TEXT_V_ALIGN_T)
Definition: sch_field.cpp:723
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: sch_field.cpp:1110
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_field.cpp:757
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_field.cpp:1092
void SetCanAutoplace(bool aCanPlace)
Definition: sch_field.h:231
bool m_isNamedVariable
If the field name is a variable name, e.g.
Definition: sch_field.h:352
void DoHypertextAction(EDA_DRAW_FRAME *aFrame) const override
Definition: sch_field.cpp:1163
int GetPenWidth() const override
Definition: sch_field.cpp:349
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
Definition: sch_field.cpp:1254
COLOR4D GetFieldColor() const
Definition: sch_field.cpp:539
bool IsNamedVariable() const
Named variables are fields whose names are variables like ${VAR}.
Definition: sch_field.h:228
int GetId() const
Definition: sch_field.h:141
bool operator==(const SCH_ITEM &aItem) const override
Definition: sch_field.cpp:1558
SCH_FIELD & operator=(const SCH_FIELD &aField)
Definition: sch_field.cpp:117
void ImportValues(const SCH_FIELD &aSource)
Copy parameters from a SCH_FIELD source.
Definition: sch_field.cpp:510
bool operator<(const SCH_ITEM &aItem) const override
Definition: sch_field.cpp:1535
wxString GetShownName() const
Get the fields name as displayed on the schematic or in the symbol fields table.
Definition: sch_field.cpp:203
VECTOR2I GetLibPosition() const
Definition: sch_field.h:277
bool IsEmpty()
Return true if both the name and value of the field are empty.
Definition: sch_field.h:174
SCH_FIELD(const VECTOR2I &aPos, int aFieldId, SCH_ITEM *aParent, const wxString &aName=wxEmptyString)
Definition: sch_field.cpp:47
bool m_renderCacheValid
Definition: sch_field.h:358
void BeginEdit(const VECTOR2I &aStartPoint) override
Begin drawing a symbol library draw item at aPosition.
Definition: sch_field.cpp:1104
bool IsReplaceable() const override
Override this method in any derived object that supports test find and replace.
Definition: sch_field.cpp:925
void SetSchTextSize(int aSize)
Definition: sch_field.h:183
GR_TEXT_H_ALIGN_T GetEffectiveHorizJustify() const
Definition: sch_field.cpp:686
std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
Definition: sch_field.cpp:559
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:1229
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_field.cpp:1465
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_field.cpp:519
void SetName(const wxString &aName)
Definition: sch_field.cpp:1204
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
Definition: sch_field.cpp:209
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_field.h:250
VECTOR2I m_renderCachePos
Definition: sch_field.h:359
bool CanAutoplace() const
Definition: sch_field.h:230
std::vector< std::unique_ptr< KIFONT::GLYPH > > * GetRenderCache(const wxString &forResolvedText, const VECTOR2I &forPosition, TEXT_ATTRIBUTES &aAttrs) const
Definition: sch_field.cpp:381
void SetId(int aId)
Definition: sch_field.cpp:159
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.
Definition: sch_field.cpp:1124
void ClearCaches() override
Definition: sch_field.cpp:366
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1214
VECTOR2I GetParentPosition() const
Definition: sch_field.cpp:1501
int m_id
Field index,.
Definition: sch_field.h:346
bool m_showInChooser
This field is available as a data column for the chooser.
Definition: sch_field.h:356
void OnScintillaCharAdded(SCINTILLA_TRICKS *aScintillaTricks, wxStyledTextEvent &aEvent) const
Definition: sch_field.cpp:807
wxString m_name
Definition: sch_field.h:348
void SetNameShown(bool aShown=true)
Definition: sch_field.h:220
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_field.cpp:1080
void Copy(SCH_FIELD *aTarget) const
Copy parameters of this field to another field.
Definition: sch_field.cpp:153
KIFONT::FONT * getDrawFont() const override
Definition: sch_field.cpp:355
bool m_allowAutoPlace
This field can be autoplaced.
Definition: sch_field.h:351
VECTOR2I GetSchematicTextOffset(const RENDER_SETTINGS *aSettings) const override
This offset depends on the orientation, the type of text, and the area required to draw the associate...
Definition: sch_label.cpp:1833
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:101
const wxString & GetDefaultFont() const
Definition: sch_item.cpp:456
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition: sch_item.h:665
const SYMBOL * GetParentSymbol() const
Definition: sch_item.cpp:166
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
@ SKIP_TST_POS
Definition: sch_item.h:657
@ EQUALITY
Definition: sch_item.h:655
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition: sch_item.cpp:247
void SetLayer(SCH_LAYER_ID aLayer)
Definition: sch_item.h:289
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:288
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:417
bool IsConnectivityDirty() const
Definition: sch_item.h:520
void SwapFlags(SCH_ITEM *aItem)
Swap the non-temp and non-edit flags.
Definition: sch_item.cpp:352
bool m_private
Definition: sch_item.h:721
const KIFONT::METRICS & GetFontMetrics() const
Definition: sch_item.cpp:465
SCH_LAYER_ID m_layer
Definition: sch_item.h:718
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:325
void GetIntersheetRefs(const SCH_SHEET_PATH *aPath, std::vector< std::pair< wxString, wxString > > *pages)
Build an array of { pageNumber, pageName } pairs.
Definition: sch_label.cpp:632
virtual bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const
Resolve any references to system tokens supported by the label.
Definition: sch_label.cpp:687
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:202
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this label.
Definition: sch_label.cpp:669
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...
Definition: sch_label.cpp:350
Handle actions specific to the schematic editor.
static wxString g_BackLink
void HypertextCommand(const wxString &href)
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
size_t GetCount() const
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
const KIGFX::COLOR4D & GetBackgroundColor() const override
Return current background color settings.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:59
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
Definition: sch_sheet.cpp:211
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslated)
Definition: sch_sheet.cpp:59
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
Definition: sch_sheet.cpp:254
Schematic symbol object.
Definition: sch_symbol.h:77
wxString SubReference(int aUnit, bool aAddSeparator=true) const
Definition: sch_symbol.cpp:824
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:885
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:907
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
Definition: sch_symbol.cpp:747
void SetFootprintFieldText(const wxString &aFootprint)
Definition: sch_symbol.cpp:901
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:798
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.
Definition: sch_symbol.cpp:833
int GetUnitCount() const override
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:434
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Definition: sch_symbol.cpp:705
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)
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< SCH_PIN * > &aPins, REPORTER &aReporter)
virtual std::vector< std::string > GetPinNames() const
Definition: sim_model.h:469
const TRANSFORM & GetTransform() const
Definition: symbol.h:195
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:46
int y1
Definition: transform.h:49
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 ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
Definition: common.cpp:59
wxString GetTextVars(const wxString &aSource)
Returns any variables unexpanded, e.g.
Definition: common.cpp:121
The common library.
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:403
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:398
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:397
static constexpr EDA_ANGLE ANGLE_270
Definition: eda_angle.h:406
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:165
void GRPrintText(wxDC *aDC, const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics)
Print a graphic text through wxDC.
Definition: gr_text.cpp:109
int m_ResolveTextRecursionDepth
The number of recursions to resolve text variables.
PROJECT & Prj()
Definition: kicad.cpp:597
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:438
@ LAYER_SHEETNAME
Definition: layer_ids.h:461
@ LAYER_HIDDEN
Definition: layer_ids.h:481
@ LAYER_VALUEPART
Definition: layer_ids.h:450
@ LAYER_FIELDS
Definition: layer_ids.h:451
@ LAYER_SHEETFIELDS
Definition: layer_ids.h:463
@ LAYER_REFERENCEPART
Definition: layer_ids.h:449
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:453
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:483
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:452
@ LAYER_SHEETFILENAME
Definition: layer_ids.h:462
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:214
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.
Definition: ui_common.cpp:196
static GR_TEXT_H_ALIGN_T horizJustify(const char *horizontal)
#define TYPE_HASH(x)
Definition: property.h:71
#define DECLARE_ENUM_TO_WXANY(type)
Definition: property.h:746
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
static const std::vector< KICAD_T > labelTypes
Definition: sch_field.cpp:44
static struct SCH_FIELD_DESC _SCH_FIELD_DESC
@ INTERSHEET_REFS
Definition: sch_label.h:136
@ SHEETNAME
Definition: sch_sheet.h:45
@ SHEETFILENAME
Definition: sch_sheet.h:46
wxString UnescapeString(const wxString &aSource)
Definition for symbol library class.
wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI)
Return a default symbol field name for field aFieldNdx for all components.
#define DO_TRANSLATE
wxString GetCanonicalFieldName(int idx)
@ DATASHEET_FIELD
name of datasheet
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ INVALID_FIELD
The field ID hasn't been set yet; field is invalid.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ DESCRIPTION_FIELD
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
VECTOR2I end
constexpr 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:148
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:190
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
#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