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