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