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