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