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, see <https://www.gnu.org/licenses/>.
20 */
21
23#include <advanced_config.h>
24#include <base_units.h>
25#include <increment.h>
26#include <pgm_base.h>
27#include <sch_edit_frame.h>
28#include <sch_plotter.h>
29#include <widgets/msgpanel.h>
30#include <bitmaps.h>
31#include <string_utils.h>
33#include <schematic.h>
34#include <sch_screen.h>
35#include <sch_sheet.h>
36#include <sch_sheet_pin.h>
38#include <sch_painter.h>
39#include <default_values.h>
40#include <wx/debug.h>
41#include <wx/log.h>
45#include <core/kicad_algo.h>
46#include <core/mirror.h>
47#include <algorithm>
48#include <trigo.h>
49#include <sch_label.h>
50#include <sch_rule_area.h>
51#include <magic_enum.hpp>
52#include <api/api_enums.h>
53#include <api/api_utils.h>
54#include <api/schematic/schematic_types.pb.h>
55#include <properties/property.h>
57
58
59/* Coding polygons for global symbol graphic shapes.
60 * the first parml is the number of corners
61 * others are the corners coordinates in reduced units
62 * the real coordinate is the reduced coordinate * text half size
63 */
64static int TemplateIN_HN[] = { 6, 0, 0, -1, -1, -2, -1, -2, 1, -1, 1, 0, 0 };
65static int TemplateIN_HI[] = { 6, 0, 0, 1, 1, 2, 1, 2, -1, 1, -1, 0, 0 };
66static int TemplateIN_UP[] = { 6, 0, 0, 1, -1, 1, -2, -1, -2, -1, -1, 0, 0 };
67static int TemplateIN_BOTTOM[] = { 6, 0, 0, 1, 1, 1, 2, -1, 2, -1, 1, 0, 0 };
68
69static int TemplateOUT_HN[] = { 6, -2, 0, -1, 1, 0, 1, 0, -1, -1, -1, -2, 0 };
70static int TemplateOUT_HI[] = { 6, 2, 0, 1, -1, 0, -1, 0, 1, 1, 1, 2, 0 };
71static int TemplateOUT_UP[] = { 6, 0, -2, 1, -1, 1, 0, -1, 0, -1, -1, 0, -2 };
72static int TemplateOUT_BOTTOM[] = { 6, 0, 2, 1, 1, 1, 0, -1, 0, -1, 1, 0, 2 };
73
74static int TemplateUNSPC_HN[] = { 5, 0, -1, -2, -1, -2, 1, 0, 1, 0, -1 };
75static int TemplateUNSPC_HI[] = { 5, 0, -1, 2, -1, 2, 1, 0, 1, 0, -1 };
76static int TemplateUNSPC_UP[] = { 5, 1, 0, 1, -2, -1, -2, -1, 0, 1, 0 };
77static int TemplateUNSPC_BOTTOM[] = { 5, 1, 0, 1, 2, -1, 2, -1, 0, 1, 0 };
78
79static int TemplateBIDI_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
80static int TemplateBIDI_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
81static int TemplateBIDI_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
82static int TemplateBIDI_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
83
84static int Template3STATE_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
85static int Template3STATE_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
86static int Template3STATE_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
87static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
88
94
95
97{
98 switch( aType )
99 {
100 case LABEL_FLAG_SHAPE::L_INPUT: return _( "Input" );
101 case LABEL_FLAG_SHAPE::L_OUTPUT: return _( "Output" );
102 case LABEL_FLAG_SHAPE::L_BIDI: return _( "Bidirectional" );
103 case LABEL_FLAG_SHAPE::L_TRISTATE: return _( "Tri-State" );
104 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: return _( "Passive" );
105 default: return wxT( "???" );
106 }
107}
108
109
111{
112 SPIN newSpin = m_spin;
113
114 switch( m_spin )
115 {
116 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::BOTTOM; break;
117 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::RIGHT; break;
118 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::UP; break;
119 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::LEFT; break;
120 }
121
122 return SPIN_STYLE( newSpin );
123}
124
125
127{
128 SPIN newSpin = m_spin;
129
130 switch( m_spin )
131 {
132 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::BOTTOM; break;
133 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::UP; break;
134 case SPIN_STYLE::LEFT: break;
135 case SPIN_STYLE::RIGHT: break;
136 }
137
138 return SPIN_STYLE( newSpin );
139}
140
141
143{
144 SPIN newSpin = m_spin;
145
146 switch( m_spin )
147 {
148 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::RIGHT; break;
149 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::LEFT; break;
150 case SPIN_STYLE::UP: break;
151 case SPIN_STYLE::BOTTOM: break;
152 }
153
154 return SPIN_STYLE( newSpin );
155}
156
157
158unsigned SPIN_STYLE::CCWRotationsTo( const SPIN_STYLE& aOther ) const
159{
160 return ( ( (int) m_spin - (int) aOther.m_spin ) % 4 + 4 ) % 4;
161}
162
163
164SCH_LABEL_BASE::SCH_LABEL_BASE( const VECTOR2I& aPos, const wxString& aText, KICAD_T aType ) :
165 SCH_TEXT( aPos, aText, LAYER_NOTES, aType ),
168 m_isDangling( true ),
171{
172 SetMultilineAllowed( false );
173
174 if( !HasTextVars() )
176}
177
178
180 SCH_TEXT( aLabel ),
181 m_shape( aLabel.m_shape ),
183 m_isDangling( aLabel.m_isDangling ),
187{
188 SetMultilineAllowed( false );
189
190 m_fields = aLabel.m_fields;
191
192 for( SCH_FIELD& field : m_fields )
193 field.SetParent( this );
194}
195
196
198{
199 SCH_TEXT::operator=( aLabel );
200
201 m_fields = aLabel.m_fields;
202
203 for( SCH_FIELD& field : m_fields )
204 field.SetParent( this );
205
206 m_shape = aLabel.m_shape;
208 m_isDangling = aLabel.m_isDangling;
212
213 return *this;
214}
215
216
217const wxString SCH_LABEL_BASE::GetDefaultFieldName( const wxString& aName, bool aUseDefaultName )
218{
219 if( aName == wxT( "Intersheetrefs" ) )
220 return _( "Sheet References" );
221 else if( aName == wxT( "Netclass" ) )
222 return _( "Net Class" );
223 else if( aName.IsEmpty() && aUseDefaultName )
224 return _( "Field" );
225 else
226 return aName;
227}
228
229
234
235
236bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
237{
238 static const std::vector<KICAD_T> wireAndPinTypes = { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T };
239 static const std::vector<KICAD_T> busTypes = { SCH_ITEM_LOCATE_BUS_T };
240
241 if( SCH_TEXT::IsType( aScanTypes ) )
242 return true;
243
244 for( KICAD_T scanType : aScanTypes )
245 {
246 if( scanType == SCH_LABEL_LOCATE_ANY_T )
247 return true;
248 }
249
250 wxCHECK_MSG( Schematic(), false, wxT( "No parent SCHEMATIC set for SCH_LABEL!" ) );
251
252 // Ensure m_connected_items for Schematic()->CurrentSheet() exists.
253 // Can be not the case when "this" is living in clipboard
254 if( m_connected_items.find( Schematic()->CurrentSheet() ) == m_connected_items.end() )
255 return false;
256
257 const std::vector<SCH_ITEM*>& item_set = m_connected_items.at( Schematic()->CurrentSheet() );
258
259 for( KICAD_T scanType : aScanTypes )
260 {
261 if( scanType == SCH_LABEL_LOCATE_WIRE_T )
262 {
263 for( SCH_ITEM* connection : item_set )
264 {
265 if( connection->IsType( wireAndPinTypes ) )
266 return true;
267 }
268 }
269
270 if( scanType == SCH_LABEL_LOCATE_BUS_T )
271 {
272 for( SCH_ITEM* connection : item_set )
273 {
274 if( connection->IsType( busTypes ) )
275 return true;
276 }
277 }
278 }
279
280 return false;
281}
282
283
285{
286 SCH_TEXT::swapData( aItem );
287
288 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( aItem );
289
290 m_fields.swap( label->m_fields );
291
292 for( SCH_FIELD& field : m_fields )
293 field.SetParent( this );
294
295 for( SCH_FIELD& field : label->m_fields )
296 field.SetParent( label );
297
298 std::swap( m_shape, label->m_shape );
299 std::swap( m_connectionType, label->m_connectionType );
300 std::swap( m_isDangling, label->m_isDangling );
301 std::swap( m_lastResolvedColor, label->m_lastResolvedColor );
302}
303
304
314
315
317{
318 m_shape = (LABEL_FLAG_SHAPE) aShape;
319
320 static bool s_inUpdate = false;
321
322 if( s_inUpdate )
323 return;
324
325 s_inUpdate = true;
326
327 if( Type() == SCH_HIER_LABEL_T )
328 {
329 SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( this );
330 SCH_SCREEN* screen = dynamic_cast<SCH_SCREEN*>( label->GetParent() );
331
332 if( screen )
333 {
334 const wxString& text = label->GetText();
335
336 for( SCH_ITEM* item : screen->Items().OfType( SCH_HIER_LABEL_T ) )
337 {
338 SCH_HIERLABEL* other = static_cast<SCH_HIERLABEL*>( item );
339
340 if( other != label && other->GetText() == text )
341 other->SetLabelShape( aShape );
342 }
343
344 for( const SCH_SHEET_PATH& sheetPath : screen->GetClientSheetPaths() )
345 {
346 SCH_SHEET* sheet = sheetPath.Last();
347
348 if( sheet )
349 {
350 for( SCH_SHEET_PIN* pin : sheet->GetPins() )
351 {
352 if( pin->GetText() == text )
353 pin->SetLabelShape( aShape );
354 }
355 }
356 }
357 }
358 }
359 else if( Type() == SCH_SHEET_PIN_T )
360 {
361 SCH_SHEET_PIN* pin = static_cast<SCH_SHEET_PIN*>( this );
362 SCH_SHEET* parent = pin->GetParent();
363
364 if( parent )
365 {
366 const wxString& text = pin->GetText();
367 SCH_SCREEN* screen = parent->GetScreen();
368
369 if( screen )
370 {
371 for( SCH_ITEM* item : screen->Items().OfType( SCH_HIER_LABEL_T ) )
372 {
373 SCH_HIERLABEL* hlabel = static_cast<SCH_HIERLABEL*>( item );
374
375 if( hlabel->GetText() == text )
376 hlabel->SetLabelShape( aShape );
377 }
378 }
379
380 for( SCH_SHEET_PIN* other : parent->GetPins() )
381 {
382 if( other != pin && other->GetText() == text )
383 other->SetLabelShape( aShape );
384 }
385 }
386 }
387
388 s_inUpdate = false;
389}
390
391
393{
394 // Assume "Right" and Left" mean which side of the anchor the text will be on
395 // Thus we want to left justify text up against the anchor if we are on the right
396 switch( aSpinStyle )
397 {
398 default: wxFAIL_MSG( "Bad spin style" ); KI_FALLTHROUGH;
399
400 case SPIN_STYLE::RIGHT: // Horiz Normal Orientation
403 break;
404
405 case SPIN_STYLE::UP: // Vert Orientation UP
408 break;
409
410 case SPIN_STYLE::LEFT: // Horiz Orientation - Right justified
413 break;
414
415 case SPIN_STYLE::BOTTOM: // Vert Orientation BOTTOM
418 break;
419 }
420
422}
423
424
426{
428 {
430 return SPIN_STYLE::BOTTOM;
431 else
432 return SPIN_STYLE::UP;
433 }
434 else
435 {
437 return SPIN_STYLE::LEFT;
438 else
439 return SPIN_STYLE::RIGHT;
440 }
441}
442
443
445{
446 VECTOR2I text_offset;
447
448 // add an offset to x (or y) position to aid readability of text on a wire or line
449 int dist = GetTextOffset( aSettings ) + GetPenWidth();
450
451 switch( GetSpinStyle() )
452 {
453 case SPIN_STYLE::UP:
454 case SPIN_STYLE::BOTTOM: text_offset.x = -dist; break; // Vert Orientation
455 default:
456 case SPIN_STYLE::LEFT:
457 case SPIN_STYLE::RIGHT: text_offset.y = -dist; break; // Horiz Orientation
458 }
459
460 return text_offset;
461}
462
463
464void SCH_LABEL_BASE::SetPosition( const VECTOR2I& aPosition )
465{
466 VECTOR2I offset = aPosition - GetTextPos();
467 Move( offset );
468}
469
470
471void SCH_LABEL_BASE::Move( const VECTOR2I& aMoveVector )
472{
473 SCH_TEXT::Move( aMoveVector );
474
475 for( SCH_FIELD& field : m_fields )
476 field.Offset( aMoveVector );
477}
478
479
480void SCH_LABEL_BASE::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
481{
482 VECTOR2I pt = GetTextPos();
483 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
484 VECTOR2I offset = pt - GetTextPos();
485
486 Rotate90( !aRotateCCW );
487
488 SetTextPos( GetTextPos() + offset );
489
490 for( SCH_FIELD& field : m_fields )
491 field.SetTextPos( field.GetTextPos() + offset );
492}
493
494
495void SCH_LABEL_BASE::Rotate90( bool aClockwise )
496{
497 SCH_TEXT::Rotate90( aClockwise );
498
500 {
502 }
503 else
504 {
505 for( SCH_FIELD& field : m_fields )
506 field.Rotate( GetPosition(), !aClockwise );
507 }
508}
509
510
511void SCH_LABEL_BASE::MirrorSpinStyle( bool aLeftRight )
512{
513 SCH_TEXT::MirrorSpinStyle( aLeftRight );
514
515 for( SCH_FIELD& field : m_fields )
516 {
517 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
518 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
519 {
520 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
521 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
522 else
523 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
524 }
525
526 VECTOR2I pos = field.GetTextPos();
528
529 if( aLeftRight )
530 pos.x = GetPosition().x + delta.x;
531 else
532 pos.y = GetPosition().y + delta.y;
533
534 field.SetTextPos( pos );
535 }
536}
537
538
540{
541 VECTOR2I old_pos = GetPosition();
543
544 for( SCH_FIELD& field : m_fields )
545 {
546 if( field.GetTextAngle() == ANGLE_HORIZONTAL )
547 field.FlipHJustify();
548
549 VECTOR2I pos = field.GetTextPos();
550 VECTOR2I delta = old_pos - pos;
551 pos.x = GetPosition().x + delta.x;
552
553 field.SetPosition( pos );
554 }
555}
556
557
559{
560 VECTOR2I old_pos = GetPosition();
562
563 for( SCH_FIELD& field : m_fields )
564 {
565 if( field.GetTextAngle() == ANGLE_VERTICAL )
566 field.FlipHJustify();
567
568 VECTOR2I pos = field.GetTextPos();
569 VECTOR2I delta = old_pos - pos;
570 pos.y = GetPosition().y + delta.y;
571
572 field.SetPosition( pos );
573 }
574}
575
576
577bool SCH_LABEL_BASE::IncrementLabel( int aIncrement )
578{
579 wxString text = GetText();
580
581 if( IncrementString( text, aIncrement ) )
582 {
583 SetText( text );
584 return true;
585 }
586
587 return false;
588}
589
590
591bool SCH_LABEL_BASE::operator==( const SCH_ITEM& aOther ) const
592{
593 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
594
595 if( !other )
596 return false;
597
598 if( m_shape != other->m_shape )
599 return false;
600
601 if( m_fields.size() != other->m_fields.size() )
602 return false;
603
604 for( size_t ii = 0; ii < m_fields.size(); ++ii )
605 {
606 if( !( m_fields[ii] == other->m_fields[ii] ) )
607 return false;
608 }
609
610 return SCH_TEXT::operator==( aOther );
611}
612
613
614double SCH_LABEL_BASE::Similarity( const SCH_ITEM& aOther ) const
615{
616 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
617
618 if( !other )
619 return 0.0;
620
621 if( m_Uuid == other->m_Uuid )
622 return 1.0;
623
624 double similarity = SCH_TEXT::Similarity( aOther );
625
626 if( typeid( *this ) != typeid( aOther ) )
627 similarity *= 0.9;
628
629 if( m_shape == other->m_shape )
630 similarity *= 0.9;
631
632 for( size_t ii = 0; ii < m_fields.size(); ++ii )
633 {
634 if( ii >= other->m_fields.size() )
635 break;
636
637 similarity *= m_fields[ii].Similarity( other->m_fields[ii] );
638 }
639
640 int diff = std::abs( int( m_fields.size() ) - int( other->m_fields.size() ) );
641
642 similarity *= std::pow( 0.9, diff );
643
644 return similarity;
645}
646
647
649{
650 int margin = GetTextOffset() * 2;
651 int labelLen = GetBodyBoundingBox( nullptr ).GetSizeMax();
652 int accumulated = GetTextHeight() / 2;
653
654 if( Type() == SCH_GLOBAL_LABEL_T )
655 accumulated += margin + GetPenWidth() + margin;
656
657 for( SCH_FIELD& field : m_fields )
658 {
659 VECTOR2I offset( 0, 0 );
660
661 switch( GetSpinStyle() )
662 {
663 default:
664 case SPIN_STYLE::LEFT:
665 field.SetTextAngle( ANGLE_HORIZONTAL );
666 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
667
668 if( field.GetId() == FIELD_T::INTERSHEET_REFS )
669 offset.x = -( labelLen + margin );
670 else
671 offset.y = accumulated + field.GetTextHeight() / 2;
672
673 break;
674
675 case SPIN_STYLE::UP:
676 field.SetTextAngle( ANGLE_VERTICAL );
677 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
678
679 if( field.GetId() == FIELD_T::INTERSHEET_REFS )
680 offset.y = -( labelLen + margin );
681 else
682 offset.x = accumulated + field.GetTextHeight() / 2;
683
684 break;
685
687 field.SetTextAngle( ANGLE_HORIZONTAL );
688 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
689
690 if( field.GetId() == FIELD_T::INTERSHEET_REFS )
691 offset.x = labelLen + margin;
692 else
693 offset.y = accumulated + field.GetTextHeight() / 2;
694
695 break;
696
698 field.SetTextAngle( ANGLE_VERTICAL );
699 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
700
701 if( field.GetId() == FIELD_T::INTERSHEET_REFS )
702 offset.y = labelLen + margin;
703 else
704 offset.x = accumulated + field.GetTextHeight() / 2;
705
706 break;
707 }
708
709 field.SetTextPos( GetTextPos() + offset );
710
711 if( field.GetId() == FIELD_T::INTERSHEET_REFS )
712 accumulated += field.GetTextHeight() + margin;
713 }
714
715 if( aAlgo == AUTOPLACE_AUTO || aAlgo == AUTOPLACE_MANUAL )
716 m_fieldsAutoplaced = aAlgo;
717}
718
719
720void SCH_LABEL_BASE::GetIntersheetRefs( const SCH_SHEET_PATH* aPath, std::vector<std::pair<wxString, wxString>>* pages )
721{
722 wxCHECK( pages, /* void */ );
723
724 if( Schematic() )
725 {
726 const SCH_SHEET_PATH& path = aPath ? *aPath : Schematic()->CurrentSheet();
727 wxString resolvedLabel = GetShownText( &path, FOR_GUI );
728 auto it = Schematic()->GetPageRefsMap().find( resolvedLabel );
729
730 if( it != Schematic()->GetPageRefsMap().end() )
731 {
732 std::vector<int> pageListCopy;
733
734 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
735
736 if( !Schematic()->Settings().m_IntersheetRefsListOwnPage )
737 {
738 int currentPage = path.GetVirtualPageNumber();
739 std::erase( pageListCopy, currentPage );
740
741 if( pageListCopy.empty() )
742 return;
743 }
744
745 std::sort( pageListCopy.begin(), pageListCopy.end() );
746
747 std::map<int, wxString> sheetPages = Schematic()->GetVirtualPageToSheetPagesMap();
748 std::map<int, wxString> sheetNames = Schematic()->GetVirtualPageToSheetNamesMap();
749
750 for( int pageNum : pageListCopy )
751 pages->push_back( { sheetPages[pageNum], sheetNames[pageNum] } );
752 }
753 }
754}
755
756
757void SCH_LABEL_BASE::GetContextualTextVars( wxArrayString* aVars ) const
758{
759 for( const SCH_FIELD& field : m_fields )
760 {
761 if( field.IsMandatory() )
762 aVars->push_back( field.GetUntranslatedName().Upper() );
763 else
764 aVars->push_back( field.GetName() );
765 }
766
767 aVars->push_back( wxT( "OP" ) );
768 aVars->push_back( wxT( "CONNECTION_TYPE" ) );
769 aVars->push_back( wxT( "SHORT_NET_NAME" ) );
770 aVars->push_back( wxT( "NET_NAME" ) );
771 aVars->push_back( wxT( "NET_CLASS" ) );
772}
773
774
775bool SCH_LABEL_BASE::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
776{
777 // Per-thread regex. CONNECTION_GRAPH::resolveAllDrivers calls this from worker
778 // threads, and wxRegEx::Matches is not safe to call concurrently on one instance.
779 thread_local wxRegEx operatingPoint( wxT( "^"
780 "OP"
781 "(.([0-9])?([a-zA-Z]*))?"
782 "$" ) );
783
784 wxCHECK( aPath, false );
785
786 SCHEMATIC* schematic = Schematic();
787
788 if( !schematic )
789 return false;
790
791 wxString variant = schematic->GetCurrentVariant();
792
793 if( operatingPoint.Matches( *token ) )
794 {
795 int precision = 3;
796 wxString precisionStr( operatingPoint.GetMatch( *token, 2 ) );
797 wxString range( operatingPoint.GetMatch( *token, 3 ) );
798
799 if( !precisionStr.IsEmpty() )
800 precision = precisionStr[0] - '0';
801
802 if( range.IsEmpty() )
803 range = wxS( "~V" );
804
805 const auto name = GetConnectionName( aPath );
806 *token = name ? schematic->GetOperatingPoint( *name, precision, range ) : wxString( "?" );
807
808 return true;
809 }
810
811 if( token->Contains( ':' ) )
812 {
813 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
814 return true;
815 }
816
818 && token->IsSameAs( wxT( "CONNECTION_TYPE" ) ) )
819 {
820 const SCH_LABEL_BASE* label = static_cast<const SCH_LABEL_BASE*>( this );
821 *token = getElectricalTypeLabel( label->GetShape() );
822 return true;
823 }
824 else if( token->IsSameAs( wxT( "SHORT_NET_NAME" ) ) )
825 {
826 *token = GetConnectionName( aPath, true ).value_or( wxString() );
827
828 return true;
829 }
830 else if( token->IsSameAs( wxT( "NET_NAME" ) ) )
831 {
832 *token = GetConnectionName( aPath ).value_or( wxString() );
833
834 return true;
835 }
836 else if( token->IsSameAs( wxT( "NET_CLASS" ) ) )
837 {
838 *token = GetConnectionName( aPath ) ? GetEffectiveNetClass( aPath )->GetName() : wxString();
839
840 return true;
841 }
842 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
843 {
844 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
845 *token = wxEmptyString;
846
847 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
848 {
849 if( ruleArea->GetExcludedFromBOM( aPath, variant ) )
850 *token = wxS( "Excluded from BOM" );
851 }
852
853 return true;
854 }
855 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
856 {
857 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
858 *token = wxEmptyString;
859
860 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
861 {
862 if( ruleArea->GetExcludedFromBoard( aPath, variant ) )
863 *token = wxS( "Excluded from board" );
864 }
865
866 return true;
867 }
868 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
869 {
870 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
871 *token = wxEmptyString;
872
873 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
874 {
875 if( ruleArea->GetExcludedFromSim( aPath, variant ) )
876 *token = wxS( "Excluded from simulation" );
877 }
878
879 return true;
880 }
881 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "DNP" ) ) )
882 {
883 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
884 *token = wxEmptyString;
885
886 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
887 {
888 if( ruleArea->GetDNP( aPath, variant ) )
889 *token = wxS( "DNP" );
890 }
891
892 return true;
893 }
894
895 for( const SCH_FIELD& field : m_fields )
896 {
897 if( token->IsSameAs( field.GetName() ) )
898 {
899 *token = field.GetShownText( aPath, INTERNAL, variant, aDepth + 1 );
900 return true;
901 }
902 }
903
904 // See if parent can resolve it (these will recurse to ancestors)
905
906 if( Type() == SCH_SHEET_PIN_T && m_parent )
907 {
908 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
909
910 // aPath is expected to be either the sheet pin's owner-screen path (parent sheet as
911 // Last()) or the already-extended path whose Last() is the owning sheet itself.
912 // Only push the owner sheet when it isn't already at the end; a double-push produces
913 // a nonsense path and breaks lookups keyed on the instance (e.g. ${#} page number).
914 SCH_SHEET_PATH path = *aPath;
915
916 if( path.Last() != sheet )
917 path.push_back( sheet );
918
919 if( sheet->ResolveTextVar( &path, token, aDepth + 1 ) )
920 return true;
921 }
922 else
923 {
924 // aPath->Last() can be null when loading schematic, i.e. when all sheets are not yet loaded
925 if( aPath->Last() && aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
926 return true;
927 }
928
929 return false;
930}
931
932
934{
935 return !HasTextVars();
936}
937
938
940{
942}
943
944
952
953
954wxString SCH_LABEL_BASE::GetShownText( const SCH_SHEET_PATH* aPath, RESOLUTION_CONTEXT aContext, int aDepth ) const
955{
956 // ResolveTextVars counts expansion passes over this one string; aDepth counts re-entries
957 // and has to keep climbing, or a label that resolves through itself never stops
958 int depth = 0;
959
960 std::function<bool( wxString* )> textResolver =
961 [&]( wxString* token ) -> bool
962 {
963 return ResolveTextVar( aPath, token, aDepth + 1 );
964 };
965
966 wxString text = EDA_TEXT::GetShownText( aContext, depth );
967
968 if( HasTextVars() && aContext != RAW_VALUE )
969 {
970 text = ResolveTextVars( text, &textResolver, depth );
971 FinalizeTextVarExpansion( text, aContext );
972 }
973
974 return text;
975}
976
977
978void SCH_LABEL_BASE::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
979{
980 for( SCH_FIELD& field : m_fields )
981 aFunction( &field );
982}
983
984
985bool SCH_LABEL_BASE::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
986{
987 if( SCH_ITEM::Matches( UnescapeString( GetText() ), aSearchData ) )
988 {
989 return true;
990 }
991
992 const SCH_SEARCH_DATA* searchData = dynamic_cast<const SCH_SEARCH_DATA*>( &aSearchData );
993 SCH_CONNECTION* connection = nullptr;
994 SCH_SHEET_PATH* sheetPath = reinterpret_cast<SCH_SHEET_PATH*>( aAuxData );
995
996 if( searchData && searchData->searchNetNames && sheetPath && ( connection = Connection( sheetPath ) ) )
997 {
998 if( connection->IsBus() )
999 {
1000 auto allMembers = connection->AllMembers();
1001
1002 std::set<wxString> netNames;
1003
1004 for( std::shared_ptr<SCH_CONNECTION> member : allMembers )
1005 netNames.insert( member->GetNetName() );
1006
1007 for( const wxString& netName : netNames )
1008 {
1009 if( EDA_ITEM::Matches( netName, aSearchData ) )
1010 return true;
1011 }
1012
1013 return false;
1014 }
1015
1016 wxString netName = connection->GetNetName();
1017
1018 if( EDA_ITEM::Matches( netName, aSearchData ) )
1019 return true;
1020 }
1021
1022 return false;
1023}
1024
1025
1026bool SCH_LABEL_BASE::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
1027{
1028 EDA_SEARCH_DATA localSearchData( aSearchData );
1029 localSearchData.findString = EscapeString( aSearchData.findString, CTX_NETNAME );
1030 localSearchData.replaceString = EscapeString( aSearchData.replaceString, CTX_NETNAME );
1031
1032 return EDA_TEXT::Replace( localSearchData );
1033}
1034
1035
1036INSPECT_RESULT SCH_LABEL_BASE::Visit( INSPECTOR aInspector, void* testData, const std::vector<KICAD_T>& aScanTypes )
1037{
1038 if( IsType( aScanTypes ) )
1039 {
1040 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
1041 return INSPECT_RESULT::QUIT;
1042 }
1043
1044 for( KICAD_T scanType : aScanTypes )
1045 {
1046 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
1047 {
1048 for( SCH_FIELD& field : m_fields )
1049 {
1050 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
1051 return INSPECT_RESULT::QUIT;
1052 }
1053 }
1054 }
1055
1057}
1058
1059
1060void SCH_LABEL_BASE::GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList )
1061{
1062 DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() );
1063 aItemList.push_back( item );
1064}
1065
1066
1067std::vector<VECTOR2I> SCH_LABEL_BASE::GetConnectionPoints() const
1068{
1069 return { GetTextPos() };
1070}
1071
1072
1077
1078
1080{
1081 double ratio;
1082
1083 if( aSettings )
1084 ratio = static_cast<const SCH_RENDER_SETTINGS*>( aSettings )->m_LabelSizeRatio;
1085 else if( Schematic() )
1086 ratio = Schematic()->Settings().m_LabelSizeRatio;
1087 else
1088 ratio = DEFAULT_LABEL_SIZE_RATIO; // For previews (such as in Preferences), etc.
1089
1090 return KiROUND( ratio * GetTextSize().y );
1091}
1092
1093
1095{
1096 // build the bounding box of the label only, without taking into account its fields
1097
1098 BOX2I box;
1099 std::vector<VECTOR2I> pts;
1100
1101 CreateGraphicShape( aSettings, pts, GetTextPos() );
1102
1103 for( const VECTOR2I& pt : pts )
1104 box.Merge( pt );
1105
1106 box.Inflate( GetEffectiveTextPenWidth() / 2 );
1107 box.Normalize();
1108 return box;
1109}
1110
1111
1113{
1114 // build the bounding box of the entire label, including its fields
1115
1116 BOX2I box = GetBodyBoundingBox( nullptr );
1117
1118 for( const SCH_FIELD& field : m_fields )
1119 {
1120 if( field.IsVisible() && field.GetText() != wxEmptyString )
1121 {
1122 BOX2I fieldBBox = field.GetBoundingBox();
1123
1124 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1125 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1126
1127 box.Merge( fieldBBox );
1128 }
1129 }
1130
1131 box.Normalize();
1132
1133 return box;
1134}
1135
1136
1137bool SCH_LABEL_BASE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1138{
1139 BOX2I bbox = GetBodyBoundingBox( nullptr );
1140 bbox.Inflate( aAccuracy );
1141
1142 if( bbox.Contains( aPosition ) )
1143 return true;
1144
1145 for( const SCH_FIELD& field : m_fields )
1146 {
1147 if( field.IsVisible() )
1148 {
1149 BOX2I fieldBBox = field.GetBoundingBox();
1150 fieldBBox.Inflate( aAccuracy );
1151
1152 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1153 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1154
1155 if( fieldBBox.Contains( aPosition ) )
1156 return true;
1157 }
1158 }
1159
1160 return false;
1161}
1162
1163
1164bool SCH_LABEL_BASE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1165{
1166 BOX2I rect = aRect;
1167
1168 rect.Inflate( aAccuracy );
1169
1170 if( aContained )
1171 {
1172 return rect.Contains( GetBoundingBox() );
1173 }
1174 else
1175 {
1176 if( rect.Intersects( GetBodyBoundingBox( nullptr ) ) )
1177 return true;
1178
1179 for( const SCH_FIELD& field : m_fields )
1180 {
1181 if( field.IsVisible() )
1182 {
1183 BOX2I fieldBBox = field.GetBoundingBox();
1184
1185 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1186 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1187
1188 if( rect.Intersects( fieldBBox ) )
1189 return true;
1190 }
1191 }
1192
1193 return false;
1194 }
1195}
1196
1197
1198bool SCH_LABEL_BASE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1199{
1200 if( aContained )
1201 {
1202 return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
1203 }
1204 else
1205 {
1206 if( KIGEOM::BoxHitTest( aPoly, GetBodyBoundingBox( nullptr ), aContained ) )
1207 return true;
1208
1209 for( const SCH_FIELD& field : m_fields )
1210 {
1211 if( field.IsVisible() )
1212 {
1213 BOX2I fieldBBox = field.GetBoundingBox();
1214
1215 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1216 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1217
1218 if( KIGEOM::BoxHitTest( aPoly, fieldBBox, aContained ) )
1219 return true;
1220 }
1221 }
1222
1223 return false;
1224 }
1225}
1226
1227
1228bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1229 std::vector<DANGLING_END_ITEM>& aItemListByPos, const SCH_SHEET_PATH* aPath )
1230{
1231 bool previousState = m_isDangling;
1232 VECTOR2I text_pos = GetTextPos();
1233 bool pinOrNoConnect = false;
1234 m_isDangling = true;
1236
1237 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, text_pos );
1238 it < aItemListByPos.end() && it->GetPosition() == text_pos; it++ )
1239 {
1240 DANGLING_END_ITEM& item = *it;
1241
1242 if( item.GetItem() == this )
1243 continue;
1244
1245 switch( item.GetType() )
1246 {
1247 case PIN_END:
1248 case NO_CONNECT_END:
1249 pinOrNoConnect = true;
1251
1252 case LABEL_END:
1253 case SHEET_LABEL_END:
1254 m_isDangling = false;
1255
1256 if( aPath && item.GetType() != PIN_END )
1257 AddConnectionTo( *aPath, static_cast<SCH_ITEM*>( item.GetItem() ) );
1258
1259 break;
1260
1261 default: break;
1262 }
1263
1264 if( pinOrNoConnect )
1265 break;
1266 }
1267
1268 // A coincident label leaves us unattached to a wire merely passing through, so keep scanning
1269 // A pin or no-connect sits on a wire end the connection graph already ties us to
1270 if( !pinOrNoConnect )
1271 {
1272 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, BUS_END );
1273 it < aItemListByType.end() && it->GetType() == BUS_END; it++ )
1274 {
1275 DANGLING_END_ITEM& item = *it;
1276 DANGLING_END_ITEM& nextItem = *( ++it );
1277
1278 int accuracy = 1; // We have rounding issues with an accuracy of 0
1279
1280 if( !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(), accuracy ) )
1281 continue;
1282
1283 m_isDangling = false;
1285
1286 // Add the line to the connected items, since it won't be picked
1287 // up by a search of intersecting connection points
1288 if( aPath )
1289 {
1290 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1291 AddConnectionTo( *aPath, sch_item );
1292 sch_item->AddConnectionTo( *aPath, this );
1293 }
1294
1295 break;
1296 }
1297
1299 {
1300 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, WIRE_END );
1301 it < aItemListByType.end() && it->GetType() == WIRE_END; it++ )
1302 {
1303 DANGLING_END_ITEM& item = *it;
1304 DANGLING_END_ITEM& nextItem = *( ++it );
1305
1306 int accuracy = 1; // We have rounding issues with an accuracy of 0
1307
1308 if( !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(), accuracy ) )
1309 continue;
1310
1311 m_isDangling = false;
1313
1314 // Add the line to the connected items, since it won't be picked
1315 // up by a search of intersecting connection points
1316 if( aPath )
1317 {
1318 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1319 AddConnectionTo( *aPath, sch_item );
1320 sch_item->AddConnectionTo( *aPath, this );
1321 }
1322
1323 break;
1324 }
1325 }
1326 }
1327
1328 if( m_isDangling )
1330
1331 return previousState != m_isDangling;
1332}
1333
1334
1335bool SCH_LABEL_BASE::HasConnectivityChanges( const SCH_ITEM* aItem, const SCH_SHEET_PATH* aInstance ) const
1336{
1337 // Do not compare to ourself.
1338 if( aItem == this || !IsConnectable() )
1339 return false;
1340
1341 const SCH_LABEL_BASE* label = dynamic_cast<const SCH_LABEL_BASE*>( aItem );
1342
1343 // Don't compare against a different SCH_ITEM.
1344 wxCHECK( label, false );
1345
1346 if( GetPosition() != label->GetPosition() )
1347 return true;
1348
1349 if( GetShownText( aInstance, FOR_NETNAME ) != label->GetShownText( aInstance, FOR_NETNAME ) )
1350 return true;
1351
1352 std::vector<wxString> netclasses;
1353 std::vector<wxString> otherNetclasses;
1354
1355 for( const SCH_FIELD& field : m_fields )
1356 {
1357 if( field.GetUntranslatedName() == wxT( "Netclass" ) )
1358 netclasses.push_back( field.GetText() );
1359 }
1360
1361 for( const SCH_FIELD& field : label->m_fields )
1362 {
1363 if( field.GetUntranslatedName() == wxT( "Netclass" ) )
1364 otherNetclasses.push_back( field.GetText() );
1365 }
1366
1367 return netclasses != otherNetclasses;
1368}
1369
1370
1371void SCH_LABEL_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1372{
1373 wxString msg;
1374
1375 switch( Type() )
1376 {
1377 case SCH_LABEL_T: msg = _( "Label" ); break;
1378 case SCH_DIRECTIVE_LABEL_T: msg = _( "Directive Label" ); break;
1379 case SCH_GLOBAL_LABEL_T: msg = _( "Global Label" ); break;
1380 case SCH_HIER_LABEL_T: msg = _( "Hierarchical Label" ); break;
1381 case SCH_SHEET_PIN_T: msg = _( "Hierarchical Sheet Pin" ); break;
1382 default: return;
1383 }
1384
1385 // Don't use GetShownText() here; we want to show the user the variable references
1386 aList.emplace_back( msg, UnescapeString( GetText() ) );
1387
1388 // Display electrical type if it is relevant
1390 aList.emplace_back( _( "Type" ), getElectricalTypeLabel( GetShape() ) );
1391
1392 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1393
1394 wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
1395 int style = IsBold() && IsItalic() ? 3 : IsBold() ? 2 : IsItalic() ? 1 : 0;
1396 aList.emplace_back( _( "Style" ), textStyle[style] );
1397
1398 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1399
1400 switch( GetSpinStyle() )
1401 {
1402 case SPIN_STYLE::LEFT: msg = _( "Align right" ); break;
1403 case SPIN_STYLE::UP: msg = _( "Align bottom" ); break;
1404 case SPIN_STYLE::RIGHT: msg = _( "Align left" ); break;
1405 case SPIN_STYLE::BOTTOM: msg = _( "Align top" ); break;
1406 default: msg = wxT( "???" ); break;
1407 }
1408
1409 aList.emplace_back( _( "Justification" ), msg );
1410
1411 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1413}
1414
1415
1416void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit,
1417 int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1418{
1419 static std::vector<VECTOR2I> s_poly;
1420
1421 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
1422 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
1423 SCH_CONNECTION* connection = Connection();
1424 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1425 COLOR4D color = settings->GetLayerColor( layer );
1426 int penWidth = GetEffectiveTextPenWidth( settings->GetDefaultPenWidth() );
1427 COLOR4D bg = settings->GetBackgroundColor();
1428
1429 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1430 bg = COLOR4D::WHITE;
1431
1432 if( aPlotter->GetColorMode() && GetLabelColor() != COLOR4D::UNSPECIFIED )
1433 color = GetLabelColor();
1434
1435 if( color.m_text && Schematic() )
1436 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1437
1438 if( aDimmed )
1439 {
1440 color.Desaturate();
1441 color = color.Mix( bg, 0.5f );
1442 }
1443
1444 penWidth = std::max( penWidth, settings->GetMinPenWidth() );
1445 aPlotter->SetCurrentLineWidth( penWidth );
1446
1447 KIFONT::FONT* font = GetDrawFont( settings );
1448
1449 VECTOR2I textpos = GetTextPos() + GetSchematicTextOffset( settings );
1450 CreateGraphicShape( settings, s_poly, GetTextPos() );
1451
1453 attrs.m_StrokeWidth = penWidth;
1454 attrs.m_Multiline = false;
1455
1456 if( aBackground )
1457 {
1458 // No filled shapes (yet)
1459 }
1460 else
1461 {
1462 aPlotter->PlotText( textpos, color, GetShownText( sheet, FOR_CANVAS ), attrs, font, GetFontMetrics() );
1463
1464 if( aPlotter->GetColorMode() )
1465 {
1466 // For the graphic shape use the override color or the layer color, but not the
1467 // net/netclass color.
1468 COLOR4D shapeColor;
1469
1471 shapeColor = GetTextColor();
1472 else
1473 shapeColor = settings->GetLayerColor( m_layer );
1474
1475 if( aDimmed )
1476 {
1477 shapeColor.Desaturate();
1478 shapeColor = shapeColor.Mix( bg, 0.5f );
1479 }
1480
1481 aPlotter->SetColor( shapeColor );
1482 }
1483
1485 {
1486 aPlotter->MoveTo( s_poly[0] );
1487 aPlotter->LineTo( s_poly[1] );
1488 aPlotter->PenFinish();
1489
1490 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1491 aPlotter->FilledCircle( s_poly[2], diameter, nullptr );
1492 }
1493 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1494 {
1495 aPlotter->MoveTo( s_poly[0] );
1496 aPlotter->LineTo( s_poly[1] );
1497 aPlotter->PenFinish();
1498
1499 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1500 aPlotter->ThickCircle( s_poly[2], diameter, penWidth, nullptr );
1501 }
1502 else
1503 {
1504 if( !s_poly.empty() )
1505 aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth, nullptr );
1506 }
1507
1508 // Make sheet pins and hierarchical labels clickable hyperlinks
1509 bool linkAlreadyPlotted = false;
1510 BOX2I bodyBBox = GetBodyBoundingBox( settings );
1511
1512 if( aPlotOpts.m_PDFHierarchicalLinks )
1513 {
1514 if( Type() == SCH_HIER_LABEL_T )
1515 {
1516 if( sheet->size() >= 2 )
1517 {
1518 SCH_SHEET_PATH path = *sheet;
1519 path.pop_back();
1520 aPlotter->HyperlinkBox( bodyBBox, EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1521 linkAlreadyPlotted = true;
1522 }
1523 }
1524 else if( Type() == SCH_SHEET_PIN_T )
1525 {
1526 SCH_SHEET_PATH path = *sheet;
1527 SCH_SHEET* parent = static_cast<SCH_SHEET*>( m_parent );
1528 path.push_back( parent );
1529 aPlotter->HyperlinkBox( bodyBBox, EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1530 linkAlreadyPlotted = true;
1531 }
1532 }
1533
1534 // Plot attributes to a hypertext menu
1535 if( aPlotOpts.m_PDFPropertyPopups && !linkAlreadyPlotted )
1536 {
1537 std::vector<wxString> properties;
1538
1539 if( connection )
1540 {
1541 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Net" ), connection->Name() ) );
1542
1543 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Resolved netclass" ),
1544 GetEffectiveNetClass()->GetHumanReadableName() ) );
1545 }
1546
1547 for( const SCH_FIELD& field : GetFields() )
1548 {
1549 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
1550 field.GetName(),
1551 field.GetShownText( FOR_GUI ) ) );
1552 }
1553
1554 if( !properties.empty() )
1555 aPlotter->HyperlinkMenu( bodyBBox, properties );
1556 }
1557
1558 if( Type() == SCH_HIER_LABEL_T )
1559 aPlotter->Bookmark( bodyBBox, GetShownText( FOR_GUI ), _( "Hierarchical Labels" ) );
1560 }
1561
1562 for( SCH_FIELD& field : m_fields )
1563 field.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
1564}
1565
1566
1571
1572
1574{
1575 m_autoRotateOnPlacement = autoRotate;
1576}
1577
1578
1579SCH_LABEL::SCH_LABEL( const VECTOR2I& pos, const wxString& text ) :
1581{
1584 m_isDangling = true;
1585}
1586
1587
1588template<typename LabelProto>
1589void packLabel( LabelProto& aOutput, const SCH_LABEL_BASE& aLabel )
1590{
1591 using namespace kiapi::schematic;
1592
1593 aOutput.mutable_id()->set_value( aLabel.m_Uuid.AsStdString() );
1595 aOutput.set_locked( aLabel.IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
1596 : kiapi::common::types::LockedState::LS_UNLOCKED );
1597
1598 aLabel.EDA_TEXT::Serialize( *aOutput.mutable_text(), schIUScale );
1599 kiapi::common::PackVector2( *aOutput.mutable_position(), aLabel.GetPosition(), schIUScale );
1600 aOutput.set_fields_autoplaced( aLabel.GetFieldsAutoplaced() != AUTOPLACE_NONE );
1601
1602 for( const SCH_FIELD& field : aLabel.GetFields() )
1603 {
1604 if( field.IsMandatory() )
1605 continue;
1606
1607 field.Serialize( *aOutput.add_fields(), schIUScale );
1608 }
1609}
1610
1611
1612template<typename LabelProto>
1613bool unpackLabel( const LabelProto& aInput, SCH_LABEL_BASE& aLabel )
1614{
1615 using namespace kiapi::schematic;
1616
1617 const_cast<KIID&>( aLabel.m_Uuid ) = KIID( aInput.id().value() );
1618 aLabel.SetLocked( aInput.locked() == kiapi::common::types::LockedState::LS_LOCKED );
1619
1620 if( !aLabel.EDA_TEXT::Deserialize( aInput.text(), schIUScale ) )
1621 return false;
1622
1624 aLabel.SetPosition( kiapi::common::UnpackVector2( aInput.position(), schIUScale ) );
1625 aLabel.SetFieldsAutoplaced( aInput.fields_autoplaced() ? AUTOPLACE_AUTO : AUTOPLACE_NONE );
1626 aLabel.GetFields().clear();
1627
1628 for( const types::SchematicField& field : aInput.fields() )
1629 {
1630 aLabel.GetFields().emplace_back( &aLabel, FIELD_T::USER );
1631 aLabel.GetFields().back().Deserialize( field, schIUScale );
1632 }
1633
1634 return true;
1635}
1636
1637
1638void SCH_LABEL::Serialize( google::protobuf::Any& aContainer ) const
1639{
1640 kiapi::schematic::types::LocalLabel label;
1641
1642 packLabel( label, *this );
1643
1644 kiapi::common::PackCustomProperties( label.mutable_custom_properties(), *this );
1645 aContainer.PackFrom( label );
1646}
1647
1648
1649bool SCH_LABEL::Deserialize( const google::protobuf::Any& aContainer )
1650{
1651 kiapi::schematic::types::LocalLabel label;
1652
1653 if( !aContainer.UnpackTo( &label ) )
1654 return false;
1655
1656 kiapi::common::UnpackCustomProperties( label.custom_properties(), *this );
1657
1658 return unpackLabel( label, *this );
1659}
1660
1661
1663{
1664 BOX2I rect = GetTextBox( aSettings );
1665
1666 rect.Offset( 0, -GetTextOffset() );
1668
1669 if( !GetTextAngle().IsZero() )
1670 {
1671 // Rotate rect
1672 VECTOR2I pos = rect.GetOrigin();
1673 VECTOR2I end = rect.GetEnd();
1674
1675 RotatePoint( pos, GetTextPos(), GetTextAngle() );
1677
1678 rect.SetOrigin( pos );
1679 rect.SetEnd( end );
1680
1681 rect.Normalize();
1682 }
1683
1684 // Labels have a position point that is outside of the TextBox
1685 rect.Merge( GetPosition() );
1686
1687 return rect;
1688}
1689
1690
1691wxString SCH_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1692{
1693 return wxString::Format( _( "Label '%s'" ), aFull ? GetShownText( FOR_GUI )
1695}
1696
1697
1702
1703
1705 SCH_LABEL_BASE( pos, wxEmptyString, SCH_DIRECTIVE_LABEL_T )
1706{
1709 m_pinLength = schIUScale.MilsToIU( 100 );
1710 m_symbolSize = schIUScale.MilsToIU( 20 );
1711 m_isDangling = true;
1712}
1713
1714
1716{
1717 SCH_LABEL_BASE::swapData( aItem );
1718
1719 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( aItem );
1720
1721 std::swap( m_pinLength, label->m_pinLength );
1722 std::swap( m_symbolSize, label->m_symbolSize );
1723}
1724
1725
1727 SCH_LABEL_BASE( aClassLabel )
1728{
1729 m_pinLength = aClassLabel.m_pinLength;
1730 m_symbolSize = aClassLabel.m_symbolSize;
1731}
1732
1733
1735{
1736 for( SCH_RULE_AREA* ruleArea : m_connected_rule_areas )
1737 ruleArea->RemoveDirective( this );
1738}
1739
1740
1741void SCH_DIRECTIVE_LABEL::Serialize( google::protobuf::Any& aContainer ) const
1742{
1743 kiapi::schematic::types::DirectiveLabel label;
1744
1745 packLabel( label, *this );
1747 kiapi::common::PackDistance( *label.mutable_pin_length(), m_pinLength, schIUScale );
1748 kiapi::common::PackDistance( *label.mutable_symbol_size(), m_symbolSize, schIUScale );
1749
1750 kiapi::common::PackCustomProperties( label.mutable_custom_properties(), *this );
1751 aContainer.PackFrom( label );
1752}
1753
1754
1755bool SCH_DIRECTIVE_LABEL::Deserialize( const google::protobuf::Any& aContainer )
1756{
1757 kiapi::schematic::types::DirectiveLabel label;
1758
1759 if( !aContainer.UnpackTo( &label ) )
1760 return false;
1761
1762 kiapi::common::UnpackCustomProperties( label.custom_properties(), *this );
1763
1764 if( !unpackLabel( label, *this ) )
1765 return false;
1766
1768
1769 if( label.has_pin_length() )
1770 m_pinLength = kiapi::common::UnpackDistance( label.pin_length(), schIUScale );
1771
1772 if( label.has_symbol_size() )
1773 m_symbolSize = kiapi::common::UnpackDistance( label.symbol_size(), schIUScale );
1774
1775 return true;
1776}
1777
1778
1780{
1781 if( !SCH_LABEL_BASE::operator==( aOther ) )
1782 return false;
1783
1784 const SCH_DIRECTIVE_LABEL* other = dynamic_cast<const SCH_DIRECTIVE_LABEL*>( &aOther );
1785
1786 if( !other )
1787 return false;
1788
1789 return m_pinLength == other->m_pinLength && m_symbolSize == other->m_symbolSize;
1790}
1791
1792
1794{
1795 int pen = 0;
1796
1797 if( Schematic() )
1799
1800 return GetEffectiveTextPenWidth( pen );
1801}
1802
1803
1805{
1806 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1807 // vertical shape (like a text reduced to only "I" letter).
1808 // So the mirroring is not exactly similar to a SCH_TEXT item
1809 SCH_TEXT::MirrorSpinStyle( !aLeftRight );
1810
1811 for( SCH_FIELD& field : m_fields )
1812 {
1813 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
1814 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
1815 {
1816 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1817 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1818 else
1819 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1820 }
1821
1822 VECTOR2I pos = field.GetTextPos();
1823 VECTOR2I delta = (VECTOR2I) GetPosition() - pos;
1824
1825 if( aLeftRight )
1826 pos.x = GetPosition().x + delta.x;
1827 else
1828 pos.y = GetPosition().y + delta.y;
1829
1830 field.SetTextPos( pos );
1831 }
1832}
1833
1834
1836{
1837 VECTOR2I old_pos = GetPosition();
1838
1839 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1840 // vertical shape (like a text reduced to only "I" letter).
1841 // So the mirroring is not exactly similar to a SCH_TEXT item
1842 // Text is NOT really mirrored; it is moved to a suitable horizontal position
1843 SetSpinStyle( GetSpinStyle().MirrorX() );
1844
1845 SetTextX( MIRRORVAL( GetTextPos().x, aCenter ) );
1846
1847 for( SCH_FIELD& field : m_fields )
1848 {
1849 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1850 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1851 else if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1852 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1853
1854 VECTOR2I pos = field.GetTextPos();
1855 VECTOR2I delta = old_pos - pos;
1856 pos.x = GetPosition().x + delta.x;
1857
1858 field.SetPosition( pos );
1859 }
1860}
1861
1862
1864{
1865 VECTOR2I old_pos = GetPosition();
1866 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1867 // vertical shape (like a text reduced to only "I" letter).
1868 // So the mirroring is not exactly similar to a SCH_TEXT item
1869 // Text is NOT really mirrored; it is moved to a suitable vertical position
1870 SetSpinStyle( GetSpinStyle().MirrorY() );
1871
1872 SetTextY( MIRRORVAL( GetTextPos().y, aCenter ) );
1873
1874 for( SCH_FIELD& field : m_fields )
1875 {
1876 VECTOR2I pos = field.GetTextPos();
1877 VECTOR2I delta = old_pos - pos;
1878 pos.y = GetPosition().y + delta.y;
1879
1880 field.SetPosition( pos );
1881 }
1882}
1883
1884
1885void SCH_DIRECTIVE_LABEL::CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings, std::vector<VECTOR2I>& aPoints,
1886 const VECTOR2I& aPos ) const
1887{
1888 int symbolSize = m_symbolSize;
1889
1890 aPoints.clear();
1891
1892 switch( m_shape )
1893 {
1894 case LABEL_FLAG_SHAPE::F_DOT: symbolSize = KiROUND( symbolSize * 0.7 ); KI_FALLTHROUGH;
1895
1897 // First 3 points are used for generating shape
1898 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1899 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1900 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1901
1902 // These points are just used to bulk out the bounding box
1903 aPoints.emplace_back( VECTOR2I( -m_symbolSize, m_pinLength ) );
1904 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1905 aPoints.emplace_back( VECTOR2I( m_symbolSize, m_pinLength + symbolSize ) );
1906 break;
1907
1909 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1910 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1911 aPoints.emplace_back( VECTOR2I( -2 * m_symbolSize, m_pinLength ) );
1912 aPoints.emplace_back( VECTOR2I( 0, m_pinLength + symbolSize ) );
1913 aPoints.emplace_back( VECTOR2I( 2 * m_symbolSize, m_pinLength ) );
1914 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1915 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1916 break;
1917
1919 symbolSize = KiROUND( symbolSize * 0.8 );
1920
1921 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1922 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1923 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength - symbolSize ) );
1924 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength + symbolSize ) );
1925 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength + symbolSize ) );
1926 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength - symbolSize ) );
1927 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1928 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1929 break;
1930
1931 default: break;
1932 }
1933
1934 // Rotate outlines and move corners to real position
1935 for( VECTOR2I& aPoint : aPoints )
1936 {
1937 switch( GetSpinStyle() )
1938 {
1939 default:
1940 case SPIN_STYLE::LEFT: break;
1941 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
1942 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
1943 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
1944 }
1945
1946 aPoint += aPos;
1947 }
1948}
1949
1950
1952{
1953 int margin = GetTextOffset();
1954 int symbolWidth = m_symbolSize;
1955 int origin = m_pinLength;
1956
1958 symbolWidth *= 2;
1959
1960 if( IsItalic() )
1961 margin = KiROUND( margin * 1.5 );
1962
1963 VECTOR2I offset;
1964
1965 for( SCH_FIELD& field : m_fields )
1966 {
1967 if( field.GetText() == wxEmptyString )
1968 continue;
1969
1970 switch( GetSpinStyle() )
1971 {
1972 default:
1973 case SPIN_STYLE::LEFT:
1974 field.SetTextAngle( ANGLE_HORIZONTAL );
1975 offset = { symbolWidth + margin, origin };
1976 break;
1977
1978 case SPIN_STYLE::UP:
1979 field.SetTextAngle( ANGLE_VERTICAL );
1980 offset = { -origin, -( symbolWidth + margin ) };
1981 break;
1982
1983 case SPIN_STYLE::RIGHT:
1984 field.SetTextAngle( ANGLE_HORIZONTAL );
1985 offset = { symbolWidth + margin, -origin };
1986 break;
1987
1988 case SPIN_STYLE::BOTTOM:
1989 field.SetTextAngle( ANGLE_VERTICAL );
1990 offset = { origin, -( symbolWidth + margin ) };
1991 break;
1992 }
1993
1994 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1995 field.SetTextPos( GetPosition() + offset );
1996
1997 origin -= field.GetTextHeight() + margin;
1998 }
1999
2000 if( aAlgo == AUTOPLACE_AUTO || aAlgo == AUTOPLACE_MANUAL )
2001 m_fieldsAutoplaced = aAlgo;
2002}
2003
2004
2005wxString SCH_DIRECTIVE_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2006{
2007 if( m_fields.empty() )
2008 {
2009 return _( "Directive Label" );
2010 }
2011 else
2012 {
2013 const SCH_FIELD& firstField = m_fields[0];
2014 wxString content = aFull ? firstField.GetShownText( FOR_GUI ) : KIUI::EllipsizeMenuText( firstField.GetText() );
2015
2016 if( content.IsEmpty() )
2017 return wxString::Format( _( "Directive Label [%s (empty)]" ), UnescapeString( m_fields[0].GetName() ) );
2018 else
2019 return wxString::Format( _( "Directive Label [%s %s]" ), UnescapeString( m_fields[0].GetName() ), content );
2020 }
2021}
2022
2023
2025{
2026 m_connected_rule_areas.insert( aRuleArea );
2027}
2028
2029
2034
2035
2037{
2038 m_connected_rule_areas.erase( aRuleArea );
2039}
2040
2041
2042const std::unordered_set<SCH_RULE_AREA*> SCH_DIRECTIVE_LABEL::GetConnectedRuleAreas() const
2043{
2045}
2046
2047
2049{
2050 return m_isDangling && m_connected_rule_areas.empty();
2051}
2052
2054{
2055 for( SCH_FIELD& field : m_fields )
2056 {
2057 if( field.GetUntranslatedName() == wxT( "Netclass" ) || field.GetUntranslatedName() == wxT( "Component Class" ) )
2058 {
2059 wxString text = field.GetText();
2060
2061 if( IncrementString( text, aIncrement ) )
2062 {
2063 field.SetText( text );
2064 }
2065 }
2066 }
2067
2068 return true;
2069}
2070
2071
2072SCH_GLOBALLABEL::SCH_GLOBALLABEL( const VECTOR2I& pos, const wxString& text ) :
2074{
2077 m_isDangling = true;
2078
2080
2081 m_fields.emplace_back(
2084 m_fields.back().SetText( wxT( "${INTERSHEET_REFS}" ) );
2085 m_fields.back().SetVisible( false );
2086 m_fields.back().SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
2087 m_fields.back().SetTextPos( pos );
2088}
2089
2090
2092 SCH_LABEL_BASE( aGlobalLabel )
2093{
2094}
2095
2096
2097void SCH_GLOBALLABEL::Serialize( google::protobuf::Any& aContainer ) const
2098{
2099 using namespace kiapi::schematic;
2100
2101 types::GlobalLabel label;
2102
2103 label.mutable_id()->set_value( m_Uuid.AsStdString() );
2105 label.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
2106 : kiapi::common::types::LockedState::LS_UNLOCKED );
2107
2108 EDA_TEXT::Serialize( *label.mutable_text(), schIUScale );
2109 kiapi::common::PackVector2( *label.mutable_position(), GetPosition(), schIUScale );
2110 label.set_fields_autoplaced( GetFieldsAutoplaced() != AUTOPLACE_NONE );
2111
2113
2114 for( const SCH_FIELD& field : GetFields() )
2115 {
2116 if( field.IsMandatory() )
2117 continue;
2118
2119 field.Serialize( *label.add_fields(), schIUScale );
2120 }
2121
2122 if( const SCH_FIELD* field = GetField( FIELD_T::INTERSHEET_REFS ) )
2123 field->Serialize( *label.mutable_intersheet_refs_field(), schIUScale );
2124
2125 aContainer.PackFrom( label );
2126}
2127
2128
2129bool SCH_GLOBALLABEL::Deserialize( const google::protobuf::Any& aContainer )
2130{
2131 kiapi::schematic::types::GlobalLabel label;
2132
2133 if( !aContainer.UnpackTo( &label ) )
2134 return false;
2135
2136 kiapi::common::UnpackCustomProperties( label.custom_properties(), *this );
2137
2138 if( !unpackLabel( label, *this ) )
2139 return false;
2140
2142 label.shape() ) );
2143
2144 if( label.has_intersheet_refs_field() )
2145 GetField( FIELD_T::INTERSHEET_REFS )->Deserialize( label.intersheet_refs_field(), schIUScale );
2146
2147 return true;
2148}
2149
2150
2152{
2153 if( SCH_FIELD* field = FindField( m_fields, aFieldType ) )
2154 return field;
2155
2156 m_fields.emplace_back( this, aFieldType );
2157 return &m_fields.back();
2158}
2159
2160
2162{
2163 return FindField( m_fields, aFieldType );
2164}
2165
2166
2168{
2169 int horiz = GetLabelBoxExpansion( aSettings );
2170
2171 // Center the text on the center line of "E" instead of "R" to make room for an overbar
2172 int vert = GetTextHeight() * 0.0715;
2173
2174 switch( m_shape )
2175 {
2179 horiz += GetTextHeight() * 3 / 4; // Use three-quarters-height as proxy for triangle size
2180 break;
2181
2184 default: break;
2185 }
2186
2187 switch( GetSpinStyle() )
2188 {
2189 default:
2190 case SPIN_STYLE::LEFT: return VECTOR2I( -horiz, vert );
2191 case SPIN_STYLE::UP: return VECTOR2I( vert, -horiz );
2192 case SPIN_STYLE::RIGHT: return VECTOR2I( horiz, vert );
2193 case SPIN_STYLE::BOTTOM: return VECTOR2I( vert, horiz );
2194 }
2195}
2196
2197
2203
2204
2205bool SCH_GLOBALLABEL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
2206{
2207 wxCHECK( aPath, false );
2208
2210
2211 if( !schematic )
2212 return false;
2213
2214 if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) )
2215 {
2216 SCHEMATIC_SETTINGS& settings = schematic->Settings();
2217 std::map<wxString, std::set<int>>& pageRefs = schematic->GetPageRefsMap();
2218 wxString ref;
2219 auto it = pageRefs.end();
2220
2221 // The map is keyed on the label's own shown text, so only a label carrying variables can
2222 // resolve through itself; that one has to stop before the stack does
2223 if( !HasTextVars() || aDepth < ADVANCED_CFG::GetCfg().m_ResolveTextRecursionDepth )
2224 it = pageRefs.find( GetShownText( aPath, FOR_GUI, aDepth ) );
2225
2226 if( it == pageRefs.end() )
2227 {
2228 ref = "?";
2229 }
2230 else
2231 {
2232 std::vector<int> pageListCopy;
2233
2234 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
2235 std::sort( pageListCopy.begin(), pageListCopy.end() );
2236
2237 if( !settings.m_IntersheetRefsListOwnPage )
2238 {
2239 int currentPage = aPath->GetVirtualPageNumber();
2240 std::erase( pageListCopy, currentPage );
2241 }
2242
2243 std::map<int, wxString> sheetPages = schematic->GetVirtualPageToSheetPagesMap();
2244
2245 if( settings.m_IntersheetRefsFormatShort && pageListCopy.size() > 2 )
2246 {
2247 ref.Append( wxString::Format( wxT( "%s..%s" ),
2248 sheetPages[pageListCopy.front()],
2249 sheetPages[pageListCopy.back()] ) );
2250 }
2251 else
2252 {
2253 for( const int& pageNo : pageListCopy )
2254 ref.Append( wxString::Format( wxT( "%s," ), sheetPages[pageNo] ) );
2255
2256 if( !ref.IsEmpty() && ref.Last() == ',' )
2257 ref.RemoveLast();
2258 }
2259 }
2260
2261 *token = settings.m_IntersheetRefsPrefix + ref + settings.m_IntersheetRefsSuffix;
2262 return true;
2263 }
2264
2265 return SCH_LABEL_BASE::ResolveTextVar( aPath, token, aDepth );
2266}
2267
2268
2274
2275
2276void SCH_GLOBALLABEL::CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings, std::vector<VECTOR2I>& aPoints,
2277 const VECTOR2I& aPos ) const
2278{
2279 int margin = GetLabelBoxExpansion( aRenderSettings );
2280 int halfSize = ( GetTextHeight() / 2 ) + margin;
2281 int linewidth = GetPenWidth();
2282 int symb_len = GetTextBox( aRenderSettings ).GetWidth() + 2 * margin;
2283
2284 int x = symb_len + linewidth + 3;
2285 int y = halfSize + linewidth + 3;
2286
2287 aPoints.clear();
2288
2289 // Create outline shape : 6 points
2290 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
2291 aPoints.emplace_back( VECTOR2I( 0, -y ) ); // Up
2292 aPoints.emplace_back( VECTOR2I( -x, -y ) ); // left
2293 aPoints.emplace_back( VECTOR2I( -x, 0 ) ); // Up left
2294 aPoints.emplace_back( VECTOR2I( -x, y ) ); // left down
2295 aPoints.emplace_back( VECTOR2I( 0, y ) ); // down
2296
2297 int x_offset = 0;
2298
2299 switch( m_shape )
2300 {
2302 x_offset = -halfSize;
2303 aPoints[0].x += halfSize;
2304 break;
2305
2306 case LABEL_FLAG_SHAPE::L_OUTPUT: aPoints[3].x -= halfSize; break;
2307
2310 x_offset = -halfSize;
2311 aPoints[0].x += halfSize;
2312 aPoints[3].x -= halfSize;
2313 break;
2314
2316 default: break;
2317 }
2318
2319 // Rotate outlines and move corners in real position
2320 for( VECTOR2I& aPoint : aPoints )
2321 {
2322 aPoint.x += x_offset;
2323
2324 switch( GetSpinStyle() )
2325 {
2326 default:
2327 case SPIN_STYLE::LEFT: break;
2328 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
2329 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
2330 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
2331 }
2332
2333 aPoint += aPos;
2334 }
2335
2336 aPoints.push_back( aPoints[0] ); // closing
2337}
2338
2339
2340wxString SCH_GLOBALLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2341{
2342 return wxString::Format( _( "Global Label '%s'" ), aFull ? GetShownText( FOR_GUI )
2344}
2345
2346
2351
2352
2353SCH_HIERLABEL::SCH_HIERLABEL( const VECTOR2I& pos, const wxString& text, KICAD_T aType ) :
2354 SCH_LABEL_BASE( pos, text, aType )
2355{
2358 m_isDangling = true;
2359}
2360
2361
2362void SCH_HIERLABEL::Serialize( google::protobuf::Any& aContainer ) const
2363{
2364 kiapi::schematic::types::HierarchicalLabel label;
2365
2366 packLabel( label, *this );
2368
2369 kiapi::common::PackCustomProperties( label.mutable_custom_properties(), *this );
2370 aContainer.PackFrom( label );
2371}
2372
2373
2374bool SCH_HIERLABEL::Deserialize( const google::protobuf::Any& aContainer )
2375{
2376 kiapi::schematic::types::HierarchicalLabel label;
2377
2378 if( !aContainer.UnpackTo( &label ) )
2379 return false;
2380
2381 kiapi::common::UnpackCustomProperties( label.custom_properties(), *this );
2382
2383 if( !unpackLabel( label, *this ) )
2384 return false;
2385
2387
2388 return true;
2389}
2390
2391
2397
2398
2399void SCH_HIERLABEL::CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
2400 const VECTOR2I& aPos ) const
2401{
2402 CreateGraphicShape( aSettings, aPoints, aPos, m_shape );
2403}
2404
2405
2406void SCH_HIERLABEL::CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
2407 const VECTOR2I& aPos, LABEL_FLAG_SHAPE aShape ) const
2408{
2409 int* Template = TemplateShape[static_cast<int>( aShape )][static_cast<int>( GetSpinStyle() )];
2410 int halfSize = GetTextHeight() / 2;
2411 int imax = *Template;
2412 Template++;
2413
2414 aPoints.clear();
2415
2416 for( int ii = 0; ii < imax; ii++ )
2417 {
2418 VECTOR2I corner;
2419 corner.x = ( halfSize * ( *Template ) ) + aPos.x;
2420 Template++;
2421
2422 corner.y = ( halfSize * ( *Template ) ) + aPos.y;
2423 Template++;
2424
2425 aPoints.push_back( corner );
2426 }
2427}
2428
2429
2431{
2432 int penWidth = GetEffectiveTextPenWidth();
2433 int margin = GetTextOffset();
2434
2435 int x = GetTextPos().x;
2436 int y = GetTextPos().y;
2437
2438 int height = GetTextHeight() + penWidth + margin;
2439 int length = GetTextBox( aSettings ).GetWidth();
2440
2441 length += height; // add height for triangular shapes
2442
2443 int dx, dy;
2444
2445 switch( GetSpinStyle() )
2446 {
2447 default:
2448 case SPIN_STYLE::LEFT:
2449 dx = -length;
2450 dy = height;
2451 x += schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2452 y -= height / 2;
2453 break;
2454
2455 case SPIN_STYLE::UP:
2456 dx = height;
2457 dy = -length;
2458 x -= height / 2;
2459 y += schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2460 break;
2461
2462 case SPIN_STYLE::RIGHT:
2463 dx = length;
2464 dy = height;
2465 x -= schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2466 y -= height / 2;
2467 break;
2468
2469 case SPIN_STYLE::BOTTOM:
2470 dx = height;
2471 dy = length;
2472 x -= height / 2;
2473 y -= schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2474 break;
2475 }
2476
2477 BOX2I box( VECTOR2I( x, y ), VECTOR2I( dx, dy ) );
2478 box.Normalize();
2479 return box;
2480}
2481
2482
2484{
2485 VECTOR2I text_offset;
2486 int dist = GetTextOffset( aSettings );
2487
2488 dist += GetTextWidth();
2489
2490 switch( GetSpinStyle() )
2491 {
2492 default:
2493 case SPIN_STYLE::LEFT: text_offset.x = -dist; break; // Orientation horiz normale
2494 case SPIN_STYLE::UP: text_offset.y = -dist; break; // Orientation vert UP
2495 case SPIN_STYLE::RIGHT: text_offset.x = dist; break; // Orientation horiz inverse
2496 case SPIN_STYLE::BOTTOM: text_offset.y = dist; break; // Orientation vert BOTTOM
2497 }
2498
2499 return text_offset;
2500}
2501
2502
2503wxString SCH_HIERLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2504{
2505 return wxString::Format( _( "Hierarchical Label '%s'" ), aFull ? GetShownText( FOR_GUI )
2507}
2508
2509
2514
2515
2517{
2518 wxString msg =
2519#include "sch_text_help_md.h"
2520 ;
2521
2522 HTML_MESSAGE_BOX* dlg = new HTML_MESSAGE_BOX( aParentWindow, _( "Syntax Help" ) );
2523 wxSize sz( 320, 320 );
2524
2525 dlg->SetMinSize( dlg->ConvertDialogToPixels( sz ) );
2526 dlg->SetDialogSizeInDU( sz.x, sz.y );
2527
2528 wxString html_txt;
2529 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
2530 dlg->AddHTML_Text( html_txt );
2531 dlg->ShowModeless();
2532
2533 return dlg;
2534}
2535
2536
2537static struct SCH_LABEL_DESC
2538{
2540 {
2541 auto& labelShapeEnum = ENUM_MAP<LABEL_SHAPE>::Instance();
2542
2543 if( labelShapeEnum.Choices().GetCount() == 0 )
2544 {
2545 labelShapeEnum.Map( LABEL_SHAPE::LABEL_INPUT, _HKI( "Input" ) )
2546 .Map( LABEL_SHAPE::LABEL_OUTPUT, _HKI( "Output" ) )
2547 .Map( LABEL_SHAPE::LABEL_BIDI, _HKI( "Bidirectional" ) )
2548 .Map( LABEL_SHAPE::LABEL_TRISTATE, _HKI( "Tri-state" ) )
2549 .Map( LABEL_SHAPE::LABEL_PASSIVE, _HKI( "Passive" ) );
2550 }
2551
2556
2560
2564
2568
2573
2574 auto hasLabelShape = []( INSPECTABLE* aItem ) -> bool
2575 {
2576 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aItem ) )
2577 return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_SHEET_PIN_T } );
2578
2579 return false;
2580 };
2581
2584 .SetAvailableFunc( hasLabelShape );
2585
2586 propMgr.Mask( TYPE_HASH( SCH_LABEL_BASE ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
2587 }
2589
2590
2592{
2594 {
2595 auto& flagShapeEnum = ENUM_MAP<FLAG_SHAPE>::Instance();
2596
2597 if( flagShapeEnum.Choices().GetCount() == 0 )
2598 {
2599 flagShapeEnum.Map( FLAG_SHAPE::FLAG_DOT, _HKI( "Dot" ) )
2600 .Map( FLAG_SHAPE::FLAG_CIRCLE, _HKI( "Circle" ) )
2601 .Map( FLAG_SHAPE::FLAG_DIAMOND, _HKI( "Diamond" ) )
2602 .Map( FLAG_SHAPE::FLAG_RECTANGLE, _HKI( "Rectangle" ) );
2603 }
2604
2610
2612
2615
2616 propMgr.AddProperty( new PROPERTY<SCH_DIRECTIVE_LABEL, int>( _HKI( "Pin length" ),
2619
2620 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Text" ) );
2621 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
2622 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Italic" ) );
2623 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Bold" ) );
2624 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ) );
2625 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ) );
2626 }
2628
2629
const char * name
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:55
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
BITMAPS
A list of all bitmap identifiers.
@ add_line_label
@ add_hierarchical_label
BOX2< VECTOR2I > BOX2I
Definition box2.h:927
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:995
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
constexpr int GetSizeMax() const
Definition box2.h:232
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:553
constexpr const Vec GetEnd() const
Definition box2.h:209
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:234
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition box2.h:143
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:653
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:165
constexpr const Vec & GetOrigin() const
Definition box2.h:207
constexpr void SetEnd(coord_type x, coord_type y)
Definition box2.h:294
constexpr void Offset(coord_type dx, coord_type dy)
Definition box2.h:256
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:308
static const COLOR4D WHITE
Definition color4d.h:402
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:399
static std::vector< DANGLING_END_ITEM >::iterator get_lower_type(std::vector< DANGLING_END_ITEM > &aItemListByType, const DANGLING_END_T &aType)
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition sch_item.cpp:993
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:597
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:482
EDA_ITEM * GetParent() const
Definition eda_item.h:112
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:153
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:607
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition eda_text.cpp:165
virtual VECTOR2I GetTextSize() const
Definition eda_text.h:301
COLOR4D GetTextColor() const
Definition eda_text.h:310
virtual VECTOR2I GetTextPos() const
Definition eda_text.h:313
bool IsItalic() const
Definition eda_text.h:200
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
virtual void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:539
virtual void SetTextX(int aX)
Definition eda_text.cpp:546
virtual int GetTextHeight() const
Definition eda_text.h:307
KIFONT::FONT * GetFont() const
Definition eda_text.h:286
virtual void SetTextY(int aY)
Definition eda_text.cpp:552
BOX2I GetTextBox(const RENDER_SETTINGS *aSettings, int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition eda_text.cpp:737
virtual wxString GetShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:128
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:373
virtual int GetTextWidth() const
Definition eda_text.h:304
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:239
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition eda_text.cpp:445
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:139
static wxString GotoPageHref(const wxString &aDestination)
Generate a href to a page in the current schematic.
virtual void cacheShownText()
Definition eda_text.cpp:587
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:178
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:270
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:422
bool IsBold() const
Definition eda_text.h:215
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:231
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:263
void SetMultilineAllowed(bool aAllow)
Definition eda_text.cpp:357
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:365
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:248
static ENUM_MAP< T > & Instance()
Definition property.h:770
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:39
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:94
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
std::shared_ptr< wxString > m_text
Definition color4d.h:396
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:530
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition color4d.h:292
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
virtual const COLOR4D & GetBackgroundColor() const =0
Return current background color settings.
Definition kiid.h:46
std::string AsStdString() const
Definition kiid.cpp:270
const wxString GetName() const
Gets the name of this (maybe aggregate) netclass in a format for internal usage or for export to exte...
Definition netclass.cpp:368
COLOR4D GetSchematicColor(bool aIsForSave=false) const
Definition netclass.h:233
Base plotter engine class.
Definition plotter.h:136
virtual void FilledCircle(const VECTOR2I &pos, int diametre, void *aData)
Definition plotter.cpp:520
void MoveTo(const VECTOR2I &pos)
Definition plotter.h:308
RENDER_SETTINGS * RenderSettings()
Definition plotter.h:167
virtual void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString)
Create a bookmark to a symbol.
Definition plotter.h:528
virtual void HyperlinkBox(const BOX2I &aBox, const wxString &aDestinationURL)
Create a clickable hyperlink with a rectangular click area.
Definition plotter.h:506
bool GetColorMode() const
Definition plotter.h:164
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:313
void PenFinish()
Definition plotter.h:324
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:617
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth, void *aData)=0
Draw a polygon ( filled or not ).
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition plotter.h:517
virtual void ThickCircle(const VECTOR2I &pos, int diametre, int width, void *aData)
Definition plotter.cpp:514
virtual void SetColor(const COLOR4D &color)=0
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Definition property.h:263
Provide class metadata.Helper macro to map type hashes to names.
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()
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:148
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
SCHEMATIC_SETTINGS & Settings() const
std::map< wxString, std::set< int > > & GetPageRefsMap()
Definition schematic.h:365
wxString GetCurrentVariant() const
Return the current variant being edited.
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:303
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
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 Name(bool aIgnoreSheet=false) const
bool IsBus() const
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
void MirrorSpinStyle(bool aLeftRight) override
void RemoveConnectedRuleArea(SCH_RULE_AREA *aRuleArea)
Removes a specific rule area from the cache.
void ClearConnectedRuleAreas()
Removes all rule areas from the cache.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
SCH_DIRECTIVE_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0))
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
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.
FLAG_SHAPE GetFlagShape() const
Definition sch_label.h:475
int GetPenWidth() const override
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:524
~SCH_DIRECTIVE_LABEL() override
bool operator==(const SCH_ITEM &aOther) const override
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
void SetPinLength(int aLength)
Definition sch_label.h:479
virtual bool IsDangling() const override
Determines dangling state from connectivity and cached connected rule areas.
void AddConnectedRuleArea(SCH_RULE_AREA *aRuleArea)
Adds an entry to the connected rule area cache.
void SetFlagShape(FLAG_SHAPE aShape)
Definition sch_label.h:476
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
bool IncrementLabel(int aIncrement) override
Increment the netclass and component class labels if possible.
const std::unordered_set< SCH_RULE_AREA * > GetConnectedRuleAreas() const
int GetPinLength() const
Definition sch_label.h:478
Schematic editor (Eeschema) main window.
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:138
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this label.
std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
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.
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const override
Resolve any references to system tokens supported by the label.
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...
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
SCH_GLOBALLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
const BOX2I GetBodyBoundingBox(const RENDER_SETTINGS *aSettings) const override
Return the bounding box of the label only, without taking in account its fields.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
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.
SCH_HIERLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString, KICAD_T aType=SCH_HIER_LABEL_T)
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
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...
virtual bool IsConnectable() const
Definition sch_item.h:531
void SetLocked(bool aLocked) override
Definition sch_item.h:256
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition sch_item.cpp:78
std::map< SCH_SHEET_PATH, std::vector< SCH_ITEM * >, SHEET_PATH_CMP > m_connected_items
Store pointers to other items that are connected to this one, per sheet.
Definition sch_item.h:799
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:281
bool IsLocked() const override
Definition sch_item.cpp:158
void AddConnectionTo(const SCH_SHEET_PATH &aPath, SCH_ITEM *aItem)
Add a connection link between this item and another.
Definition sch_item.cpp:597
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition sch_item.cpp:556
void SetFieldsAutoplaced(AUTOPLACE_ALGO aAlgo)
Definition sch_item.h:637
bool IsConnectivityDirty() const
Definition sch_item.h:598
std::optional< wxString > GetConnectionName(const SCH_SHEET_PATH *aSheet=nullptr, bool aLocal=false, bool aIgnoreSheet=false) const
Return the connection name for this sheet instance, if connected.
Definition sch_item.cpp:539
AUTOPLACE_ALGO m_fieldsAutoplaced
Definition sch_item.h:794
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:52
AUTOPLACE_ALGO GetFieldsAutoplaced() const
Return whether the fields have been automatically placed.
Definition sch_item.h:636
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:503
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:390
const KIFONT::METRICS & GetFontMetrics() const
Definition sch_item.cpp:815
SCH_LAYER_ID m_layer
Definition sch_item.h:790
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition sch_item.h:180
bool operator==(const SCH_ITEM &aItem) const override
const wxString & GetCachedDriverName() const override
SCH_LABEL_BASE(const VECTOR2I &aPos, const wxString &aText, KICAD_T aType)
COLOR4D m_lastResolvedColor
Definition sch_label.h:378
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
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...
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
std::vector< int > ViewGetLayers() const override
Return the layers the item is drawn on (which may be more than its "home" layer)
bool HasCachedDriverName() const override
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
SCH_LABEL_BASE & operator=(const SCH_LABEL_BASE &aLabel)
std::vector< SCH_FIELD > m_fields
Definition sch_label.h:370
CONNECTION_TYPE m_connectionType
Definition sch_label.h:374
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
int GetNextFieldOrdinal() const
Return the next ordinal for a user field for this label.
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.
void SetLabelShape(LABEL_SHAPE aShape)
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
SPIN_STYLE GetSpinStyle() const
void GetIntersheetRefs(const SCH_SHEET_PATH *aPath, std::vector< std::pair< wxString, wxString > > *pages)
Build an array of { pageNumber, pageName } pairs.
void MirrorSpinStyle(bool aLeftRight) override
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
COLOR4D GetLabelColor() const
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition sch_label.h:179
LABEL_FLAG_SHAPE GetShape() const
Definition sch_label.h:178
const BOX2I GetBoundingBox() const override
Return the bounding box of the label including its fields.
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void SetPosition(const VECTOR2I &aPosition) override
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
virtual bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const
Resolve any references to system tokens supported by the label.
LABEL_SHAPE GetLabelShape() const
Definition sch_label.h:175
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
bool m_autoRotateOnPlacement
Definition sch_label.h:376
wxString m_cached_driver_name
Definition sch_label.h:380
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
int GetLabelBoxExpansion(const RENDER_SETTINGS *aSettings=nullptr) const
virtual bool IncrementLabel(int aIncrement)
Increment the label text if it ends with a number.
void SetAutoRotateOnPlacement(bool autoRotate=true)
void cacheShownText() override
void Rotate90(bool aClockwise) override
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.
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, int aDepth=0) const override
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
LABEL_FLAG_SHAPE m_shape
Definition sch_label.h:372
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this label.
virtual const BOX2I GetBodyBoundingBox(const RENDER_SETTINGS *aSettings) const
Return the bounding box of the label only, without taking in account its fields.
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:302
std::vector< SCH_FIELD > & GetFields()
Definition sch_label.h:210
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.
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...
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
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 ...
double Similarity(const SCH_ITEM &aItem) const override
Return a measure of how likely the other object is to represent the same object.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
const BOX2I GetBodyBoundingBox(const RENDER_SETTINGS *aSettings) const override
Return the bounding box of the label only, without taking in account its fields.
SCH_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
Definition sch_screen.h:191
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:118
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
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
SCH_SCREEN * GetScreen() const
Definition sch_sheet.h:145
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition sch_sheet.h:241
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition sch_text.cpp:274
KIFONT::FONT * GetDrawFont(const RENDER_SETTINGS *aSettings) const override
Definition sch_text.cpp:327
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition sch_text.h:108
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition sch_text.cpp:203
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
VECTOR2I GetPosition() const override
Definition sch_text.h:143
virtual void Rotate90(bool aClockwise)
Definition sch_text.cpp:254
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition sch_text.cpp:164
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:731
int GetPenWidth() const override
Definition sch_text.cpp:321
virtual void MirrorSpinStyle(bool aLeftRight)
Definition sch_text.cpp:265
bool operator==(const SCH_ITEM &aItem) const override
Definition sch_text.cpp:714
int GetTextOffset(const RENDER_SETTINGS *aSettings=nullptr) const
Definition sch_text.cpp:306
SCH_TEXT(const VECTOR2I &aPos={ 0, 0 }, const wxString &aText=wxEmptyString, SCH_LAYER_ID aLayer=LAYER_NOTES, KICAD_T aType=SCH_TEXT_T)
Definition sch_text.cpp:55
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
SPIN Spin() const
Definition sch_label.h:69
SPIN m_spin
Definition sch_label.h:89
SPIN_STYLE()=default
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
unsigned CCWRotationsTo(const SPIN_STYLE &aOther) const
Get CCW rotation needed to get to the given spin style.
SPIN_STYLE RotateCCW()
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
void FinalizeTextVarExpansion(wxString &aText, RESOLUTION_CONTEXT aContext)
Definition common.cpp:88
wxString ResolveTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aResolver, int &aDepth)
Multi-pass text variable expansion and math expression evaluation.
Definition common.cpp:333
RESOLUTION_CONTEXT
Definition common.h:87
@ FOR_GUI
Definition common.h:89
@ FOR_CANVAS
Definition common.h:88
@ FOR_NETNAME
Definition common.h:90
@ RAW_VALUE
Definition common.h:94
@ INTERNAL
Definition common.h:92
#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 _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:424
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:419
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:418
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:427
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:426
@ NONE
Definition eda_fill.h:42
@ NO_FILL
Definition eda_fill.h:30
RECURSE_MODE
Definition eda_item.h:50
INSPECT_RESULT
Definition eda_item.h:44
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition eda_item.h:91
a few functions useful in geometry calculations.
KICOMMON_API bool IncrementString(wxString &name, int aIncrement)
Generic string incrementer.
Definition increment.cpp:30
@ LAYER_DANGLING
Definition layer_ids.h:499
@ LAYER_DEVICE
Definition layer_ids.h:488
@ LAYER_HIERLABEL
Definition layer_ids.h:479
@ LAYER_GLOBLABEL
Definition layer_ids.h:478
@ LAYER_NOTES
Definition layer_ids.h:489
@ LAYER_BUS
Definition layer_ids.h:475
@ LAYER_FIELDS
Definition layer_ids.h:484
@ LAYER_LOCLABEL
Definition layer_ids.h:477
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:486
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:517
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:485
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition macros.h:79
constexpr T MIRRORVAL(T aPoint, T aMirrorRef)
Returns the mirror of aPoint relative to the aMirrorRef.
Definition mirror.h:32
Message panel definition file.
bool BoxHitTest(const VECTOR2I &aHitPoint, const BOX2I &aHittee, int aAccuracy)
Perform a point-to-box hit test.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
std::optional< wxString > AppendConnectionInfo(const SCH_ITEM &aItem, std::vector< MSG_PANEL_ITEM > &aList, const SCH_SHEET_PATH *aPath=nullptr)
Append connection details; return its name for a signal, or no value for a bus/missing row.
KICOMMON_API int UnpackDistance(const types::Distance &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackDistance(types::Distance &aOutput, int aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:411
#define _HKI(x)
Definition page_info.cpp:40
see class PGM_BASE
#define TYPE_HASH(x)
Definition property.h:74
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition property.h:877
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
CONNECTION_TYPE
@ BUS
This item represents a bus vector.
@ NET
This item represents a net.
@ NONE
No connection to this item.
const SCH_FIELD * FindField(const std::vector< SCH_FIELD > &aFields, FIELD_T aFieldId)
Definition sch_field.h:393
int NextFieldOrdinal(const std::vector< SCH_FIELD > &aFields)
Definition sch_field.h:382
AUTOPLACE_ALGO
Definition sch_item.h:68
@ AUTOPLACE_MANUAL
Definition sch_item.h:71
@ AUTOPLACE_NONE
Definition sch_item.h:69
@ 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
static int TemplateIN_HI[]
Definition sch_label.cpp:65
static int TemplateUNSPC_HI[]
Definition sch_label.cpp:75
static int TemplateOUT_HN[]
Definition sch_label.cpp:69
static int Template3STATE_HN[]
Definition sch_label.cpp:84
static int TemplateBIDI_HN[]
Definition sch_label.cpp:79
static int * TemplateShape[5][4]
Definition sch_label.cpp:89
static int TemplateIN_HN[]
Definition sch_label.cpp:64
static int TemplateIN_BOTTOM[]
Definition sch_label.cpp:67
static int TemplateUNSPC_HN[]
Definition sch_label.cpp:74
static int Template3STATE_BOTTOM[]
Definition sch_label.cpp:87
bool unpackLabel(const LabelProto &aInput, SCH_LABEL_BASE &aLabel)
static int TemplateBIDI_BOTTOM[]
Definition sch_label.cpp:82
static struct SCH_LABEL_DESC _SCH_LABEL_DESC
static int Template3STATE_UP[]
Definition sch_label.cpp:86
static int TemplateOUT_UP[]
Definition sch_label.cpp:71
static int TemplateOUT_HI[]
Definition sch_label.cpp:70
static int TemplateUNSPC_UP[]
Definition sch_label.cpp:76
static int TemplateUNSPC_BOTTOM[]
Definition sch_label.cpp:77
static int TemplateOUT_BOTTOM[]
Definition sch_label.cpp:72
static int Template3STATE_HI[]
Definition sch_label.cpp:85
static int TemplateIN_UP[]
Definition sch_label.cpp:66
void packLabel(LabelProto &aOutput, const SCH_LABEL_BASE &aLabel)
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition sch_label.cpp:96
static int TemplateBIDI_UP[]
Definition sch_label.cpp:81
static int TemplateBIDI_HI[]
Definition sch_label.cpp:80
static struct SCH_DIRECTIVE_LABEL_DESC _SCH_DIRECTIVE_LABEL_DESC
FLAG_SHAPE
Definition sch_label.h:124
@ FLAG_CIRCLE
Definition sch_label.h:126
@ FLAG_RECTANGLE
Definition sch_label.h:128
@ FLAG_DOT
Definition sch_label.h:125
@ FLAG_DIAMOND
Definition sch_label.h:127
LABEL_FLAG_SHAPE
Definition sch_label.h:97
@ L_BIDI
Definition sch_label.h:100
@ L_TRISTATE
Definition sch_label.h:101
@ L_UNSPECIFIED
Definition sch_label.h:102
@ F_DOT
Definition sch_label.h:105
@ F_ROUND
Definition sch_label.h:106
@ L_OUTPUT
Definition sch_label.h:99
@ F_DIAMOND
Definition sch_label.h:107
@ L_INPUT
Definition sch_label.h:98
@ F_RECTANGLE
Definition sch_label.h:108
LABEL_SHAPE
Definition sch_label.h:115
@ LABEL_BIDI
Definition sch_label.h:118
@ LABEL_INPUT
Definition sch_label.h:116
@ LABEL_OUTPUT
Definition sch_label.h:117
@ LABEL_PASSIVE
Definition sch_label.h:120
@ LABEL_TRISTATE
Definition sch_label.h:119
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
void ConvertMarkdown2Html(const wxString &aMarkdownInput, wxString &aHtmlOutput)
bool m_PDFPropertyPopups
Definition sch_plotter.h:62
bool m_PDFHierarchicalLinks
Definition sch_plotter.h:63
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ INTERSHEET_REFS
Global label cross-reference page numbers.
@ UNTRANSLATED
std::string path
KIBIS_PIN * pin
VECTOR2I end
const int accuracy
int delta
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition trigo.cpp:171
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:225
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:70
@ SCH_ITEM_LOCATE_WIRE_T
Definition typeinfo.h:182
@ SCH_FIELD_T
Definition typeinfo.h:146
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:167
@ SCH_LABEL_T
Definition typeinfo.h:163
@ SCH_LOCATE_ANY_T
Definition typeinfo.h:195
@ SCH_ITEM_LOCATE_BUS_T
Definition typeinfo.h:183
@ SCH_HIER_LABEL_T
Definition typeinfo.h:165
@ SCH_LABEL_LOCATE_ANY_T
Definition typeinfo.h:187
@ SCH_LABEL_LOCATE_WIRE_T
Definition typeinfo.h:188
@ SCH_SHEET_PIN_T
Definition typeinfo.h:170
@ SCH_LABEL_LOCATE_BUS_T
Definition typeinfo.h:189
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:164
@ SCH_PIN_T
Definition typeinfo.h:149
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683