KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_label.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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2015 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <advanced_config.h>
27#include <base_units.h>
28#include <pgm_base.h>
29#include <sch_edit_frame.h>
30#include <sch_plotter.h>
31#include <widgets/msgpanel.h>
32#include <bitmaps.h>
33#include <string_utils.h>
34#include <schematic.h>
36#include <sch_painter.h>
37#include <default_values.h>
38#include <wx/debug.h>
39#include <wx/log.h>
43#include <core/kicad_algo.h>
44#include <core/mirror.h>
45#include <trigo.h>
46#include <sch_label.h>
47#include <magic_enum.hpp>
48#include <api/api_utils.h>
49#include <api/schematic/schematic_types.pb.h>
50
51
52bool IncrementLabelMember( wxString& name, int aIncrement )
53{
54 if( name.IsEmpty() )
55 return true;
56
57 wxString suffix;
58 wxString digits;
59 wxString outputFormat;
60 wxString outputNumber;
61 int ii = name.Len() - 1;
62 int dCount = 0;
63
64 while( ii >= 0 && !wxIsdigit( name.GetChar( ii ) ) )
65 {
66 suffix = name.GetChar( ii ) + suffix;
67 ii--;
68 }
69
70 while( ii >= 0 && wxIsdigit( name.GetChar( ii ) ) )
71 {
72 digits = name.GetChar( ii ) + digits;
73 ii--;
74 dCount++;
75 }
76
77 if( digits.IsEmpty() )
78 return true;
79
80 long number = 0;
81
82 if( digits.ToLong( &number ) )
83 {
84 number += aIncrement;
85
86 // Don't let result go below zero
87
88 if( number > -1 )
89 {
90 name.Remove( ii + 1 );
91 //write out a format string with correct number of leading zeroes
92 outputFormat.Printf( wxS( "%%0%dld" ), dCount );
93 //write out the number using the format string
94 outputNumber.Printf( outputFormat, number );
95 name << outputNumber << suffix;
96 return true;
97 }
98 }
99
100 return false;
101}
102
103
104/* Coding polygons for global symbol graphic shapes.
105 * the first parml is the number of corners
106 * others are the corners coordinates in reduced units
107 * the real coordinate is the reduced coordinate * text half size
108 */
109static int TemplateIN_HN[] = { 6, 0, 0, -1, -1, -2, -1, -2, 1, -1, 1, 0, 0 };
110static int TemplateIN_HI[] = { 6, 0, 0, 1, 1, 2, 1, 2, -1, 1, -1, 0, 0 };
111static int TemplateIN_UP[] = { 6, 0, 0, 1, -1, 1, -2, -1, -2, -1, -1, 0, 0 };
112static int TemplateIN_BOTTOM[] = { 6, 0, 0, 1, 1, 1, 2, -1, 2, -1, 1, 0, 0 };
113
114static int TemplateOUT_HN[] = { 6, -2, 0, -1, 1, 0, 1, 0, -1, -1, -1, -2, 0 };
115static int TemplateOUT_HI[] = { 6, 2, 0, 1, -1, 0, -1, 0, 1, 1, 1, 2, 0 };
116static int TemplateOUT_UP[] = { 6, 0, -2, 1, -1, 1, 0, -1, 0, -1, -1, 0, -2 };
117static int TemplateOUT_BOTTOM[] = { 6, 0, 2, 1, 1, 1, 0, -1, 0, -1, 1, 0, 2 };
118
119static int TemplateUNSPC_HN[] = { 5, 0, -1, -2, -1, -2, 1, 0, 1, 0, -1 };
120static int TemplateUNSPC_HI[] = { 5, 0, -1, 2, -1, 2, 1, 0, 1, 0, -1 };
121static int TemplateUNSPC_UP[] = { 5, 1, 0, 1, -2, -1, -2, -1, 0, 1, 0 };
122static int TemplateUNSPC_BOTTOM[] = { 5, 1, 0, 1, 2, -1, 2, -1, 0, 1, 0 };
123
124static int TemplateBIDI_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
125static int TemplateBIDI_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
126static int TemplateBIDI_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
127static int TemplateBIDI_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
128
129static int Template3STATE_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
130static int Template3STATE_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
131static int Template3STATE_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
132static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
133
134static int* TemplateShape[5][4] =
135{
141};
142
143
145{
146 switch( aType )
147 {
148 case LABEL_FLAG_SHAPE::L_INPUT: return _( "Input" );
149 case LABEL_FLAG_SHAPE::L_OUTPUT: return _( "Output" );
150 case LABEL_FLAG_SHAPE::L_BIDI: return _( "Bidirectional" );
151 case LABEL_FLAG_SHAPE::L_TRISTATE: return _( "Tri-State" );
152 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: return _( "Passive" );
153 default: return wxT( "???" );
154 }
155}
156
157
159{
160 SPIN newSpin = m_spin;
161
162 switch( m_spin )
163 {
164 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::BOTTOM; break;
165 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::RIGHT; break;
166 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::UP; break;
167 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::LEFT; break;
168 }
169
170 return SPIN_STYLE( newSpin );
171}
172
173
175{
176 SPIN newSpin = m_spin;
177
178 switch( m_spin )
179 {
180 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::BOTTOM; break;
181 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::UP; break;
182 case SPIN_STYLE::LEFT: break;
183 case SPIN_STYLE::RIGHT: break;
184 }
185
186 return SPIN_STYLE( newSpin );
187}
188
189
191{
192 SPIN newSpin = m_spin;
193
194 switch( m_spin )
195 {
196 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::RIGHT; break;
197 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::LEFT; break;
198 case SPIN_STYLE::UP: break;
199 case SPIN_STYLE::BOTTOM: break;
200 }
201
202 return SPIN_STYLE( newSpin );
203}
204
205
206unsigned SPIN_STYLE::CCWRotationsTo( const SPIN_STYLE& aOther ) const
207{
208 return ( ( (int) m_spin - (int) aOther.m_spin ) % 4 + 4 ) % 4;
209}
210
211
212SCH_LABEL_BASE::SCH_LABEL_BASE( const VECTOR2I& aPos, const wxString& aText, KICAD_T aType ) :
213 SCH_TEXT( aPos, aText, LAYER_NOTES, aType ),
214 m_shape( L_UNSPECIFIED ),
215 m_connectionType( CONNECTION_TYPE::NONE ),
216 m_isDangling( true ),
217 m_lastResolvedColor( COLOR4D::UNSPECIFIED )
218{
219 SetMultilineAllowed( false );
220 ClearFieldsAutoplaced(); // fields are not yet autoplaced.
221
222 if( !HasTextVars() )
224}
225
226
228 SCH_TEXT( aLabel ),
229 m_shape( aLabel.m_shape ),
230 m_connectionType( aLabel.m_connectionType ),
231 m_isDangling( aLabel.m_isDangling ),
232 m_lastResolvedColor( aLabel.m_lastResolvedColor ),
233 m_cached_driver_name( aLabel.m_cached_driver_name )
234{
235 SetMultilineAllowed( false );
236
237 m_fields = aLabel.m_fields;
238
239 for( SCH_FIELD& field : m_fields )
240 field.SetParent( this );
241}
242
243
245{
246 SCH_TEXT::operator=( aLabel );
247
249
250 return *this;
251}
252
253
254const wxString SCH_LABEL_BASE::GetDefaultFieldName( const wxString& aName, bool aUseDefaultName )
255{
256 if( aName == wxT( "Intersheetrefs" ) )
257 return _( "Sheet References" );
258 else if( aName == wxT( "Netclass" ) )
259 return _( "Net Class" );
260 else if( aName.IsEmpty() && aUseDefaultName )
261 return _( "Field" );
262 else
263 return aName;
264}
265
266
267bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
268{
269 static const std::vector<KICAD_T> wireAndPinTypes = { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T };
270 static const std::vector<KICAD_T> busTypes = { SCH_ITEM_LOCATE_BUS_T };
271
272 if( SCH_TEXT::IsType( aScanTypes ) )
273 return true;
274
275 for( KICAD_T scanType : aScanTypes )
276 {
277 if( scanType == SCH_LABEL_LOCATE_ANY_T )
278 return true;
279 }
280
281 wxCHECK_MSG( Schematic(), false, wxT( "No parent SCHEMATIC set for SCH_LABEL!" ) );
282
283 // Ensure m_connected_items for Schematic()->CurrentSheet() exists.
284 // Can be not the case when "this" is living in clipboard
285 if( m_connected_items.find( Schematic()->CurrentSheet() ) == m_connected_items.end() )
286 return false;
287
288 const SCH_ITEM_VEC& item_set = m_connected_items.at( Schematic()->CurrentSheet() );
289
290 for( KICAD_T scanType : aScanTypes )
291 {
292 if( scanType == SCH_LABEL_LOCATE_WIRE_T )
293 {
294 for( SCH_ITEM* connection : item_set )
295 {
296 if( connection->IsType( wireAndPinTypes ) )
297 return true;
298 }
299 }
300
301 if ( scanType == SCH_LABEL_LOCATE_BUS_T )
302 {
303 for( SCH_ITEM* connection : item_set )
304 {
305 if( connection->IsType( busTypes ) )
306 return true;
307 }
308 }
309 }
310
311 return false;
312}
313
314
316{
317 SCH_TEXT::SwapData( aItem );
318
319 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( aItem );
320
321 m_fields.swap( label->m_fields );
322 std::swap( m_fieldsAutoplaced, label->m_fieldsAutoplaced );
323
324 for( SCH_FIELD& field : m_fields )
325 field.SetParent( this );
326
327 for( SCH_FIELD& field : label->m_fields )
328 field.SetParent( label );
329
330 std::swap( m_shape, label->m_shape );
331 std::swap( m_connectionType, label->m_connectionType );
332 std::swap( m_isDangling, label->m_isDangling );
333 std::swap( m_lastResolvedColor, label->m_lastResolvedColor );
334}
335
336
338{
339 if( GetTextColor() != COLOR4D::UNSPECIFIED )
341 else if( !IsConnectivityDirty() )
342 m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor();
343
344 return m_lastResolvedColor;
345}
346
347
349{
350 // Assume "Right" and Left" mean which side of the anchor the text will be on
351 // Thus we want to left justify text up against the anchor if we are on the right
352 switch( aSpinStyle )
353 {
354 default:
355 wxFAIL_MSG( "Bad spin style" );
357
358 case SPIN_STYLE::RIGHT: // Horiz Normal Orientation
361 break;
362
363 case SPIN_STYLE::UP: // Vert Orientation UP
366 break;
367
368 case SPIN_STYLE::LEFT: // Horiz Orientation - Right justified
371 break;
372
373 case SPIN_STYLE::BOTTOM: // Vert Orientation BOTTOM
376 break;
377 }
378
380}
381
382
384{
386 {
388 return SPIN_STYLE::BOTTOM;
389 else
390 return SPIN_STYLE::UP;
391 }
392 else
393 {
395 return SPIN_STYLE::LEFT;
396 else
397 return SPIN_STYLE::RIGHT;
398 }
399}
400
401
403{
404 VECTOR2I text_offset;
405
406 // add an offset to x (or y) position to aid readability of text on a wire or line
407 int dist = GetTextOffset( aSettings ) + GetPenWidth();
408
409 switch( GetSpinStyle() )
410 {
411 case SPIN_STYLE::UP:
412 case SPIN_STYLE::BOTTOM: text_offset.x = -dist; break; // Vert Orientation
413 default:
414 case SPIN_STYLE::LEFT:
415 case SPIN_STYLE::RIGHT: text_offset.y = -dist; break; // Horiz Orientation
416 }
417
418 return text_offset;
419}
420
421
422void SCH_LABEL_BASE::SetPosition( const VECTOR2I& aPosition )
423{
424 VECTOR2I offset = aPosition - GetTextPos();
425 Move( offset );
426}
427
428
429void SCH_LABEL_BASE::Move( const VECTOR2I& aMoveVector )
430{
431 SCH_TEXT::Move( aMoveVector );
432
433 for( SCH_FIELD& field : m_fields )
434 field.Offset( aMoveVector );
435}
436
437
438void SCH_LABEL_BASE::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
439{
440 VECTOR2I pt = GetTextPos();
441 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
442 VECTOR2I offset = pt - GetTextPos();
443
444 Rotate90( !aRotateCCW );
445
446 SetTextPos( GetTextPos() + offset );
447
448 for( SCH_FIELD& field : m_fields )
449 field.SetTextPos( field.GetTextPos() + offset );
450}
451
452
453void SCH_LABEL_BASE::Rotate90( bool aClockwise )
454{
455 SCH_TEXT::Rotate90( aClockwise );
456
458 {
459 AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
460 }
461 else
462 {
463 for( SCH_FIELD& field : m_fields )
464 {
465 field.Rotate( GetPosition(), !aClockwise );
466 }
467 }
468}
469
470
471void SCH_LABEL_BASE::MirrorSpinStyle( bool aLeftRight )
472{
473 SCH_TEXT::MirrorSpinStyle( aLeftRight );
474
475 for( SCH_FIELD& field : m_fields )
476 {
477 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
478 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
479 {
480 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
481 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
482 else
483 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
484 }
485
486 VECTOR2I pos = field.GetTextPos();
488
489 if( aLeftRight )
490 pos.x = GetPosition().x + delta.x;
491 else
492 pos.y = GetPosition().y + delta.y;
493
494 field.SetTextPos( pos );
495 }
496}
497
498
500{
501 VECTOR2I old_pos = GetPosition();
503
504 for( SCH_FIELD& field : m_fields )
505 {
506 if( field.GetTextAngle() == ANGLE_HORIZONTAL )
507 field.FlipHJustify();
508
509 VECTOR2I pos = field.GetTextPos();
510 VECTOR2I delta = old_pos - pos;
511 pos.x = GetPosition().x + delta.x;
512
513 field.SetPosition( pos );
514 }
515}
516
517
519{
520 VECTOR2I old_pos = GetPosition();
522
523 for( SCH_FIELD& field : m_fields )
524 {
525 if( field.GetTextAngle() == ANGLE_VERTICAL )
526 field.FlipHJustify();
527
528 VECTOR2I pos = field.GetTextPos();
529 VECTOR2I delta = old_pos - pos;
530 pos.y = GetPosition().y + delta.y;
531
532 field.SetPosition( pos );
533 }
534}
535
536
537bool SCH_LABEL_BASE::IncrementLabel( int aIncrement )
538{
539 wxString text = GetText();
540
541 if( IncrementLabelMember( text, aIncrement ) )
542 {
543 SetText( text );
544 return true;
545 }
546
547 return false;
548}
549
550
551bool SCH_LABEL_BASE::operator==( const SCH_ITEM& aOther ) const
552{
553 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
554
555 if( !other )
556 return false;
557
558 if( m_shape != other->m_shape )
559 return false;
560
561 if( m_connectionType != other->m_connectionType )
562 return false;
563
564 if( m_fields.size() != other->m_fields.size() )
565 return false;
566
567 for( size_t ii = 0; ii < m_fields.size(); ++ii )
568 {
569 if( !( m_fields[ii] == other->m_fields[ii] ) )
570 return false;
571 }
572
573 return SCH_TEXT::operator==( aOther );
574}
575
576
577double SCH_LABEL_BASE::Similarity( const SCH_ITEM& aOther ) const
578{
579 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
580
581 if( !other )
582 return 0.0;
583
584 if( m_Uuid == other->m_Uuid )
585 return 1.0;
586
587 double similarity = SCH_TEXT::Similarity( aOther );
588
589 if( typeid( *this ) != typeid( aOther ) )
590 similarity *= 0.9;
591
592 if( m_shape == other->m_shape )
593 similarity *= 0.9;
594
595 if( m_connectionType == other->m_connectionType )
596 similarity *= 0.9;
597
598 for( size_t ii = 0; ii < m_fields.size(); ++ii )
599 {
600 if( ii >= other->m_fields.size() )
601 break;
602
603 similarity *= m_fields[ii].Similarity( other->m_fields[ii] );
604 }
605
606 int diff = std::abs( int( m_fields.size() ) - int( other->m_fields.size() ) );
607
608 similarity *= std::pow( 0.9, diff );
609
610 return similarity;
611}
612
613
614void SCH_LABEL_BASE::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
615{
616 int margin = GetTextOffset() * 2;
617 int labelLen = GetBodyBoundingBox().GetSizeMax();
618 int accumulated = GetTextHeight() / 2;
619
620 if( Type() == SCH_GLOBAL_LABEL_T )
621 accumulated += margin + GetPenWidth() + margin;
622
623 for( SCH_FIELD& field : m_fields )
624 {
625 VECTOR2I offset( 0, 0 );
626
627 switch( GetSpinStyle() )
628 {
629 default:
630 case SPIN_STYLE::LEFT:
631 field.SetTextAngle( ANGLE_HORIZONTAL );
632 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
633
634 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
635 offset.x = - ( labelLen + margin );
636 else
637 offset.y = accumulated + field.GetTextHeight() / 2;
638
639 break;
640
641 case SPIN_STYLE::UP:
642 field.SetTextAngle( ANGLE_VERTICAL );
643 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
644
645 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
646 offset.y = - ( labelLen + margin );
647 else
648 offset.x = accumulated + field.GetTextHeight() / 2;
649
650 break;
651
653 field.SetTextAngle( ANGLE_HORIZONTAL );
654 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
655
656 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
657 offset.x = labelLen + margin;
658 else
659 offset.y = accumulated + field.GetTextHeight() / 2;
660
661 break;
662
664 field.SetTextAngle( ANGLE_VERTICAL );
665 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
666
667 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
668 offset.y = labelLen + margin;
669 else
670 offset.x = accumulated + field.GetTextHeight() / 2;
671
672 break;
673 }
674
675 field.SetTextPos( GetTextPos() + offset );
676
677 if( field.GetCanonicalName() != wxT( "Intersheetrefs" ) )
678 accumulated += field.GetTextHeight() + margin;
679 }
680
682}
683
684
686 std::vector<std::pair<wxString, wxString>>* pages )
687{
688 wxCHECK( pages, /* void */ );
689
690 if( Schematic() )
691 {
692 wxString resolvedLabel = GetShownText( &Schematic()->CurrentSheet(), false );
693 auto it = Schematic()->GetPageRefsMap().find( resolvedLabel );
694
695 if( it != Schematic()->GetPageRefsMap().end() )
696 {
697 std::vector<int> pageListCopy;
698
699 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
700
701 if( !Schematic()->Settings().m_IntersheetRefsListOwnPage )
702 {
703 int currentPage = Schematic()->CurrentSheet().GetVirtualPageNumber();
704 alg::delete_matching( pageListCopy, currentPage );
705
706 if( pageListCopy.empty() )
707 return;
708 }
709
710 std::sort( pageListCopy.begin(), pageListCopy.end() );
711
712 std::map<int, wxString> sheetPages = Schematic()->GetVirtualPageToSheetPagesMap();
713 std::map<int, wxString> sheetNames = Schematic()->GetVirtualPageToSheetNamesMap();
714
715 for( int pageNum : pageListCopy )
716 pages->push_back( { sheetPages[ pageNum ], sheetNames[ pageNum ] } );
717 }
718 }
719}
720
721
722void SCH_LABEL_BASE::GetContextualTextVars( wxArrayString* aVars ) const
723{
724 for( const SCH_FIELD& field : m_fields )
725 aVars->push_back( field.GetCanonicalName().Upper() );
726
727 aVars->push_back( wxT( "OP" ) );
728 aVars->push_back( wxT( "CONNECTION_TYPE" ) );
729 aVars->push_back( wxT( "SHORT_NET_NAME" ) );
730 aVars->push_back( wxT( "NET_NAME" ) );
731 aVars->push_back( wxT( "NET_CLASS" ) );
732}
733
734
735bool SCH_LABEL_BASE::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token,
736 int aDepth ) const
737{
738 static wxRegEx operatingPoint( wxT( "^"
739 "OP"
740 "(.([0-9])?([a-zA-Z]*))?"
741 "$" ) );
742
743 wxCHECK( aPath, false );
744
745 SCHEMATIC* schematic = Schematic();
746
747 if( !schematic )
748 return false;
749
750 if( operatingPoint.Matches( *token ) )
751 {
752 int precision = 3;
753 wxString precisionStr( operatingPoint.GetMatch( *token, 2 ) );
754 wxString range( operatingPoint.GetMatch( *token, 3 ) );
755
756 if( !precisionStr.IsEmpty() )
757 precision = precisionStr[0] - '0';
758
759 if( range.IsEmpty() )
760 range = wxS( "~V" );
761
762 const SCH_CONNECTION* connection = Connection();
763 *token = wxS( "?" );
764
765 if( connection )
766 *token = schematic->GetOperatingPoint( connection->Name( false ), precision, range );
767
768 return true;
769 }
770
771 if( token->Contains( ':' ) )
772 {
773 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
774 return true;
775 }
776
778 && token->IsSameAs( wxT( "CONNECTION_TYPE" ) ) )
779 {
780 const SCH_LABEL_BASE* label = static_cast<const SCH_LABEL_BASE*>( this );
781 *token = getElectricalTypeLabel( label->GetShape() );
782 return true;
783 }
784 else if( token->IsSameAs( wxT( "SHORT_NET_NAME" ) ) )
785 {
786 const SCH_CONNECTION* connection = Connection();
787 *token = wxEmptyString;
788
789 if( connection )
790 *token = connection->LocalName();
791
792 return true;
793 }
794 else if( token->IsSameAs( wxT( "NET_NAME" ) ) )
795 {
796 const SCH_CONNECTION* connection = Connection();
797 *token = wxEmptyString;
798
799 if( connection )
800 *token = connection->Name();
801
802 return true;
803 }
804 else if( token->IsSameAs( wxT( "NET_CLASS" ) ) )
805 {
806 const SCH_CONNECTION* connection = Connection();
807 *token = wxEmptyString;
808
809 if( connection )
810 *token = GetEffectiveNetClass()->GetVariableSubstitutionName();
811
812 return true;
813 }
814
815 for( const SCH_FIELD& field : m_fields)
816 {
817 if( token->IsSameAs( field.GetName() ) )
818 {
819 *token = field.GetShownText( false, aDepth + 1 );
820 return true;
821 }
822 }
823
824 // See if parent can resolve it (these will recurse to ancestors)
825
826 if( Type() == SCH_SHEET_PIN_T && m_parent )
827 {
828 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
829
830 SCH_SHEET_PATH path = *aPath;
831 path.push_back( sheet );
832
833 if( sheet->ResolveTextVar( &path, token, aDepth + 1 ) )
834 return true;
835 }
836 else
837 {
838 if( aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
839 return true;
840 }
841
842 return false;
843}
844
845
847{
848 return !HasTextVars();
849}
850
851
853{
855}
856
857
859{
861
862 if( !HasTextVars() )
864}
865
866
867wxString SCH_LABEL_BASE::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText,
868 int aDepth ) const
869{
870 std::function<bool( wxString* )> textResolver =
871 [&]( wxString* token ) -> bool
872 {
873 return ResolveTextVar( aPath, token, aDepth + 1 );
874 };
875
876 wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
877
878 if( text == wxS( "~" ) ) // Legacy placeholder for empty string
879 {
880 text = wxS( "" );
881 }
882 else if( HasTextVars() )
883 {
884 if( aDepth < ADVANCED_CFG::GetCfg().m_ResolveTextRecursionDepth )
885 text = ExpandTextVars( text, &textResolver );
886 }
887
888 return text;
889}
890
891
892void SCH_LABEL_BASE::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
893{
894 for( SCH_FIELD& field : m_fields )
895 aFunction( &field );
896}
897
898
899bool SCH_LABEL_BASE::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
900{
901 return SCH_ITEM::Matches( UnescapeString( GetText() ), aSearchData );
902}
903
904
905bool SCH_LABEL_BASE::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
906{
907 EDA_SEARCH_DATA localSearchData( aSearchData );
908 localSearchData.findString = EscapeString( aSearchData.findString, CTX_NETNAME );
909 localSearchData.replaceString = EscapeString( aSearchData.replaceString, CTX_NETNAME );
910
911 return EDA_TEXT::Replace( localSearchData );
912}
913
914
916 const std::vector<KICAD_T>& aScanTypes )
917{
918 if( IsType( aScanTypes ) )
919 {
920 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
921 return INSPECT_RESULT::QUIT;
922 }
923
924 for( KICAD_T scanType : aScanTypes )
925 {
926 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
927 {
928 for( SCH_FIELD& field : m_fields )
929 {
930 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
931 return INSPECT_RESULT::QUIT;
932 }
933 }
934 }
935
936 return INSPECT_RESULT::CONTINUE;
937}
938
939
940void SCH_LABEL_BASE::GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList )
941{
942 DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() );
943 aItemList.push_back( item );
944}
945
946
947std::vector<VECTOR2I> SCH_LABEL_BASE::GetConnectionPoints() const
948{
949 return { GetTextPos() };
950}
951
952
953void SCH_LABEL_BASE::ViewGetLayers( int aLayers[], int& aCount ) const
954{
955 aCount = 5;
956 aLayers[0] = LAYER_DANGLING;
957 aLayers[1] = LAYER_DEVICE;
958 aLayers[2] = LAYER_NETCLASS_REFS;
959 aLayers[3] = LAYER_FIELDS;
960 aLayers[4] = LAYER_SELECTION_SHADOWS;
961}
962
963
965{
966 double ratio;
967
968 if( aSettings )
969 ratio = static_cast<const SCH_RENDER_SETTINGS*>( aSettings )->m_LabelSizeRatio;
970 else if( Schematic() )
972 else
973 ratio = DEFAULT_LABEL_SIZE_RATIO; // For previews (such as in Preferences), etc.
974
975 return KiROUND( ratio * GetTextSize().y );
976}
977
978
980{
981 // build the bounding box of the label only, without taking into account its fields
982
983 BOX2I box;
984 std::vector<VECTOR2I> pts;
985
986 CreateGraphicShape( nullptr, pts, GetTextPos() );
987
988 for( const VECTOR2I& pt : pts )
989 box.Merge( pt );
990
992 box.Normalize();
993 return box;
994}
995
996
998{
999 // build the bounding box of the entire label, including its fields
1000
1001 BOX2I box = GetBodyBoundingBox();
1002
1003 for( const SCH_FIELD& field : m_fields )
1004 {
1005 if( field.IsVisible() && field.GetText() != wxEmptyString )
1006 {
1007 BOX2I fieldBBox = field.GetBoundingBox();
1008
1009 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1010 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1011
1012 box.Merge( fieldBBox );
1013 }
1014 }
1015
1016 box.Normalize();
1017
1018 return box;
1019}
1020
1021
1022bool SCH_LABEL_BASE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1023{
1024 BOX2I bbox = GetBodyBoundingBox();
1025 bbox.Inflate( aAccuracy );
1026
1027 if( bbox.Contains( aPosition ) )
1028 return true;
1029
1030 for( const SCH_FIELD& field : m_fields )
1031 {
1032 if( field.IsVisible() )
1033 {
1034 BOX2I fieldBBox = field.GetBoundingBox();
1035 fieldBBox.Inflate( aAccuracy );
1036
1037 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1038 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1039
1040 if( fieldBBox.Contains( aPosition ) )
1041 return true;
1042 }
1043 }
1044
1045 return false;
1046}
1047
1048
1049bool SCH_LABEL_BASE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1050{
1051 BOX2I rect = aRect;
1052
1053 rect.Inflate( aAccuracy );
1054
1055 if( aContained )
1056 {
1057 return rect.Contains( GetBoundingBox() );
1058 }
1059 else
1060 {
1061 if( rect.Intersects( GetBodyBoundingBox() ) )
1062 return true;
1063
1064 for( const SCH_FIELD& field : m_fields )
1065 {
1066 if( field.IsVisible() )
1067 {
1068 BOX2I fieldBBox = field.GetBoundingBox();
1069
1070 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1071 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1072
1073 if( rect.Intersects( fieldBBox ) )
1074 return true;
1075 }
1076 }
1077
1078 return false;
1079 }
1080}
1081
1082
1083bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1084 std::vector<DANGLING_END_ITEM>& aItemListByPos,
1085 const SCH_SHEET_PATH* aPath )
1086{
1087 bool previousState = m_isDangling;
1088 VECTOR2I text_pos = GetTextPos();
1089 m_isDangling = true;
1090 m_connectionType = CONNECTION_TYPE::NONE;
1091
1092 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, text_pos );
1093 it < aItemListByPos.end() && it->GetPosition() == text_pos; it++ )
1094 {
1095 DANGLING_END_ITEM& item = *it;
1096
1097 if( item.GetItem() == this )
1098 continue;
1099
1100 switch( item.GetType() )
1101 {
1102 case PIN_END:
1103 case LABEL_END:
1104 case SHEET_LABEL_END:
1105 case NO_CONNECT_END:
1106 if( text_pos == item.GetPosition() )
1107 {
1108 m_isDangling = false;
1109
1110 if( aPath && item.GetType() != PIN_END )
1111 AddConnectionTo( *aPath, static_cast<SCH_ITEM*>( item.GetItem() ) );
1112 }
1113 break;
1114
1115 default: break;
1116 }
1117
1118 if( !m_isDangling )
1119 break;
1120 }
1121
1122 if( m_isDangling )
1123 {
1124 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, BUS_END );
1125 it < aItemListByType.end() && it->GetType() == BUS_END; it++ )
1126 {
1127 DANGLING_END_ITEM& item = *it;
1128 DANGLING_END_ITEM& nextItem = *( ++it );
1129
1130 int accuracy = 1; // We have rounding issues with an accuracy of 0
1131
1132 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(),
1133 accuracy );
1134
1135 if( m_isDangling )
1136 continue;
1137
1138 m_connectionType = CONNECTION_TYPE::BUS;
1139
1140 // Add the line to the connected items, since it won't be picked
1141 // up by a search of intersecting connection points
1142 if( aPath )
1143 {
1144 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1145 AddConnectionTo( *aPath, sch_item );
1146 sch_item->AddConnectionTo( *aPath, this );
1147 }
1148 break;
1149 }
1150
1151 if( m_isDangling )
1152 {
1153 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, WIRE_END );
1154 it < aItemListByType.end() && it->GetType() == WIRE_END; it++ )
1155 {
1156 DANGLING_END_ITEM& item = *it;
1157 DANGLING_END_ITEM& nextItem = *( ++it );
1158
1159 int accuracy = 1; // We have rounding issues with an accuracy of 0
1160
1161 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(),
1162 nextItem.GetPosition(), accuracy );
1163
1164 if( m_isDangling )
1165 continue;
1166
1167 m_connectionType = CONNECTION_TYPE::NET;
1168
1169 // Add the line to the connected items, since it won't be picked
1170 // up by a search of intersecting connection points
1171 if( aPath )
1172 {
1173 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1174 AddConnectionTo( *aPath, sch_item );
1175 sch_item->AddConnectionTo( *aPath, this );
1176 }
1177 break;
1178 }
1179 }
1180 }
1181
1182 if( m_isDangling )
1183 m_connectionType = CONNECTION_TYPE::NONE;
1184
1185 return previousState != m_isDangling;
1186}
1187
1188
1190 const SCH_SHEET_PATH* aInstance ) const
1191{
1192 // Do not compare to ourself.
1193 if( aItem == this || !IsConnectable() )
1194 return false;
1195
1196 const SCH_LABEL_BASE* label = dynamic_cast<const SCH_LABEL_BASE*>( aItem );
1197
1198 // Don't compare against a different SCH_ITEM.
1199 wxCHECK( label, false );
1200
1201 if( GetPosition() != label->GetPosition() )
1202 return true;
1203
1204 if( GetShownText( aInstance ) != label->GetShownText( aInstance ) )
1205 return true;
1206
1207 std::vector<wxString> netclasses;
1208 std::vector<wxString> otherNetclasses;
1209
1210 for( const SCH_FIELD& field : m_fields )
1211 {
1212 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1213 netclasses.push_back( field.GetText() );
1214 }
1215
1216 for( const SCH_FIELD& field : label->m_fields )
1217 {
1218 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1219 otherNetclasses.push_back( field.GetText() );
1220 }
1221
1222 return netclasses != otherNetclasses;
1223}
1224
1225
1226void SCH_LABEL_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1227{
1228 wxString msg;
1229
1230 switch( Type() )
1231 {
1232 case SCH_LABEL_T: msg = _( "Label" ); break;
1233 case SCH_DIRECTIVE_LABEL_T: msg = _( "Directive Label" ); break;
1234 case SCH_GLOBAL_LABEL_T: msg = _( "Global Label" ); break;
1235 case SCH_HIER_LABEL_T: msg = _( "Hierarchical Label" ); break;
1236 case SCH_SHEET_PIN_T: msg = _( "Hierarchical Sheet Pin" ); break;
1237 default: return;
1238 }
1239
1240 // Don't use GetShownText() here; we want to show the user the variable references
1241 aList.emplace_back( msg, UnescapeString( GetText() ) );
1242
1243 // Display electrical type if it is relevant
1245 aList.emplace_back( _( "Type" ), getElectricalTypeLabel( GetShape() ) );
1246
1247 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1248
1249 wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
1250 int style = IsBold() && IsItalic() ? 3 : IsBold() ? 2 : IsItalic() ? 1 : 0;
1251 aList.emplace_back( _( "Style" ), textStyle[style] );
1252
1253 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1254
1255 switch( GetSpinStyle() )
1256 {
1257 case SPIN_STYLE::LEFT: msg = _( "Align right" ); break;
1258 case SPIN_STYLE::UP: msg = _( "Align bottom" ); break;
1259 case SPIN_STYLE::RIGHT: msg = _( "Align left" ); break;
1260 case SPIN_STYLE::BOTTOM: msg = _( "Align top" ); break;
1261 default: msg = wxT( "???" ); break;
1262 }
1263
1264 aList.emplace_back( _( "Justification" ), msg );
1265
1266 SCH_CONNECTION* conn = nullptr;
1267
1268 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1269 conn = Connection();
1270
1271 if( conn )
1272 {
1273 conn->AppendInfoToMsgPanel( aList );
1274
1275 if( !conn->IsBus() )
1276 {
1277 aList.emplace_back( _( "Resolved Netclass" ),
1278 UnescapeString( GetEffectiveNetClass()->GetName() ) );
1279 }
1280 }
1281}
1282
1283
1284void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
1285 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1286{
1287 static std::vector<VECTOR2I> s_poly;
1288
1289 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
1290 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
1291 SCH_CONNECTION* connection = Connection();
1292 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1293 COLOR4D color = settings->GetLayerColor( layer );
1294 int penWidth = GetEffectiveTextPenWidth( settings->GetDefaultPenWidth() );
1295
1296 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1297 color = GetTextColor();
1298
1299 penWidth = std::max( penWidth, settings->GetMinPenWidth() );
1300 aPlotter->SetCurrentLineWidth( penWidth );
1301
1302 KIFONT::FONT* font = GetFont();
1303
1304 if( !font )
1305 font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), IsBold(), IsItalic() );
1306
1307 VECTOR2I textpos = GetTextPos() + GetSchematicTextOffset( aPlotter->RenderSettings() );
1308 CreateGraphicShape( aPlotter->RenderSettings(), s_poly, GetTextPos() );
1309
1311 attrs.m_StrokeWidth = penWidth;
1312 attrs.m_Multiline = false;
1313
1314 if( aBackground )
1315 {
1316 // No filled shapes (yet)
1317 }
1318 else
1319 {
1320 aPlotter->PlotText( textpos, color, GetShownText( sheet, true ), attrs, font,
1321 GetFontMetrics() );
1322
1323 if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
1324 {
1325 aPlotter->MoveTo( s_poly[0] );
1326 aPlotter->LineTo( s_poly[1] );
1327 aPlotter->PenFinish();
1328
1329 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1330 aPlotter->FilledCircle( s_poly[2], diameter , FILLED, nullptr );
1331 }
1332 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1333 {
1334 aPlotter->MoveTo( s_poly[0] );
1335 aPlotter->LineTo( s_poly[1] );
1336 aPlotter->PenFinish();
1337
1338 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1339 aPlotter->ThickCircle( s_poly[2], diameter, penWidth, FILLED, nullptr );
1340 }
1341 else
1342 {
1343 if( !s_poly.empty() )
1344 aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth );
1345 }
1346
1347 // Make sheet pins and hierarchical labels clickable hyperlinks
1348 bool linkAlreadyPlotted = false;
1349 if( aPlotOpts.m_PDFHierarchicalLinks )
1350 {
1351 if( Type() == SCH_HIER_LABEL_T )
1352 {
1353 if( sheet->size() >= 2 )
1354 {
1355 SCH_SHEET_PATH path = *sheet;
1356 path.pop_back();
1357 aPlotter->HyperlinkBox( GetBodyBoundingBox(),
1358 EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1359 linkAlreadyPlotted = true;
1360 }
1361 }
1362 else if( Type() == SCH_SHEET_PIN_T )
1363 {
1364 SCH_SHEET_PATH path = *sheet;
1365 SCH_SHEET* parent = static_cast<SCH_SHEET*>( m_parent );
1366 path.push_back( parent );
1367 aPlotter->HyperlinkBox( GetBodyBoundingBox(),
1368 EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1369 linkAlreadyPlotted = true;
1370 }
1371 }
1372
1373 // Plot attributes to a hypertext menu
1374 if( aPlotOpts.m_PDFPropertyPopups && !linkAlreadyPlotted )
1375 {
1376 std::vector<wxString> properties;
1377
1378 if( connection )
1379 {
1380 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Net" ),
1381 connection->Name() ) );
1382
1383 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
1384 _( "Resolved netclass" ),
1385 GetEffectiveNetClass()->GetName() ) );
1386 }
1387
1388 for( const SCH_FIELD& field : GetFields() )
1389 {
1390 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), field.GetName(),
1391 field.GetShownText( false ) ) );
1392 }
1393
1394 if( !properties.empty() )
1395 aPlotter->HyperlinkMenu( GetBodyBoundingBox(), properties );
1396 }
1397
1398 if( Type() == SCH_HIER_LABEL_T )
1399 {
1400 aPlotter->Bookmark( GetBodyBoundingBox(), GetShownText( false ),
1401 _( "Hierarchical Labels" ) );
1402 }
1403 }
1404
1405 for( SCH_FIELD& field : m_fields )
1406 field.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
1407}
1408
1409
1410void SCH_LABEL_BASE::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
1411 const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
1412{
1413 static std::vector<VECTOR2I> s_poly;
1414
1415 SCH_CONNECTION* connection = Connection();
1416 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1417 wxDC* DC = aSettings->GetPrintDC();
1418 COLOR4D color = aSettings->GetLayerColor( layer );
1419 bool blackAndWhiteMode = GetGRForceBlackPenState();
1420 int penWidth = GetEffectivePenWidth( aSettings );
1421 VECTOR2I text_offset = aOffset + GetSchematicTextOffset( aSettings );
1422
1423 if( !blackAndWhiteMode && GetTextColor() != COLOR4D::UNSPECIFIED )
1424 color = GetTextColor();
1425
1426 EDA_TEXT::Print( aSettings, text_offset, color );
1427
1428 CreateGraphicShape( aSettings, s_poly, GetTextPos() + aOffset );
1429
1430 if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
1431 {
1432 GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
1433
1434 int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
1435 GRFilledCircle( DC, s_poly[2], radius, penWidth, color, color );
1436 }
1437 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1438 {
1439 GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
1440
1441 int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
1442 GRCircle( DC, s_poly[2], radius, penWidth, color );
1443 }
1444 else
1445 {
1446 if( !s_poly.empty() )
1447 GRPoly( DC, s_poly.size(), &s_poly[0], false, penWidth, color, color );
1448 }
1449
1450 for( SCH_FIELD& field : m_fields )
1451 field.Print( aSettings, aUnit, aBodyStyle, aOffset, aForceNoFill, aDimmed );
1452}
1453
1454
1456{
1458}
1459
1460
1462{
1463 m_autoRotateOnPlacement = autoRotate;
1464}
1465
1466
1467SCH_LABEL::SCH_LABEL( const VECTOR2I& pos, const wxString& text ) :
1469{
1471 m_shape = LABEL_FLAG_SHAPE::L_INPUT;
1472 m_isDangling = true;
1473}
1474
1475
1476void SCH_LABEL::Serialize( google::protobuf::Any &aContainer ) const
1477{
1478 kiapi::schematic::types::LocalLabel label;
1479
1480 label.mutable_id()->set_value( m_Uuid.AsStdString() );
1481 kiapi::common::PackVector2( *label.mutable_position(), GetPosition() );
1482
1483 aContainer.PackFrom( label );
1484}
1485
1486
1487bool SCH_LABEL::Deserialize( const google::protobuf::Any &aContainer )
1488{
1489 kiapi::schematic::types::LocalLabel label;
1490
1491 if( !aContainer.UnpackTo( &label ) )
1492 return false;
1493
1494 const_cast<KIID&>( m_Uuid ) = KIID( label.id().value() );
1495 SetPosition( kiapi::common::UnpackVector2( label.position() ) );
1496
1497 return true;
1498}
1499
1500
1502{
1503 BOX2I rect = GetTextBox();
1504
1505 rect.Offset( 0, -GetTextOffset() );
1507
1508 if( !GetTextAngle().IsZero() )
1509 {
1510 // Rotate rect
1511 VECTOR2I pos = rect.GetOrigin();
1512 VECTOR2I end = rect.GetEnd();
1513
1514 RotatePoint( pos, GetTextPos(), GetTextAngle() );
1515 RotatePoint( end, GetTextPos(), GetTextAngle() );
1516
1517 rect.SetOrigin( pos );
1518 rect.SetEnd( end );
1519
1520 rect.Normalize();
1521 }
1522
1523 // Labels have a position point that is outside of the TextBox
1524 rect.Merge( GetPosition() );
1525
1526 return rect;
1527}
1528
1529
1530wxString SCH_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1531{
1532 return wxString::Format( _( "Label '%s'" ),
1533 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
1534}
1535
1536
1538{
1539 return BITMAPS::add_line_label;
1540}
1541
1542
1544 SCH_LABEL_BASE( pos, wxEmptyString, SCH_DIRECTIVE_LABEL_T )
1545{
1547 m_shape = LABEL_FLAG_SHAPE::F_ROUND;
1550 m_isDangling = true;
1551}
1552
1553
1555{
1556 SCH_LABEL_BASE::SwapData( aItem );
1557
1558 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( aItem );
1559
1560 std::swap( m_pinLength, label->m_pinLength );
1561 std::swap( m_symbolSize, label->m_symbolSize );
1562}
1563
1564
1566 SCH_LABEL_BASE( aClassLabel )
1567{
1568 m_pinLength = aClassLabel.m_pinLength;
1569 m_symbolSize = aClassLabel.m_symbolSize;
1570}
1571
1572
1573void SCH_DIRECTIVE_LABEL::Serialize( google::protobuf::Any &aContainer ) const
1574{
1575 // TODO
1576}
1577
1578
1579bool SCH_DIRECTIVE_LABEL::Deserialize( const google::protobuf::Any &aContainer )
1580{
1581 // TODO
1582 return false;
1583}
1584
1585
1587{
1588 int pen = 0;
1589
1590 if( Schematic() )
1592
1593 return GetEffectiveTextPenWidth( pen );
1594}
1595
1596
1598{
1599 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1600 // vertical shape (like a text reduced to only "I" letter).
1601 // So the mirroring is not exactly similar to a SCH_TEXT item
1602 SCH_TEXT::MirrorSpinStyle( !aLeftRight );
1603
1604 for( SCH_FIELD& field : m_fields )
1605 {
1606 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
1607 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
1608 {
1609 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1610 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1611 else
1612 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1613 }
1614
1615 VECTOR2I pos = field.GetTextPos();
1617
1618 if( aLeftRight )
1619 pos.x = GetPosition().x + delta.x;
1620 else
1621 pos.y = GetPosition().y + delta.y;
1622
1623 field.SetTextPos( pos );
1624 }
1625}
1626
1627
1629{
1630 VECTOR2I old_pos = GetPosition();
1631 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1632 // vertical shape (like a text reduced to only "I" letter).
1633 // So the mirroring is not exactly similar to a SCH_TEXT item
1634 // Text is NOT really mirrored; it is moved to a suitable horizontal position
1635 SetSpinStyle( GetSpinStyle().MirrorX() );
1636
1637 SetTextX( MIRRORVAL( GetTextPos().x, aCenter ) );
1638
1639 for( SCH_FIELD& field : m_fields )
1640 {
1641 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1642 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1643 else if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1644 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1645
1646 VECTOR2I pos = field.GetTextPos();
1647 VECTOR2I delta = old_pos - pos;
1648 pos.x = GetPosition().x + delta.x;
1649
1650 field.SetPosition( pos );
1651 }
1652}
1653
1654
1656{
1657 VECTOR2I old_pos = GetPosition();
1658 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1659 // vertical shape (like a text reduced to only "I" letter).
1660 // So the mirroring is not exactly similar to a SCH_TEXT item
1661 // Text is NOT really mirrored; it is moved to a suitable vertical position
1662 SetSpinStyle( GetSpinStyle().MirrorY() );
1663
1664 SetTextY( MIRRORVAL( GetTextPos().y, aCenter ) );
1665
1666 for( SCH_FIELD& field : m_fields )
1667 {
1668 VECTOR2I pos = field.GetTextPos();
1669 VECTOR2I delta = old_pos - pos;
1670 pos.y = GetPosition().y + delta.y;
1671
1672 field.SetPosition( pos );
1673 }
1674}
1675
1676
1678 std::vector<VECTOR2I>& aPoints,
1679 const VECTOR2I& aPos ) const
1680{
1681 int symbolSize = m_symbolSize;
1682
1683 aPoints.clear();
1684
1685 switch( m_shape )
1686 {
1687 case LABEL_FLAG_SHAPE::F_DOT:
1688 symbolSize = KiROUND( symbolSize * 0.7 );
1690
1691 case LABEL_FLAG_SHAPE::F_ROUND:
1692 // First 3 points are used for generating shape
1693 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1694 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1695 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1696
1697 // These points are just used to bulk out the bounding box
1698 aPoints.emplace_back( VECTOR2I( -m_symbolSize, m_pinLength ) );
1699 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1700 aPoints.emplace_back( VECTOR2I( m_symbolSize, m_pinLength + symbolSize ) );
1701 break;
1702
1703 case LABEL_FLAG_SHAPE::F_DIAMOND:
1704 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1705 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1706 aPoints.emplace_back( VECTOR2I( -2 * m_symbolSize, m_pinLength ) );
1707 aPoints.emplace_back( VECTOR2I( 0, m_pinLength + symbolSize ) );
1708 aPoints.emplace_back( VECTOR2I( 2 * m_symbolSize, m_pinLength ) );
1709 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1710 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1711 break;
1712
1713 case LABEL_FLAG_SHAPE::F_RECTANGLE:
1714 symbolSize = KiROUND( symbolSize * 0.8 );
1715
1716 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1717 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1718 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength - symbolSize ) );
1719 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength + symbolSize ) );
1720 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength + symbolSize ) );
1721 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength - symbolSize ) );
1722 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1723 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1724 break;
1725
1726 default:
1727 break;
1728 }
1729
1730 // Rotate outlines and move corners to real position
1731 for( VECTOR2I& aPoint : aPoints )
1732 {
1733 switch( GetSpinStyle() )
1734 {
1735 default:
1736 case SPIN_STYLE::LEFT: break;
1737 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
1738 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
1739 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
1740 }
1741
1742 aPoint += aPos;
1743 }
1744}
1745
1746
1748{
1749 int margin = GetTextOffset();
1750 int symbolWidth = m_symbolSize;
1751 int origin = m_pinLength;
1752
1753 if( m_shape == LABEL_FLAG_SHAPE::F_DIAMOND || m_shape == LABEL_FLAG_SHAPE::F_RECTANGLE )
1754 symbolWidth *= 2;
1755
1756 if( IsItalic() )
1757 margin = KiROUND( margin * 1.5 );
1758
1759 VECTOR2I offset;
1760
1761 for( SCH_FIELD& field : m_fields )
1762 {
1763 if( field.GetText() == wxEmptyString )
1764 continue;
1765
1766 switch( GetSpinStyle() )
1767 {
1768 default:
1769 case SPIN_STYLE::LEFT:
1770 field.SetTextAngle( ANGLE_HORIZONTAL );
1771 offset = { symbolWidth + margin, origin };
1772 break;
1773
1774 case SPIN_STYLE::UP:
1775 field.SetTextAngle( ANGLE_VERTICAL );
1776 offset = { -origin, -( symbolWidth + margin ) };
1777 break;
1778
1779 case SPIN_STYLE::RIGHT:
1780 field.SetTextAngle( ANGLE_HORIZONTAL );
1781 offset = { symbolWidth + margin, -origin };
1782 break;
1783
1784 case SPIN_STYLE::BOTTOM:
1785 field.SetTextAngle( ANGLE_VERTICAL );
1786 offset = { origin, -( symbolWidth + margin ) };
1787 break;
1788 }
1789
1790 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1791 field.SetTextPos( GetPosition() + offset );
1792
1793 origin -= field.GetTextHeight() + margin;
1794 }
1795
1797}
1798
1799
1800wxString SCH_DIRECTIVE_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1801{
1802 if( m_fields.empty() )
1803 {
1804 return _( "Directive Label" );
1805 }
1806 else
1807 {
1808 return wxString::Format( _( "Directive Label [%s %s]" ),
1809 UnescapeString( m_fields[0].GetName() ),
1810 aFull ? m_fields[0].GetShownText( false )
1812 }
1813}
1814
1815
1817{
1818 m_connected_rule_areas.insert( aRuleArea );
1819}
1820
1821
1823{
1824 m_connected_rule_areas.clear();
1825}
1826
1827
1829{
1830 m_connected_rule_areas.erase( aRuleArea );
1831}
1832
1833
1835{
1836 return m_isDangling && m_connected_rule_areas.empty();
1837}
1838
1839
1840SCH_GLOBALLABEL::SCH_GLOBALLABEL( const VECTOR2I& pos, const wxString& text ) :
1842{
1844 m_shape = LABEL_FLAG_SHAPE::L_BIDI;
1845 m_isDangling = true;
1846
1848
1849 m_fields.emplace_back( SCH_FIELD( pos, 0, this, wxT( "Sheet References" ) ) );
1850 m_fields[0].SetText( wxT( "${INTERSHEET_REFS}" ) );
1851 m_fields[0].SetVisible( false );
1852 m_fields[0].SetLayer( LAYER_INTERSHEET_REFS );
1853 m_fields[0].SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
1854}
1855
1856
1858 SCH_LABEL_BASE( aGlobalLabel )
1859{
1860}
1861
1862
1863void SCH_GLOBALLABEL::Serialize( google::protobuf::Any &aContainer ) const
1864{
1865 // TODO
1866}
1867
1868
1869bool SCH_GLOBALLABEL::Deserialize( const google::protobuf::Any &aContainer )
1870{
1871 // TODO
1872 return false;
1873}
1874
1875
1877{
1878 int horiz = GetLabelBoxExpansion( aSettings );
1879
1880 // Center the text on the center line of "E" instead of "R" to make room for an overbar
1881 int vert = GetTextHeight() * 0.0715;
1882
1883 switch( m_shape )
1884 {
1885 case LABEL_FLAG_SHAPE::L_INPUT:
1886 case LABEL_FLAG_SHAPE::L_BIDI:
1887 case LABEL_FLAG_SHAPE::L_TRISTATE:
1888 horiz += GetTextHeight() * 3 / 4; // Use three-quarters-height as proxy for triangle size
1889 break;
1890
1891 case LABEL_FLAG_SHAPE::L_OUTPUT:
1892 case LABEL_FLAG_SHAPE::L_UNSPECIFIED:
1893 default:
1894 break;
1895 }
1896
1897 switch( GetSpinStyle() )
1898 {
1899 default:
1900 case SPIN_STYLE::LEFT: return VECTOR2I( -horiz, vert );
1901 case SPIN_STYLE::UP: return VECTOR2I( vert, -horiz );
1902 case SPIN_STYLE::RIGHT: return VECTOR2I( horiz, vert );
1903 case SPIN_STYLE::BOTTOM: return VECTOR2I( vert, horiz );
1904 }
1905}
1906
1907
1909{
1910 SCH_LABEL_BASE::SetSpinStyle( aSpinStyle );
1912}
1913
1914
1915bool SCH_GLOBALLABEL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token,
1916 int aDepth ) const
1917{
1918 wxCHECK( aPath, false );
1919
1920 SCHEMATIC* schematic = Schematic();
1921
1922 if( !schematic )
1923 return false;
1924
1925 if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) )
1926 {
1927 SCHEMATIC_SETTINGS& settings = schematic->Settings();
1928 wxString ref;
1929 auto it = schematic->GetPageRefsMap().find( GetShownText( aPath ) );
1930
1931 if( it == schematic->GetPageRefsMap().end() )
1932 {
1933 ref = "?";
1934 }
1935 else
1936 {
1937 std::vector<int> pageListCopy;
1938
1939 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
1940 std::sort( pageListCopy.begin(), pageListCopy.end() );
1941
1942 if( !settings.m_IntersheetRefsListOwnPage )
1943 {
1944 int currentPage = schematic->CurrentSheet().GetVirtualPageNumber();
1945 alg::delete_matching( pageListCopy, currentPage );
1946 }
1947
1948 std::map<int, wxString> sheetPages = schematic->GetVirtualPageToSheetPagesMap();
1949
1950 if( ( settings.m_IntersheetRefsFormatShort ) && ( pageListCopy.size() > 2 ) )
1951 {
1952 ref.Append( wxString::Format( wxT( "%s..%s" ),
1953 sheetPages[pageListCopy.front()],
1954 sheetPages[pageListCopy.back()] ) );
1955 }
1956 else
1957 {
1958 for( const int& pageNo : pageListCopy )
1959 ref.Append( wxString::Format( wxT( "%s," ), sheetPages[pageNo] ) );
1960
1961 if( !ref.IsEmpty() && ref.Last() == ',' )
1962 ref.RemoveLast();
1963 }
1964 }
1965
1966 *token = settings.m_IntersheetRefsPrefix + ref + settings.m_IntersheetRefsSuffix;
1967 return true;
1968 }
1969
1970 return SCH_LABEL_BASE::ResolveTextVar( aPath, token, aDepth );
1971}
1972
1973
1974void SCH_GLOBALLABEL::ViewGetLayers( int aLayers[], int& aCount ) const
1975{
1976 aCount = 6;
1977 aLayers[0] = LAYER_DANGLING;
1978 aLayers[1] = LAYER_DEVICE;
1979 aLayers[2] = LAYER_INTERSHEET_REFS;
1980 aLayers[3] = LAYER_NETCLASS_REFS;
1981 aLayers[4] = LAYER_FIELDS;
1982 aLayers[5] = LAYER_SELECTION_SHADOWS;
1983}
1984
1985
1987 std::vector<VECTOR2I>& aPoints,
1988 const VECTOR2I& aPos ) const
1989{
1990 int margin = GetLabelBoxExpansion( aRenderSettings );
1991 int halfSize = ( GetTextHeight() / 2 ) + margin;
1992 int linewidth = GetPenWidth();
1993 int symb_len = GetTextBox().GetWidth() + 2 * margin;
1994
1995 int x = symb_len + linewidth + 3;
1996 int y = halfSize + linewidth + 3;
1997
1998 aPoints.clear();
1999
2000 // Create outline shape : 6 points
2001 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
2002 aPoints.emplace_back( VECTOR2I( 0, -y ) ); // Up
2003 aPoints.emplace_back( VECTOR2I( -x, -y ) ); // left
2004 aPoints.emplace_back( VECTOR2I( -x, 0 ) ); // Up left
2005 aPoints.emplace_back( VECTOR2I( -x, y ) ); // left down
2006 aPoints.emplace_back( VECTOR2I( 0, y ) ); // down
2007
2008 int x_offset = 0;
2009
2010 switch( m_shape )
2011 {
2012 case LABEL_FLAG_SHAPE::L_INPUT:
2013 x_offset = -halfSize;
2014 aPoints[0].x += halfSize;
2015 break;
2016
2017 case LABEL_FLAG_SHAPE::L_OUTPUT:
2018 aPoints[3].x -= halfSize;
2019 break;
2020
2021 case LABEL_FLAG_SHAPE::L_BIDI:
2022 case LABEL_FLAG_SHAPE::L_TRISTATE:
2023 x_offset = -halfSize;
2024 aPoints[0].x += halfSize;
2025 aPoints[3].x -= halfSize;
2026 break;
2027
2028 case LABEL_FLAG_SHAPE::L_UNSPECIFIED:
2029 default:
2030 break;
2031 }
2032
2033 // Rotate outlines and move corners in real position
2034 for( VECTOR2I& aPoint : aPoints )
2035 {
2036 aPoint.x += x_offset;
2037
2038 switch( GetSpinStyle() )
2039 {
2040 default:
2041 case SPIN_STYLE::LEFT: break;
2042 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
2043 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
2044 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
2045 }
2046
2047 aPoint += aPos;
2048 }
2049
2050 aPoints.push_back( aPoints[0] ); // closing
2051}
2052
2053
2054wxString SCH_GLOBALLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2055{
2056 return wxString::Format( _( "Global Label '%s'" ),
2057 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
2058}
2059
2060
2062{
2063 return BITMAPS::add_glabel;
2064}
2065
2066
2067SCH_HIERLABEL::SCH_HIERLABEL( const VECTOR2I& pos, const wxString& text, KICAD_T aType ) :
2068 SCH_LABEL_BASE( pos, text, aType )
2069{
2071 m_shape = LABEL_FLAG_SHAPE::L_INPUT;
2072 m_isDangling = true;
2073}
2074
2075
2076void SCH_HIERLABEL::Serialize( google::protobuf::Any &aContainer ) const
2077{
2078 // TODO
2079}
2080
2081
2082bool SCH_HIERLABEL::Deserialize( const google::protobuf::Any &aContainer )
2083{
2084 // TODO
2085 return false;
2086}
2087
2088
2090{
2091 SCH_LABEL_BASE::SetSpinStyle( aSpinStyle );
2093}
2094
2095
2097 std::vector<VECTOR2I>& aPoints, const VECTOR2I& aPos ) const
2098{
2099 CreateGraphicShape( aSettings, aPoints, aPos, m_shape );
2100}
2101
2102
2104 std::vector<VECTOR2I>& aPoints, const VECTOR2I& aPos,
2105 LABEL_FLAG_SHAPE aShape ) const
2106{
2107 int* Template = TemplateShape[static_cast<int>( aShape )][static_cast<int>( GetSpinStyle() )];
2108 int halfSize = GetTextHeight() / 2;
2109 int imax = *Template;
2110 Template++;
2111
2112 aPoints.clear();
2113
2114 for( int ii = 0; ii < imax; ii++ )
2115 {
2116 VECTOR2I corner;
2117 corner.x = ( halfSize * (*Template) ) + aPos.x;
2118 Template++;
2119
2120 corner.y = ( halfSize * (*Template) ) + aPos.y;
2121 Template++;
2122
2123 aPoints.push_back( corner );
2124 }
2125}
2126
2127
2129{
2130 int penWidth = GetEffectiveTextPenWidth();
2131 int margin = GetTextOffset();
2132
2133 int x = GetTextPos().x;
2134 int y = GetTextPos().y;
2135
2136 int height = GetTextHeight() + penWidth + margin;
2137 int length = GetTextBox().GetWidth();
2138
2139 length += height; // add height for triangular shapes
2140
2141 int dx, dy;
2142
2143 switch( GetSpinStyle() )
2144 {
2145 default:
2146 case SPIN_STYLE::LEFT:
2147 dx = -length;
2148 dy = height;
2150 y -= height / 2;
2151 break;
2152
2153 case SPIN_STYLE::UP:
2154 dx = height;
2155 dy = -length;
2156 x -= height / 2;
2158 break;
2159
2160 case SPIN_STYLE::RIGHT:
2161 dx = length;
2162 dy = height;
2164 y -= height / 2;
2165 break;
2166
2167 case SPIN_STYLE::BOTTOM:
2168 dx = height;
2169 dy = length;
2170 x -= height / 2;
2172 break;
2173 }
2174
2175 BOX2I box( VECTOR2I( x, y ), VECTOR2I( dx, dy ) );
2176 box.Normalize();
2177 return box;
2178}
2179
2180
2182{
2183 VECTOR2I text_offset;
2184 int dist = GetTextOffset( aSettings );
2185
2186 dist += GetTextWidth();
2187
2188 switch( GetSpinStyle() )
2189 {
2190 default:
2191 case SPIN_STYLE::LEFT: text_offset.x = -dist; break; // Orientation horiz normale
2192 case SPIN_STYLE::UP: text_offset.y = -dist; break; // Orientation vert UP
2193 case SPIN_STYLE::RIGHT: text_offset.x = dist; break; // Orientation horiz inverse
2194 case SPIN_STYLE::BOTTOM: text_offset.y = dist; break; // Orientation vert BOTTOM
2195 }
2196
2197 return text_offset;
2198}
2199
2200
2201wxString SCH_HIERLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2202{
2203 return wxString::Format( _( "Hierarchical Label '%s'" ),
2204 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
2205}
2206
2207
2209{
2210 return BITMAPS::add_hierarchical_label;
2211}
2212
2213
2215{
2216 wxString msg =
2217#include "sch_text_help_md.h"
2218 ;
2219
2220 HTML_MESSAGE_BOX* dlg = new HTML_MESSAGE_BOX( nullptr, _( "Syntax Help" ) );
2221 wxSize sz( 320, 320 );
2222
2223 dlg->SetMinSize( dlg->ConvertDialogToPixels( sz ) );
2224 dlg->SetDialogSizeInDU( sz.x, sz.y );
2225
2226 wxString html_txt;
2227 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
2228 dlg->AddHTML_Text( html_txt );
2229 dlg->ShowModeless();
2230
2231 return dlg;
2232}
2233
2234
2235static struct SCH_LABEL_DESC
2236{
2238 {
2239 auto& labelShapeEnum = ENUM_MAP<LABEL_SHAPE>::Instance();
2240
2241 if( labelShapeEnum.Choices().GetCount() == 0 )
2242 {
2243 labelShapeEnum.Map( LABEL_SHAPE::LABEL_INPUT, _HKI( "Input" ) )
2244 .Map( LABEL_SHAPE::LABEL_OUTPUT, _HKI( "Output" ) )
2245 .Map( LABEL_SHAPE::LABEL_BIDI, _HKI( "Bidirectional" ) )
2246 .Map( LABEL_SHAPE::LABEL_TRISTATE, _HKI( "Tri-state" ) )
2247 .Map( LABEL_SHAPE::LABEL_PASSIVE, _HKI( "Passive" ) );
2248 }
2249
2254
2258
2262
2266
2271
2272 auto hasLabelShape =
2273 []( INSPECTABLE* aItem ) -> bool
2274 {
2275 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aItem ) )
2276 return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T } );
2277
2278 return false;
2279 };
2280
2281 propMgr.AddProperty( new PROPERTY_ENUM<SCH_LABEL_BASE, LABEL_SHAPE>( _HKI( "Shape" ),
2283 .SetAvailableFunc( hasLabelShape );
2284
2285 propMgr.Mask( TYPE_HASH( SCH_LABEL_BASE ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
2286 }
2288
2289
2291{
2293 {
2294 auto& flagShapeEnum = ENUM_MAP<FLAG_SHAPE>::Instance();
2295
2296 if( flagShapeEnum.Choices().GetCount() == 0 )
2297 {
2298 flagShapeEnum.Map( FLAG_SHAPE::FLAG_DOT, _HKI( "Dot" ) )
2299 .Map( FLAG_SHAPE::FLAG_CIRCLE, _HKI( "Circle" ) )
2300 .Map( FLAG_SHAPE::FLAG_DIAMOND, _HKI( "Diamond" ) )
2301 .Map( FLAG_SHAPE::FLAG_RECTANGLE, _HKI( "Rectangle" ) );
2302 }
2303
2309
2311
2314
2315 propMgr.AddProperty( new PROPERTY<SCH_DIRECTIVE_LABEL, int>( _HKI( "Pin length" ),
2317 PROPERTY_DISPLAY::PT_SIZE ) );
2318
2319 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Text" ) );
2320 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
2321 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Italic" ) );
2322 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Bold" ) );
2324 _HKI( "Horizontal Justification" ) );
2326 _HKI( "Vertical Justification" ) );
2327 }
2329
2330
int color
Definition: DXF_plotter.cpp:58
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
constexpr int GetSizeMax() const
Definition: box2.h:235
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 size_type GetWidth() const
Definition: box2.h:214
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:658
constexpr bool Contains(const Vec &aPoint) const
Definition: box2.h:168
constexpr const Vec & GetOrigin() const
Definition: box2.h:210
constexpr void SetEnd(coord_type x, coord_type y)
Definition: box2.h:297
constexpr void Offset(coord_type dx, coord_type dy)
Definition: box2.h:259
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:311
static std::vector< DANGLING_END_ITEM >::iterator get_lower_type(std::vector< DANGLING_END_ITEM > &aItemListByType, const DANGLING_END_T &aType)
Definition: sch_item.cpp:605
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition: sch_item.cpp:594
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:95
DANGLING_END_T GetType() const
Definition: sch_item.h:131
EDA_ITEM * GetItem() const
Definition: sch_item.h:129
VECTOR2I GetPosition() const
Definition: sch_item.h:128
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition: eda_item.h:489
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:377
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:500
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
int GetTextHeight() const
Definition: eda_text.h:247
const VECTOR2I & GetTextPos() const
Definition: eda_text.h:253
COLOR4D GetTextColor() const
Definition: eda_text.h:250
bool IsItalic() const
Definition: eda_text.h:152
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:130
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:449
void SetTextX(int aX)
Definition: eda_text.cpp:455
KIFONT::FONT * GetFont() const
Definition: eda_text.h:230
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:601
void SetTextY(int aY)
Definition: eda_text.cpp:461
int GetTextWidth() const
Definition: eda_text.h:244
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:306
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:183
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition: eda_text.cpp:375
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition: eda_text.h:113
static wxString GotoPageHref(const wxString &aDestination)
Generate a href to a page in the current schematic.
Definition: eda_text.cpp:1189
virtual void cacheShownText()
Definition: eda_text.cpp:494
const TEXT_ATTRIBUTES & GetAttributes() const
Definition: eda_text.h:214
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition: eda_text.cpp:354
bool IsBold() const
Definition: eda_text.h:167
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:105
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:182
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:204
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, const COLOR4D &aColor, OUTLINE_MODE aDisplay_mode=FILLED)
Print this text object to the device context aDC.
Definition: eda_text.cpp:754
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.cpp:290
VECTOR2I GetTextSize() const
Definition: eda_text.h:241
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:298
static ENUM_MAP< T > & Instance()
Definition: property.h:663
void SetDialogSizeInDU(int aWidth, int aHeight)
Set the dialog size, using a "logical" value.
void AddHTML_Text(const wxString &message)
Add HTML text (without any change) to message list.
void ShowModeless()
Show a modeless version of the dialog (without an OK button).
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:36
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
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
int GetDefaultPenWidth() const
const wxString & GetDefaultFont() const
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:244
Base plotter engine class.
Definition: plotter.h:105
virtual void ThickCircle(const VECTOR2I &pos, int diametre, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:646
virtual void FilledCircle(const VECTOR2I &pos, int diametre, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:662
void MoveTo(const VECTOR2I &pos)
Definition: plotter.h:244
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:136
virtual void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString)
Create a bookmark to a symbol.
Definition: plotter.h:476
virtual void HyperlinkBox(const BOX2I &aBox, const wxString &aDestinationURL)
Create a clickable hyperlink with a rectangular click area.
Definition: plotter.h:454
bool GetColorMode() const
Definition: plotter.h:133
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
void LineTo(const VECTOR2I &pos)
Definition: plotter.h:249
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
void PenFinish()
Definition: plotter.h:260
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:753
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:465
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 AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
Definition: schematic.h:77
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:152
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:720
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:314
std::map< wxString, std::set< int > > & GetPageRefsMap()
Definition: schematic.h:196
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
Definition: schematic.cpp:494
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
Definition: schematic.cpp:478
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:444
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString LocalName() const
wxString Name(bool aIgnoreSheet=false) const
bool IsBus() const
void AppendInfoToMsgPanel(std::vector< MSG_PANEL_ITEM > &aList) const
Adds information about the connection object to aList.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:1573
void MirrorSpinStyle(bool aLeftRight) override
Definition: sch_label.cpp:1597
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_label.cpp:1554
void RemoveConnectedRuleArea(SCH_RULE_AREA *aRuleArea)
Removes a specific rule area from the cache.
Definition: sch_label.cpp:1828
void ClearConnectedRuleAreas()
Removes all rule areas from the cache.
Definition: sch_label.cpp:1822
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:1655
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:1628
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:1747
SCH_DIRECTIVE_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0))
Definition: sch_label.cpp:1543
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:1800
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:1579
void CreateGraphicShape(const RENDER_SETTINGS *aSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &aPos) const override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.cpp:1677
FLAG_SHAPE GetFlagShape() const
Definition: sch_label.h:460
int GetPenWidth() const override
Definition: sch_label.cpp:1586
std::unordered_set< SCH_RULE_AREA * > m_connected_rule_areas
Cache of any rule areas with borders which this label connects to.
Definition: sch_label.h:502
void SetPinLength(int aLength)
Definition: sch_label.h:464
virtual bool IsDangling() const override
Determines dangling state from connectivity and cached connected rule areas.
Definition: sch_label.cpp:1834
void AddConnectedRuleArea(SCH_RULE_AREA *aRuleArea)
Adds an entry to the connected rule area cache.
Definition: sch_label.cpp:1816
void SetFlagShape(FLAG_SHAPE aShape)
Definition: sch_label.h:461
int GetPinLength() const
Definition: sch_label.h:463
Schematic editor (Eeschema) main window.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
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:1252
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_label.cpp:1974
void CreateGraphicShape(const RENDER_SETTINGS *aRenderSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &aPos) const override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.cpp:1986
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const override
Resolve any references to system tokens supported by the label.
Definition: sch_label.cpp:1915
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:1876
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
Definition: sch_label.cpp:1908
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:1869
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:1863
SCH_GLOBALLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
Definition: sch_label.cpp:1840
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:2061
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:2054
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:2082
const BOX2I GetBodyBoundingBox() const override
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:2128
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
Definition: sch_label.cpp:2089
void CreateGraphicShape(const RENDER_SETTINGS *aSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &aPos) const override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.cpp:2096
SCH_HIERLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString, KICAD_T aType=SCH_HIER_LABEL_T)
Definition: sch_label.cpp:2067
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:2208
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:2076
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:2201
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:2181
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
virtual bool IsConnectable() const
Definition: sch_item.h:449
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition: sch_item.cpp:101
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
void AddConnectionTo(const SCH_SHEET_PATH &aPath, SCH_ITEM *aItem)
Add a connection link between this item and another.
Definition: sch_item.cpp:286
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition: sch_item.cpp:250
void ClearFieldsAutoplaced()
Definition: sch_item.h:551
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:727
bool IsConnectivityDirty() const
Definition: sch_item.h:510
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:221
const KIFONT::METRICS & GetFontMetrics() const
Definition: sch_item.cpp:466
std::map< SCH_SHEET_PATH, SCH_ITEM_VEC, SHEET_PATH_CMP > m_connected_items
Store pointers to other items that are connected to this one, per sheet.
Definition: sch_item.h:732
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
Definition: sch_item.cpp:475
SCH_LAYER_ID m_layer
Definition: sch_item.h:723
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:181
bool operator==(const SCH_ITEM &aItem) const override
Definition: sch_label.cpp:551
const wxString & GetCachedDriverName() const override
Definition: sch_label.cpp:852
SCH_LABEL_BASE(const VECTOR2I &aPos, const wxString &aText, KICAD_T aType)
Definition: sch_label.cpp:212
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_label.cpp:953
COLOR4D m_lastResolvedColor
Definition: sch_label.h:373
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
Definition: sch_label.cpp:867
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_label.cpp:429
void Print(const SCH_RENDER_SETTINGS *aSettings, int aUnit, int aBodyStyle, const VECTOR2I &offset, bool aForceNoFill, bool aDimmed) override
Print an item.
Definition: sch_label.cpp:1410
bool m_isDangling
Definition: sch_label.h:370
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
Definition: sch_label.cpp:915
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_label.cpp:899
bool HasCachedDriverName() const override
Definition: sch_label.cpp:846
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_label.cpp:1022
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
Definition: sch_label.cpp:940
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1455
SCH_LABEL_BASE & operator=(const SCH_LABEL_BASE &aLabel)
Definition: sch_label.cpp:244
std::vector< SCH_FIELD > m_fields
Definition: sch_label.h:365
CONNECTION_TYPE m_connectionType
Definition: sch_label.h:369
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:499
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_label.cpp:1284
void SetLabelShape(LABEL_SHAPE aShape)
Definition: sch_label.h:182
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
Definition: sch_label.cpp:1189
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_label.cpp:315
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:383
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:685
void MirrorSpinStyle(bool aLeftRight) override
Definition: sch_label.cpp:471
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Definition: sch_label.cpp:947
COLOR4D GetLabelColor() const
Definition: sch_label.cpp:337
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:177
const BOX2I GetBoundingBox() const override
Return the bounding box of the label including its fields.
Definition: sch_label.cpp:997
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_label.cpp:267
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:518
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_label.cpp:422
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:735
LABEL_SHAPE GetLabelShape() const
Definition: sch_label.h:181
bool m_autoRotateOnPlacement
Definition: sch_label.h:371
wxString m_cached_driver_name
Definition: sch_label.h:375
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_label.cpp:438
int GetLabelBoxExpansion(const RENDER_SETTINGS *aSettings=nullptr) const
Definition: sch_label.cpp:964
bool IncrementLabel(int aIncrement)
Increment the label text, if it ends with a number.
Definition: sch_label.cpp:537
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1461
void cacheShownText() override
Definition: sch_label.cpp:858
void Rotate90(bool aClockwise) override
Definition: sch_label.cpp:453
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_label.cpp:1226
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:254
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:614
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
Definition: sch_label.cpp:892
LABEL_FLAG_SHAPE m_shape
Definition: sch_label.h:367
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this label.
Definition: sch_label.cpp:722
virtual const BOX2I GetBodyBoundingBox() const
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:979
virtual void CreateGraphicShape(const RENDER_SETTINGS *aSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &Pos) const
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.h:295
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:201
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos, const SCH_SHEET_PATH *aPath=nullptr) override
Test the schematic item to aItemList to check if it's dangling state has changed.
Definition: sch_label.cpp:1083
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:402
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:348
bool Replace(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) override
Perform a text replace using the find and replace criteria in aSearchData on items that support text ...
Definition: sch_label.cpp:905
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_label.cpp:577
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:1487
SCH_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
Definition: sch_label.cpp:1467
const BOX2I GetBodyBoundingBox() const override
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:1501
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:1537
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:1530
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:1476
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.
size_t size() const
Forwarded method from std::vector.
int GetVirtualPageNumber() const
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
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:252
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_text.h:106
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_text.cpp:158
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:2214
VECTOR2I GetPosition() const override
Definition: sch_text.h:141
virtual void Rotate90(bool aClockwise)
Definition: sch_text.cpp:209
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_text.cpp:119
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_text.cpp:687
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_text.cpp:231
int GetPenWidth() const override
Definition: sch_text.cpp:282
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:221
bool operator==(const SCH_ITEM &aItem) const override
Definition: sch_text.cpp:670
int GetTextOffset(const RENDER_SETTINGS *aSettings=nullptr) const
Definition: sch_text.cpp:267
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
Definition: sch_label.cpp:174
SPIN m_spin
Definition: sch_label.h:90
SPIN_STYLE()=default
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
Definition: sch_label.cpp:190
unsigned CCWRotationsTo(const SPIN_STYLE &aOther) const
Get CCW rotation needed to get to the given spin style.
Definition: sch_label.cpp:206
SPIN_STYLE RotateCCW()
Definition: sch_label.cpp:158
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)
Definition: common.cpp:59
#define DEFAULT_LABEL_SIZE_RATIO
The offset of the pin name string from the end of the pin in mils.
#define DANGLING_SYMBOL_SIZE
< The size of the rectangle indicating an unconnected wire or label
#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
static constexpr EDA_ANGLE ANGLE_180
Definition: eda_angle.h:405
INSPECT_RESULT
Definition: eda_item.h:43
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:82
void GRCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aColor)
Definition: gr_basic.cpp:357
void GRLine(wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:171
static const bool FILLED
Definition: gr_basic.cpp:30
void GRPoly(wxDC *DC, int n, const VECTOR2I *Points, bool Fill, int width, const COLOR4D &Color, const COLOR4D &BgColor)
Draw a new polyline and fill it if Fill, in drawing space.
Definition: gr_basic.cpp:341
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:165
void GRFilledCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aStrokeColor, const COLOR4D &aFillColor)
Draw a circle onto the drawing context aDC centered at the user coordinates (x,y).
Definition: gr_basic.cpp:369
@ LAYER_DANGLING
Definition: layer_ids.h:382
@ LAYER_DEVICE
Definition: layer_ids.h:371
@ LAYER_HIERLABEL
Definition: layer_ids.h:362
@ LAYER_GLOBLABEL
Definition: layer_ids.h:361
@ LAYER_NOTES
Definition: layer_ids.h:372
@ LAYER_BUS
Definition: layer_ids.h:358
@ LAYER_FIELDS
Definition: layer_ids.h:367
@ LAYER_LOCLABEL
Definition: layer_ids.h:360
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:369
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:398
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:368
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
constexpr T MIRRORVAL(T aPoint, T aMirrorRef)
Returns the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:36
Message panel definition file.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:213
void delete_matching(_Container &__c, _Value __value)
Covers for the horrifically named std::remove and std::remove_if (neither of which remove anything).
Definition: kicad_algo.h:165
void PackVector2(kiapi::common::types::Vector2 &aOutput, const VECTOR2I aInput)
Definition: api_utils.cpp:69
VECTOR2I UnpackVector2(const types::Vector2 &aInput)
Definition: api_utils.cpp:75
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:390
see class PGM_BASE
#define TYPE_HASH(x)
Definition: property.h:71
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:765
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
CONNECTION_TYPE
@ NONE
No connection to this item.
@ NO_CONNECT_END
Definition: sch_item.h:86
@ SHEET_LABEL_END
Definition: sch_item.h:85
@ LABEL_END
Definition: sch_item.h:82
@ BUS_END
Definition: sch_item.h:79
@ PIN_END
Definition: sch_item.h:81
@ WIRE_END
Definition: sch_item.h:78
std::vector< SCH_ITEM * > SCH_ITEM_VEC
Definition: sch_item.h:155
@ FIELDS_AUTOPLACED_AUTO
Definition: sch_item.h:70
static int TemplateIN_HI[]
Definition: sch_label.cpp:110
static int TemplateUNSPC_HI[]
Definition: sch_label.cpp:120
static int TemplateOUT_HN[]
Definition: sch_label.cpp:114
static int Template3STATE_HN[]
Definition: sch_label.cpp:129
static int TemplateBIDI_HN[]
Definition: sch_label.cpp:124
static int * TemplateShape[5][4]
Definition: sch_label.cpp:134
bool IncrementLabelMember(wxString &name, int aIncrement)
Definition: sch_label.cpp:52
static int TemplateIN_HN[]
Definition: sch_label.cpp:109
static int TemplateIN_BOTTOM[]
Definition: sch_label.cpp:112
static int TemplateUNSPC_HN[]
Definition: sch_label.cpp:119
static int Template3STATE_BOTTOM[]
Definition: sch_label.cpp:132
static int TemplateBIDI_BOTTOM[]
Definition: sch_label.cpp:127
static struct SCH_LABEL_DESC _SCH_LABEL_DESC
static int Template3STATE_UP[]
Definition: sch_label.cpp:131
static int TemplateOUT_UP[]
Definition: sch_label.cpp:116
static int TemplateOUT_HI[]
Definition: sch_label.cpp:115
static int TemplateUNSPC_UP[]
Definition: sch_label.cpp:121
static int TemplateUNSPC_BOTTOM[]
Definition: sch_label.cpp:122
static int TemplateOUT_BOTTOM[]
Definition: sch_label.cpp:117
static int Template3STATE_HI[]
Definition: sch_label.cpp:130
static int TemplateIN_UP[]
Definition: sch_label.cpp:111
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition: sch_label.cpp:144
static int TemplateBIDI_UP[]
Definition: sch_label.cpp:126
static int TemplateBIDI_HI[]
Definition: sch_label.cpp:125
static struct SCH_DIRECTIVE_LABEL_DESC _SCH_DIRECTIVE_LABEL_DESC
FLAG_SHAPE
Definition: sch_label.h:125
LABEL_FLAG_SHAPE
Definition: sch_label.h:98
@ L_BIDI
Definition: sch_label.h:101
@ L_TRISTATE
Definition: sch_label.h:102
@ L_UNSPECIFIED
Definition: sch_label.h:103
@ L_OUTPUT
Definition: sch_label.h:100
@ L_INPUT
Definition: sch_label.h:99
LABEL_SHAPE
Definition: sch_label.h:116
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_NETNAME
Definition: string_utils.h:53
void ConvertMarkdown2Html(const wxString &aMarkdownInput, wxString &aHtmlOutput)
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
wxString replaceString
bool m_PDFPropertyPopups
Definition: sch_plotter.h:91
bool m_PDFHierarchicalLinks
Definition: sch_plotter.h:92
constexpr int delta
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:175
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
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_ITEM_LOCATE_WIRE_T
Definition: typeinfo.h:185
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:171
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:198
@ SCH_ITEM_LOCATE_BUS_T
Definition: typeinfo.h:186
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:190
@ SCH_LABEL_LOCATE_WIRE_T
Definition: typeinfo.h:191
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:173
@ SCH_LABEL_LOCATE_BUS_T
Definition: typeinfo.h:192
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
@ SCH_PIN_T
Definition: typeinfo.h:153
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691