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