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