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