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 =
974 [&]( wxString* token ) -> bool
975 {
976 return ResolveTextVar( aPath, token, depth + 1 );
977 };
978
979 wxString text = EDA_TEXT::GetShownText( aAllowExtraText, depth );
980
981 if( HasTextVars() )
982 text = ResolveTextVars( text, &textResolver, depth );
983
984 // Convert escape markers back to literals for final display
985 text.Replace( wxT( "<<<ESC_DOLLAR:" ), wxT( "${" ) );
986 text.Replace( wxT( "<<<ESC_AT:" ), wxT( "@{" ) );
987
988 return text;
989}
990
991
992void SCH_LABEL_BASE::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction, RECURSE_MODE aMode )
993{
994 for( SCH_FIELD& field : m_fields )
995 aFunction( &field );
996}
997
998
999bool SCH_LABEL_BASE::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
1000{
1001 if( SCH_ITEM::Matches( UnescapeString( GetText() ), aSearchData ) )
1002 {
1003 return true;
1004 }
1005
1006 const SCH_SEARCH_DATA* searchData = dynamic_cast<const SCH_SEARCH_DATA*>( &aSearchData );
1007 SCH_CONNECTION* connection = nullptr;
1008 SCH_SHEET_PATH* sheetPath = reinterpret_cast<SCH_SHEET_PATH*>( aAuxData );
1009
1010 if( searchData && searchData->searchNetNames && sheetPath && ( connection = Connection( sheetPath ) ) )
1011 {
1012 if( connection->IsBus() )
1013 {
1014 auto allMembers = connection->AllMembers();
1015
1016 std::set<wxString> netNames;
1017
1018 for( std::shared_ptr<SCH_CONNECTION> member : allMembers )
1019 netNames.insert( member->GetNetName() );
1020
1021 for( const wxString& netName : netNames )
1022 {
1023 if( EDA_ITEM::Matches( netName, aSearchData ) )
1024 return true;
1025 }
1026
1027 return false;
1028 }
1029
1030 wxString netName = connection->GetNetName();
1031
1032 if( EDA_ITEM::Matches( netName, aSearchData ) )
1033 return true;
1034 }
1035
1036 return false;
1037}
1038
1039
1040bool SCH_LABEL_BASE::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
1041{
1042 EDA_SEARCH_DATA localSearchData( aSearchData );
1043 localSearchData.findString = EscapeString( aSearchData.findString, CTX_NETNAME );
1044 localSearchData.replaceString = EscapeString( aSearchData.replaceString, CTX_NETNAME );
1045
1046 return EDA_TEXT::Replace( localSearchData );
1047}
1048
1049
1050INSPECT_RESULT SCH_LABEL_BASE::Visit( INSPECTOR aInspector, void* testData, const std::vector<KICAD_T>& aScanTypes )
1051{
1052 if( IsType( aScanTypes ) )
1053 {
1054 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
1055 return INSPECT_RESULT::QUIT;
1056 }
1057
1058 for( KICAD_T scanType : aScanTypes )
1059 {
1060 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
1061 {
1062 for( SCH_FIELD& field : m_fields )
1063 {
1064 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
1065 return INSPECT_RESULT::QUIT;
1066 }
1067 }
1068 }
1069
1071}
1072
1073
1074void SCH_LABEL_BASE::GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList )
1075{
1076 DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() );
1077 aItemList.push_back( item );
1078}
1079
1080
1081std::vector<VECTOR2I> SCH_LABEL_BASE::GetConnectionPoints() const
1082{
1083 return { GetTextPos() };
1084}
1085
1086
1091
1092
1094{
1095 double ratio;
1096
1097 if( aSettings )
1098 ratio = static_cast<const SCH_RENDER_SETTINGS*>( aSettings )->m_LabelSizeRatio;
1099 else if( Schematic() )
1100 ratio = Schematic()->Settings().m_LabelSizeRatio;
1101 else
1102 ratio = DEFAULT_LABEL_SIZE_RATIO; // For previews (such as in Preferences), etc.
1103
1104 return KiROUND( ratio * GetTextSize().y );
1105}
1106
1107
1109{
1110 // build the bounding box of the label only, without taking into account its fields
1111
1112 BOX2I box;
1113 std::vector<VECTOR2I> pts;
1114
1115 CreateGraphicShape( aSettings, pts, GetTextPos() );
1116
1117 for( const VECTOR2I& pt : pts )
1118 box.Merge( pt );
1119
1120 box.Inflate( GetEffectiveTextPenWidth() / 2 );
1121 box.Normalize();
1122 return box;
1123}
1124
1125
1127{
1128 // build the bounding box of the entire label, including its fields
1129
1130 BOX2I box = GetBodyBoundingBox( nullptr );
1131
1132 for( const SCH_FIELD& field : m_fields )
1133 {
1134 if( field.IsVisible() && field.GetText() != wxEmptyString )
1135 {
1136 BOX2I fieldBBox = field.GetBoundingBox();
1137
1138 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1139 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1140
1141 box.Merge( fieldBBox );
1142 }
1143 }
1144
1145 box.Normalize();
1146
1147 return box;
1148}
1149
1150
1151bool SCH_LABEL_BASE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1152{
1153 BOX2I bbox = GetBodyBoundingBox( nullptr );
1154 bbox.Inflate( aAccuracy );
1155
1156 if( bbox.Contains( aPosition ) )
1157 return true;
1158
1159 for( const SCH_FIELD& field : m_fields )
1160 {
1161 if( field.IsVisible() )
1162 {
1163 BOX2I fieldBBox = field.GetBoundingBox();
1164 fieldBBox.Inflate( aAccuracy );
1165
1166 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1167 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1168
1169 if( fieldBBox.Contains( aPosition ) )
1170 return true;
1171 }
1172 }
1173
1174 return false;
1175}
1176
1177
1178bool SCH_LABEL_BASE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1179{
1180 BOX2I rect = aRect;
1181
1182 rect.Inflate( aAccuracy );
1183
1184 if( aContained )
1185 {
1186 return rect.Contains( GetBoundingBox() );
1187 }
1188 else
1189 {
1190 if( rect.Intersects( GetBodyBoundingBox( nullptr ) ) )
1191 return true;
1192
1193 for( const SCH_FIELD& field : m_fields )
1194 {
1195 if( field.IsVisible() )
1196 {
1197 BOX2I fieldBBox = field.GetBoundingBox();
1198
1199 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1200 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1201
1202 if( rect.Intersects( fieldBBox ) )
1203 return true;
1204 }
1205 }
1206
1207 return false;
1208 }
1209}
1210
1211
1212bool SCH_LABEL_BASE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
1213{
1214 if( aContained )
1215 {
1216 return KIGEOM::BoxHitTest( aPoly, GetBoundingBox(), aContained );
1217 }
1218 else
1219 {
1220 if( KIGEOM::BoxHitTest( aPoly, GetBodyBoundingBox( nullptr ), aContained ) )
1221 return true;
1222
1223 for( const SCH_FIELD& field : m_fields )
1224 {
1225 if( field.IsVisible() )
1226 {
1227 BOX2I fieldBBox = field.GetBoundingBox();
1228
1229 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1230 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1231
1232 if( KIGEOM::BoxHitTest( aPoly, fieldBBox, aContained ) )
1233 return true;
1234 }
1235 }
1236
1237 return false;
1238 }
1239}
1240
1241
1242bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1243 std::vector<DANGLING_END_ITEM>& aItemListByPos, const SCH_SHEET_PATH* aPath )
1244{
1245 bool previousState = m_isDangling;
1246 VECTOR2I text_pos = GetTextPos();
1247 bool pinOrNoConnect = false;
1248 m_isDangling = true;
1250
1251 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, text_pos );
1252 it < aItemListByPos.end() && it->GetPosition() == text_pos; it++ )
1253 {
1254 DANGLING_END_ITEM& item = *it;
1255
1256 if( item.GetItem() == this )
1257 continue;
1258
1259 switch( item.GetType() )
1260 {
1261 case PIN_END:
1262 case NO_CONNECT_END:
1263 pinOrNoConnect = true;
1265
1266 case LABEL_END:
1267 case SHEET_LABEL_END:
1268 m_isDangling = false;
1269
1270 if( aPath && item.GetType() != PIN_END )
1271 AddConnectionTo( *aPath, static_cast<SCH_ITEM*>( item.GetItem() ) );
1272
1273 break;
1274
1275 default: break;
1276 }
1277
1278 if( pinOrNoConnect )
1279 break;
1280 }
1281
1282 // A coincident label leaves us unattached to a wire merely passing through, so keep scanning
1283 // A pin or no-connect sits on a wire end the connection graph already ties us to
1284 if( !pinOrNoConnect )
1285 {
1286 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, BUS_END );
1287 it < aItemListByType.end() && it->GetType() == BUS_END; it++ )
1288 {
1289 DANGLING_END_ITEM& item = *it;
1290 DANGLING_END_ITEM& nextItem = *( ++it );
1291
1292 int accuracy = 1; // We have rounding issues with an accuracy of 0
1293
1294 if( !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(), accuracy ) )
1295 continue;
1296
1297 m_isDangling = false;
1299
1300 // Add the line to the connected items, since it won't be picked
1301 // up by a search of intersecting connection points
1302 if( aPath )
1303 {
1304 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1305 AddConnectionTo( *aPath, sch_item );
1306 sch_item->AddConnectionTo( *aPath, this );
1307 }
1308
1309 break;
1310 }
1311
1313 {
1314 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, WIRE_END );
1315 it < aItemListByType.end() && it->GetType() == WIRE_END; it++ )
1316 {
1317 DANGLING_END_ITEM& item = *it;
1318 DANGLING_END_ITEM& nextItem = *( ++it );
1319
1320 int accuracy = 1; // We have rounding issues with an accuracy of 0
1321
1322 if( !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(), accuracy ) )
1323 continue;
1324
1325 m_isDangling = false;
1327
1328 // Add the line to the connected items, since it won't be picked
1329 // up by a search of intersecting connection points
1330 if( aPath )
1331 {
1332 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1333 AddConnectionTo( *aPath, sch_item );
1334 sch_item->AddConnectionTo( *aPath, this );
1335 }
1336
1337 break;
1338 }
1339 }
1340 }
1341
1342 if( m_isDangling )
1344
1345 return previousState != m_isDangling;
1346}
1347
1348
1349bool SCH_LABEL_BASE::HasConnectivityChanges( const SCH_ITEM* aItem, const SCH_SHEET_PATH* aInstance ) const
1350{
1351 // Do not compare to ourself.
1352 if( aItem == this || !IsConnectable() )
1353 return false;
1354
1355 const SCH_LABEL_BASE* label = dynamic_cast<const SCH_LABEL_BASE*>( aItem );
1356
1357 // Don't compare against a different SCH_ITEM.
1358 wxCHECK( label, false );
1359
1360 if( GetPosition() != label->GetPosition() )
1361 return true;
1362
1363 if( GetShownText( aInstance ) != label->GetShownText( aInstance ) )
1364 return true;
1365
1366 std::vector<wxString> netclasses;
1367 std::vector<wxString> otherNetclasses;
1368
1369 for( const SCH_FIELD& field : m_fields )
1370 {
1371 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1372 netclasses.push_back( field.GetText() );
1373 }
1374
1375 for( const SCH_FIELD& field : label->m_fields )
1376 {
1377 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1378 otherNetclasses.push_back( field.GetText() );
1379 }
1380
1381 return netclasses != otherNetclasses;
1382}
1383
1384
1385void SCH_LABEL_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1386{
1387 wxString msg;
1388
1389 switch( Type() )
1390 {
1391 case SCH_LABEL_T: msg = _( "Label" ); break;
1392 case SCH_DIRECTIVE_LABEL_T: msg = _( "Directive Label" ); break;
1393 case SCH_GLOBAL_LABEL_T: msg = _( "Global Label" ); break;
1394 case SCH_HIER_LABEL_T: msg = _( "Hierarchical Label" ); break;
1395 case SCH_SHEET_PIN_T: msg = _( "Hierarchical Sheet Pin" ); break;
1396 default: return;
1397 }
1398
1399 // Don't use GetShownText() here; we want to show the user the variable references
1400 aList.emplace_back( msg, UnescapeString( GetText() ) );
1401
1402 // Display electrical type if it is relevant
1404 aList.emplace_back( _( "Type" ), getElectricalTypeLabel( GetShape() ) );
1405
1406 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1407
1408 wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
1409 int style = IsBold() && IsItalic() ? 3 : IsBold() ? 2 : IsItalic() ? 1 : 0;
1410 aList.emplace_back( _( "Style" ), textStyle[style] );
1411
1412 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1413
1414 switch( GetSpinStyle() )
1415 {
1416 case SPIN_STYLE::LEFT: msg = _( "Align right" ); break;
1417 case SPIN_STYLE::UP: msg = _( "Align bottom" ); break;
1418 case SPIN_STYLE::RIGHT: msg = _( "Align left" ); break;
1419 case SPIN_STYLE::BOTTOM: msg = _( "Align top" ); break;
1420 default: msg = wxT( "???" ); break;
1421 }
1422
1423 aList.emplace_back( _( "Justification" ), msg );
1424
1425 SCH_CONNECTION* conn = nullptr;
1426
1427 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1428 conn = Connection();
1429
1430 if( conn )
1431 {
1432 conn->AppendInfoToMsgPanel( aList );
1433
1434 if( !conn->IsBus() )
1435 {
1436 aList.emplace_back( _( "Resolved Netclass" ),
1437 UnescapeString( GetEffectiveNetClass()->GetHumanReadableName() ) );
1438 }
1439 }
1440}
1441
1442
1443void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts, int aUnit,
1444 int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1445{
1446 static std::vector<VECTOR2I> s_poly;
1447
1448 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
1449 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
1450 SCH_CONNECTION* connection = Connection();
1451 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1452 COLOR4D color = settings->GetLayerColor( layer );
1453 int penWidth = GetEffectiveTextPenWidth( settings->GetDefaultPenWidth() );
1454 COLOR4D bg = settings->GetBackgroundColor();
1455
1456 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1457 bg = COLOR4D::WHITE;
1458
1459 if( aPlotter->GetColorMode() && GetLabelColor() != COLOR4D::UNSPECIFIED )
1460 color = GetLabelColor();
1461
1462 if( color.m_text && Schematic() )
1463 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
1464
1465 if( aDimmed )
1466 {
1467 color.Desaturate();
1468 color = color.Mix( bg, 0.5f );
1469 }
1470
1471 penWidth = std::max( penWidth, settings->GetMinPenWidth() );
1472 aPlotter->SetCurrentLineWidth( penWidth );
1473
1474 KIFONT::FONT* font = GetDrawFont( settings );
1475
1476 VECTOR2I textpos = GetTextPos() + GetSchematicTextOffset( settings );
1477 CreateGraphicShape( settings, s_poly, GetTextPos() );
1478
1480 attrs.m_StrokeWidth = penWidth;
1481 attrs.m_Multiline = false;
1482
1483 if( aBackground )
1484 {
1485 // No filled shapes (yet)
1486 }
1487 else
1488 {
1489 aPlotter->PlotText( textpos, color, GetShownText( sheet, true ), attrs, font, GetFontMetrics() );
1490
1491 if( aPlotter->GetColorMode() )
1492 {
1493 // For the graphic shape use the override color or the layer color, but not the
1494 // net/netclass color.
1495 COLOR4D shapeColor;
1496
1498 shapeColor = GetTextColor();
1499 else
1500 shapeColor = settings->GetLayerColor( m_layer );
1501
1502 if( aDimmed )
1503 {
1504 shapeColor.Desaturate();
1505 shapeColor = shapeColor.Mix( bg, 0.5f );
1506 }
1507
1508 aPlotter->SetColor( shapeColor );
1509 }
1510
1512 {
1513 aPlotter->MoveTo( s_poly[0] );
1514 aPlotter->LineTo( s_poly[1] );
1515 aPlotter->PenFinish();
1516
1517 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1518 aPlotter->FilledCircle( s_poly[2], diameter, nullptr );
1519 }
1520 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1521 {
1522 aPlotter->MoveTo( s_poly[0] );
1523 aPlotter->LineTo( s_poly[1] );
1524 aPlotter->PenFinish();
1525
1526 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1527 aPlotter->ThickCircle( s_poly[2], diameter, penWidth, nullptr );
1528 }
1529 else
1530 {
1531 if( !s_poly.empty() )
1532 aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth, nullptr );
1533 }
1534
1535 // Make sheet pins and hierarchical labels clickable hyperlinks
1536 bool linkAlreadyPlotted = false;
1537 BOX2I bodyBBox = GetBodyBoundingBox( settings );
1538
1539 if( aPlotOpts.m_PDFHierarchicalLinks )
1540 {
1541 if( Type() == SCH_HIER_LABEL_T )
1542 {
1543 if( sheet->size() >= 2 )
1544 {
1545 SCH_SHEET_PATH path = *sheet;
1546 path.pop_back();
1547 aPlotter->HyperlinkBox( bodyBBox, EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1548 linkAlreadyPlotted = true;
1549 }
1550 }
1551 else if( Type() == SCH_SHEET_PIN_T )
1552 {
1553 SCH_SHEET_PATH path = *sheet;
1554 SCH_SHEET* parent = static_cast<SCH_SHEET*>( m_parent );
1555 path.push_back( parent );
1556 aPlotter->HyperlinkBox( bodyBBox, EDA_TEXT::GotoPageHref( path.GetPageNumber() ) );
1557 linkAlreadyPlotted = true;
1558 }
1559 }
1560
1561 // Plot attributes to a hypertext menu
1562 if( aPlotOpts.m_PDFPropertyPopups && !linkAlreadyPlotted )
1563 {
1564 std::vector<wxString> properties;
1565
1566 if( connection )
1567 {
1568 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Net" ), connection->Name() ) );
1569
1570 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Resolved netclass" ),
1571 GetEffectiveNetClass()->GetHumanReadableName() ) );
1572 }
1573
1574 for( const SCH_FIELD& field : GetFields() )
1575 {
1576 properties.emplace_back(
1577 wxString::Format( wxT( "!%s = %s" ), field.GetName(), field.GetShownText( false ) ) );
1578 }
1579
1580 if( !properties.empty() )
1581 aPlotter->HyperlinkMenu( bodyBBox, properties );
1582 }
1583
1584 if( Type() == SCH_HIER_LABEL_T )
1585 aPlotter->Bookmark( bodyBBox, GetShownText( false ), _( "Hierarchical Labels" ) );
1586 }
1587
1588 for( SCH_FIELD& field : m_fields )
1589 field.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
1590}
1591
1592
1597
1598
1600{
1601 m_autoRotateOnPlacement = autoRotate;
1602}
1603
1604
1605SCH_LABEL::SCH_LABEL( const VECTOR2I& pos, const wxString& text ) :
1607{
1610 m_isDangling = true;
1611}
1612
1613
1614template<typename LabelProto>
1615void packLabel( LabelProto& aOutput, const SCH_LABEL_BASE& aLabel )
1616{
1617 using namespace kiapi::schematic;
1618
1619 aOutput.mutable_id()->set_value( aLabel.m_Uuid.AsStdString() );
1621 aOutput.set_locked( aLabel.IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
1622 : kiapi::common::types::LockedState::LS_UNLOCKED );
1623
1624 google::protobuf::Any any;
1625 aLabel.EDA_TEXT::Serialize( any, schIUScale );
1626 any.UnpackTo( aOutput.mutable_text() );
1627 kiapi::common::PackVector2( *aOutput.mutable_position(), aLabel.GetPosition(), schIUScale );
1628
1629 for( const SCH_FIELD& field : aLabel.GetFields() )
1630 {
1631 if( field.IsMandatory() )
1632 continue;
1633
1634 field.Serialize( any );
1635 any.UnpackTo( aOutput.mutable_fields()->Add() );
1636 }
1637}
1638
1639
1640template<typename LabelProto>
1641bool unpackLabel( const LabelProto& aInput, SCH_LABEL_BASE& aLabel )
1642{
1643 using namespace kiapi::schematic;
1644
1645 const_cast<KIID&>( aLabel.m_Uuid ) = KIID( aInput.id().value() );
1647 aLabel.SetLocked( aInput.locked() == kiapi::common::types::LockedState::LS_LOCKED );
1648
1649 google::protobuf::Any any;
1650 any.PackFrom( aInput.text() );
1651
1652 if( !aLabel.EDA_TEXT::Deserialize( any, schIUScale ) )
1653 return false;
1654
1655 aLabel.SetPosition( kiapi::common::UnpackVector2( aInput.position(), schIUScale ) );
1656 aLabel.GetFields().clear();
1657
1658 for( const types::SchematicField& field : aInput.fields() )
1659 {
1660 aLabel.GetFields().emplace_back( &aLabel, FIELD_T::USER );
1661 any.PackFrom( field );
1662 aLabel.GetFields().back().Deserialize( any );
1663 }
1664
1665 return true;
1666}
1667
1668
1669void SCH_LABEL::Serialize( google::protobuf::Any& aContainer ) const
1670{
1671 kiapi::schematic::types::LocalLabel label;
1672
1673 packLabel( label, *this );
1674
1675 aContainer.PackFrom( label );
1676}
1677
1678
1679bool SCH_LABEL::Deserialize( const google::protobuf::Any& aContainer )
1680{
1681 kiapi::schematic::types::LocalLabel label;
1682
1683 if( !aContainer.UnpackTo( &label ) )
1684 return false;
1685
1686 return unpackLabel( label, *this );
1687}
1688
1689
1691{
1692 BOX2I rect = GetTextBox( aSettings );
1693
1694 rect.Offset( 0, -GetTextOffset() );
1696
1697 if( !GetTextAngle().IsZero() )
1698 {
1699 // Rotate rect
1700 VECTOR2I pos = rect.GetOrigin();
1701 VECTOR2I end = rect.GetEnd();
1702
1703 RotatePoint( pos, GetTextPos(), GetTextAngle() );
1705
1706 rect.SetOrigin( pos );
1707 rect.SetEnd( end );
1708
1709 rect.Normalize();
1710 }
1711
1712 // Labels have a position point that is outside of the TextBox
1713 rect.Merge( GetPosition() );
1714
1715 return rect;
1716}
1717
1718
1719wxString SCH_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1720{
1721 return wxString::Format( _( "Label '%s'" ), aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
1722}
1723
1724
1729
1730
1732 SCH_LABEL_BASE( pos, wxEmptyString, SCH_DIRECTIVE_LABEL_T )
1733{
1736 m_pinLength = schIUScale.MilsToIU( 100 );
1737 m_symbolSize = schIUScale.MilsToIU( 20 );
1738 m_isDangling = true;
1739}
1740
1741
1743{
1744 SCH_LABEL_BASE::swapData( aItem );
1745
1746 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( aItem );
1747
1748 std::swap( m_pinLength, label->m_pinLength );
1749 std::swap( m_symbolSize, label->m_symbolSize );
1750}
1751
1752
1754 SCH_LABEL_BASE( aClassLabel )
1755{
1756 m_pinLength = aClassLabel.m_pinLength;
1757 m_symbolSize = aClassLabel.m_symbolSize;
1758}
1759
1760
1762{
1763 for( SCH_RULE_AREA* ruleArea : m_connected_rule_areas )
1764 ruleArea->RemoveDirective( this );
1765}
1766
1767
1768void SCH_DIRECTIVE_LABEL::Serialize( google::protobuf::Any& aContainer ) const
1769{
1770 kiapi::schematic::types::DirectiveLabel label;
1771
1772 packLabel( label, *this );
1774 kiapi::common::PackDistance( *label.mutable_pin_length(), m_pinLength, schIUScale );
1775 kiapi::common::PackDistance( *label.mutable_symbol_size(), m_symbolSize, schIUScale );
1776
1777 aContainer.PackFrom( label );
1778}
1779
1780
1781bool SCH_DIRECTIVE_LABEL::Deserialize( const google::protobuf::Any& aContainer )
1782{
1783 kiapi::schematic::types::DirectiveLabel label;
1784
1785 if( !aContainer.UnpackTo( &label ) )
1786 return false;
1787
1788 if( !unpackLabel( label, *this ) )
1789 return false;
1790
1792
1793 if( label.has_pin_length() )
1794 m_pinLength = kiapi::common::UnpackDistance( label.pin_length(), schIUScale );
1795
1796 if( label.has_symbol_size() )
1797 m_symbolSize = kiapi::common::UnpackDistance( label.symbol_size(), schIUScale );
1798
1799 return true;
1800}
1801
1802
1804{
1805 if( !SCH_LABEL_BASE::operator==( aOther ) )
1806 return false;
1807
1808 const SCH_DIRECTIVE_LABEL* other = dynamic_cast<const SCH_DIRECTIVE_LABEL*>( &aOther );
1809
1810 if( !other )
1811 return false;
1812
1813 return m_pinLength == other->m_pinLength && m_symbolSize == other->m_symbolSize;
1814}
1815
1816
1818{
1819 int pen = 0;
1820
1821 if( Schematic() )
1823
1824 return GetEffectiveTextPenWidth( pen );
1825}
1826
1827
1829{
1830 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1831 // vertical shape (like a text reduced to only "I" letter).
1832 // So the mirroring is not exactly similar to a SCH_TEXT item
1833 SCH_TEXT::MirrorSpinStyle( !aLeftRight );
1834
1835 for( SCH_FIELD& field : m_fields )
1836 {
1837 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
1838 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
1839 {
1840 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1841 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1842 else
1843 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1844 }
1845
1846 VECTOR2I pos = field.GetTextPos();
1847 VECTOR2I delta = (VECTOR2I) GetPosition() - pos;
1848
1849 if( aLeftRight )
1850 pos.x = GetPosition().x + delta.x;
1851 else
1852 pos.y = GetPosition().y + delta.y;
1853
1854 field.SetTextPos( pos );
1855 }
1856}
1857
1858
1860{
1861 VECTOR2I old_pos = GetPosition();
1862
1863 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1864 // vertical shape (like a text reduced to only "I" letter).
1865 // So the mirroring is not exactly similar to a SCH_TEXT item
1866 // Text is NOT really mirrored; it is moved to a suitable horizontal position
1867 SetSpinStyle( GetSpinStyle().MirrorX() );
1868
1869 SetTextX( MIRRORVAL( GetTextPos().x, aCenter ) );
1870
1871 for( SCH_FIELD& field : m_fields )
1872 {
1873 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1874 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1875 else if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1876 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1877
1878 VECTOR2I pos = field.GetTextPos();
1879 VECTOR2I delta = old_pos - pos;
1880 pos.x = GetPosition().x + delta.x;
1881
1882 field.SetPosition( pos );
1883 }
1884}
1885
1886
1888{
1889 VECTOR2I old_pos = GetPosition();
1890 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1891 // vertical shape (like a text reduced to only "I" letter).
1892 // So the mirroring is not exactly similar to a SCH_TEXT item
1893 // Text is NOT really mirrored; it is moved to a suitable vertical position
1894 SetSpinStyle( GetSpinStyle().MirrorY() );
1895
1896 SetTextY( MIRRORVAL( GetTextPos().y, aCenter ) );
1897
1898 for( SCH_FIELD& field : m_fields )
1899 {
1900 VECTOR2I pos = field.GetTextPos();
1901 VECTOR2I delta = old_pos - pos;
1902 pos.y = GetPosition().y + delta.y;
1903
1904 field.SetPosition( pos );
1905 }
1906}
1907
1908
1909void SCH_DIRECTIVE_LABEL::CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings, std::vector<VECTOR2I>& aPoints,
1910 const VECTOR2I& aPos ) const
1911{
1912 int symbolSize = m_symbolSize;
1913
1914 aPoints.clear();
1915
1916 switch( m_shape )
1917 {
1918 case LABEL_FLAG_SHAPE::F_DOT: symbolSize = KiROUND( symbolSize * 0.7 ); KI_FALLTHROUGH;
1919
1921 // First 3 points are used for generating shape
1922 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1923 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1924 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1925
1926 // These points are just used to bulk out the bounding box
1927 aPoints.emplace_back( VECTOR2I( -m_symbolSize, m_pinLength ) );
1928 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1929 aPoints.emplace_back( VECTOR2I( m_symbolSize, m_pinLength + symbolSize ) );
1930 break;
1931
1933 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1934 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1935 aPoints.emplace_back( VECTOR2I( -2 * m_symbolSize, m_pinLength ) );
1936 aPoints.emplace_back( VECTOR2I( 0, m_pinLength + symbolSize ) );
1937 aPoints.emplace_back( VECTOR2I( 2 * m_symbolSize, m_pinLength ) );
1938 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1939 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1940 break;
1941
1943 symbolSize = KiROUND( symbolSize * 0.8 );
1944
1945 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1946 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1947 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength - symbolSize ) );
1948 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength + symbolSize ) );
1949 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength + symbolSize ) );
1950 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength - symbolSize ) );
1951 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1952 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1953 break;
1954
1955 default: break;
1956 }
1957
1958 // Rotate outlines and move corners to real position
1959 for( VECTOR2I& aPoint : aPoints )
1960 {
1961 switch( GetSpinStyle() )
1962 {
1963 default:
1964 case SPIN_STYLE::LEFT: break;
1965 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
1966 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
1967 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
1968 }
1969
1970 aPoint += aPos;
1971 }
1972}
1973
1974
1976{
1977 int margin = GetTextOffset();
1978 int symbolWidth = m_symbolSize;
1979 int origin = m_pinLength;
1980
1982 symbolWidth *= 2;
1983
1984 if( IsItalic() )
1985 margin = KiROUND( margin * 1.5 );
1986
1987 VECTOR2I offset;
1988
1989 for( SCH_FIELD& field : m_fields )
1990 {
1991 if( field.GetText() == wxEmptyString )
1992 continue;
1993
1994 switch( GetSpinStyle() )
1995 {
1996 default:
1997 case SPIN_STYLE::LEFT:
1998 field.SetTextAngle( ANGLE_HORIZONTAL );
1999 offset = { symbolWidth + margin, origin };
2000 break;
2001
2002 case SPIN_STYLE::UP:
2003 field.SetTextAngle( ANGLE_VERTICAL );
2004 offset = { -origin, -( symbolWidth + margin ) };
2005 break;
2006
2007 case SPIN_STYLE::RIGHT:
2008 field.SetTextAngle( ANGLE_HORIZONTAL );
2009 offset = { symbolWidth + margin, -origin };
2010 break;
2011
2012 case SPIN_STYLE::BOTTOM:
2013 field.SetTextAngle( ANGLE_VERTICAL );
2014 offset = { origin, -( symbolWidth + margin ) };
2015 break;
2016 }
2017
2018 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
2019 field.SetTextPos( GetPosition() + offset );
2020
2021 origin -= field.GetTextHeight() + margin;
2022 }
2023
2024 if( aAlgo == AUTOPLACE_AUTO || aAlgo == AUTOPLACE_MANUAL )
2025 m_fieldsAutoplaced = aAlgo;
2026}
2027
2028
2029wxString SCH_DIRECTIVE_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2030{
2031 if( m_fields.empty() )
2032 {
2033 return _( "Directive Label" );
2034 }
2035 else
2036 {
2037 const SCH_FIELD& firstField = m_fields[0];
2038 wxString content = aFull ? firstField.GetShownText( false ) : KIUI::EllipsizeMenuText( firstField.GetText() );
2039
2040 if( content.IsEmpty() )
2041 {
2042 return wxString::Format( _( "Directive Label [%s (empty)]" ), UnescapeString( m_fields[0].GetName() ) );
2043 }
2044 else
2045 {
2046 return wxString::Format( _( "Directive Label [%s %s]" ), UnescapeString( m_fields[0].GetName() ), content );
2047 }
2048 }
2049}
2050
2051
2053{
2054 m_connected_rule_areas.insert( aRuleArea );
2055}
2056
2057
2062
2063
2065{
2066 m_connected_rule_areas.erase( aRuleArea );
2067}
2068
2069
2070const std::unordered_set<SCH_RULE_AREA*> SCH_DIRECTIVE_LABEL::GetConnectedRuleAreas() const
2071{
2073}
2074
2075
2077{
2078 return m_isDangling && m_connected_rule_areas.empty();
2079}
2080
2082{
2083 for( SCH_FIELD& field : m_fields )
2084 {
2085 if( field.GetCanonicalName() == wxT( "Netclass" ) || field.GetCanonicalName() == wxT( "Component Class" ) )
2086 {
2087 wxString text = field.GetText();
2088
2089 if( IncrementString( text, aIncrement ) )
2090 {
2091 field.SetText( text );
2092 }
2093 }
2094 }
2095
2096 return true;
2097}
2098
2099
2100SCH_GLOBALLABEL::SCH_GLOBALLABEL( const VECTOR2I& pos, const wxString& text ) :
2102{
2105 m_isDangling = true;
2106
2108
2109 m_fields.emplace_back(
2111 m_fields.back().SetText( wxT( "${INTERSHEET_REFS}" ) );
2112 m_fields.back().SetVisible( false );
2113 m_fields.back().SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
2114 m_fields.back().SetTextPos( pos );
2115}
2116
2117
2119 SCH_LABEL_BASE( aGlobalLabel )
2120{
2121}
2122
2123
2124void SCH_GLOBALLABEL::Serialize( google::protobuf::Any& aContainer ) const
2125{
2126 using namespace kiapi::schematic;
2127
2128 types::GlobalLabel label;
2129
2130 label.mutable_id()->set_value( m_Uuid.AsStdString() );
2132 label.set_locked( IsLocked() ? kiapi::common::types::LockedState::LS_LOCKED
2133 : kiapi::common::types::LockedState::LS_UNLOCKED );
2134
2135 google::protobuf::Any any;
2137 any.UnpackTo( label.mutable_text() );
2138 kiapi::common::PackVector2( *label.mutable_position(), GetPosition(), schIUScale );
2139
2141
2142 for( const SCH_FIELD& field : GetFields() )
2143 {
2144 if( field.IsMandatory() )
2145 continue;
2146
2147 field.Serialize( any );
2148 any.UnpackTo( label.mutable_fields()->Add() );
2149 }
2150
2151 if( const SCH_FIELD* field = GetField( FIELD_T::INTERSHEET_REFS ) )
2152 {
2153 google::protobuf::Any fieldAny;
2154 field->Serialize( fieldAny );
2155 fieldAny.UnpackTo( label.mutable_intersheet_refs_field() );
2156 }
2157
2158 aContainer.PackFrom( label );
2159}
2160
2161
2162bool SCH_GLOBALLABEL::Deserialize( const google::protobuf::Any& aContainer )
2163{
2164 kiapi::schematic::types::GlobalLabel label;
2165
2166 if( !aContainer.UnpackTo( &label ) )
2167 return false;
2168
2169 if( !unpackLabel( label, *this ) )
2170 return false;
2171
2173 label.shape() ) );
2174
2175 if( label.has_intersheet_refs_field() )
2176 {
2177 google::protobuf::Any any;
2178 any.PackFrom( label.intersheet_refs_field() );
2180 }
2181
2182 return true;
2183}
2184
2185
2187{
2188 if( SCH_FIELD* field = FindField( m_fields, aFieldType ) )
2189 return field;
2190
2191 m_fields.emplace_back( this, aFieldType );
2192 return &m_fields.back();
2193}
2194
2195
2197{
2198 return FindField( m_fields, aFieldType );
2199}
2200
2201
2203{
2204 int horiz = GetLabelBoxExpansion( aSettings );
2205
2206 // Center the text on the center line of "E" instead of "R" to make room for an overbar
2207 int vert = GetTextHeight() * 0.0715;
2208
2209 switch( m_shape )
2210 {
2214 horiz += GetTextHeight() * 3 / 4; // Use three-quarters-height as proxy for triangle size
2215 break;
2216
2219 default: break;
2220 }
2221
2222 switch( GetSpinStyle() )
2223 {
2224 default:
2225 case SPIN_STYLE::LEFT: return VECTOR2I( -horiz, vert );
2226 case SPIN_STYLE::UP: return VECTOR2I( vert, -horiz );
2227 case SPIN_STYLE::RIGHT: return VECTOR2I( horiz, vert );
2228 case SPIN_STYLE::BOTTOM: return VECTOR2I( vert, horiz );
2229 }
2230}
2231
2232
2238
2239
2240bool SCH_GLOBALLABEL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, int aDepth ) const
2241{
2242 wxCHECK( aPath, false );
2243
2244 SCHEMATIC* schematic = Schematic();
2245
2246 if( !schematic )
2247 return false;
2248
2249 if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) )
2250 {
2251 SCHEMATIC_SETTINGS& settings = schematic->Settings();
2252 wxString ref;
2253 auto it = schematic->GetPageRefsMap().find( GetShownText( aPath ) );
2254
2255 if( it == schematic->GetPageRefsMap().end() )
2256 {
2257 ref = "?";
2258 }
2259 else
2260 {
2261 std::vector<int> pageListCopy;
2262
2263 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
2264 std::sort( pageListCopy.begin(), pageListCopy.end() );
2265
2266 if( !settings.m_IntersheetRefsListOwnPage )
2267 {
2268 int currentPage = schematic->CurrentSheet().GetVirtualPageNumber();
2269 std::erase( pageListCopy, currentPage );
2270 }
2271
2272 std::map<int, wxString> sheetPages = schematic->GetVirtualPageToSheetPagesMap();
2273
2274 if( ( settings.m_IntersheetRefsFormatShort ) && ( pageListCopy.size() > 2 ) )
2275 {
2276 ref.Append( wxString::Format( wxT( "%s..%s" ), sheetPages[pageListCopy.front()],
2277 sheetPages[pageListCopy.back()] ) );
2278 }
2279 else
2280 {
2281 for( const int& pageNo : pageListCopy )
2282 ref.Append( wxString::Format( wxT( "%s," ), sheetPages[pageNo] ) );
2283
2284 if( !ref.IsEmpty() && ref.Last() == ',' )
2285 ref.RemoveLast();
2286 }
2287 }
2288
2289 *token = settings.m_IntersheetRefsPrefix + ref + settings.m_IntersheetRefsSuffix;
2290 return true;
2291 }
2292
2293 return SCH_LABEL_BASE::ResolveTextVar( aPath, token, aDepth );
2294}
2295
2296
2302
2303
2304void SCH_GLOBALLABEL::CreateGraphicShape( const RENDER_SETTINGS* aRenderSettings, std::vector<VECTOR2I>& aPoints,
2305 const VECTOR2I& aPos ) const
2306{
2307 int margin = GetLabelBoxExpansion( aRenderSettings );
2308 int halfSize = ( GetTextHeight() / 2 ) + margin;
2309 int linewidth = GetPenWidth();
2310 int symb_len = GetTextBox( aRenderSettings ).GetWidth() + 2 * margin;
2311
2312 int x = symb_len + linewidth + 3;
2313 int y = halfSize + linewidth + 3;
2314
2315 aPoints.clear();
2316
2317 // Create outline shape : 6 points
2318 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
2319 aPoints.emplace_back( VECTOR2I( 0, -y ) ); // Up
2320 aPoints.emplace_back( VECTOR2I( -x, -y ) ); // left
2321 aPoints.emplace_back( VECTOR2I( -x, 0 ) ); // Up left
2322 aPoints.emplace_back( VECTOR2I( -x, y ) ); // left down
2323 aPoints.emplace_back( VECTOR2I( 0, y ) ); // down
2324
2325 int x_offset = 0;
2326
2327 switch( m_shape )
2328 {
2330 x_offset = -halfSize;
2331 aPoints[0].x += halfSize;
2332 break;
2333
2334 case LABEL_FLAG_SHAPE::L_OUTPUT: aPoints[3].x -= halfSize; break;
2335
2338 x_offset = -halfSize;
2339 aPoints[0].x += halfSize;
2340 aPoints[3].x -= halfSize;
2341 break;
2342
2344 default: break;
2345 }
2346
2347 // Rotate outlines and move corners in real position
2348 for( VECTOR2I& aPoint : aPoints )
2349 {
2350 aPoint.x += x_offset;
2351
2352 switch( GetSpinStyle() )
2353 {
2354 default:
2355 case SPIN_STYLE::LEFT: break;
2356 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
2357 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
2358 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
2359 }
2360
2361 aPoint += aPos;
2362 }
2363
2364 aPoints.push_back( aPoints[0] ); // closing
2365}
2366
2367
2368wxString SCH_GLOBALLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2369{
2370 return wxString::Format( _( "Global Label '%s'" ),
2371 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
2372}
2373
2374
2379
2380
2381SCH_HIERLABEL::SCH_HIERLABEL( const VECTOR2I& pos, const wxString& text, KICAD_T aType ) :
2382 SCH_LABEL_BASE( pos, text, aType )
2383{
2386 m_isDangling = true;
2387}
2388
2389
2390void SCH_HIERLABEL::Serialize( google::protobuf::Any& aContainer ) const
2391{
2392 kiapi::schematic::types::HierarchicalLabel label;
2393
2394 packLabel( label, *this );
2396
2397 aContainer.PackFrom( label );
2398}
2399
2400
2401bool SCH_HIERLABEL::Deserialize( const google::protobuf::Any& aContainer )
2402{
2403 kiapi::schematic::types::HierarchicalLabel label;
2404
2405 if( !aContainer.UnpackTo( &label ) )
2406 return false;
2407
2408 if( !unpackLabel( label, *this ) )
2409 return false;
2410
2412
2413 return true;
2414}
2415
2416
2422
2423
2424void SCH_HIERLABEL::CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
2425 const VECTOR2I& aPos ) const
2426{
2427 CreateGraphicShape( aSettings, aPoints, aPos, m_shape );
2428}
2429
2430
2431void SCH_HIERLABEL::CreateGraphicShape( const RENDER_SETTINGS* aSettings, std::vector<VECTOR2I>& aPoints,
2432 const VECTOR2I& aPos, LABEL_FLAG_SHAPE aShape ) const
2433{
2434 int* Template = TemplateShape[static_cast<int>( aShape )][static_cast<int>( GetSpinStyle() )];
2435 int halfSize = GetTextHeight() / 2;
2436 int imax = *Template;
2437 Template++;
2438
2439 aPoints.clear();
2440
2441 for( int ii = 0; ii < imax; ii++ )
2442 {
2443 VECTOR2I corner;
2444 corner.x = ( halfSize * ( *Template ) ) + aPos.x;
2445 Template++;
2446
2447 corner.y = ( halfSize * ( *Template ) ) + aPos.y;
2448 Template++;
2449
2450 aPoints.push_back( corner );
2451 }
2452}
2453
2454
2456{
2457 int penWidth = GetEffectiveTextPenWidth();
2458 int margin = GetTextOffset();
2459
2460 int x = GetTextPos().x;
2461 int y = GetTextPos().y;
2462
2463 int height = GetTextHeight() + penWidth + margin;
2464 int length = GetTextBox( aSettings ).GetWidth();
2465
2466 length += height; // add height for triangular shapes
2467
2468 int dx, dy;
2469
2470 switch( GetSpinStyle() )
2471 {
2472 default:
2473 case SPIN_STYLE::LEFT:
2474 dx = -length;
2475 dy = height;
2476 x += schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2477 y -= height / 2;
2478 break;
2479
2480 case SPIN_STYLE::UP:
2481 dx = height;
2482 dy = -length;
2483 x -= height / 2;
2484 y += schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2485 break;
2486
2487 case SPIN_STYLE::RIGHT:
2488 dx = length;
2489 dy = height;
2490 x -= schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2491 y -= height / 2;
2492 break;
2493
2494 case SPIN_STYLE::BOTTOM:
2495 dx = height;
2496 dy = length;
2497 x -= height / 2;
2498 y -= schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE );
2499 break;
2500 }
2501
2502 BOX2I box( VECTOR2I( x, y ), VECTOR2I( dx, dy ) );
2503 box.Normalize();
2504 return box;
2505}
2506
2507
2509{
2510 VECTOR2I text_offset;
2511 int dist = GetTextOffset( aSettings );
2512
2513 dist += GetTextWidth();
2514
2515 switch( GetSpinStyle() )
2516 {
2517 default:
2518 case SPIN_STYLE::LEFT: text_offset.x = -dist; break; // Orientation horiz normale
2519 case SPIN_STYLE::UP: text_offset.y = -dist; break; // Orientation vert UP
2520 case SPIN_STYLE::RIGHT: text_offset.x = dist; break; // Orientation horiz inverse
2521 case SPIN_STYLE::BOTTOM: text_offset.y = dist; break; // Orientation vert BOTTOM
2522 }
2523
2524 return text_offset;
2525}
2526
2527
2528wxString SCH_HIERLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
2529{
2530 return wxString::Format( _( "Hierarchical Label '%s'" ),
2531 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ) );
2532}
2533
2534
2539
2540
2542{
2543 wxString msg =
2544#include "sch_text_help_md.h"
2545 ;
2546
2547 HTML_MESSAGE_BOX* dlg = new HTML_MESSAGE_BOX( aParentWindow, _( "Syntax Help" ) );
2548 wxSize sz( 320, 320 );
2549
2550 dlg->SetMinSize( dlg->ConvertDialogToPixels( sz ) );
2551 dlg->SetDialogSizeInDU( sz.x, sz.y );
2552
2553 wxString html_txt;
2554 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
2555 dlg->AddHTML_Text( html_txt );
2556 dlg->ShowModeless();
2557
2558 return dlg;
2559}
2560
2561
2562static struct SCH_LABEL_DESC
2563{
2565 {
2566 auto& labelShapeEnum = ENUM_MAP<LABEL_SHAPE>::Instance();
2567
2568 if( labelShapeEnum.Choices().GetCount() == 0 )
2569 {
2570 labelShapeEnum.Map( LABEL_SHAPE::LABEL_INPUT, _HKI( "Input" ) )
2571 .Map( LABEL_SHAPE::LABEL_OUTPUT, _HKI( "Output" ) )
2572 .Map( LABEL_SHAPE::LABEL_BIDI, _HKI( "Bidirectional" ) )
2573 .Map( LABEL_SHAPE::LABEL_TRISTATE, _HKI( "Tri-state" ) )
2574 .Map( LABEL_SHAPE::LABEL_PASSIVE, _HKI( "Passive" ) );
2575 }
2576
2581
2585
2589
2593
2598
2599 auto hasLabelShape = []( INSPECTABLE* aItem ) -> bool
2600 {
2601 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aItem ) )
2602 return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_SHEET_PIN_T } );
2603
2604 return false;
2605 };
2606
2609 .SetAvailableFunc( hasLabelShape );
2610
2611 propMgr.Mask( TYPE_HASH( SCH_LABEL_BASE ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
2612 }
2614
2615
2617{
2619 {
2620 auto& flagShapeEnum = ENUM_MAP<FLAG_SHAPE>::Instance();
2621
2622 if( flagShapeEnum.Choices().GetCount() == 0 )
2623 {
2624 flagShapeEnum.Map( FLAG_SHAPE::FLAG_DOT, _HKI( "Dot" ) )
2625 .Map( FLAG_SHAPE::FLAG_CIRCLE, _HKI( "Circle" ) )
2626 .Map( FLAG_SHAPE::FLAG_DIAMOND, _HKI( "Diamond" ) )
2627 .Map( FLAG_SHAPE::FLAG_RECTANGLE, _HKI( "Rectangle" ) );
2628 }
2629
2635
2637
2640
2644
2645 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Text" ) );
2646 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
2647 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Italic" ) );
2648 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Bold" ) );
2649 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ) );
2650 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ) );
2651 }
2653
2654
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:46
std::string AsStdString() const
Definition kiid.cpp:270
const wxString GetName() const
Gets the name of this (maybe aggregate) netclass in a format for internal usage or for export to exte...
Definition netclass.cpp: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:735
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:718
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:310
#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:483
@ LAYER_DEVICE
Definition layer_ids.h:472
@ LAYER_HIERLABEL
Definition layer_ids.h:463
@ LAYER_GLOBLABEL
Definition layer_ids.h:462
@ LAYER_NOTES
Definition layer_ids.h:473
@ LAYER_BUS
Definition layer_ids.h:459
@ LAYER_FIELDS
Definition layer_ids.h:468
@ LAYER_LOCLABEL
Definition layer_ids.h:461
@ LAYER_NETCLASS_REFS
Definition layer_ids.h:470
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:501
@ LAYER_INTERSHEET_REFS
Definition layer_ids.h:469
#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