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