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
22#include <advanced_config.h>
23#include <base_units.h>
24#include <increment.h>
25#include <pgm_base.h>
26#include <sch_edit_frame.h>
27#include <sch_plotter.h>
28#include <widgets/msgpanel.h>
29#include <bitmaps.h>
30#include <string_utils.h>
32#include <schematic.h>
33#include <sch_screen.h>
34#include <sch_sheet.h>
35#include <sch_sheet_pin.h>
37#include <sch_painter.h>
38#include <default_values.h>
39#include <wx/debug.h>
40#include <wx/log.h>
44#include <core/kicad_algo.h>
45#include <core/mirror.h>
46#include <algorithm>
47#include <trigo.h>
48#include <sch_label.h>
49#include <sch_rule_area.h>
50#include <magic_enum.hpp>
51#include <api/api_enums.h>
52#include <api/api_utils.h>
53#include <api/schematic/schematic_types.pb.h>
54#include <properties/property.h>
56
57
58/* Coding polygons for global symbol graphic shapes.
59 * the first parml is the number of corners
60 * others are the corners coordinates in reduced units
61 * the real coordinate is the reduced coordinate * text half size
62 */
63static int TemplateIN_HN[] = { 6, 0, 0, -1, -1, -2, -1, -2, 1, -1, 1, 0, 0 };
64static int TemplateIN_HI[] = { 6, 0, 0, 1, 1, 2, 1, 2, -1, 1, -1, 0, 0 };
65static int TemplateIN_UP[] = { 6, 0, 0, 1, -1, 1, -2, -1, -2, -1, -1, 0, 0 };
66static int TemplateIN_BOTTOM[] = { 6, 0, 0, 1, 1, 1, 2, -1, 2, -1, 1, 0, 0 };
67
68static int TemplateOUT_HN[] = { 6, -2, 0, -1, 1, 0, 1, 0, -1, -1, -1, -2, 0 };
69static int TemplateOUT_HI[] = { 6, 2, 0, 1, -1, 0, -1, 0, 1, 1, 1, 2, 0 };
70static int TemplateOUT_UP[] = { 6, 0, -2, 1, -1, 1, 0, -1, 0, -1, -1, 0, -2 };
71static int TemplateOUT_BOTTOM[] = { 6, 0, 2, 1, 1, 1, 0, -1, 0, -1, 1, 0, 2 };
72
73static int TemplateUNSPC_HN[] = { 5, 0, -1, -2, -1, -2, 1, 0, 1, 0, -1 };
74static int TemplateUNSPC_HI[] = { 5, 0, -1, 2, -1, 2, 1, 0, 1, 0, -1 };
75static int TemplateUNSPC_UP[] = { 5, 1, 0, 1, -2, -1, -2, -1, 0, 1, 0 };
76static int TemplateUNSPC_BOTTOM[] = { 5, 1, 0, 1, 2, -1, 2, -1, 0, 1, 0 };
77
78static int TemplateBIDI_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
79static int TemplateBIDI_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
80static int TemplateBIDI_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
81static int TemplateBIDI_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
82
83static int Template3STATE_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
84static int Template3STATE_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
85static int Template3STATE_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
86static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
87
93
94
96{
97 switch( aType )
98 {
99 case LABEL_FLAG_SHAPE::L_INPUT: return _( "Input" );
100 case LABEL_FLAG_SHAPE::L_OUTPUT: return _( "Output" );
101 case LABEL_FLAG_SHAPE::L_BIDI: return _( "Bidirectional" );
102 case LABEL_FLAG_SHAPE::L_TRISTATE: return _( "Tri-State" );
103 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: return _( "Passive" );
104 default: return wxT( "???" );
105 }
106}
107
108
110{
111 SPIN newSpin = m_spin;
112
113 switch( m_spin )
114 {
115 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::BOTTOM; break;
116 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::RIGHT; break;
117 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::UP; break;
118 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::LEFT; break;
119 }
120
121 return SPIN_STYLE( newSpin );
122}
123
124
126{
127 SPIN newSpin = m_spin;
128
129 switch( m_spin )
130 {
131 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::BOTTOM; break;
132 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::UP; break;
133 case SPIN_STYLE::LEFT: break;
134 case SPIN_STYLE::RIGHT: break;
135 }
136
137 return SPIN_STYLE( newSpin );
138}
139
140
142{
143 SPIN newSpin = m_spin;
144
145 switch( m_spin )
146 {
147 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::RIGHT; break;
148 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::LEFT; break;
149 case SPIN_STYLE::UP: break;
150 case SPIN_STYLE::BOTTOM: break;
151 }
152
153 return SPIN_STYLE( newSpin );
154}
155
156
157unsigned SPIN_STYLE::CCWRotationsTo( const SPIN_STYLE& aOther ) const
158{
159 return ( ( (int) m_spin - (int) aOther.m_spin ) % 4 + 4 ) % 4;
160}
161
162
163SCH_LABEL_BASE::SCH_LABEL_BASE( const VECTOR2I& aPos, const wxString& aText, KICAD_T aType ) :
164 SCH_TEXT( aPos, aText, LAYER_NOTES, aType ),
167 m_isDangling( true ),
170{
171 SetMultilineAllowed( false );
172
173 if( !HasTextVars() )
175}
176
177
179 SCH_TEXT( aLabel ),
180 m_shape( aLabel.m_shape ),
182 m_isDangling( aLabel.m_isDangling ),
186{
187 SetMultilineAllowed( false );
188
189 m_fields = aLabel.m_fields;
190
191 for( SCH_FIELD& field : m_fields )
192 field.SetParent( this );
193}
194
195
197{
198 SCH_TEXT::operator=( aLabel );
199
200 m_fields = aLabel.m_fields;
201
202 for( SCH_FIELD& field : m_fields )
203 field.SetParent( this );
204
205 m_shape = aLabel.m_shape;
207 m_isDangling = aLabel.m_isDangling;
211
212 return *this;
213}
214
215
216const wxString SCH_LABEL_BASE::GetDefaultFieldName( const wxString& aName, bool aUseDefaultName )
217{
218 if( aName == wxT( "Intersheetrefs" ) )
219 return _( "Sheet References" );
220 else if( aName == wxT( "Netclass" ) )
221 return _( "Net Class" );
222 else if( aName.IsEmpty() && aUseDefaultName )
223 return _( "Field" );
224 else
225 return aName;
226}
227
228
233
234
235bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
236{
237 static const std::vector<KICAD_T> wireAndPinTypes = { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T };
238 static const std::vector<KICAD_T> busTypes = { SCH_ITEM_LOCATE_BUS_T };
239
240 if( SCH_TEXT::IsType( aScanTypes ) )
241 return true;
242
243 for( KICAD_T scanType : aScanTypes )
244 {
245 if( scanType == SCH_LABEL_LOCATE_ANY_T )
246 return true;
247 }
248
249 wxCHECK_MSG( Schematic(), false, wxT( "No parent SCHEMATIC set for SCH_LABEL!" ) );
250
251 // Ensure m_connected_items for Schematic()->CurrentSheet() exists.
252 // Can be not the case when "this" is living in clipboard
253 if( m_connected_items.find( Schematic()->CurrentSheet() ) == m_connected_items.end() )
254 return false;
255
256 const std::vector<SCH_ITEM*>& item_set = m_connected_items.at( Schematic()->CurrentSheet() );
257
258 for( KICAD_T scanType : aScanTypes )
259 {
260 if( scanType == SCH_LABEL_LOCATE_WIRE_T )
261 {
262 for( SCH_ITEM* connection : item_set )
263 {
264 if( connection->IsType( wireAndPinTypes ) )
265 return true;
266 }
267 }
268
269 if( scanType == SCH_LABEL_LOCATE_BUS_T )
270 {
271 for( SCH_ITEM* connection : item_set )
272 {
273 if( connection->IsType( busTypes ) )
274 return true;
275 }
276 }
277 }
278
279 return false;
280}
281
282
284{
285 SCH_TEXT::swapData( aItem );
286
287 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( aItem );
288
289 m_fields.swap( label->m_fields );
290 std::swap( m_fieldsAutoplaced, label->m_fieldsAutoplaced );
291
292 for( SCH_FIELD& field : m_fields )
293 field.SetParent( this );
294
295 for( SCH_FIELD& field : label->m_fields )
296 field.SetParent( label );
297
298 std::swap( m_shape, label->m_shape );
299 std::swap( m_connectionType, label->m_connectionType );
300 std::swap( m_isDangling, label->m_isDangling );
301 std::swap( m_lastResolvedColor, label->m_lastResolvedColor );
302}
303
304
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 wxString resolvedLabel = GetShownText( &Schematic()->CurrentSheet(), false );
727 auto it = Schematic()->GetPageRefsMap().find( resolvedLabel );
728
729 if( it != Schematic()->GetPageRefsMap().end() )
730 {
731 std::vector<int> pageListCopy;
732
733 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
734
735 if( !Schematic()->Settings().m_IntersheetRefsListOwnPage )
736 {
737 int currentPage = Schematic()->CurrentSheet().GetVirtualPageNumber();
738 std::erase( pageListCopy, currentPage );
739
740 if( pageListCopy.empty() )
741 return;
742 }
743
744 std::sort( pageListCopy.begin(), pageListCopy.end() );
745
746 std::map<int, wxString> sheetPages = Schematic()->GetVirtualPageToSheetPagesMap();
747 std::map<int, wxString> sheetNames = Schematic()->GetVirtualPageToSheetNamesMap();
748
749 for( int pageNum : pageListCopy )
750 pages->push_back( { sheetPages[pageNum], sheetNames[pageNum] } );
751 }
752 }
753}
754
755
756void SCH_LABEL_BASE::GetContextualTextVars( wxArrayString* aVars ) const
757{
758 for( const SCH_FIELD& field : m_fields )
759 {
760 if( field.IsMandatory() )
761 aVars->push_back( field.GetCanonicalName().Upper() );
762 else
763 aVars->push_back( field.GetName() );
764 }
765
766 aVars->push_back( wxT( "OP" ) );
767 aVars->push_back( wxT( "CONNECTION_TYPE" ) );
768 aVars->push_back( wxT( "SHORT_NET_NAME" ) );
769 aVars->push_back( wxT( "NET_NAME" ) );
770 aVars->push_back( wxT( "NET_CLASS" ) );
771}
772
773
774bool SCH_LABEL_BASE::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
775{
776 // Per-thread regex. CONNECTION_GRAPH::resolveAllDrivers calls this from worker
777 // threads, and wxRegEx::Matches is not safe to call concurrently on one instance.
778 thread_local wxRegEx operatingPoint( wxT( "^"
779 "OP"
780 "(.([0-9])?([a-zA-Z]*))?"
781 "$" ) );
782
783 wxCHECK( aPath, false );
784
785 SCHEMATIC* schematic = Schematic();
786
787 if( !schematic )
788 return false;
789
790 wxString variant = schematic->GetCurrentVariant();
791
792 if( operatingPoint.Matches( *token ) )
793 {
794 int precision = 3;
795 wxString precisionStr( operatingPoint.GetMatch( *token, 2 ) );
796 wxString range( operatingPoint.GetMatch( *token, 3 ) );
797
798 if( !precisionStr.IsEmpty() )
799 precision = precisionStr[0] - '0';
800
801 if( range.IsEmpty() )
802 range = wxS( "~V" );
803
804 const SCH_CONNECTION* connection = Connection();
805 *token = wxS( "?" );
806
807 if( connection )
808 *token = schematic->GetOperatingPoint( connection->Name( false ), precision, range );
809
810 return true;
811 }
812
813 if( token->Contains( ':' ) )
814 {
815 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
816 return true;
817 }
818
820 && token->IsSameAs( wxT( "CONNECTION_TYPE" ) ) )
821 {
822 const SCH_LABEL_BASE* label = static_cast<const SCH_LABEL_BASE*>( this );
823 *token = getElectricalTypeLabel( label->GetShape() );
824 return true;
825 }
826 else if( token->IsSameAs( wxT( "SHORT_NET_NAME" ) ) )
827 {
828 const SCH_CONNECTION* connection = Connection();
829 *token = wxEmptyString;
830
831 if( connection )
832 *token = connection->LocalName();
833
834 return true;
835 }
836 else if( token->IsSameAs( wxT( "NET_NAME" ) ) )
837 {
838 const SCH_CONNECTION* connection = Connection();
839 *token = wxEmptyString;
840
841 if( connection )
842 *token = connection->Name();
843
844 return true;
845 }
846 else if( token->IsSameAs( wxT( "NET_CLASS" ) ) )
847 {
848 const SCH_CONNECTION* connection = Connection();
849 *token = wxEmptyString;
850
851 if( connection )
852 *token = GetEffectiveNetClass()->GetName();
853
854 return true;
855 }
856 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "EXCLUDE_FROM_BOM" ) ) )
857 {
858 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
859 *token = wxEmptyString;
860
861 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
862 {
863 if( ruleArea->GetExcludedFromBOM( aPath, variant ) )
864 *token = _( "Excluded from BOM" );
865 }
866
867 return true;
868 }
869 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "EXCLUDE_FROM_BOARD" ) ) )
870 {
871 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
872 *token = wxEmptyString;
873
874 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
875 {
876 if( ruleArea->GetExcludedFromBoard( aPath, variant ) )
877 *token = _( "Excluded from board" );
878 }
879
880 return true;
881 }
882 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "EXCLUDE_FROM_SIM" ) ) )
883 {
884 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
885 *token = wxEmptyString;
886
887 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
888 {
889 if( ruleArea->GetExcludedFromSim( aPath, variant ) )
890 *token = _( "Excluded from simulation" );
891 }
892
893 return true;
894 }
895 else if( Type() == SCH_DIRECTIVE_LABEL_T && token->IsSameAs( wxT( "DNP" ) ) )
896 {
897 const SCH_DIRECTIVE_LABEL* directive = static_cast<const SCH_DIRECTIVE_LABEL*>( this );
898 *token = wxEmptyString;
899
900 for( SCH_RULE_AREA* ruleArea : directive->GetConnectedRuleAreas() )
901 {
902 if( ruleArea->GetDNP( aPath, variant ) )
903 *token = _( "DNP" );
904 }
905
906 return true;
907 }
908
909 for( const SCH_FIELD& field : m_fields )
910 {
911 if( token->IsSameAs( field.GetName() ) )
912 {
913 *token = field.GetShownText( false, aDepth + 1 );
914 return true;
915 }
916 }
917
918 // See if parent can resolve it (these will recurse to ancestors)
919
920 if( Type() == SCH_SHEET_PIN_T && m_parent )
921 {
922 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
923
924 // aPath is expected to be either the sheet pin's owner-screen path (parent sheet as
925 // Last()) or the already-extended path whose Last() is the owning sheet itself.
926 // Only push the owner sheet when it isn't already at the end; a double-push produces
927 // a nonsense path and breaks lookups keyed on the instance (e.g. ${#} page number).
928 SCH_SHEET_PATH path = *aPath;
929
930 if( path.Last() != sheet )
931 path.push_back( sheet );
932
933 if( sheet->ResolveTextVar( &path, token, aDepth + 1 ) )
934 return true;
935 }
936 else
937 {
938 // aPath->Last() can be null when loading schematic, i.e. when all sheets are not yet loaded
939 if( aPath->Last() && aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
940 return true;
941 }
942
943 return false;
944}
945
946
948{
949 return !HasTextVars();
950}
951
952
954{
956}
957
958
966
967
968wxString SCH_LABEL_BASE::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText, int aDepth ) const
969{
970 // Use local depth counter so each text element starts fresh
971 int depth = 0;
972
973 std::function<bool( wxString* )> textResolver = [&]( wxString* token ) -> bool
974 {
975 return ResolveTextVar( aPath, token, depth + 1 );
976 };
977
978 wxString text = EDA_TEXT::GetShownText( aAllowExtraText, depth );
979
980 if( HasTextVars() )
981 text = ResolveTextVars( text, &textResolver, depth );
982
983 // Convert escape markers back to literals for final display
984 text.Replace( wxT( "<<<ESC_DOLLAR:" ), wxT( "${" ) );
985 text.Replace( wxT( "<<<ESC_AT:" ), wxT( "@{" ) );
986
987 return text;
988}
989
990
991void SCH_LABEL_BASE::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
992{
993 for( SCH_FIELD& field : m_fields )
994 aFunction( &field );
995}
996
997
998bool SCH_LABEL_BASE::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
999{
1000 if( SCH_ITEM::Matches( UnescapeString( GetText() ), aSearchData ) )
1001 {
1002 return true;
1003 }
1004
1005 const SCH_SEARCH_DATA* searchData = dynamic_cast<const SCH_SEARCH_DATA*>( &aSearchData );
1006 SCH_CONNECTION* connection = nullptr;
1007 SCH_SHEET_PATH* sheetPath = reinterpret_cast<SCH_SHEET_PATH*>( aAuxData );
1008
1009 if( searchData && searchData->searchNetNames && sheetPath && ( connection = Connection( sheetPath ) ) )
1010 {
1011 if( connection->IsBus() )
1012 {
1013 auto allMembers = connection->AllMembers();
1014
1015 std::set<wxString> netNames;
1016
1017 for( std::shared_ptr<SCH_CONNECTION> member : allMembers )
1018 netNames.insert( member->GetNetName() );
1019
1020 for( const wxString& netName : netNames )
1021 {
1022 if( EDA_ITEM::Matches( netName, aSearchData ) )
1023 return true;
1024 }
1025
1026 return false;
1027 }
1028
1029 wxString netName = connection->GetNetName();
1030
1031 if( EDA_ITEM::Matches( netName, aSearchData ) )
1032 return true;
1033 }
1034
1035 return false;
1036}
1037
1038
1039bool SCH_LABEL_BASE::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
1040{
1041 EDA_SEARCH_DATA localSearchData( aSearchData );
1042 localSearchData.findString = EscapeString( aSearchData.findString, CTX_NETNAME );
1043 localSearchData.replaceString = EscapeString( aSearchData.replaceString, CTX_NETNAME );
1044
1045 return EDA_TEXT::Replace( localSearchData );
1046}
1047
1048
1049INSPECT_RESULT SCH_LABEL_BASE::Visit( INSPECTOR aInspector, void* testData, const std::vector<KICAD_T>& aScanTypes )
1050{
1051 if( IsType( aScanTypes ) )
1052 {
1053 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
1054 return INSPECT_RESULT::QUIT;
1055 }
1056
1057 for( KICAD_T scanType : aScanTypes )
1058 {
1059 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
1060 {
1061 for( SCH_FIELD& field : m_fields )
1062 {
1063 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
1064 return INSPECT_RESULT::QUIT;
1065 }
1066 }
1067 }
1068
1070}
1071
1072
1073void SCH_LABEL_BASE::GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList )
1074{
1075 DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() );
1076 aItemList.push_back( item );
1077}
1078
1079
1080std::vector<VECTOR2I> SCH_LABEL_BASE::GetConnectionPoints() const
1081{
1082 return { GetTextPos() };
1083}
1084
1085
1090
1091
1093{
1094 double ratio;
1095
1096 if( aSettings )
1097 ratio = static_cast<const SCH_RENDER_SETTINGS*>( aSettings )->m_LabelSizeRatio;
1098 else if( Schematic() )
1099 ratio = Schematic()->Settings().m_LabelSizeRatio;
1100 else
1101 ratio = DEFAULT_LABEL_SIZE_RATIO; // For previews (such as in Preferences), etc.
1102
1103 return KiROUND( ratio * GetTextSize().y );
1104}
1105
1106
1108{
1109 // build the bounding box of the label only, without taking into account its fields
1110
1111 BOX2I box;
1112 std::vector<VECTOR2I> pts;
1113
1114 CreateGraphicShape( aSettings, pts, GetTextPos() );
1115
1116 for( const VECTOR2I& pt : pts )
1117 box.Merge( pt );
1118
1119 box.Inflate( GetEffectiveTextPenWidth() / 2 );
1120 box.Normalize();
1121 return box;
1122}
1123
1124
1126{
1127 // build the bounding box of the entire label, including its fields
1128
1129 BOX2I box = GetBodyBoundingBox( nullptr );
1130
1131 for( const SCH_FIELD& field : m_fields )
1132 {
1133 if( field.IsVisible() && field.GetText() != wxEmptyString )
1134 {
1135 BOX2I fieldBBox = field.GetBoundingBox();
1136
1137 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1138 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1139
1140 box.Merge( fieldBBox );
1141 }
1142 }
1143
1144 box.Normalize();
1145
1146 return box;
1147}
1148
1149
1150bool SCH_LABEL_BASE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1151{
1152 BOX2I bbox = GetBodyBoundingBox( nullptr );
1153 bbox.Inflate( aAccuracy );
1154
1155 if( bbox.Contains( aPosition ) )
1156 return true;
1157
1158 for( const SCH_FIELD& field : m_fields )
1159 {
1160 if( field.IsVisible() )
1161 {
1162 BOX2I fieldBBox = field.GetBoundingBox();
1163 fieldBBox.Inflate( aAccuracy );
1164
1165 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1166 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1167
1168 if( fieldBBox.Contains( aPosition ) )
1169 return true;
1170 }
1171 }
1172
1173 return false;
1174}
1175
1176
1177bool SCH_LABEL_BASE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1178{
1179 BOX2I rect = aRect;
1180
1181 rect.Inflate( aAccuracy );
1182
1183 if( aContained )
1184 {
1185 return rect.Contains( GetBoundingBox() );
1186 }
1187 else
1188 {
1189 if( rect.Intersects( GetBodyBoundingBox( nullptr ) ) )
1190 return true;
1191
1192 for( const SCH_FIELD& field : m_fields )
1193 {
1194 if( field.IsVisible() )
1195 {
1196 BOX2I fieldBBox = field.GetBoundingBox();
1197
1198 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1199 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1200
1201 if( rect.Intersects( fieldBBox ) )
1202 return true;
1203 }
1204 }
1205
1206 return false;
1207 }
1208}
1209
1210
1211bool SCH_LABEL_BASE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1212{
1213 if( aContained )
1214 {
1215 return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
1216 }
1217 else
1218 {
1219 if( KIGEOM::BoxHitTest( aPoly, GetBodyBoundingBox( nullptr ), aContained ) )
1220 return true;
1221
1222 for( const SCH_FIELD& field : m_fields )
1223 {
1224 if( field.IsVisible() )
1225 {
1226 BOX2I fieldBBox = field.GetBoundingBox();
1227
1228 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1229 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1230
1231 if( KIGEOM::BoxHitTest( aPoly, fieldBBox, aContained ) )
1232 return true;
1233 }
1234 }
1235
1236 return false;
1237 }
1238}
1239
1240
1241bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1242 std::vector<DANGLING_END_ITEM>& aItemListByPos, const SCH_SHEET_PATH* aPath )
1243{
1244 bool previousState = m_isDangling;
1245 VECTOR2I text_pos = GetTextPos();
1246 m_isDangling = true;
1248
1249 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, text_pos );
1250 it < aItemListByPos.end() && it->GetPosition() == text_pos; it++ )
1251 {
1252 DANGLING_END_ITEM& item = *it;
1253
1254 if( item.GetItem() == this )
1255 continue;
1256
1257 switch( item.GetType() )
1258 {
1259 case PIN_END:
1260 case LABEL_END:
1261 case SHEET_LABEL_END:
1262 case NO_CONNECT_END:
1263 if( text_pos == item.GetPosition() )
1264 {
1265 m_isDangling = false;
1266
1267 if( aPath && item.GetType() != PIN_END )
1268 AddConnectionTo( *aPath, static_cast<SCH_ITEM*>( item.GetItem() ) );
1269 }
1270 break;
1271
1272 default: break;
1273 }
1274
1275 if( !m_isDangling )
1276 break;
1277 }
1278
1279 if( m_isDangling )
1280 {
1281 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, BUS_END );
1282 it < aItemListByType.end() && it->GetType() == BUS_END; it++ )
1283 {
1284 DANGLING_END_ITEM& item = *it;
1285 DANGLING_END_ITEM& nextItem = *( ++it );
1286
1287 int accuracy = 1; // We have rounding issues with an accuracy of 0
1288
1289 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(), accuracy );
1290
1291 if( m_isDangling )
1292 continue;
1293
1295
1296 // Add the line to the connected items, since it won't be picked
1297 // up by a search of intersecting connection points
1298 if( aPath )
1299 {
1300 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1301 AddConnectionTo( *aPath, sch_item );
1302 sch_item->AddConnectionTo( *aPath, this );
1303 }
1304
1305 break;
1306 }
1307
1308 if( m_isDangling )
1309 {
1310 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, WIRE_END );
1311 it < aItemListByType.end() && it->GetType() == WIRE_END; it++ )
1312 {
1313 DANGLING_END_ITEM& item = *it;
1314 DANGLING_END_ITEM& nextItem = *( ++it );
1315
1316 int accuracy = 1; // We have rounding issues with an accuracy of 0
1317
1318 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(), accuracy );
1319
1320 if( m_isDangling )
1321 continue;
1322
1324
1325 // Add the line to the connected items, since it won't be picked
1326 // up by a search of intersecting connection points
1327 if( aPath )
1328 {
1329 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1330 AddConnectionTo( *aPath, sch_item );
1331 sch_item->AddConnectionTo( *aPath, this );
1332 }
1333
1334 break;
1335 }
1336 }
1337 }
1338
1339 if( m_isDangling )
1341
1342 return previousState != m_isDangling;
1343}
1344
1345
1346bool SCH_LABEL_BASE::HasConnectivityChanges( const SCH_ITEM* aItem, const SCH_SHEET_PATH* aInstance ) const
1347{
1348 // Do not compare to ourself.
1349 if( aItem == this || !IsConnectable() )
1350 return false;
1351
1352 const SCH_LABEL_BASE* label = dynamic_cast<const SCH_LABEL_BASE*>( aItem );
1353
1354 // Don't compare against a different SCH_ITEM.
1355 wxCHECK( label, false );
1356
1357 if( GetPosition() != label->GetPosition() )
1358 return true;
1359
1360 if( GetShownText( aInstance ) != label->GetShownText( aInstance ) )
1361 return true;
1362
1363 std::vector<wxString> netclasses;
1364 std::vector<wxString> otherNetclasses;
1365
1366 for( const SCH_FIELD& field : m_fields )
1367 {
1368 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1369 netclasses.push_back( field.GetText() );
1370 }
1371
1372 for( const SCH_FIELD& field : label->m_fields )
1373 {
1374 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1375 otherNetclasses.push_back( field.GetText() );
1376 }
1377
1378 return netclasses != otherNetclasses;
1379}
1380
1381
1382void SCH_LABEL_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1383{
1384 wxString msg;
1385
1386 switch( Type() )
1387 {
1388 case SCH_LABEL_T: msg = _( "Label" ); break;
1389 case SCH_DIRECTIVE_LABEL_T: msg = _( "Directive Label" ); break;
1390 case SCH_GLOBAL_LABEL_T: msg = _( "Global Label" ); break;
1391 case SCH_HIER_LABEL_T: msg = _( "Hierarchical Label" ); break;
1392 case SCH_SHEET_PIN_T: msg = _( "Hierarchical Sheet Pin" ); break;
1393 default: return;
1394 }
1395
1396 // Don't use GetShownText() here; we want to show the user the variable references
1397 aList.emplace_back( msg, UnescapeString( GetText() ) );
1398
1399 // Display electrical type if it is relevant
1401 aList.emplace_back( _( "Type" ), getElectricalTypeLabel( GetShape() ) );
1402
1403 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1404
1405 wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
1406 int style = IsBold() && IsItalic() ? 3 : IsBold() ? 2 : IsItalic() ? 1 : 0;
1407 aList.emplace_back( _( "Style" ), textStyle[style] );
1408
1409 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1410
1411 switch( GetSpinStyle() )
1412 {
1413 case SPIN_STYLE::LEFT: msg = _( "Align right" ); break;
1414 case SPIN_STYLE::UP: msg = _( "Align bottom" ); break;
1415 case SPIN_STYLE::RIGHT: msg = _( "Align left" ); break;
1416 case SPIN_STYLE::BOTTOM: msg = _( "Align top" ); break;
1417 default: msg = wxT( "???" ); break;
1418 }
1419
1420 aList.emplace_back( _( "Justification" ), msg );
1421
1422 SCH_CONNECTION* conn = nullptr;
1423
1424 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1425 conn = Connection();
1426
1427 if( conn )
1428 {
1429 conn->AppendInfoToMsgPanel( aList );
1430
1431 if( !conn->IsBus() )
1432 {
1433 aList.emplace_back( _( "Resolved Netclass" ),
1434 UnescapeString( GetEffectiveNetClass()->GetHumanReadableName() ) );
1435 }
1436 }
1437}
1438
1439
1440void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit,
1441 int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1442{
1443 static std::vector<VECTOR2I> s_poly;
1444
1445 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
1446 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
1447 SCH_CONNECTION* connection = Connection();
1448 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1449 COLOR4D color = settings->GetLayerColor( layer );
1450 int penWidth = GetEffectiveTextPenWidth( settings->GetDefaultPenWidth() );
1451 COLOR4D bg = settings->GetBackgroundColor();
1452
1453 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1454 bg = COLOR4D::WHITE;
1455
1456 if( aPlotter->GetColorMode() && GetLabelColor() != COLOR4D::UNSPECIFIED )
1457 color = GetLabelColor();
1458
1459 if( color.m_text && Schematic() )
1460 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1461
1462 if( aDimmed )
1463 {
1464 color.Desaturate();
1465 color = color.Mix( bg, 0.5f );
1466 }
1467
1468 penWidth = std::max( penWidth, settings->GetMinPenWidth() );
1469 aPlotter->SetCurrentLineWidth( penWidth );
1470
1471 KIFONT::FONT* font = GetDrawFont( settings );
1472
1473 VECTOR2I textpos = GetTextPos() + GetSchematicTextOffset( settings );
1474 CreateGraphicShape( settings, s_poly, GetTextPos() );
1475
1477 attrs.m_StrokeWidth = penWidth;
1478 attrs.m_Multiline = false;
1479
1480 if( aBackground )
1481 {
1482 // No filled shapes (yet)
1483 }
1484 else
1485 {
1486 aPlotter->PlotText( textpos, color, GetShownText( sheet, true ), attrs, font, GetFontMetrics() );
1487
1488 if( aPlotter->GetColorMode() )
1489 {
1490 // For the graphic shape use the override color or the layer color, but not the
1491 // net/netclass color.
1492 COLOR4D shapeColor;
1493
1495 shapeColor = GetTextColor();
1496 else
1497 shapeColor = settings->GetLayerColor( m_layer );
1498
1499 if( aDimmed )
1500 {
1501 shapeColor.Desaturate();
1502 shapeColor = shapeColor.Mix( bg, 0.5f );
1503 }
1504
1505 aPlotter->SetColor( shapeColor );
1506 }
1507
1509 {
1510 aPlotter->MoveTo( s_poly[0] );
1511 aPlotter->LineTo( s_poly[1] );
1512 aPlotter->PenFinish();
1513
1514 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1515 aPlotter->FilledCircle( s_poly[2], diameter, nullptr );
1516 }
1517 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1518 {
1519 aPlotter->MoveTo( s_poly[0] );
1520 aPlotter->LineTo( s_poly[1] );
1521 aPlotter->PenFinish();
1522
1523 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1524 aPlotter->ThickCircle( s_poly[2], diameter, penWidth, nullptr );
1525 }
1526 else
1527 {
1528 if( !s_poly.empty() )
1529 aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth, nullptr );
1530 }
1531
1532 // Make sheet pins and hierarchical labels clickable hyperlinks
1533 bool linkAlreadyPlotted = false;
1534 BOX2I bodyBBox = GetBodyBoundingBox( settings );
1535
1536 if( aPlotOpts.m_PDFHierarchicalLinks )
1537 {
1538 if( Type() == SCH_HIER_LABEL_T )
1539 {
1540 if( sheet->size() >= 2 )
1541 {
1542 SCH_SHEET_PATH path = *sheet;
1543 path.pop_back();
1544 aPlotter->HyperlinkBox( bodyBBox, EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1545 linkAlreadyPlotted = true;
1546 }
1547 }
1548 else if( Type() == SCH_SHEET_PIN_T )
1549 {
1550 SCH_SHEET_PATH path = *sheet;
1551 SCH_SHEET* parent = static_cast<SCH_SHEET*>( m_parent );
1552 path.push_back( parent );
1553 aPlotter->HyperlinkBox( bodyBBox, EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1554 linkAlreadyPlotted = true;
1555 }
1556 }
1557
1558 // Plot attributes to a hypertext menu
1559 if( aPlotOpts.m_PDFPropertyPopups && !linkAlreadyPlotted )
1560 {
1561 std::vector<wxString> properties;
1562
1563 if( connection )
1564 {
1565 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Net" ), connection->Name() ) );
1566
1567 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Resolved netclass" ),
1568 GetEffectiveNetClass()->GetHumanReadableName() ) );
1569 }
1570
1571 for( const SCH_FIELD& field : GetFields() )
1572 {
1573 properties.emplace_back(
1574 wxString::Format( wxT( "!%s = %s" ), field.GetName(), field.GetShownText( false ) ) );
1575 }
1576
1577 if( !properties.empty() )
1578 aPlotter->HyperlinkMenu( bodyBBox, properties );
1579 }
1580
1581 if( Type() == SCH_HIER_LABEL_T )
1582 aPlotter->Bookmark( bodyBBox, GetShownText( false ), _( "Hierarchical Labels" ) );
1583 }
1584
1585 for( SCH_FIELD& field : m_fields )
1586 field.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
1587}
1588
1589
1594
1595
1597{
1598 m_autoRotateOnPlacement = autoRotate;
1599}
1600
1601
1602SCH_LABEL::SCH_LABEL( const VECTOR2I& pos, const wxString& text ) :
1604{
1607 m_isDangling = true;
1608}
1609
1610
1611template<typename LabelProto>
1612void packLabel( LabelProto& aOutput, const SCH_LABEL_BASE& aLabel )
1613{
1614 using namespace kiapi::schematic;
1615
1616 aOutput.mutable_id()->set_value( aLabel.m_Uuid.AsStdString() );
1618 aOutput.set_locked( aLabel.IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
1619 : kiapi::common::types::LockedState::LS_UNLOCKED );
1620
1621 google::protobuf::Any any;
1622 aLabel.EDA_TEXT::Serialize( any, schIUScale );
1623 any.UnpackTo( aOutput.mutable_text() );
1624 kiapi::common::PackVector2( *aOutput.mutable_position(), aLabel.GetPosition(), schIUScale );
1625
1626 for( const SCH_FIELD& field : aLabel.GetFields() )
1627 {
1628 if( field.IsMandatory() )
1629 continue;
1630
1631 field.Serialize( any );
1632 any.UnpackTo( aOutput.mutable_fields()->Add() );
1633 }
1634}
1635
1636
1637template<typename LabelProto>
1638bool unpackLabel( const LabelProto& aInput, SCH_LABEL_BASE& aLabel )
1639{
1640 using namespace kiapi::schematic;
1641
1642 const_cast<KIID&>( aLabel.m_Uuid ) = KIID( aInput.id().value() );
1644 aLabel.SetLocked( aInput.locked() == kiapi::common::types::LockedState::LS_LOCKED );
1645
1646 google::protobuf::Any any;
1647 any.PackFrom( aInput.text() );
1648
1649 if( !aLabel.EDA_TEXT::Deserialize( any, schIUScale ) )
1650 return false;
1651
1652 aLabel.SetPosition( kiapi::common::UnpackVector2( aInput.position(), schIUScale ) );
1653 aLabel.GetFields().clear();
1654
1655 for( const types::SchematicField& field : aInput.fields() )
1656 {
1657 aLabel.GetFields().emplace_back( &aLabel, FIELD_T::USER );
1658 any.PackFrom( field );
1659 aLabel.GetFields().back().Deserialize( any );
1660 }
1661
1662 return true;
1663}
1664
1665
1666void SCH_LABEL::Serialize( google::protobuf::Any& aContainer ) const
1667{
1668 kiapi::schematic::types::LocalLabel label;
1669
1670 packLabel( label, *this );
1671
1672 aContainer.PackFrom( label );
1673}
1674
1675
1676bool SCH_LABEL::Deserialize( const google::protobuf::Any& aContainer )
1677{
1678 kiapi::schematic::types::LocalLabel label;
1679
1680 if( !aContainer.UnpackTo( &label ) )
1681 return false;
1682
1683 return unpackLabel( label, *this );
1684}
1685
1686
1688{
1689 BOX2I rect = GetTextBox( aSettings );
1690
1691 rect.Offset( 0, -GetTextOffset() );
1693
1694 if( !GetTextAngle().IsZero() )
1695 {
1696 // Rotate rect
1697 VECTOR2I pos = rect.GetOrigin();
1698 VECTOR2I end = rect.GetEnd();
1699
1700 RotatePoint( pos, GetTextPos(), GetTextAngle() );
1702
1703 rect.SetOrigin( pos );
1704 rect.SetEnd( end );
1705
1706 rect.Normalize();
1707 }
1708
1709 // Labels have a position point that is outside of the TextBox
1710 rect.Merge( GetPosition() );
1711
1712 return rect;
1713}
1714
1715
1716wxString SCH_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1717{
1718 return wxString::Format( _( "Label '%s'" ), aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
1719}
1720
1721
1726
1727
1729 SCH_LABEL_BASE( pos, wxEmptyString, SCH_DIRECTIVE_LABEL_T )
1730{
1733 m_pinLength = schIUScale.MilsToIU( 100 );
1734 m_symbolSize = schIUScale.MilsToIU( 20 );
1735 m_isDangling = true;
1736}
1737
1738
1740{
1741 SCH_LABEL_BASE::swapData( aItem );
1742
1743 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( aItem );
1744
1745 std::swap( m_pinLength, label->m_pinLength );
1746 std::swap( m_symbolSize, label->m_symbolSize );
1747}
1748
1749
1751 SCH_LABEL_BASE( aClassLabel )
1752{
1753 m_pinLength = aClassLabel.m_pinLength;
1754 m_symbolSize = aClassLabel.m_symbolSize;
1755}
1756
1757
1759{
1760 for( SCH_RULE_AREA* ruleArea : m_connected_rule_areas )
1761 ruleArea->RemoveDirective( this );
1762}
1763
1764
1765void SCH_DIRECTIVE_LABEL::Serialize( google::protobuf::Any& aContainer ) const
1766{
1767 kiapi::schematic::types::DirectiveLabel label;
1768
1769 packLabel( label, *this );
1771 kiapi::common::PackDistance( *label.mutable_pin_length(), m_pinLength, schIUScale );
1772 kiapi::common::PackDistance( *label.mutable_symbol_size(), m_symbolSize, schIUScale );
1773
1774 aContainer.PackFrom( label );
1775}
1776
1777
1778bool SCH_DIRECTIVE_LABEL::Deserialize( const google::protobuf::Any& aContainer )
1779{
1780 kiapi::schematic::types::DirectiveLabel label;
1781
1782 if( !aContainer.UnpackTo( &label ) )
1783 return false;
1784
1785 if( !unpackLabel( label, *this ) )
1786 return false;
1787
1789
1790 if( label.has_pin_length() )
1791 m_pinLength = kiapi::common::UnpackDistance( label.pin_length(), schIUScale );
1792
1793 if( label.has_symbol_size() )
1794 m_symbolSize = kiapi::common::UnpackDistance( label.symbol_size(), schIUScale );
1795
1796 return true;
1797}
1798
1799
1801{
1802 if( !SCH_LABEL_BASE::operator==( aOther ) )
1803 return false;
1804
1805 const SCH_DIRECTIVE_LABEL* other = dynamic_cast<const SCH_DIRECTIVE_LABEL*>( &aOther );
1806
1807 if( !other )
1808 return false;
1809
1810 return m_pinLength == other->m_pinLength && m_symbolSize == other->m_symbolSize;
1811}
1812
1813
1815{
1816 int pen = 0;
1817
1818 if( Schematic() )
1820
1821 return GetEffectiveTextPenWidth( pen );
1822}
1823
1824
1826{
1827 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1828 // vertical shape (like a text reduced to only "I" letter).
1829 // So the mirroring is not exactly similar to a SCH_TEXT item
1830 SCH_TEXT::MirrorSpinStyle( !aLeftRight );
1831
1832 for( SCH_FIELD& field : m_fields )
1833 {
1834 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
1835 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
1836 {
1837 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1838 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1839 else
1840 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1841 }
1842
1843 VECTOR2I pos = field.GetTextPos();
1844 VECTOR2I delta = (VECTOR2I) GetPosition() - pos;
1845
1846 if( aLeftRight )
1847 pos.x = GetPosition().x + delta.x;
1848 else
1849 pos.y = GetPosition().y + delta.y;
1850
1851 field.SetTextPos( pos );
1852 }
1853}
1854
1855
1857{
1858 VECTOR2I old_pos = GetPosition();
1859
1860 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1861 // vertical shape (like a text reduced to only "I" letter).
1862 // So the mirroring is not exactly similar to a SCH_TEXT item
1863 // Text is NOT really mirrored; it is moved to a suitable horizontal position
1864 SetSpinStyle( GetSpinStyle().MirrorX() );
1865
1866 SetTextX( MIRRORVAL( GetTextPos().x, aCenter ) );
1867
1868 for( SCH_FIELD& field : m_fields )
1869 {
1870 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1871 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1872 else if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1873 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1874
1875 VECTOR2I pos = field.GetTextPos();
1876 VECTOR2I delta = old_pos - pos;
1877 pos.x = GetPosition().x + delta.x;
1878
1879 field.SetPosition( pos );
1880 }
1881}
1882
1883
1885{
1886 VECTOR2I old_pos = GetPosition();
1887 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1888 // vertical shape (like a text reduced to only "I" letter).
1889 // So the mirroring is not exactly similar to a SCH_TEXT item
1890 // Text is NOT really mirrored; it is moved to a suitable vertical position
1891 SetSpinStyle( GetSpinStyle().MirrorY() );
1892
1893 SetTextY( MIRRORVAL( GetTextPos().y, aCenter ) );
1894
1895 for( SCH_FIELD& field : m_fields )
1896 {
1897 VECTOR2I pos = field.GetTextPos();
1898 VECTOR2I delta = old_pos - pos;
1899 pos.y = GetPosition().y + delta.y;
1900
1901 field.SetPosition( pos );
1902 }
1903}
1904
1905
1906void SCH_DIRECTIVE_LABEL::CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings, std::vector<VECTOR2I>& aPoints,
1907 const VECTOR2I& aPos ) const
1908{
1909 int symbolSize = m_symbolSize;
1910
1911 aPoints.clear();
1912
1913 switch( m_shape )
1914 {
1915 case LABEL_FLAG_SHAPE::F_DOT: symbolSize = KiROUND( symbolSize * 0.7 ); KI_FALLTHROUGH;
1916
1918 // First 3 points are used for generating shape
1919 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1920 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1921 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1922
1923 // These points are just used to bulk out the bounding box
1924 aPoints.emplace_back( VECTOR2I( -m_symbolSize, m_pinLength ) );
1925 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1926 aPoints.emplace_back( VECTOR2I( m_symbolSize, m_pinLength + symbolSize ) );
1927 break;
1928
1930 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1931 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1932 aPoints.emplace_back( VECTOR2I( -2 * m_symbolSize, m_pinLength ) );
1933 aPoints.emplace_back( VECTOR2I( 0, m_pinLength + symbolSize ) );
1934 aPoints.emplace_back( VECTOR2I( 2 * m_symbolSize, m_pinLength ) );
1935 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1936 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1937 break;
1938
1940 symbolSize = KiROUND( symbolSize * 0.8 );
1941
1942 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1943 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1944 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength - symbolSize ) );
1945 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength + symbolSize ) );
1946 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength + symbolSize ) );
1947 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength - symbolSize ) );
1948 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1949 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1950 break;
1951
1952 default: break;
1953 }
1954
1955 // Rotate outlines and move corners to real position
1956 for( VECTOR2I& aPoint : aPoints )
1957 {
1958 switch( GetSpinStyle() )
1959 {
1960 default:
1961 case SPIN_STYLE::LEFT: break;
1962 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
1963 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
1964 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
1965 }
1966
1967 aPoint += aPos;
1968 }
1969}
1970
1971
1973{
1974 int margin = GetTextOffset();
1975 int symbolWidth = m_symbolSize;
1976 int origin = m_pinLength;
1977
1979 symbolWidth *= 2;
1980
1981 if( IsItalic() )
1982 margin = KiROUND( margin * 1.5 );
1983
1984 VECTOR2I offset;
1985
1986 for( SCH_FIELD& field : m_fields )
1987 {
1988 if( field.GetText() == wxEmptyString )
1989 continue;
1990
1991 switch( GetSpinStyle() )
1992 {
1993 default:
1994 case SPIN_STYLE::LEFT:
1995 field.SetTextAngle( ANGLE_HORIZONTAL );
1996 offset = { symbolWidth + margin, origin };
1997 break;
1998
1999 case SPIN_STYLE::UP:
2000 field.SetTextAngle( ANGLE_VERTICAL );
2001 offset = { -origin, -( symbolWidth + margin ) };
2002 break;
2003
2004 case SPIN_STYLE::RIGHT:
2005 field.SetTextAngle( ANGLE_HORIZONTAL );
2006 offset = { symbolWidth + margin, -origin };
2007 break;
2008
2009 case SPIN_STYLE::BOTTOM:
2010 field.SetTextAngle( ANGLE_VERTICAL );
2011 offset = { origin, -( symbolWidth + margin ) };
2012 break;
2013 }
2014
2015 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
2016 field.SetTextPos( GetPosition() + offset );
2017
2018 origin -= field.GetTextHeight() + margin;
2019 }
2020
2021 if( aAlgo == AUTOPLACE_AUTO || aAlgo == AUTOPLACE_MANUAL )
2022 m_fieldsAutoplaced = aAlgo;
2023}
2024
2025
2026wxString SCH_DIRECTIVE_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2027{
2028 if( m_fields.empty() )
2029 {
2030 return _( "Directive Label" );
2031 }
2032 else
2033 {
2034 const SCH_FIELD& firstField = m_fields[0];
2035 wxString content = aFull ? firstField.GetShownText( false ) : KIUI::EllipsizeMenuText( firstField.GetText() );
2036
2037 if( content.IsEmpty() )
2038 {
2039 return wxString::Format( _( "Directive Label [%s (empty)]" ), UnescapeString( m_fields[0].GetName() ) );
2040 }
2041 else
2042 {
2043 return wxString::Format( _( "Directive Label [%s %s]" ), UnescapeString( m_fields[0].GetName() ), content );
2044 }
2045 }
2046}
2047
2048
2050{
2051 m_connected_rule_areas.insert( aRuleArea );
2052}
2053
2054
2059
2060
2062{
2063 m_connected_rule_areas.erase( aRuleArea );
2064}
2065
2066
2067const std::unordered_set<SCH_RULE_AREA*> SCH_DIRECTIVE_LABEL::GetConnectedRuleAreas() const
2068{
2070}
2071
2072
2074{
2075 return m_isDangling && m_connected_rule_areas.empty();
2076}
2077
2079{
2080 for( SCH_FIELD& field : m_fields )
2081 {
2082 if( field.GetCanonicalName() == wxT( "Netclass" ) || field.GetCanonicalName() == wxT( "Component Class" ) )
2083 {
2084 wxString text = field.GetText();
2085
2086 if( IncrementString( text, aIncrement ) )
2087 {
2088 field.SetText( text );
2089 }
2090 }
2091 }
2092
2093 return true;
2094}
2095
2096
2097SCH_GLOBALLABEL::SCH_GLOBALLABEL( const VECTOR2I& pos, const wxString& text ) :
2099{
2102 m_isDangling = true;
2103
2105
2106 m_fields.emplace_back(
2108 m_fields.back().SetText( wxT( "${INTERSHEET_REFS}" ) );
2109 m_fields.back().SetVisible( false );
2110 m_fields.back().SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
2111 m_fields.back().SetTextPos( pos );
2112}
2113
2114
2116 SCH_LABEL_BASE( aGlobalLabel )
2117{
2118}
2119
2120
2121void SCH_GLOBALLABEL::Serialize( google::protobuf::Any& aContainer ) const
2122{
2123 using namespace kiapi::schematic;
2124
2125 types::GlobalLabel label;
2126
2127 label.mutable_id()->set_value( m_Uuid.AsStdString() );
2129 label.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
2130 : kiapi::common::types::LockedState::LS_UNLOCKED );
2131
2132 google::protobuf::Any any;
2134 any.UnpackTo( label.mutable_text() );
2135 kiapi::common::PackVector2( *label.mutable_position(), GetPosition(), schIUScale );
2136
2138
2139 for( const SCH_FIELD& field : GetFields() )
2140 {
2141 if( field.IsMandatory() )
2142 continue;
2143
2144 field.Serialize( any );
2145 any.UnpackTo( label.mutable_fields()->Add() );
2146 }
2147
2148 if( const SCH_FIELD* field = GetField( FIELD_T::INTERSHEET_REFS ) )
2149 {
2150 google::protobuf::Any fieldAny;
2151 field->Serialize( fieldAny );
2152 fieldAny.UnpackTo( label.mutable_intersheet_refs_field() );
2153 }
2154
2155 aContainer.PackFrom( label );
2156}
2157
2158
2159bool SCH_GLOBALLABEL::Deserialize( const google::protobuf::Any& aContainer )
2160{
2161 kiapi::schematic::types::GlobalLabel label;
2162
2163 if( !aContainer.UnpackTo( &label ) )
2164 return false;
2165
2166 if( !unpackLabel( label, *this ) )
2167 return false;
2168
2170 label.shape() ) );
2171
2172 if( label.has_intersheet_refs_field() )
2173 {
2174 google::protobuf::Any any;
2175 any.PackFrom( label.intersheet_refs_field() );
2177 }
2178
2179 return true;
2180}
2181
2182
2184{
2185 if( SCH_FIELD* field = FindField( m_fields, aFieldType ) )
2186 return field;
2187
2188 m_fields.emplace_back( this, aFieldType );
2189 return &m_fields.back();
2190}
2191
2192
2194{
2195 return FindField( m_fields, aFieldType );
2196}
2197
2198
2200{
2201 int horiz = GetLabelBoxExpansion( aSettings );
2202
2203 // Center the text on the center line of "E" instead of "R" to make room for an overbar
2204 int vert = GetTextHeight() * 0.0715;
2205
2206 switch( m_shape )
2207 {
2211 horiz += GetTextHeight() * 3 / 4; // Use three-quarters-height as proxy for triangle size
2212 break;
2213
2216 default: break;
2217 }
2218
2219 switch( GetSpinStyle() )
2220 {
2221 default:
2222 case SPIN_STYLE::LEFT: return VECTOR2I( -horiz, vert );
2223 case SPIN_STYLE::UP: return VECTOR2I( vert, -horiz );
2224 case SPIN_STYLE::RIGHT: return VECTOR2I( horiz, vert );
2225 case SPIN_STYLE::BOTTOM: return VECTOR2I( vert, horiz );
2226 }
2227}
2228
2229
2235
2236
2237bool SCH_GLOBALLABEL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
2238{
2239 wxCHECK( aPath, false );
2240
2241 SCHEMATIC* schematic = Schematic();
2242
2243 if( !schematic )
2244 return false;
2245
2246 if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) )
2247 {
2248 SCHEMATIC_SETTINGS& settings = schematic->Settings();
2249 wxString ref;
2250 auto it = schematic->GetPageRefsMap().find( GetShownText( aPath ) );
2251
2252 if( it == schematic->GetPageRefsMap().end() )
2253 {
2254 ref = "?";
2255 }
2256 else
2257 {
2258 std::vector<int> pageListCopy;
2259
2260 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
2261 std::sort( pageListCopy.begin(), pageListCopy.end() );
2262
2263 if( !settings.m_IntersheetRefsListOwnPage )
2264 {
2265 int currentPage = schematic->CurrentSheet().GetVirtualPageNumber();
2266 std::erase( pageListCopy, currentPage );
2267 }
2268
2269 std::map<int, wxString> sheetPages = schematic->GetVirtualPageToSheetPagesMap();
2270
2271 if( ( settings.m_IntersheetRefsFormatShort ) && ( pageListCopy.size() > 2 ) )
2272 {
2273 ref.Append( wxString::Format( wxT( "%s..%s" ), sheetPages[pageListCopy.front()],
2274 sheetPages[pageListCopy.back()] ) );
2275 }
2276 else
2277 {
2278 for( const int& pageNo : pageListCopy )
2279 ref.Append( wxString::Format( wxT( "%s," ), sheetPages[pageNo] ) );
2280
2281 if( !ref.IsEmpty() && ref.Last() == ',' )
2282 ref.RemoveLast();
2283 }
2284 }
2285
2286 *token = settings.m_IntersheetRefsPrefix + ref + settings.m_IntersheetRefsSuffix;
2287 return true;
2288 }
2289
2290 return SCH_LABEL_BASE::ResolveTextVar( aPath, token, aDepth );
2291}
2292
2293
2299
2300
2301void SCH_GLOBALLABEL::CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings, std::vector<VECTOR2I>& aPoints,
2302 const VECTOR2I& aPos ) const
2303{
2304 int margin = GetLabelBoxExpansion( aRenderSettings );
2305 int halfSize = ( GetTextHeight() / 2 ) + margin;
2306 int linewidth = GetPenWidth();
2307 int symb_len = GetTextBox( aRenderSettings ).GetWidth() + 2 * margin;
2308
2309 int x = symb_len + linewidth + 3;
2310 int y = halfSize + linewidth + 3;
2311
2312 aPoints.clear();
2313
2314 // Create outline shape : 6 points
2315 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
2316 aPoints.emplace_back( VECTOR2I( 0, -y ) ); // Up
2317 aPoints.emplace_back( VECTOR2I( -x, -y ) ); // left
2318 aPoints.emplace_back( VECTOR2I( -x, 0 ) ); // Up left
2319 aPoints.emplace_back( VECTOR2I( -x, y ) ); // left down
2320 aPoints.emplace_back( VECTOR2I( 0, y ) ); // down
2321
2322 int x_offset = 0;
2323
2324 switch( m_shape )
2325 {
2327 x_offset = -halfSize;
2328 aPoints[0].x += halfSize;
2329 break;
2330
2331 case LABEL_FLAG_SHAPE::L_OUTPUT: aPoints[3].x -= halfSize; break;
2332
2335 x_offset = -halfSize;
2336 aPoints[0].x += halfSize;
2337 aPoints[3].x -= halfSize;
2338 break;
2339
2341 default: break;
2342 }
2343
2344 // Rotate outlines and move corners in real position
2345 for( VECTOR2I& aPoint : aPoints )
2346 {
2347 aPoint.x += x_offset;
2348
2349 switch( GetSpinStyle() )
2350 {
2351 default:
2352 case SPIN_STYLE::LEFT: break;
2353 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
2354 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
2355 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
2356 }
2357
2358 aPoint += aPos;
2359 }
2360
2361 aPoints.push_back( aPoints[0] ); // closing
2362}
2363
2364
2365wxString SCH_GLOBALLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2366{
2367 return wxString::Format( _( "Global Label '%s'" ),
2368 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
2369}
2370
2371
2376
2377
2378SCH_HIERLABEL::SCH_HIERLABEL( const VECTOR2I& pos, const wxString& text, KICAD_T aType ) :
2379 SCH_LABEL_BASE( pos, text, aType )
2380{
2383 m_isDangling = true;
2384}
2385
2386
2387void SCH_HIERLABEL::Serialize( google::protobuf::Any& aContainer ) const
2388{
2389 kiapi::schematic::types::HierarchicalLabel label;
2390
2391 packLabel( label, *this );
2393
2394 aContainer.PackFrom( label );
2395}
2396
2397
2398bool SCH_HIERLABEL::Deserialize( const google::protobuf::Any& aContainer )
2399{
2400 kiapi::schematic::types::HierarchicalLabel label;
2401
2402 if( !aContainer.UnpackTo( &label ) )
2403 return false;
2404
2405 if( !unpackLabel( label, *this ) )
2406 return false;
2407
2409
2410 return true;
2411}
2412
2413
2419
2420
2421void SCH_HIERLABEL::CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
2422 const VECTOR2I& aPos ) const
2423{
2424 CreateGraphicShape( aSettings, aPoints, aPos, m_shape );
2425}
2426
2427
2428void SCH_HIERLABEL::CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
2429 const VECTOR2I& aPos, LABEL_FLAG_SHAPE aShape ) const
2430{
2431 int* Template = TemplateShape[static_cast<int>( aShape )][static_cast<int>( GetSpinStyle() )];
2432 int halfSize = GetTextHeight() / 2;
2433 int imax = *Template;
2434 Template++;
2435
2436 aPoints.clear();
2437
2438 for( int ii = 0; ii < imax; ii++ )
2439 {
2440 VECTOR2I corner;
2441 corner.x = ( halfSize * ( *Template ) ) + aPos.x;
2442 Template++;
2443
2444 corner.y = ( halfSize * ( *Template ) ) + aPos.y;
2445 Template++;
2446
2447 aPoints.push_back( corner );
2448 }
2449}
2450
2451
2453{
2454 int penWidth = GetEffectiveTextPenWidth();
2455 int margin = GetTextOffset();
2456
2457 int x = GetTextPos().x;
2458 int y = GetTextPos().y;
2459
2460 int height = GetTextHeight() + penWidth + margin;
2461 int length = GetTextBox( aSettings ).GetWidth();
2462
2463 length += height; // add height for triangular shapes
2464
2465 int dx, dy;
2466
2467 switch( GetSpinStyle() )
2468 {
2469 default:
2470 case SPIN_STYLE::LEFT:
2471 dx = -length;
2472 dy = height;
2473 x += schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2474 y -= height / 2;
2475 break;
2476
2477 case SPIN_STYLE::UP:
2478 dx = height;
2479 dy = -length;
2480 x -= height / 2;
2481 y += schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2482 break;
2483
2484 case SPIN_STYLE::RIGHT:
2485 dx = length;
2486 dy = height;
2487 x -= schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2488 y -= height / 2;
2489 break;
2490
2491 case SPIN_STYLE::BOTTOM:
2492 dx = height;
2493 dy = length;
2494 x -= height / 2;
2495 y -= schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2496 break;
2497 }
2498
2499 BOX2I box( VECTOR2I( x, y ), VECTOR2I( dx, dy ) );
2500 box.Normalize();
2501 return box;
2502}
2503
2504
2506{
2507 VECTOR2I text_offset;
2508 int dist = GetTextOffset( aSettings );
2509
2510 dist += GetTextWidth();
2511
2512 switch( GetSpinStyle() )
2513 {
2514 default:
2515 case SPIN_STYLE::LEFT: text_offset.x = -dist; break; // Orientation horiz normale
2516 case SPIN_STYLE::UP: text_offset.y = -dist; break; // Orientation vert UP
2517 case SPIN_STYLE::RIGHT: text_offset.x = dist; break; // Orientation horiz inverse
2518 case SPIN_STYLE::BOTTOM: text_offset.y = dist; break; // Orientation vert BOTTOM
2519 }
2520
2521 return text_offset;
2522}
2523
2524
2525wxString SCH_HIERLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2526{
2527 return wxString::Format( _( "Hierarchical Label '%s'" ),
2528 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
2529}
2530
2531
2536
2537
2539{
2540 wxString msg =
2541#include "sch_text_help_md.h"
2542 ;
2543
2544 HTML_MESSAGE_BOX* dlg = new HTML_MESSAGE_BOX( aParentWindow, _( "Syntax Help" ) );
2545 wxSize sz( 320, 320 );
2546
2547 dlg->SetMinSize( dlg->ConvertDialogToPixels( sz ) );
2548 dlg->SetDialogSizeInDU( sz.x, sz.y );
2549
2550 wxString html_txt;
2551 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
2552 dlg->AddHTML_Text( html_txt );
2553 dlg->ShowModeless();
2554
2555 return dlg;
2556}
2557
2558
2559static struct SCH_LABEL_DESC
2560{
2562 {
2563 auto& labelShapeEnum = ENUM_MAP<LABEL_SHAPE>::Instance();
2564
2565 if( labelShapeEnum.Choices().GetCount() == 0 )
2566 {
2567 labelShapeEnum.Map( LABEL_SHAPE::LABEL_INPUT, _HKI( "Input" ) )
2568 .Map( LABEL_SHAPE::LABEL_OUTPUT, _HKI( "Output" ) )
2569 .Map( LABEL_SHAPE::LABEL_BIDI, _HKI( "Bidirectional" ) )
2570 .Map( LABEL_SHAPE::LABEL_TRISTATE, _HKI( "Tri-state" ) )
2571 .Map( LABEL_SHAPE::LABEL_PASSIVE, _HKI( "Passive" ) );
2572 }
2573
2578
2582
2586
2590
2595
2596 auto hasLabelShape = []( INSPECTABLE* aItem ) -> bool
2597 {
2598 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aItem ) )
2599 return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_SHEET_PIN_T } );
2600
2601 return false;
2602 };
2603
2606 .SetAvailableFunc( hasLabelShape );
2607
2608 propMgr.Mask( TYPE_HASH( SCH_LABEL_BASE ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
2609 }
2611
2612
2614{
2616 {
2617 auto& flagShapeEnum = ENUM_MAP<FLAG_SHAPE>::Instance();
2618
2619 if( flagShapeEnum.Choices().GetCount() == 0 )
2620 {
2621 flagShapeEnum.Map( FLAG_SHAPE::FLAG_DOT, _HKI( "Dot" ) )
2622 .Map( FLAG_SHAPE::FLAG_CIRCLE, _HKI( "Circle" ) )
2623 .Map( FLAG_SHAPE::FLAG_DIAMOND, _HKI( "Diamond" ) )
2624 .Map( FLAG_SHAPE::FLAG_RECTANGLE, _HKI( "Rectangle" ) );
2625 }
2626
2632
2634
2637
2641
2642 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Text" ) );
2643 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
2644 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Italic" ) );
2645 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Bold" ) );
2646 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ) );
2647 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ) );
2648 }
2650
2651
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:47
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:918
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
constexpr int GetSizeMax() const
Definition box2.h:231
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:554
constexpr const Vec GetEnd() const
Definition box2.h:208
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:233
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition box2.h:142
constexpr size_type GetWidth() const
Definition box2.h:210
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:654
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:164
constexpr const Vec & GetOrigin() const
Definition box2.h:206
constexpr void SetEnd(coord_type x, coord_type y)
Definition box2.h:293
constexpr void Offset(coord_type dx, coord_type dy)
Definition box2.h:255
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:307
static const COLOR4D WHITE
Definition color4d.h:401
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
static std::vector< DANGLING_END_ITEM >::iterator get_lower_type(std::vector< DANGLING_END_ITEM > &aItemListByType, const DANGLING_END_T &aType)
Definition sch_item.cpp:970
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition sch_item.cpp:959
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition sch_item.h:93
DANGLING_END_T GetType() const
Definition sch_item.h:129
EDA_ITEM * GetItem() const
Definition sch_item.h:127
VECTOR2I GetPosition() const
Definition sch_item.h:126
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:531
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:416
EDA_ITEM * GetParent() const
Definition eda_item.h:110
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:89
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:543
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:89
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:282
COLOR4D GetTextColor() const
Definition eda_text.h:291
virtual VECTOR2I GetTextPos() const
Definition eda_text.h:294
bool IsItalic() const
Definition eda_text.h:190
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:110
virtual void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:576
virtual void SetTextX(int aX)
Definition eda_text.cpp:583
virtual int GetTextHeight() const
Definition eda_text.h:288
KIFONT::FONT * GetFont() const
Definition eda_text.h:268
virtual void SetTextY(int aY)
Definition eda_text.cpp:589
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:773
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:412
virtual int GetTextWidth() const
Definition eda_text.h:285
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:221
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition eda_text.cpp:482
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:129
static wxString GotoPageHref(const wxString &aDestination)
Generate a href to a page in the current schematic.
virtual void cacheShownText()
Definition eda_text.cpp:624
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:168
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:252
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:461
bool IsBold() const
Definition eda_text.h:205
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:121
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:265
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:294
void SetMultilineAllowed(bool aAllow)
Definition eda_text.cpp:396
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:404
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:221
static ENUM_MAP< T > & Instance()
Definition property.h:721
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:38
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:395
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:528
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:44
std::string AsStdString() const
Definition kiid.cpp:248
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:354
COLOR4D GetSchematicColor(bool aIsForSave=false) const
Definition netclass.h:225
Base plotter engine class.
Definition plotter.h:133
virtual void FilledCircle(const VECTOR2I &pos, int diametre, void *aData)
Definition plotter.cpp:615
void MoveTo(const VECTOR2I &pos)
Definition plotter.h:305
RENDER_SETTINGS * RenderSettings()
Definition plotter.h:164
virtual void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString)
Create a bookmark to a symbol.
Definition plotter.h:525
virtual void HyperlinkBox(const BOX2I &aBox, const wxString &aDestinationURL)
Create a clickable hyperlink with a rectangular click area.
Definition plotter.h:503
bool GetColorMode() const
Definition plotter.h:161
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:310
void PenFinish()
Definition plotter.h:321
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:712
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:514
virtual void ThickCircle(const VECTOR2I &pos, int diametre, int width, void *aData)
Definition plotter.cpp:609
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:262
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:90
SCHEMATIC_SETTINGS & Settings() const
std::map< wxString, std::set< int > > & GetPageRefsMap()
Definition schematic.h:249
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:189
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString GetNetName() const
const std::vector< std::shared_ptr< SCH_CONNECTION > > AllMembers() const
wxString LocalName() const
wxString Name(bool aIgnoreSheet=false) const
bool IsBus() const
void AppendInfoToMsgPanel(std::vector< MSG_PANEL_ITEM > &aList) const
Adds information about the connection object to aList.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
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:478
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:527
~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:482
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:479
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:481
Schematic editor (Eeschema) main window.
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) 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:524
void SetLocked(bool aLocked) override
Definition sch_item.h:251
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:784
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:268
bool IsLocked() const override
Definition sch_item.cpp:148
void AddConnectionTo(const SCH_SHEET_PATH &aPath, SCH_ITEM *aItem)
Add a connection link between this item and another.
Definition sch_item.cpp:564
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition sch_item.cpp:523
bool IsConnectivityDirty() const
Definition sch_item.h:585
AUTOPLACE_ALGO m_fieldsAutoplaced
Definition sch_item.h:779
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:52
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:487
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:377
const KIFONT::METRICS & GetFontMetrics() const
Definition sch_item.cpp:781
SCH_LAYER_ID m_layer
Definition sch_item.h:775
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition sch_item.h:177
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:381
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
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:373
CONNECTION_TYPE m_connectionType
Definition sch_label.h:377
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:379
wxString m_cached_driver_name
Definition sch_label.h:383
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)
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
LABEL_FLAG_SHAPE m_shape
Definition sch_label.h:375
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:305
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:185
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:115
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:44
SCH_SCREEN * GetScreen() const
Definition sch_sheet.h:139
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition sch_sheet.h:227
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:277
KIFONT::FONT * GetDrawFont(const RENDER_SETTINGS *aSettings) const override
Definition sch_text.cpp:330
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition sch_text.h:111
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition sch_text.cpp:206
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
VECTOR2I GetPosition() const override
Definition sch_text.h:146
virtual void Rotate90(bool aClockwise)
Definition sch_text.cpp:257
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition sch_text.cpp:167
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:734
int GetPenWidth() const override
Definition sch_text.cpp:324
virtual void MirrorSpinStyle(bool aLeftRight)
Definition sch_text.cpp:268
bool operator==(const SCH_ITEM &aItem) const override
Definition sch_text.cpp:717
int GetTextOffset(const RENDER_SETTINGS *aSettings=nullptr) const
Definition sch_text.cpp:309
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().
A type-safe container of any type.
Definition ki_any.h:92
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:296
#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:413
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:408
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:407
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:416
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:415
RECURSE_MODE
Definition eda_item.h:48
INSPECT_RESULT
Definition eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition eda_item.h:89
@ NONE
Definition eda_shape.h:72
@ NO_FILL
Definition eda_shape.h:60
a few functions useful in geometry calculations.
KICOMMON_API bool IncrementString(wxString &name, int aIncrement)
Generic string incrementer.
Definition increment.cpp:29
@ LAYER_DANGLING
Definition layer_ids.h:475
@ LAYER_DEVICE
Definition layer_ids.h:464
@ LAYER_HIERLABEL
Definition layer_ids.h:455
@ LAYER_GLOBLABEL
Definition layer_ids.h:454
@ LAYER_NOTES
Definition layer_ids.h:465
@ LAYER_BUS
Definition layer_ids.h:451
@ LAYER_FIELDS
Definition layer_ids.h:460
@ LAYER_LOCLABEL
Definition layer_ids.h:453
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:462
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:493
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:461
#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.
KICOMMON_API int UnpackDistance(const types::Distance &aInput, const EDA_IU_SCALE &aScale)
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)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
#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:828
@ 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:383
int NextFieldOrdinal(const std::vector< SCH_FIELD > &aFields)
Definition sch_field.h:372
AUTOPLACE_ALGO
Definition sch_item.h:65
@ AUTOPLACE_MANUAL
Definition sch_item.h:68
@ AUTOPLACE_AUTO
Definition sch_item.h:67
@ NO_CONNECT_END
Definition sch_item.h:84
@ SHEET_LABEL_END
Definition sch_item.h:83
@ LABEL_END
Definition sch_item.h:80
@ BUS_END
Definition sch_item.h:77
@ PIN_END
Definition sch_item.h:79
@ WIRE_END
Definition sch_item.h:76
static int TemplateIN_HI[]
Definition sch_label.cpp:64
static int TemplateUNSPC_HI[]
Definition sch_label.cpp:74
static int TemplateOUT_HN[]
Definition sch_label.cpp:68
static int Template3STATE_HN[]
Definition sch_label.cpp:83
static int TemplateBIDI_HN[]
Definition sch_label.cpp:78
static int * TemplateShape[5][4]
Definition sch_label.cpp:88
static int TemplateIN_HN[]
Definition sch_label.cpp:63
static int TemplateIN_BOTTOM[]
Definition sch_label.cpp:66
static int TemplateUNSPC_HN[]
Definition sch_label.cpp:73
static int Template3STATE_BOTTOM[]
Definition sch_label.cpp:86
bool unpackLabel(const LabelProto &aInput, SCH_LABEL_BASE &aLabel)
static int TemplateBIDI_BOTTOM[]
Definition sch_label.cpp:81
static struct SCH_LABEL_DESC _SCH_LABEL_DESC
static int Template3STATE_UP[]
Definition sch_label.cpp:85
static int TemplateOUT_UP[]
Definition sch_label.cpp:70
static int TemplateOUT_HI[]
Definition sch_label.cpp:69
static int TemplateUNSPC_UP[]
Definition sch_label.cpp:75
static int TemplateUNSPC_BOTTOM[]
Definition sch_label.cpp:76
static int TemplateOUT_BOTTOM[]
Definition sch_label.cpp:71
static int Template3STATE_HI[]
Definition sch_label.cpp:84
static int TemplateIN_UP[]
Definition sch_label.cpp:65
void packLabel(LabelProto &aOutput, const SCH_LABEL_BASE &aLabel)
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition sch_label.cpp:95
static int TemplateBIDI_UP[]
Definition sch_label.cpp:80
static int TemplateBIDI_HI[]
Definition sch_label.cpp:79
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:61
bool m_PDFHierarchicalLinks
Definition sch_plotter.h:62
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.
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:71
@ SCH_ITEM_LOCATE_WIRE_T
Definition typeinfo.h:183
@ SCH_FIELD_T
Definition typeinfo.h:147
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:168
@ SCH_LABEL_T
Definition typeinfo.h:164
@ SCH_LOCATE_ANY_T
Definition typeinfo.h:196
@ SCH_ITEM_LOCATE_BUS_T
Definition typeinfo.h:184
@ SCH_HIER_LABEL_T
Definition typeinfo.h:166
@ SCH_LABEL_LOCATE_ANY_T
Definition typeinfo.h:188
@ SCH_LABEL_LOCATE_WIRE_T
Definition typeinfo.h:189
@ SCH_SHEET_PIN_T
Definition typeinfo.h:171
@ SCH_LABEL_LOCATE_BUS_T
Definition typeinfo.h:190
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:165
@ SCH_PIN_T
Definition typeinfo.h:150
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683