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 (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <base_units.h>
27#include <pgm_base.h>
28#include <sch_edit_frame.h>
29#include <sch_plotter.h>
30#include <widgets/msgpanel.h>
31#include <bitmaps.h>
32#include <string_utils.h>
33#include <schematic.h>
35#include <sch_painter.h>
36#include <default_values.h>
37#include <wx/debug.h>
38#include <wx/log.h>
42#include <core/kicad_algo.h>
43#include <core/mirror.h>
44#include <trigo.h>
45#include <sch_label.h>
46#include <magic_enum.hpp>
47#include <api/api_utils.h>
48#include <api/schematic/schematic_types.pb.h>
49
50
51bool IncrementLabelMember( wxString& name, int aIncrement )
52{
53 if( name.IsEmpty() )
54 return true;
55
56 wxString suffix;
57 wxString digits;
58 wxString outputFormat;
59 wxString outputNumber;
60 int ii = name.Len() - 1;
61 int dCount = 0;
62
63 while( ii >= 0 && !wxIsdigit( name.GetChar( ii ) ) )
64 {
65 suffix = name.GetChar( ii ) + suffix;
66 ii--;
67 }
68
69 while( ii >= 0 && wxIsdigit( name.GetChar( ii ) ) )
70 {
71 digits = name.GetChar( ii ) + digits;
72 ii--;
73 dCount++;
74 }
75
76 if( digits.IsEmpty() )
77 return true;
78
79 long number = 0;
80
81 if( digits.ToLong( &number ) )
82 {
83 number += aIncrement;
84
85 // Don't let result go below zero
86
87 if( number > -1 )
88 {
89 name.Remove( ii + 1 );
90 //write out a format string with correct number of leading zeroes
91 outputFormat.Printf( wxS( "%%0%dld" ), dCount );
92 //write out the number using the format string
93 outputNumber.Printf( outputFormat, number );
94 name << outputNumber << suffix;
95 return true;
96 }
97 }
98
99 return false;
100}
101
102
103/* Coding polygons for global symbol graphic shapes.
104 * the first parml is the number of corners
105 * others are the corners coordinates in reduced units
106 * the real coordinate is the reduced coordinate * text half size
107 */
108static int TemplateIN_HN[] = { 6, 0, 0, -1, -1, -2, -1, -2, 1, -1, 1, 0, 0 };
109static int TemplateIN_HI[] = { 6, 0, 0, 1, 1, 2, 1, 2, -1, 1, -1, 0, 0 };
110static int TemplateIN_UP[] = { 6, 0, 0, 1, -1, 1, -2, -1, -2, -1, -1, 0, 0 };
111static int TemplateIN_BOTTOM[] = { 6, 0, 0, 1, 1, 1, 2, -1, 2, -1, 1, 0, 0 };
112
113static int TemplateOUT_HN[] = { 6, -2, 0, -1, 1, 0, 1, 0, -1, -1, -1, -2, 0 };
114static int TemplateOUT_HI[] = { 6, 2, 0, 1, -1, 0, -1, 0, 1, 1, 1, 2, 0 };
115static int TemplateOUT_UP[] = { 6, 0, -2, 1, -1, 1, 0, -1, 0, -1, -1, 0, -2 };
116static int TemplateOUT_BOTTOM[] = { 6, 0, 2, 1, 1, 1, 0, -1, 0, -1, 1, 0, 2 };
117
118static int TemplateUNSPC_HN[] = { 5, 0, -1, -2, -1, -2, 1, 0, 1, 0, -1 };
119static int TemplateUNSPC_HI[] = { 5, 0, -1, 2, -1, 2, 1, 0, 1, 0, -1 };
120static int TemplateUNSPC_UP[] = { 5, 1, 0, 1, -2, -1, -2, -1, 0, 1, 0 };
121static int TemplateUNSPC_BOTTOM[] = { 5, 1, 0, 1, 2, -1, 2, -1, 0, 1, 0 };
122
123static int TemplateBIDI_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
124static int TemplateBIDI_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
125static int TemplateBIDI_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
126static int TemplateBIDI_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
127
128static int Template3STATE_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
129static int Template3STATE_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
130static int Template3STATE_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
131static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
132
133static int* TemplateShape[5][4] =
134{
140};
141
142
144{
145 switch( aType )
146 {
147 case LABEL_FLAG_SHAPE::L_INPUT: return _( "Input" );
148 case LABEL_FLAG_SHAPE::L_OUTPUT: return _( "Output" );
149 case LABEL_FLAG_SHAPE::L_BIDI: return _( "Bidirectional" );
150 case LABEL_FLAG_SHAPE::L_TRISTATE: return _( "Tri-State" );
151 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: return _( "Passive" );
152 default: return wxT( "???" );
153 }
154}
155
156
158{
159 SPIN newSpin = m_spin;
160
161 switch( m_spin )
162 {
163 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::BOTTOM; break;
164 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::RIGHT; break;
165 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::UP; break;
166 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::LEFT; break;
167 }
168
169 return SPIN_STYLE( newSpin );
170}
171
172
174{
175 SPIN newSpin = m_spin;
176
177 switch( m_spin )
178 {
179 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::BOTTOM; break;
180 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::UP; break;
181 case SPIN_STYLE::LEFT: break;
182 case SPIN_STYLE::RIGHT: break;
183 }
184
185 return SPIN_STYLE( newSpin );
186}
187
188
190{
191 SPIN newSpin = m_spin;
192
193 switch( m_spin )
194 {
195 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::RIGHT; break;
196 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::LEFT; break;
197 case SPIN_STYLE::UP: break;
198 case SPIN_STYLE::BOTTOM: break;
199 }
200
201 return SPIN_STYLE( newSpin );
202}
203
204
205SCH_LABEL_BASE::SCH_LABEL_BASE( const VECTOR2I& aPos, const wxString& aText, KICAD_T aType ) :
206 SCH_TEXT( aPos, aText, LAYER_NOTES, aType ),
207 m_shape( L_UNSPECIFIED ),
208 m_connectionType( CONNECTION_TYPE::NONE ),
209 m_isDangling( true ),
210 m_lastResolvedColor( COLOR4D::UNSPECIFIED )
211{
212 SetMultilineAllowed( false );
213 ClearFieldsAutoplaced(); // fields are not yet autoplaced.
214
215 if( !HasTextVars() )
217}
218
219
221 SCH_TEXT( aLabel ),
222 m_shape( aLabel.m_shape ),
223 m_connectionType( aLabel.m_connectionType ),
224 m_isDangling( aLabel.m_isDangling ),
225 m_lastResolvedColor( aLabel.m_lastResolvedColor ),
226 m_cached_driver_name( aLabel.m_cached_driver_name )
227{
228 SetMultilineAllowed( false );
229
230 m_fields = aLabel.m_fields;
231
232 for( SCH_FIELD& field : m_fields )
233 field.SetParent( this );
234}
235
236
238{
239 SCH_TEXT::operator=( aLabel );
240
242
243 return *this;
244}
245
246
247const wxString SCH_LABEL_BASE::GetDefaultFieldName( const wxString& aName, bool aUseDefaultName )
248{
249 if( aName == wxT( "Intersheetrefs" ) )
250 return _( "Sheet References" );
251 else if( aName == wxT( "Netclass" ) )
252 return _( "Net Class" );
253 else if( aName.IsEmpty() && aUseDefaultName )
254 return _( "Field" );
255 else
256 return aName;
257}
258
259
260bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
261{
262 if( SCH_TEXT::IsType( aScanTypes ) )
263 return true;
264
265 for( KICAD_T scanType : aScanTypes )
266 {
267 if( scanType == SCH_LABEL_LOCATE_ANY_T )
268 return true;
269 }
270
271 wxCHECK_MSG( Schematic(), false, wxT( "No parent SCHEMATIC set for SCH_LABEL!" ) );
272
273 // Ensure m_connected_items for Schematic()->CurrentSheet() exists.
274 // Can be not the case when "this" is living in clipboard
275 if( m_connected_items.find( Schematic()->CurrentSheet() ) == m_connected_items.end() )
276 return false;
277
278 const SCH_ITEM_VEC& item_set = m_connected_items.at( Schematic()->CurrentSheet() );
279
280 for( KICAD_T scanType : aScanTypes )
281 {
282 if( scanType == SCH_LABEL_LOCATE_WIRE_T )
283 {
284 for( SCH_ITEM* connection : item_set )
285 {
286 if( connection->IsType( { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T } ) )
287 return true;
288 }
289 }
290
291 if ( scanType == SCH_LABEL_LOCATE_BUS_T )
292 {
293 for( SCH_ITEM* connection : item_set )
294 {
295 if( connection->IsType( { SCH_ITEM_LOCATE_BUS_T } ) )
296 return true;
297 }
298 }
299 }
300
301 return false;
302}
303
304
306{
307 SCH_TEXT::SwapData( aItem );
308
309 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( aItem );
310
311 m_fields.swap( label->m_fields );
312 std::swap( m_fieldsAutoplaced, label->m_fieldsAutoplaced );
313
314 for( SCH_FIELD& field : m_fields )
315 field.SetParent( this );
316
317 for( SCH_FIELD& field : label->m_fields )
318 field.SetParent( label );
319
320 std::swap( m_shape, label->m_shape );
321 std::swap( m_connectionType, label->m_connectionType );
322 std::swap( m_isDangling, label->m_isDangling );
323 std::swap( m_lastResolvedColor, label->m_lastResolvedColor );
324}
325
326
328{
329 if( GetTextColor() != COLOR4D::UNSPECIFIED )
331 else if( !IsConnectivityDirty() )
332 m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor();
333
334 return m_lastResolvedColor;
335}
336
337
339{
340 // Assume "Right" and Left" mean which side of the anchor the text will be on
341 // Thus we want to left justify text up against the anchor if we are on the right
342 switch( aSpinStyle )
343 {
344 default:
345 wxFAIL_MSG( "Bad spin style" );
347
348 case SPIN_STYLE::RIGHT: // Horiz Normal Orientation
351 break;
352
353 case SPIN_STYLE::UP: // Vert Orientation UP
356 break;
357
358 case SPIN_STYLE::LEFT: // Horiz Orientation - Right justified
361 break;
362
363 case SPIN_STYLE::BOTTOM: // Vert Orientation BOTTOM
366 break;
367 }
368
370}
371
372
374{
376 {
378 return SPIN_STYLE::BOTTOM;
379 else
380 return SPIN_STYLE::UP;
381 }
382 else
383 {
385 return SPIN_STYLE::LEFT;
386 else
387 return SPIN_STYLE::RIGHT;
388 }
389}
390
391
393{
394 VECTOR2I text_offset;
395
396 // add an offset to x (or y) position to aid readability of text on a wire or line
397 int dist = GetTextOffset( aSettings ) + GetPenWidth();
398
399 switch( GetSpinStyle() )
400 {
401 case SPIN_STYLE::UP:
402 case SPIN_STYLE::BOTTOM: text_offset.x = -dist; break; // Vert Orientation
403 default:
404 case SPIN_STYLE::LEFT:
405 case SPIN_STYLE::RIGHT: text_offset.y = -dist; break; // Horiz Orientation
406 }
407
408 return text_offset;
409}
410
411
412void SCH_LABEL_BASE::SetPosition( const VECTOR2I& aPosition )
413{
414 VECTOR2I offset = aPosition - GetTextPos();
415 Move( offset );
416}
417
418
419void SCH_LABEL_BASE::Move( const VECTOR2I& aMoveVector )
420{
421 SCH_TEXT::Move( aMoveVector );
422
423 for( SCH_FIELD& field : m_fields )
424 field.Offset( aMoveVector );
425}
426
427
428void SCH_LABEL_BASE::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
429{
430 VECTOR2I pt = GetTextPos();
431 RotatePoint( pt, aCenter, aRotateCCW ? ANGLE_270 : ANGLE_90 );
432 VECTOR2I offset = pt - GetTextPos();
433
434 Rotate90( aRotateCCW );
435
436 SetTextPos( GetTextPos() + offset );
437
438 for( SCH_FIELD& field : m_fields )
439 field.SetTextPos( field.GetTextPos() + offset );
440}
441
442
443void SCH_LABEL_BASE::Rotate90( bool aClockwise )
444{
445 SCH_TEXT::Rotate90( aClockwise );
446
448 {
449 AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
450 }
451 else
452 {
453 for( SCH_FIELD& field : m_fields )
454 {
455 if( field.GetTextAngle().IsVertical()
456 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
457 {
458 if( !aClockwise )
459 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
460
461 field.SetTextAngle( ANGLE_HORIZONTAL );
462 }
463 else if( field.GetTextAngle().IsVertical()
464 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
465 {
466 if( !aClockwise )
467 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
468
469 field.SetTextAngle( ANGLE_HORIZONTAL );
470 }
471 else if( field.GetTextAngle().IsHorizontal()
472 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
473 {
474 if( aClockwise )
475 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
476
477 field.SetTextAngle( ANGLE_VERTICAL );
478 }
479 else if( field.GetTextAngle().IsHorizontal()
480 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
481 {
482 if( aClockwise )
483 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
484
485 field.SetTextAngle( ANGLE_VERTICAL );
486 }
487
488 VECTOR2I pos = field.GetTextPos();
489 RotatePoint( pos, GetPosition(), aClockwise ? -ANGLE_90 : ANGLE_90 );
490 field.SetTextPos( pos );
491 }
492 }
493}
494
495
496void SCH_LABEL_BASE::MirrorSpinStyle( bool aLeftRight )
497{
498 SCH_TEXT::MirrorSpinStyle( aLeftRight );
499
500 for( SCH_FIELD& field : m_fields )
501 {
502 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
503 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
504 {
505 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
506 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
507 else
508 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
509 }
510
511 VECTOR2I pos = field.GetTextPos();
513
514 if( aLeftRight )
515 pos.x = GetPosition().x + delta.x;
516 else
517 pos.y = GetPosition().y + delta.y;
518
519 field.SetTextPos( pos );
520 }
521}
522
523
525{
526 VECTOR2I old_pos = GetPosition();
528
529 for( SCH_FIELD& field : m_fields )
530 {
531 if( field.GetTextAngle() == ANGLE_HORIZONTAL )
532 field.FlipHJustify();
533
534 VECTOR2I pos = field.GetTextPos();
535 VECTOR2I delta = old_pos - pos;
536 pos.x = GetPosition().x + delta.x;
537
538 field.SetPosition( pos );
539 }
540}
541
542
544{
545 VECTOR2I old_pos = GetPosition();
547
548 for( SCH_FIELD& field : m_fields )
549 {
550 if( field.GetTextAngle() == ANGLE_VERTICAL )
551 field.FlipHJustify();
552
553 VECTOR2I pos = field.GetTextPos();
554 VECTOR2I delta = old_pos - pos;
555 pos.y = GetPosition().y + delta.y;
556
557 field.SetPosition( pos );
558 }
559}
560
561
562bool SCH_LABEL_BASE::IncrementLabel( int aIncrement )
563{
564 wxString text = GetText();
565
566 if( IncrementLabelMember( text, aIncrement ) )
567 {
568 SetText( text );
569 return true;
570 }
571
572 return false;
573}
574
575
576bool SCH_LABEL_BASE::operator==( const SCH_ITEM& aOther ) const
577{
578 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
579
580 if( !other )
581 return false;
582
583 if( m_shape != other->m_shape )
584 return false;
585
586 if( m_connectionType != other->m_connectionType )
587 return false;
588
589 if( m_fields.size() != other->m_fields.size() )
590 return false;
591
592 for( size_t ii = 0; ii < m_fields.size(); ++ii )
593 {
594 if( !( m_fields[ii] == other->m_fields[ii] ) )
595 return false;
596 }
597
598 return SCH_TEXT::operator==( aOther );
599}
600
601
602double SCH_LABEL_BASE::Similarity( const SCH_ITEM& aOther ) const
603{
604 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
605
606 if( !other )
607 return 0.0;
608
609 if( m_Uuid == other->m_Uuid )
610 return 1.0;
611
612 double similarity = SCH_TEXT::Similarity( aOther );
613
614 if( typeid( *this ) != typeid( aOther ) )
615 similarity *= 0.9;
616
617 if( m_shape == other->m_shape )
618 similarity *= 0.9;
619
620 if( m_connectionType == other->m_connectionType )
621 similarity *= 0.9;
622
623 for( size_t ii = 0; ii < m_fields.size(); ++ii )
624 {
625 if( ii >= other->m_fields.size() )
626 break;
627
628 similarity *= m_fields[ii].Similarity( other->m_fields[ii] );
629 }
630
631 int diff = std::abs( int( m_fields.size() ) - int( other->m_fields.size() ) );
632
633 similarity *= std::pow( 0.9, diff );
634
635 return similarity;
636}
637
638
639void SCH_LABEL_BASE::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
640{
641 int margin = GetTextOffset() * 2;
642 int labelLen = GetBodyBoundingBox().GetSizeMax();
643 int accumulated = GetTextHeight() / 2;
644
645 if( Type() == SCH_GLOBAL_LABEL_T )
646 accumulated += margin + GetPenWidth() + margin;
647
648 for( SCH_FIELD& field : m_fields )
649 {
650 VECTOR2I offset( 0, 0 );
651
652 switch( GetSpinStyle() )
653 {
654 default:
655 case SPIN_STYLE::LEFT:
656 field.SetTextAngle( ANGLE_HORIZONTAL );
657 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
658
659 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
660 offset.x = - ( labelLen + margin );
661 else
662 offset.y = accumulated + field.GetTextHeight() / 2;
663
664 break;
665
666 case SPIN_STYLE::UP:
667 field.SetTextAngle( ANGLE_VERTICAL );
668 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
669
670 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
671 offset.y = - ( labelLen + margin );
672 else
673 offset.x = accumulated + field.GetTextHeight() / 2;
674
675 break;
676
678 field.SetTextAngle( ANGLE_HORIZONTAL );
679 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
680
681 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
682 offset.x = labelLen + margin;
683 else
684 offset.y = accumulated + field.GetTextHeight() / 2;
685
686 break;
687
689 field.SetTextAngle( ANGLE_VERTICAL );
690 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
691
692 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
693 offset.y = labelLen + margin;
694 else
695 offset.x = accumulated + field.GetTextHeight() / 2;
696
697 break;
698 }
699
700 field.SetTextPos( GetTextPos() + offset );
701
702 if( field.GetCanonicalName() != wxT( "Intersheetrefs" ) )
703 accumulated += field.GetTextHeight() + margin;
704 }
705
707}
708
709
711 std::vector<std::pair<wxString, wxString>>* pages )
712{
713 wxCHECK( pages, /* void */ );
714
715 if( Schematic() )
716 {
717 wxString resolvedLabel = GetShownText( &Schematic()->CurrentSheet(), false );
718 auto it = Schematic()->GetPageRefsMap().find( resolvedLabel );
719
720 if( it != Schematic()->GetPageRefsMap().end() )
721 {
722 std::vector<int> pageListCopy;
723
724 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
725
726 if( !Schematic()->Settings().m_IntersheetRefsListOwnPage )
727 {
728 int currentPage = Schematic()->CurrentSheet().GetVirtualPageNumber();
729 alg::delete_matching( pageListCopy, currentPage );
730
731 if( pageListCopy.empty() )
732 return;
733 }
734
735 std::sort( pageListCopy.begin(), pageListCopy.end() );
736
737 std::map<int, wxString> sheetPages = Schematic()->GetVirtualPageToSheetPagesMap();
738 std::map<int, wxString> sheetNames = Schematic()->GetVirtualPageToSheetNamesMap();
739
740 for( int pageNum : pageListCopy )
741 pages->push_back( { sheetPages[ pageNum ], sheetNames[ pageNum ] } );
742 }
743 }
744}
745
746
747void SCH_LABEL_BASE::GetContextualTextVars( wxArrayString* aVars ) const
748{
749 for( const SCH_FIELD& field : m_fields )
750 aVars->push_back( field.GetCanonicalName().Upper() );
751
752 aVars->push_back( wxT( "OP" ) );
753 aVars->push_back( wxT( "CONNECTION_TYPE" ) );
754 aVars->push_back( wxT( "SHORT_NET_NAME" ) );
755 aVars->push_back( wxT( "NET_NAME" ) );
756 aVars->push_back( wxT( "NET_CLASS" ) );
757}
758
759
760bool SCH_LABEL_BASE::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token,
761 int aDepth ) const
762{
763 static wxRegEx operatingPoint( wxT( "^"
764 "OP"
765 "(.([0-9])?([a-zA-Z]*))?"
766 "$" ) );
767
768 wxCHECK( aPath, false );
769
770 SCHEMATIC* schematic = Schematic();
771
772 if( !schematic )
773 return false;
774
775 if( operatingPoint.Matches( *token ) )
776 {
777 int precision = 3;
778 wxString precisionStr( operatingPoint.GetMatch( *token, 2 ) );
779 wxString range( operatingPoint.GetMatch( *token, 3 ) );
780
781 if( !precisionStr.IsEmpty() )
782 precision = precisionStr[0] - '0';
783
784 if( range.IsEmpty() )
785 range = wxS( "~V" );
786
787 const SCH_CONNECTION* connection = Connection();
788 *token = wxS( "?" );
789
790 if( connection )
791 *token = schematic->GetOperatingPoint( connection->Name( false ), precision, range );
792
793 return true;
794 }
795
796 if( token->Contains( ':' ) )
797 {
798 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
799 return true;
800 }
801
803 && token->IsSameAs( wxT( "CONNECTION_TYPE" ) ) )
804 {
805 const SCH_LABEL_BASE* label = static_cast<const SCH_LABEL_BASE*>( this );
806 *token = getElectricalTypeLabel( label->GetShape() );
807 return true;
808 }
809 else if( token->IsSameAs( wxT( "SHORT_NET_NAME" ) ) )
810 {
811 const SCH_CONNECTION* connection = Connection();
812 *token = wxEmptyString;
813
814 if( connection )
815 *token = connection->LocalName();
816
817 return true;
818 }
819 else if( token->IsSameAs( wxT( "NET_NAME" ) ) )
820 {
821 const SCH_CONNECTION* connection = Connection();
822 *token = wxEmptyString;
823
824 if( connection )
825 *token = connection->Name();
826
827 return true;
828 }
829 else if( token->IsSameAs( wxT( "NET_CLASS" ) ) )
830 {
831 const SCH_CONNECTION* connection = Connection();
832 *token = wxEmptyString;
833
834 if( connection )
835 *token = GetEffectiveNetClass()->GetName();
836
837 return true;
838 }
839
840 for( const SCH_FIELD& field : m_fields)
841 {
842 if( token->IsSameAs( field.GetName() ) )
843 {
844 *token = field.GetShownText( false, aDepth + 1 );
845 return true;
846 }
847 }
848
849 // See if parent can resolve it (these will recurse to ancestors)
850
851 if( Type() == SCH_SHEET_PIN_T && m_parent )
852 {
853 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
854
855 SCH_SHEET_PATH path = *aPath;
856 path.push_back( sheet );
857
858 if( sheet->ResolveTextVar( &path, token, aDepth + 1 ) )
859 return true;
860 }
861 else
862 {
863 if( aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
864 return true;
865 }
866
867 return false;
868}
869
870
872{
873 return !HasTextVars();
874}
875
876
878{
880}
881
882
884{
886
887 if( !HasTextVars() )
889}
890
891
892wxString SCH_LABEL_BASE::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText,
893 int aDepth ) const
894{
895 std::function<bool( wxString* )> textResolver =
896 [&]( wxString* token ) -> bool
897 {
898 return ResolveTextVar( aPath, token, aDepth );
899 };
900
901 wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
902
903 if( text == wxS( "~" ) ) // Legacy placeholder for empty string
904 {
905 text = wxS( "" );
906 }
907 else if( HasTextVars() )
908 {
909 if( aDepth < 10 )
910 text = ExpandTextVars( text, &textResolver );
911 }
912
913 return text;
914}
915
916
917void SCH_LABEL_BASE::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
918{
919 for( SCH_FIELD& field : m_fields )
920 aFunction( &field );
921}
922
923
924bool SCH_LABEL_BASE::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
925{
926 return SCH_ITEM::Matches( UnescapeString( GetText() ), aSearchData );
927}
928
929
930bool SCH_LABEL_BASE::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
931{
932 EDA_SEARCH_DATA localSearchData( aSearchData );
933 localSearchData.findString = EscapeString( aSearchData.findString, CTX_NETNAME );
934 localSearchData.replaceString = EscapeString( aSearchData.replaceString, CTX_NETNAME );
935
936 return EDA_TEXT::Replace( localSearchData );
937}
938
939
941 const std::vector<KICAD_T>& aScanTypes )
942{
943 if( IsType( aScanTypes ) )
944 {
945 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
946 return INSPECT_RESULT::QUIT;
947 }
948
949 for( KICAD_T scanType : aScanTypes )
950 {
951 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
952 {
953 for( SCH_FIELD& field : m_fields )
954 {
955 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
956 return INSPECT_RESULT::QUIT;
957 }
958 }
959 }
960
961 return INSPECT_RESULT::CONTINUE;
962}
963
964
965void SCH_LABEL_BASE::GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList )
966{
967 DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() );
968 aItemList.push_back( item );
969}
970
971
972std::vector<VECTOR2I> SCH_LABEL_BASE::GetConnectionPoints() const
973{
974 return { GetTextPos() };
975}
976
977
978void SCH_LABEL_BASE::ViewGetLayers( int aLayers[], int& aCount ) const
979{
980 aCount = 5;
981 aLayers[0] = LAYER_DANGLING;
982 aLayers[1] = LAYER_DEVICE;
983 aLayers[2] = LAYER_NETCLASS_REFS;
984 aLayers[3] = LAYER_FIELDS;
985 aLayers[4] = LAYER_SELECTION_SHADOWS;
986}
987
988
990{
991 double ratio;
992
993 if( aSettings )
994 ratio = static_cast<const SCH_RENDER_SETTINGS*>( aSettings )->m_LabelSizeRatio;
995 else if( Schematic() )
997 else
998 ratio = DEFAULT_LABEL_SIZE_RATIO; // For previews (such as in Preferences), etc.
999
1000 return KiROUND( ratio * GetTextSize().y );
1001}
1002
1003
1005{
1006 // build the bounding box of the label only, without taking into account its fields
1007
1008 BOX2I box;
1009 std::vector<VECTOR2I> pts;
1010
1011 CreateGraphicShape( nullptr, pts, GetTextPos() );
1012
1013 for( const VECTOR2I& pt : pts )
1014 box.Merge( pt );
1015
1016 box.Inflate( GetEffectiveTextPenWidth() / 2 );
1017 box.Normalize();
1018 return box;
1019}
1020
1021
1023{
1024 // build the bounding box of the entire label, including its fields
1025
1026 BOX2I box = GetBodyBoundingBox();
1027
1028 for( const SCH_FIELD& field : m_fields )
1029 {
1030 if( field.IsVisible() )
1031 {
1032 BOX2I fieldBBox = field.GetBoundingBox();
1033
1034 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1035 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1036
1037 box.Merge( fieldBBox );
1038 }
1039 }
1040
1041 box.Normalize();
1042
1043 return box;
1044}
1045
1046
1047bool SCH_LABEL_BASE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1048{
1049 BOX2I bbox = GetBodyBoundingBox();
1050 bbox.Inflate( aAccuracy );
1051
1052 if( bbox.Contains( aPosition ) )
1053 return true;
1054
1055 for( const SCH_FIELD& field : m_fields )
1056 {
1057 if( field.IsVisible() )
1058 {
1059 BOX2I fieldBBox = field.GetBoundingBox();
1060 fieldBBox.Inflate( aAccuracy );
1061
1062 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1063 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1064
1065 if( fieldBBox.Contains( aPosition ) )
1066 return true;
1067 }
1068 }
1069
1070 return false;
1071}
1072
1073
1074bool SCH_LABEL_BASE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1075{
1076 BOX2I rect = aRect;
1077
1078 rect.Inflate( aAccuracy );
1079
1080 if( aContained )
1081 {
1082 return rect.Contains( GetBoundingBox() );
1083 }
1084 else
1085 {
1086 if( rect.Intersects( GetBodyBoundingBox() ) )
1087 return true;
1088
1089 for( const SCH_FIELD& field : m_fields )
1090 {
1091 if( field.IsVisible() )
1092 {
1093 BOX2I fieldBBox = field.GetBoundingBox();
1094
1095 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1096 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1097
1098 if( rect.Intersects( fieldBBox ) )
1099 return true;
1100 }
1101 }
1102
1103 return false;
1104 }
1105}
1106
1107
1108bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1109 std::vector<DANGLING_END_ITEM>& aItemListByPos,
1110 const SCH_SHEET_PATH* aPath )
1111{
1112 bool previousState = m_isDangling;
1113 VECTOR2I text_pos = GetTextPos();
1114 m_isDangling = true;
1115 m_connectionType = CONNECTION_TYPE::NONE;
1116
1117 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, text_pos );
1118 it < aItemListByPos.end() && it->GetPosition() == text_pos; it++ )
1119 {
1120 DANGLING_END_ITEM& item = *it;
1121
1122 if( item.GetItem() == this )
1123 continue;
1124
1125 switch( item.GetType() )
1126 {
1127 case PIN_END:
1128 case LABEL_END:
1129 case SHEET_LABEL_END:
1130 case NO_CONNECT_END:
1131 if( text_pos == item.GetPosition() )
1132 {
1133 m_isDangling = false;
1134
1135 if( aPath && item.GetType() != PIN_END )
1136 AddConnectionTo( *aPath, static_cast<SCH_ITEM*>( item.GetItem() ) );
1137 }
1138 break;
1139
1140 default: break;
1141 }
1142
1143 if( !m_isDangling )
1144 break;
1145 }
1146
1147 if( m_isDangling )
1148 {
1149 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, BUS_END );
1150 it < aItemListByType.end() && it->GetType() == BUS_END; it++ )
1151 {
1152 DANGLING_END_ITEM& item = *it;
1153 DANGLING_END_ITEM& nextItem = *( ++it );
1154
1155 int accuracy = 1; // We have rounding issues with an accuracy of 0
1156
1157 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(),
1158 accuracy );
1159
1160 if( m_isDangling )
1161 continue;
1162
1163 m_connectionType = CONNECTION_TYPE::BUS;
1164
1165 // Add the line to the connected items, since it won't be picked
1166 // up by a search of intersecting connection points
1167 if( aPath )
1168 {
1169 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1170 AddConnectionTo( *aPath, sch_item );
1171 sch_item->AddConnectionTo( *aPath, this );
1172 }
1173 break;
1174 }
1175
1176 if( m_isDangling )
1177 {
1178 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, WIRE_END );
1179 it < aItemListByType.end() && it->GetType() == WIRE_END; it++ )
1180 {
1181 DANGLING_END_ITEM& item = *it;
1182 DANGLING_END_ITEM& nextItem = *( ++it );
1183
1184 int accuracy = 1; // We have rounding issues with an accuracy of 0
1185
1186 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(),
1187 nextItem.GetPosition(), accuracy );
1188
1189 if( m_isDangling )
1190 continue;
1191
1192 m_connectionType = CONNECTION_TYPE::NET;
1193
1194 // Add the line to the connected items, since it won't be picked
1195 // up by a search of intersecting connection points
1196 if( aPath )
1197 {
1198 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1199 AddConnectionTo( *aPath, sch_item );
1200 sch_item->AddConnectionTo( *aPath, this );
1201 }
1202 break;
1203 }
1204 }
1205 }
1206
1207 if( m_isDangling )
1208 m_connectionType = CONNECTION_TYPE::NONE;
1209
1210 return previousState != m_isDangling;
1211}
1212
1213
1215 const SCH_SHEET_PATH* aInstance ) const
1216{
1217 // Do not compare to ourself.
1218 if( aItem == this || !IsConnectable() )
1219 return false;
1220
1221 const SCH_LABEL_BASE* label = dynamic_cast<const SCH_LABEL_BASE*>( aItem );
1222
1223 // Don't compare against a different SCH_ITEM.
1224 wxCHECK( label, false );
1225
1226 if( GetPosition() != label->GetPosition() )
1227 return true;
1228
1229 if( GetShownText( aInstance ) != label->GetShownText( aInstance ) )
1230 return true;
1231
1232 std::vector<wxString> netclasses;
1233 std::vector<wxString> otherNetclasses;
1234
1235 for( const SCH_FIELD& field : m_fields )
1236 {
1237 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1238 netclasses.push_back( field.GetText() );
1239 }
1240
1241 for( const SCH_FIELD& field : label->m_fields )
1242 {
1243 if( field.GetCanonicalName() == wxT( "Netclass" ) )
1244 otherNetclasses.push_back( field.GetText() );
1245 }
1246
1247 return netclasses != otherNetclasses;
1248}
1249
1250
1251void SCH_LABEL_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1252{
1253 wxString msg;
1254
1255 switch( Type() )
1256 {
1257 case SCH_LABEL_T: msg = _( "Label" ); break;
1258 case SCH_DIRECTIVE_LABEL_T: msg = _( "Directive Label" ); break;
1259 case SCH_GLOBAL_LABEL_T: msg = _( "Global Label" ); break;
1260 case SCH_HIER_LABEL_T: msg = _( "Hierarchical Label" ); break;
1261 case SCH_SHEET_PIN_T: msg = _( "Hierarchical Sheet Pin" ); break;
1262 default: return;
1263 }
1264
1265 // Don't use GetShownText() here; we want to show the user the variable references
1266 aList.emplace_back( msg, UnescapeString( GetText() ) );
1267
1268 // Display electrical type if it is relevant
1270 aList.emplace_back( _( "Type" ), getElectricalTypeLabel( GetShape() ) );
1271
1272 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1273
1274 wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
1275 int style = IsBold() && IsItalic() ? 3 : IsBold() ? 2 : IsItalic() ? 1 : 0;
1276 aList.emplace_back( _( "Style" ), textStyle[style] );
1277
1278 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1279
1280 switch( GetSpinStyle() )
1281 {
1282 case SPIN_STYLE::LEFT: msg = _( "Align right" ); break;
1283 case SPIN_STYLE::UP: msg = _( "Align bottom" ); break;
1284 case SPIN_STYLE::RIGHT: msg = _( "Align left" ); break;
1285 case SPIN_STYLE::BOTTOM: msg = _( "Align top" ); break;
1286 default: msg = wxT( "???" ); break;
1287 }
1288
1289 aList.emplace_back( _( "Justification" ), msg );
1290
1291 SCH_CONNECTION* conn = nullptr;
1292
1293 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1294 conn = Connection();
1295
1296 if( conn )
1297 {
1298 conn->AppendInfoToMsgPanel( aList );
1299
1300 if( !conn->IsBus() )
1301 {
1302 aList.emplace_back( _( "Resolved Netclass" ),
1303 UnescapeString( GetEffectiveNetClass()->GetName() ) );
1304 }
1305 }
1306}
1307
1308
1309void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
1310 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1311{
1312 static std::vector<VECTOR2I> s_poly;
1313
1314 SCH_SHEET_PATH* sheet = &Schematic()->CurrentSheet();
1315 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
1316 SCH_CONNECTION* connection = Connection();
1317 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1318 COLOR4D color = settings->GetLayerColor( layer );
1319 int penWidth = GetEffectiveTextPenWidth( settings->GetDefaultPenWidth() );
1320
1321 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1322 color = GetTextColor();
1323
1324 penWidth = std::max( penWidth, settings->GetMinPenWidth() );
1325 aPlotter->SetCurrentLineWidth( penWidth );
1326
1327 KIFONT::FONT* font = GetFont();
1328
1329 if( !font )
1330 font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), IsBold(), IsItalic() );
1331
1332 VECTOR2I textpos = GetTextPos() + GetSchematicTextOffset( aPlotter->RenderSettings() );
1333 CreateGraphicShape( aPlotter->RenderSettings(), s_poly, GetTextPos() );
1334
1336 attrs.m_StrokeWidth = penWidth;
1337 attrs.m_Multiline = false;
1338
1339 if( aBackground )
1340 {
1341 // No filled shapes (yet)
1342 }
1343 else
1344 {
1345 aPlotter->PlotText( textpos, color, GetShownText( sheet, true ), attrs, font,
1346 GetFontMetrics() );
1347
1348 if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
1349 {
1350 aPlotter->MoveTo( s_poly[0] );
1351 aPlotter->LineTo( s_poly[1] );
1352 aPlotter->PenFinish();
1353
1354 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1355 aPlotter->FilledCircle( s_poly[2], diameter , FILLED, nullptr );
1356 }
1357 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1358 {
1359 aPlotter->MoveTo( s_poly[0] );
1360 aPlotter->LineTo( s_poly[1] );
1361 aPlotter->PenFinish();
1362
1363 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1364 aPlotter->ThickCircle( s_poly[2], diameter, penWidth, FILLED, nullptr );
1365 }
1366 else
1367 {
1368 if( !s_poly.empty() )
1369 aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth );
1370 }
1371
1372 // Plot attributes to a hypertext menu
1373 if( aPlotOpts.m_PDFPropertyPopups )
1374 {
1375 std::vector<wxString> properties;
1376
1377 if( connection )
1378 {
1379 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Net" ),
1380 connection->Name() ) );
1381
1382 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
1383 _( "Resolved netclass" ),
1384 GetEffectiveNetClass()->GetName() ) );
1385 }
1386
1387 for( const SCH_FIELD& field : GetFields() )
1388 {
1389 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), field.GetName(),
1390 field.GetShownText( false ) ) );
1391 }
1392
1393 if( !properties.empty() )
1394 aPlotter->HyperlinkMenu( GetBodyBoundingBox(), properties );
1395 }
1396
1397 if( Type() == SCH_HIER_LABEL_T )
1398 {
1399 aPlotter->Bookmark( GetBodyBoundingBox(), GetShownText( false ),
1400 _( "Hierarchical Labels" ) );
1401 }
1402 }
1403
1404 for( SCH_FIELD& field : m_fields )
1405 field.Plot( aPlotter, aBackground, aPlotOpts, aUnit, aBodyStyle, aOffset, aDimmed );
1406}
1407
1408
1409void SCH_LABEL_BASE::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
1410 const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
1411{
1412 static std::vector<VECTOR2I> s_poly;
1413
1414 SCH_CONNECTION* connection = Connection();
1415 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1416 wxDC* DC = aSettings->GetPrintDC();
1417 COLOR4D color = aSettings->GetLayerColor( layer );
1418 bool blackAndWhiteMode = GetGRForceBlackPenState();
1419 int penWidth = GetEffectivePenWidth( aSettings );
1420 VECTOR2I text_offset = aOffset + GetSchematicTextOffset( aSettings );
1421
1422 if( !blackAndWhiteMode && GetTextColor() != COLOR4D::UNSPECIFIED )
1423 color = GetTextColor();
1424
1425 EDA_TEXT::Print( aSettings, text_offset, color );
1426
1427 CreateGraphicShape( aSettings, s_poly, GetTextPos() + aOffset );
1428
1429 if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
1430 {
1431 GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
1432
1433 int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
1434 GRFilledCircle( DC, s_poly[2], radius, penWidth, color, color );
1435 }
1436 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1437 {
1438 GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
1439
1440 int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
1441 GRCircle( DC, s_poly[2], radius, penWidth, color );
1442 }
1443 else
1444 {
1445 if( !s_poly.empty() )
1446 GRPoly( DC, s_poly.size(), &s_poly[0], false, penWidth, color, color );
1447 }
1448
1449 for( SCH_FIELD& field : m_fields )
1450 field.Print( aSettings, aUnit, aBodyStyle, aOffset, aForceNoFill, aDimmed );
1451}
1452
1453
1455{
1457}
1458
1459
1461{
1462 m_autoRotateOnPlacement = autoRotate;
1463}
1464
1465
1466SCH_LABEL::SCH_LABEL( const VECTOR2I& pos, const wxString& text ) :
1468{
1470 m_shape = LABEL_FLAG_SHAPE::L_INPUT;
1471 m_isDangling = true;
1472}
1473
1474
1475void SCH_LABEL::Serialize( google::protobuf::Any &aContainer ) const
1476{
1477 kiapi::schematic::types::LocalLabel label;
1478
1479 label.mutable_id()->set_value( m_Uuid.AsStdString() );
1480 kiapi::common::PackVector2( *label.mutable_position(), GetPosition() );
1481
1482 aContainer.PackFrom( label );
1483}
1484
1485
1486bool SCH_LABEL::Deserialize( const google::protobuf::Any &aContainer )
1487{
1488 kiapi::schematic::types::LocalLabel label;
1489
1490 if( !aContainer.UnpackTo( &label ) )
1491 return false;
1492
1493 const_cast<KIID&>( m_Uuid ) = KIID( label.id().value() );
1494 SetPosition( kiapi::common::UnpackVector2( label.position() ) );
1495
1496 return true;
1497}
1498
1499
1501{
1502 BOX2I rect = GetTextBox();
1503
1504 rect.Offset( 0, -GetTextOffset() );
1506
1507 if( !GetTextAngle().IsZero() )
1508 {
1509 // Rotate rect
1510 VECTOR2I pos = rect.GetOrigin();
1511 VECTOR2I end = rect.GetEnd();
1512
1513 RotatePoint( pos, GetTextPos(), GetTextAngle() );
1514 RotatePoint( end, GetTextPos(), GetTextAngle() );
1515
1516 rect.SetOrigin( pos );
1517 rect.SetEnd( end );
1518
1519 rect.Normalize();
1520 }
1521
1522 // Labels have a position point that is outside of the TextBox
1523 rect.Merge( GetPosition() );
1524
1525 return rect;
1526}
1527
1528
1529wxString SCH_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
1530{
1531 return wxString::Format( _( "Label '%s'" ),
1533}
1534
1535
1537{
1538 return BITMAPS::add_line_label;
1539}
1540
1541
1543 SCH_LABEL_BASE( pos, wxEmptyString, SCH_DIRECTIVE_LABEL_T )
1544{
1546 m_shape = LABEL_FLAG_SHAPE::F_ROUND;
1549 m_isDangling = true;
1550}
1551
1552
1554{
1555 SCH_LABEL_BASE::SwapData( aItem );
1556
1557 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( aItem );
1558
1559 std::swap( m_pinLength, label->m_pinLength );
1560 std::swap( m_symbolSize, label->m_symbolSize );
1561}
1562
1563
1565 SCH_LABEL_BASE( aClassLabel )
1566{
1567 m_pinLength = aClassLabel.m_pinLength;
1568 m_symbolSize = aClassLabel.m_symbolSize;
1569}
1570
1571
1572void SCH_DIRECTIVE_LABEL::Serialize( google::protobuf::Any &aContainer ) const
1573{
1574 // TODO
1575}
1576
1577
1578bool SCH_DIRECTIVE_LABEL::Deserialize( const google::protobuf::Any &aContainer )
1579{
1580 // TODO
1581 return false;
1582}
1583
1584
1586{
1587 int pen = 0;
1588
1589 if( Schematic() )
1591
1592 return GetEffectiveTextPenWidth( pen );
1593}
1594
1595
1597{
1598 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1599 // vertical shape (like a text reduced to only "I" letter).
1600 // So the mirroring is not exactly similar to a SCH_TEXT item
1601 SCH_TEXT::MirrorSpinStyle( !aLeftRight );
1602
1603 for( SCH_FIELD& field : m_fields )
1604 {
1605 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
1606 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
1607 {
1608 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1609 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1610 else
1611 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1612 }
1613
1614 VECTOR2I pos = field.GetTextPos();
1616
1617 if( aLeftRight )
1618 pos.x = GetPosition().x + delta.x;
1619 else
1620 pos.y = GetPosition().y + delta.y;
1621
1622 field.SetTextPos( pos );
1623 }
1624}
1625
1626
1628{
1629 VECTOR2I old_pos = GetPosition();
1630 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1631 // vertical shape (like a text reduced to only "I" letter).
1632 // So the mirroring is not exactly similar to a SCH_TEXT item
1633 // Text is NOT really mirrored; it is moved to a suitable horizontal position
1634 SetSpinStyle( GetSpinStyle().MirrorX() );
1635
1636 SetTextX( MIRRORVAL( GetTextPos().x, aCenter ) );
1637
1638 for( SCH_FIELD& field : m_fields )
1639 {
1640 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1641 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1642 else if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1643 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1644
1645 VECTOR2I pos = field.GetTextPos();
1646 VECTOR2I delta = old_pos - pos;
1647 pos.x = GetPosition().x + delta.x;
1648
1649 field.SetPosition( pos );
1650 }
1651}
1652
1653
1655{
1656 VECTOR2I old_pos = GetPosition();
1657 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1658 // vertical shape (like a text reduced to only "I" letter).
1659 // So the mirroring is not exactly similar to a SCH_TEXT item
1660 // Text is NOT really mirrored; it is moved to a suitable vertical position
1661 SetSpinStyle( GetSpinStyle().MirrorY() );
1662
1663 SetTextY( MIRRORVAL( GetTextPos().y, aCenter ) );
1664
1665 for( SCH_FIELD& field : m_fields )
1666 {
1667 VECTOR2I pos = field.GetTextPos();
1668 VECTOR2I delta = old_pos - pos;
1669 pos.y = GetPosition().y + delta.y;
1670
1671 field.SetPosition( pos );
1672 }
1673}
1674
1675
1677 std::vector<VECTOR2I>& aPoints,
1678 const VECTOR2I& aPos ) const
1679{
1680 int symbolSize = m_symbolSize;
1681
1682 aPoints.clear();
1683
1684 switch( m_shape )
1685 {
1686 case LABEL_FLAG_SHAPE::F_DOT:
1687 symbolSize = KiROUND( symbolSize * 0.7 );
1689
1690 case LABEL_FLAG_SHAPE::F_ROUND:
1691 // First 3 points are used for generating shape
1692 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1693 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1694 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1695
1696 // These points are just used to bulk out the bounding box
1697 aPoints.emplace_back( VECTOR2I( -m_symbolSize, m_pinLength ) );
1698 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1699 aPoints.emplace_back( VECTOR2I( m_symbolSize, m_pinLength + symbolSize ) );
1700 break;
1701
1702 case LABEL_FLAG_SHAPE::F_DIAMOND:
1703 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1704 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1705 aPoints.emplace_back( VECTOR2I( -2 * m_symbolSize, m_pinLength ) );
1706 aPoints.emplace_back( VECTOR2I( 0, m_pinLength + symbolSize ) );
1707 aPoints.emplace_back( VECTOR2I( 2 * m_symbolSize, m_pinLength ) );
1708 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1709 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1710 break;
1711
1712 case LABEL_FLAG_SHAPE::F_RECTANGLE:
1713 symbolSize = KiROUND( symbolSize * 0.8 );
1714
1715 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1716 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1717 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength - symbolSize ) );
1718 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength + symbolSize ) );
1719 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength + symbolSize ) );
1720 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength - symbolSize ) );
1721 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1722 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1723 break;
1724
1725 default:
1726 break;
1727 }
1728
1729 // Rotate outlines and move corners to real position
1730 for( VECTOR2I& aPoint : aPoints )
1731 {
1732 switch( GetSpinStyle() )
1733 {
1734 default:
1735 case SPIN_STYLE::LEFT: break;
1736 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
1737 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
1738 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
1739 }
1740
1741 aPoint += aPos;
1742 }
1743}
1744
1745
1747{
1748 int margin = GetTextOffset();
1749 int symbolWidth = m_symbolSize;
1750 int origin = m_pinLength;
1751
1752 if( m_shape == LABEL_FLAG_SHAPE::F_DIAMOND || m_shape == LABEL_FLAG_SHAPE::F_RECTANGLE )
1753 symbolWidth *= 2;
1754
1755 if( IsItalic() )
1756 margin = KiROUND( margin * 1.5 );
1757
1758 VECTOR2I offset;
1759
1760 for( SCH_FIELD& field : m_fields )
1761 {
1762 switch( GetSpinStyle() )
1763 {
1764 default:
1765 case SPIN_STYLE::LEFT:
1766 field.SetTextAngle( ANGLE_HORIZONTAL );
1767 offset = { symbolWidth + margin, origin };
1768 break;
1769
1770 case SPIN_STYLE::UP:
1771 field.SetTextAngle( ANGLE_VERTICAL );
1772 offset = { -origin, -( symbolWidth + margin ) };
1773 break;
1774
1775 case SPIN_STYLE::RIGHT:
1776 field.SetTextAngle( ANGLE_HORIZONTAL );
1777 offset = { symbolWidth + margin, -origin };
1778 break;
1779
1780 case SPIN_STYLE::BOTTOM:
1781 field.SetTextAngle( ANGLE_VERTICAL );
1782 offset = { origin, -( symbolWidth + margin ) };
1783 break;
1784 }
1785
1786 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1787 field.SetTextPos( GetPosition() + offset );
1788
1789 origin -= field.GetTextHeight() + margin;
1790 }
1791
1793}
1794
1795
1797{
1798 if( m_fields.empty() )
1799 {
1800 return _( "Directive Label" );
1801 }
1802 else
1803 {
1804 return wxString::Format( _( "Directive Label [%s %s]" ),
1805 UnescapeString( m_fields[0].GetName() ),
1807 }
1808}
1809
1810
1812{
1813 m_connected_rule_areas.insert( aRuleArea );
1814}
1815
1816
1818{
1819 m_connected_rule_areas.clear();
1820}
1821
1822
1824{
1825 m_connected_rule_areas.erase( aRuleArea );
1826}
1827
1828
1830{
1831 return m_isDangling && m_connected_rule_areas.empty();
1832}
1833
1834
1835SCH_GLOBALLABEL::SCH_GLOBALLABEL( const VECTOR2I& pos, const wxString& text ) :
1837{
1839 m_shape = LABEL_FLAG_SHAPE::L_BIDI;
1840 m_isDangling = true;
1841
1843
1844 m_fields.emplace_back( SCH_FIELD( pos, 0, this, wxT( "Sheet References" ) ) );
1845 m_fields[0].SetText( wxT( "${INTERSHEET_REFS}" ) );
1846 m_fields[0].SetVisible( false );
1847 m_fields[0].SetLayer( LAYER_INTERSHEET_REFS );
1848 m_fields[0].SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
1849}
1850
1851
1853 SCH_LABEL_BASE( aGlobalLabel )
1854{
1855}
1856
1857
1858void SCH_GLOBALLABEL::Serialize( google::protobuf::Any &aContainer ) const
1859{
1860 // TODO
1861}
1862
1863
1864bool SCH_GLOBALLABEL::Deserialize( const google::protobuf::Any &aContainer )
1865{
1866 // TODO
1867 return false;
1868}
1869
1870
1872{
1873 int horiz = GetLabelBoxExpansion( aSettings );
1874
1875 // Center the text on the center line of "E" instead of "R" to make room for an overbar
1876 int vert = GetTextHeight() * 0.0715;
1877
1878 switch( m_shape )
1879 {
1880 case LABEL_FLAG_SHAPE::L_INPUT:
1881 case LABEL_FLAG_SHAPE::L_BIDI:
1882 case LABEL_FLAG_SHAPE::L_TRISTATE:
1883 horiz += GetTextHeight() * 3 / 4; // Use three-quarters-height as proxy for triangle size
1884 break;
1885
1886 case LABEL_FLAG_SHAPE::L_OUTPUT:
1887 case LABEL_FLAG_SHAPE::L_UNSPECIFIED:
1888 default:
1889 break;
1890 }
1891
1892 switch( GetSpinStyle() )
1893 {
1894 default:
1895 case SPIN_STYLE::LEFT: return VECTOR2I( -horiz, vert );
1896 case SPIN_STYLE::UP: return VECTOR2I( vert, -horiz );
1897 case SPIN_STYLE::RIGHT: return VECTOR2I( horiz, vert );
1898 case SPIN_STYLE::BOTTOM: return VECTOR2I( vert, horiz );
1899 }
1900}
1901
1902
1904{
1905 SCH_LABEL_BASE::SetSpinStyle( aSpinStyle );
1907}
1908
1909
1910bool SCH_GLOBALLABEL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token,
1911 int aDepth ) const
1912{
1913 wxCHECK( aPath, false );
1914
1915 SCHEMATIC* schematic = Schematic();
1916
1917 if( !schematic )
1918 return false;
1919
1920 if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) )
1921 {
1922 SCHEMATIC_SETTINGS& settings = schematic->Settings();
1923 wxString ref;
1924 auto it = schematic->GetPageRefsMap().find( GetShownText( aPath ) );
1925
1926 if( it == schematic->GetPageRefsMap().end() )
1927 {
1928 ref = "?";
1929 }
1930 else
1931 {
1932 std::vector<int> pageListCopy;
1933
1934 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
1935 std::sort( pageListCopy.begin(), pageListCopy.end() );
1936
1937 if( !settings.m_IntersheetRefsListOwnPage )
1938 {
1939 int currentPage = schematic->CurrentSheet().GetVirtualPageNumber();
1940 alg::delete_matching( pageListCopy, currentPage );
1941 }
1942
1943 std::map<int, wxString> sheetPages = schematic->GetVirtualPageToSheetPagesMap();
1944
1945 if( ( settings.m_IntersheetRefsFormatShort ) && ( pageListCopy.size() > 2 ) )
1946 {
1947 ref.Append( wxString::Format( wxT( "%s..%s" ),
1948 sheetPages[pageListCopy.front()],
1949 sheetPages[pageListCopy.back()] ) );
1950 }
1951 else
1952 {
1953 for( const int& pageNo : pageListCopy )
1954 ref.Append( wxString::Format( wxT( "%s," ), sheetPages[pageNo] ) );
1955
1956 if( !ref.IsEmpty() && ref.Last() == ',' )
1957 ref.RemoveLast();
1958 }
1959 }
1960
1961 *token = settings.m_IntersheetRefsPrefix + ref + settings.m_IntersheetRefsSuffix;
1962 return true;
1963 }
1964
1965 return SCH_LABEL_BASE::ResolveTextVar( aPath, token, aDepth );
1966}
1967
1968
1969void SCH_GLOBALLABEL::ViewGetLayers( int aLayers[], int& aCount ) const
1970{
1971 aCount = 6;
1972 aLayers[0] = LAYER_DANGLING;
1973 aLayers[1] = LAYER_DEVICE;
1974 aLayers[2] = LAYER_INTERSHEET_REFS;
1975 aLayers[3] = LAYER_NETCLASS_REFS;
1976 aLayers[4] = LAYER_FIELDS;
1977 aLayers[5] = LAYER_SELECTION_SHADOWS;
1978}
1979
1980
1982 std::vector<VECTOR2I>& aPoints,
1983 const VECTOR2I& aPos ) const
1984{
1985 int margin = GetLabelBoxExpansion( aRenderSettings );
1986 int halfSize = ( GetTextHeight() / 2 ) + margin;
1987 int linewidth = GetPenWidth();
1988 int symb_len = GetTextBox().GetWidth() + 2 * margin;
1989
1990 int x = symb_len + linewidth + 3;
1991 int y = halfSize + linewidth + 3;
1992
1993 aPoints.clear();
1994
1995 // Create outline shape : 6 points
1996 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1997 aPoints.emplace_back( VECTOR2I( 0, -y ) ); // Up
1998 aPoints.emplace_back( VECTOR2I( -x, -y ) ); // left
1999 aPoints.emplace_back( VECTOR2I( -x, 0 ) ); // Up left
2000 aPoints.emplace_back( VECTOR2I( -x, y ) ); // left down
2001 aPoints.emplace_back( VECTOR2I( 0, y ) ); // down
2002
2003 int x_offset = 0;
2004
2005 switch( m_shape )
2006 {
2007 case LABEL_FLAG_SHAPE::L_INPUT:
2008 x_offset = -halfSize;
2009 aPoints[0].x += halfSize;
2010 break;
2011
2012 case LABEL_FLAG_SHAPE::L_OUTPUT:
2013 aPoints[3].x -= halfSize;
2014 break;
2015
2016 case LABEL_FLAG_SHAPE::L_BIDI:
2017 case LABEL_FLAG_SHAPE::L_TRISTATE:
2018 x_offset = -halfSize;
2019 aPoints[0].x += halfSize;
2020 aPoints[3].x -= halfSize;
2021 break;
2022
2023 case LABEL_FLAG_SHAPE::L_UNSPECIFIED:
2024 default:
2025 break;
2026 }
2027
2028 // Rotate outlines and move corners in real position
2029 for( VECTOR2I& aPoint : aPoints )
2030 {
2031 aPoint.x += x_offset;
2032
2033 switch( GetSpinStyle() )
2034 {
2035 default:
2036 case SPIN_STYLE::LEFT: break;
2037 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
2038 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
2039 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
2040 }
2041
2042 aPoint += aPos;
2043 }
2044
2045 aPoints.push_back( aPoints[0] ); // closing
2046}
2047
2048
2050{
2051 return wxString::Format( _( "Global Label '%s'" ),
2053}
2054
2055
2057{
2058 return BITMAPS::add_glabel;
2059}
2060
2061
2062SCH_HIERLABEL::SCH_HIERLABEL( const VECTOR2I& pos, const wxString& text, KICAD_T aType ) :
2063 SCH_LABEL_BASE( pos, text, aType )
2064{
2066 m_shape = LABEL_FLAG_SHAPE::L_INPUT;
2067 m_isDangling = true;
2068}
2069
2070
2071void SCH_HIERLABEL::Serialize( google::protobuf::Any &aContainer ) const
2072{
2073 // TODO
2074}
2075
2076
2077bool SCH_HIERLABEL::Deserialize( const google::protobuf::Any &aContainer )
2078{
2079 // TODO
2080 return false;
2081}
2082
2083
2085{
2086 SCH_LABEL_BASE::SetSpinStyle( aSpinStyle );
2088}
2089
2090
2092 std::vector<VECTOR2I>& aPoints, const VECTOR2I& aPos ) const
2093{
2094 CreateGraphicShape( aSettings, aPoints, aPos, m_shape );
2095}
2096
2097
2099 std::vector<VECTOR2I>& aPoints, const VECTOR2I& aPos,
2100 LABEL_FLAG_SHAPE aShape ) const
2101{
2102 int* Template = TemplateShape[static_cast<int>( aShape )][static_cast<int>( GetSpinStyle() )];
2103 int halfSize = GetTextHeight() / 2;
2104 int imax = *Template;
2105 Template++;
2106
2107 aPoints.clear();
2108
2109 for( int ii = 0; ii < imax; ii++ )
2110 {
2111 VECTOR2I corner;
2112 corner.x = ( halfSize * (*Template) ) + aPos.x;
2113 Template++;
2114
2115 corner.y = ( halfSize * (*Template) ) + aPos.y;
2116 Template++;
2117
2118 aPoints.push_back( corner );
2119 }
2120}
2121
2122
2124{
2125 int penWidth = GetEffectiveTextPenWidth();
2126 int margin = GetTextOffset();
2127
2128 int x = GetTextPos().x;
2129 int y = GetTextPos().y;
2130
2131 int height = GetTextHeight() + penWidth + margin;
2132 int length = GetTextBox().GetWidth();
2133
2134 length += height; // add height for triangular shapes
2135
2136 int dx, dy;
2137
2138 switch( GetSpinStyle() )
2139 {
2140 default:
2141 case SPIN_STYLE::LEFT:
2142 dx = -length;
2143 dy = height;
2145 y -= height / 2;
2146 break;
2147
2148 case SPIN_STYLE::UP:
2149 dx = height;
2150 dy = -length;
2151 x -= height / 2;
2153 break;
2154
2155 case SPIN_STYLE::RIGHT:
2156 dx = length;
2157 dy = height;
2159 y -= height / 2;
2160 break;
2161
2162 case SPIN_STYLE::BOTTOM:
2163 dx = height;
2164 dy = length;
2165 x -= height / 2;
2167 break;
2168 }
2169
2170 BOX2I box( VECTOR2I( x, y ), VECTOR2I( dx, dy ) );
2171 box.Normalize();
2172 return box;
2173}
2174
2175
2177{
2178 VECTOR2I text_offset;
2179 int dist = GetTextOffset( aSettings );
2180
2181 dist += GetTextWidth();
2182
2183 switch( GetSpinStyle() )
2184 {
2185 default:
2186 case SPIN_STYLE::LEFT: text_offset.x = -dist; break; // Orientation horiz normale
2187 case SPIN_STYLE::UP: text_offset.y = -dist; break; // Orientation vert UP
2188 case SPIN_STYLE::RIGHT: text_offset.x = dist; break; // Orientation horiz inverse
2189 case SPIN_STYLE::BOTTOM: text_offset.y = dist; break; // Orientation vert BOTTOM
2190 }
2191
2192 return text_offset;
2193}
2194
2195
2196wxString SCH_HIERLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
2197{
2198 return wxString::Format( _( "Hierarchical Label '%s'" ),
2200}
2201
2202
2204{
2205 return BITMAPS::add_hierarchical_label;
2206}
2207
2208
2210{
2211 wxString msg =
2212#include "sch_text_help_md.h"
2213 ;
2214
2215 HTML_MESSAGE_BOX* dlg = new HTML_MESSAGE_BOX( nullptr, _( "Syntax Help" ) );
2216 wxSize sz( 320, 320 );
2217
2218 dlg->SetMinSize( dlg->ConvertDialogToPixels( sz ) );
2219 dlg->SetDialogSizeInDU( sz.x, sz.y );
2220
2221 wxString html_txt;
2222 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
2223 dlg->AddHTML_Text( html_txt );
2224 dlg->ShowModeless();
2225
2226 return dlg;
2227}
2228
2229
2230static struct SCH_LABEL_DESC
2231{
2233 {
2234 auto& labelShapeEnum = ENUM_MAP<LABEL_SHAPE>::Instance();
2235
2236 if( labelShapeEnum.Choices().GetCount() == 0 )
2237 {
2238 labelShapeEnum.Map( LABEL_SHAPE::LABEL_INPUT, _HKI( "Input" ) )
2239 .Map( LABEL_SHAPE::LABEL_OUTPUT, _HKI( "Output" ) )
2240 .Map( LABEL_SHAPE::LABEL_BIDI, _HKI( "Bidirectional" ) )
2241 .Map( LABEL_SHAPE::LABEL_TRISTATE, _HKI( "Tri-state" ) )
2242 .Map( LABEL_SHAPE::LABEL_PASSIVE, _HKI( "Passive" ) );
2243 }
2244
2249
2253
2257
2261
2266
2267 auto hasLabelShape =
2268 []( INSPECTABLE* aItem ) -> bool
2269 {
2270 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aItem ) )
2271 return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T } );
2272
2273 return false;
2274 };
2275
2276 propMgr.AddProperty( new PROPERTY_ENUM<SCH_LABEL_BASE, LABEL_SHAPE>( _HKI( "Shape" ),
2278 .SetAvailableFunc( hasLabelShape );
2279
2280 propMgr.Mask( TYPE_HASH( SCH_LABEL_BASE ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
2281 }
2283
2284
2286{
2288 {
2289 auto& flagShapeEnum = ENUM_MAP<FLAG_SHAPE>::Instance();
2290
2291 if( flagShapeEnum.Choices().GetCount() == 0 )
2292 {
2293 flagShapeEnum.Map( FLAG_SHAPE::FLAG_DOT, _HKI( "Dot" ) )
2294 .Map( FLAG_SHAPE::FLAG_CIRCLE, _HKI( "Circle" ) )
2295 .Map( FLAG_SHAPE::FLAG_DIAMOND, _HKI( "Diamond" ) )
2296 .Map( FLAG_SHAPE::FLAG_RECTANGLE, _HKI( "Rectangle" ) );
2297 }
2298
2304
2306
2309
2310 propMgr.AddProperty( new PROPERTY<SCH_DIRECTIVE_LABEL, int>( _HKI( "Pin length" ),
2312 PROPERTY_DISPLAY::PT_SIZE ) );
2313
2314 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Text" ) );
2315 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
2316 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Italic" ) );
2317 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Bold" ) );
2319 _HKI( "Horizontal Justification" ) );
2321 _HKI( "Vertical Justification" ) );
2322 }
2324
2325
int color
Definition: DXF_plotter.cpp:58
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
void SetOrigin(const Vec &pos)
Definition: box2.h:227
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:136
int GetSizeMax() const
Definition: box2.h:225
const Vec & GetOrigin() const
Definition: box2.h:200
void Offset(coord_type dx, coord_type dy)
Definition: box2.h:249
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:294
size_type GetWidth() const
Definition: box2.h:204
const Vec GetEnd() const
Definition: box2.h:202
bool Contains(const Vec &aPoint) const
Definition: box2.h:158
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:541
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:280
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:623
static std::vector< DANGLING_END_ITEM >::iterator get_lower_type(std::vector< DANGLING_END_ITEM > &aItemListByType, const DANGLING_END_T &aType)
Definition: sch_item.cpp:594
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition: sch_item.cpp:583
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:95
DANGLING_END_T GetType() const
Definition: sch_item.h:139
EDA_ITEM * GetItem() const
Definition: sch_item.h:137
VECTOR2I GetPosition() const
Definition: sch_item.h:136
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition: eda_item.h:485
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:375
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:103
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:488
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:83
int GetTextHeight() const
Definition: eda_text.h:228
const VECTOR2I & GetTextPos() const
Definition: eda_text.h:234
COLOR4D GetTextColor() const
Definition: eda_text.h:231
bool IsItalic() const
Definition: eda_text.h:144
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:417
void SetTextX(int aX)
Definition: eda_text.cpp:423
KIFONT::FONT * GetFont() const
Definition: eda_text.h:211
BOX2I GetTextBox(int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition: eda_text.cpp:565
void SetTextY(int aY)
Definition: eda_text.cpp:429
int GetTextWidth() const
Definition: eda_text.h:225
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:274
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:164
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition: eda_text.cpp:343
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition: eda_text.h:117
virtual void cacheShownText()
Definition: eda_text.cpp:462
const TEXT_ATTRIBUTES & GetAttributes() const
Definition: eda_text.h:195
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition: eda_text.cpp:322
bool IsBold() const
Definition: eda_text.h:148
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:109
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:181
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:203
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, const COLOR4D &aColor, OUTLINE_MODE aDisplay_mode=FILLED)
Print this text object to the device context aDC.
Definition: eda_text.cpp:724
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.cpp:258
VECTOR2I GetTextSize() const
Definition: eda_text.h:222
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:266
static ENUM_MAP< T > & Instance()
Definition: property.h:663
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:36
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:146
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
int GetDefaultPenWidth() const
const wxString & GetDefaultFont() const
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:263
Base plotter engine class.
Definition: plotter.h:104
virtual void ThickCircle(const VECTOR2I &pos, int diametre, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:646
virtual void FilledCircle(const VECTOR2I &pos, int diametre, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:662
void MoveTo(const VECTOR2I &pos)
Definition: plotter.h:243
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:135
virtual void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString)
Create a bookmark to a symbol.
Definition: plotter.h:475
bool GetColorMode() const
Definition: plotter.h:132
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:248
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
void PenFinish()
Definition: plotter.h:259
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:464
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics, void *aData=nullptr)
Definition: plotter.cpp:753
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
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()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
These settings were stored in SCH_BASE_FRAME previously.
Holds all the data relating to one schematic.
Definition: schematic.h:75
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:136
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:701
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:287
std::map< wxString, std::set< int > > & GetPageRefsMap()
Definition: schematic.h:177
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
Definition: schematic.cpp:462
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
Definition: schematic.cpp:446
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:411
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString LocalName() const
wxString Name(bool aIgnoreSheet=false) const
bool IsBus() const
void AppendInfoToMsgPanel(std::vector< MSG_PANEL_ITEM > &aList) const
Adds information about the connection object to aList.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:1572
void MirrorSpinStyle(bool aLeftRight) override
Definition: sch_label.cpp:1596
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_label.cpp:1553
void RemoveConnectedRuleArea(SCH_RULE_AREA *aRuleArea)
Removes a specific rule area from the cache.
Definition: sch_label.cpp:1823
void ClearConnectedRuleAreas()
Removes all rule areas from the cache.
Definition: sch_label.cpp:1817
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:1654
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:1627
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:1746
SCH_DIRECTIVE_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0))
Definition: sch_label.cpp:1542
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:1578
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.
Definition: sch_label.cpp:1676
FLAG_SHAPE GetFlagShape() const
Definition: sch_label.h:455
int GetPenWidth() const override
Definition: sch_label.cpp:1585
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:496
void SetPinLength(int aLength)
Definition: sch_label.h:459
virtual bool IsDangling() const override
Determines dangling state from connectivity and cached connected rule areas.
Definition: sch_label.cpp:1829
void AddConnectedRuleArea(SCH_RULE_AREA *aRuleArea)
Adds an entry to the connected rule area cache.
Definition: sch_label.cpp:1811
void SetFlagShape(FLAG_SHAPE aShape)
Definition: sch_label.h:456
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:1796
int GetPinLength() const
Definition: sch_label.h:458
Schematic editor (Eeschema) main window.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
Definition: sch_field.cpp:1143
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_label.cpp:1969
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.
Definition: sch_label.cpp:1981
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const override
Resolve any references to system tokens supported by the label.
Definition: sch_label.cpp:1910
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...
Definition: sch_label.cpp:1871
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
Definition: sch_label.cpp:1903
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:2049
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:1864
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:1858
SCH_GLOBALLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
Definition: sch_label.cpp:1835
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:2056
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:2077
const BOX2I GetBodyBoundingBox() const override
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:2123
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
Definition: sch_label.cpp:2084
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.
Definition: sch_label.cpp:2091
SCH_HIERLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString, KICAD_T aType=SCH_HIER_LABEL_T)
Definition: sch_label.cpp:2062
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:2203
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:2071
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...
Definition: sch_label.cpp:2176
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:2196
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:174
virtual bool IsConnectable() const
Definition: sch_item.h:457
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition: sch_item.cpp:100
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:139
void AddConnectionTo(const SCH_SHEET_PATH &aPath, SCH_ITEM *aItem)
Add a connection link between this item and another.
Definition: sch_item.cpp:275
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition: sch_item.cpp:239
void ClearFieldsAutoplaced()
Definition: sch_item.h:559
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:735
bool IsConnectivityDirty() const
Definition: sch_item.h:518
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:210
const KIFONT::METRICS & GetFontMetrics() const
Definition: sch_item.cpp:455
std::map< SCH_SHEET_PATH, SCH_ITEM_VEC, SHEET_PATH_CMP > m_connected_items
Store pointers to other items that are connected to this one, per sheet.
Definition: sch_item.h:740
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
Definition: sch_item.cpp:464
SCH_LAYER_ID m_layer
Definition: sch_item.h:731
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:189
bool operator==(const SCH_ITEM &aItem) const override
Definition: sch_label.cpp:576
const wxString & GetCachedDriverName() const override
Definition: sch_label.cpp:877
SCH_LABEL_BASE(const VECTOR2I &aPos, const wxString &aText, KICAD_T aType)
Definition: sch_label.cpp:205
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_label.cpp:978
COLOR4D m_lastResolvedColor
Definition: sch_label.h:368
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
Definition: sch_label.cpp:892
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_label.cpp:419
void Print(const SCH_RENDER_SETTINGS *aSettings, int aUnit, int aBodyStyle, const VECTOR2I &offset, bool aForceNoFill, bool aDimmed) override
Print an item.
Definition: sch_label.cpp:1409
bool m_isDangling
Definition: sch_label.h:365
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...
Definition: sch_label.cpp:940
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_label.cpp:924
bool HasCachedDriverName() const override
Definition: sch_label.cpp:871
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_label.cpp:1047
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
Definition: sch_label.cpp:965
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1454
SCH_LABEL_BASE & operator=(const SCH_LABEL_BASE &aLabel)
Definition: sch_label.cpp:237
std::vector< SCH_FIELD > m_fields
Definition: sch_label.h:360
CONNECTION_TYPE m_connectionType
Definition: sch_label.h:364
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:524
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.
Definition: sch_label.cpp:1309
void SetLabelShape(LABEL_SHAPE aShape)
Definition: sch_label.h:177
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
Definition: sch_label.cpp:1214
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_label.cpp:305
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:373
void GetIntersheetRefs(const SCH_SHEET_PATH *aPath, std::vector< std::pair< wxString, wxString > > *pages)
Builds an array of { pageNumber, pageName } pairs.
Definition: sch_label.cpp:710
void MirrorSpinStyle(bool aLeftRight) override
Definition: sch_label.cpp:496
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Definition: sch_label.cpp:972
COLOR4D GetLabelColor() const
Definition: sch_label.cpp:327
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:172
const BOX2I GetBoundingBox() const override
Return the bounding box of the label including its fields.
Definition: sch_label.cpp:1022
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_label.cpp:260
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:543
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_label.cpp:412
virtual bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const
Resolve any references to system tokens supported by the label.
Definition: sch_label.cpp:760
LABEL_SHAPE GetLabelShape() const
Definition: sch_label.h:176
bool m_autoRotateOnPlacement
Definition: sch_label.h:366
wxString m_cached_driver_name
Definition: sch_label.h:370
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_label.cpp:428
int GetLabelBoxExpansion(const RENDER_SETTINGS *aSettings=nullptr) const
Definition: sch_label.cpp:989
bool IncrementLabel(int aIncrement)
Increment the label text, if it ends with a number.
Definition: sch_label.cpp:562
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1460
void cacheShownText() override
Definition: sch_label.cpp:883
void Rotate90(bool aClockwise) override
Definition: sch_label.cpp:443
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.
Definition: sch_label.cpp:1251
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:247
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:639
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
Definition: sch_label.cpp:917
LABEL_FLAG_SHAPE m_shape
Definition: sch_label.h:362
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this label.
Definition: sch_label.cpp:747
virtual const BOX2I GetBodyBoundingBox() const
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:1004
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:290
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:196
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.
Definition: sch_label.cpp:1108
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...
Definition: sch_label.cpp:392
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:338
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 ...
Definition: sch_label.cpp:930
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_label.cpp:602
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_label.cpp:1486
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:1529
SCH_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
Definition: sch_label.cpp:1466
const BOX2I GetBodyBoundingBox() const override
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:1500
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:1536
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_label.cpp:1475
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
int GetVirtualPageNumber() const
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
Definition: sch_sheet.cpp:237
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_text.h:106
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_text.cpp:157
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:2209
VECTOR2I GetPosition() const override
Definition: sch_text.h:141
virtual void Rotate90(bool aClockwise)
Definition: sch_text.cpp:208
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_text.cpp:118
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:685
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_text.cpp:230
int GetPenWidth() const override
Definition: sch_text.cpp:281
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:220
bool operator==(const SCH_ITEM &aItem) const override
Definition: sch_text.cpp:668
int GetTextOffset(const RENDER_SETTINGS *aSettings=nullptr) const
Definition: sch_text.cpp:266
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
Definition: sch_label.cpp:173
SPIN m_spin
Definition: sch_label.h:85
SPIN_STYLE()=default
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
Definition: sch_label.cpp:189
SPIN_STYLE RotateCCW()
Definition: sch_label.cpp:157
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:58
#define DEFAULT_LABEL_SIZE_RATIO
The offset of the pin name string from the end of the pin in mils.
#define DANGLING_SYMBOL_SIZE
< The size of the rectangle indicating an unconnected wire or label
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:437
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:432
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:431
static constexpr EDA_ANGLE ANGLE_270
Definition: eda_angle.h:440
static constexpr EDA_ANGLE ANGLE_180
Definition: eda_angle.h:439
INSPECT_RESULT
Definition: eda_item.h:43
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:81
void GRCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aColor)
Definition: gr_basic.cpp:357
void GRLine(wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:171
static const bool FILLED
Definition: gr_basic.cpp:30
void GRPoly(wxDC *DC, int n, const VECTOR2I *Points, bool Fill, int width, const COLOR4D &Color, const COLOR4D &BgColor)
Draw a new polyline and fill it if Fill, in drawing space.
Definition: gr_basic.cpp:341
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:165
void GRFilledCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aStrokeColor, const COLOR4D &aFillColor)
Draw a circle onto the drawing context aDC centered at the user coordinates (x,y).
Definition: gr_basic.cpp:369
@ NONE
Definition: kibis.h:54
@ LAYER_DANGLING
Definition: layer_ids.h:381
@ LAYER_DEVICE
Definition: layer_ids.h:370
@ LAYER_HIERLABEL
Definition: layer_ids.h:361
@ LAYER_GLOBLABEL
Definition: layer_ids.h:360
@ LAYER_NOTES
Definition: layer_ids.h:371
@ LAYER_BUS
Definition: layer_ids.h:357
@ LAYER_FIELDS
Definition: layer_ids.h:366
@ LAYER_LOCLABEL
Definition: layer_ids.h:359
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:368
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:395
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:367
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
T MIRRORVAL(T aPoint, T aMirrorRef)
Returns the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:31
Message panel definition file.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:213
void delete_matching(_Container &__c, _Value __value)
Covers for the horrifically named std::remove and std::remove_if (neither of which remove anything).
Definition: kicad_algo.h:165
void PackVector2(kiapi::common::types::Vector2 &aOutput, const VECTOR2I aInput)
Definition: api_utils.cpp:69
VECTOR2I UnpackVector2(const types::Vector2 &aInput)
Definition: api_utils.cpp:75
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:424
see class PGM_BASE
#define TYPE_HASH(x)
Definition: property.h:71
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:765
#define REGISTER_TYPE(x)
Definition: property_mgr.h:366
CONNECTION_TYPE
@ NO_CONNECT_END
Definition: sch_item.h:86
@ SHEET_LABEL_END
Definition: sch_item.h:85
@ LABEL_END
Definition: sch_item.h:82
@ BUS_END
Definition: sch_item.h:79
@ PIN_END
Definition: sch_item.h:81
@ WIRE_END
Definition: sch_item.h:78
std::vector< SCH_ITEM * > SCH_ITEM_VEC
Definition: sch_item.h:163
@ FIELDS_AUTOPLACED_AUTO
Definition: sch_item.h:70
static int TemplateIN_HI[]
Definition: sch_label.cpp:109
static int TemplateUNSPC_HI[]
Definition: sch_label.cpp:119
static int TemplateOUT_HN[]
Definition: sch_label.cpp:113
static int Template3STATE_HN[]
Definition: sch_label.cpp:128
static int TemplateBIDI_HN[]
Definition: sch_label.cpp:123
static int * TemplateShape[5][4]
Definition: sch_label.cpp:133
bool IncrementLabelMember(wxString &name, int aIncrement)
Definition: sch_label.cpp:51
static int TemplateIN_HN[]
Definition: sch_label.cpp:108
static int TemplateIN_BOTTOM[]
Definition: sch_label.cpp:111
static int TemplateUNSPC_HN[]
Definition: sch_label.cpp:118
static int Template3STATE_BOTTOM[]
Definition: sch_label.cpp:131
static int TemplateBIDI_BOTTOM[]
Definition: sch_label.cpp:126
static struct SCH_LABEL_DESC _SCH_LABEL_DESC
static int Template3STATE_UP[]
Definition: sch_label.cpp:130
static int TemplateOUT_UP[]
Definition: sch_label.cpp:115
static int TemplateOUT_HI[]
Definition: sch_label.cpp:114
static int TemplateUNSPC_UP[]
Definition: sch_label.cpp:120
static int TemplateUNSPC_BOTTOM[]
Definition: sch_label.cpp:121
static int TemplateOUT_BOTTOM[]
Definition: sch_label.cpp:116
static int Template3STATE_HI[]
Definition: sch_label.cpp:129
static int TemplateIN_UP[]
Definition: sch_label.cpp:110
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition: sch_label.cpp:143
static int TemplateBIDI_UP[]
Definition: sch_label.cpp:125
static int TemplateBIDI_HI[]
Definition: sch_label.cpp:124
static struct SCH_DIRECTIVE_LABEL_DESC _SCH_DIRECTIVE_LABEL_DESC
FLAG_SHAPE
Definition: sch_label.h:120
LABEL_FLAG_SHAPE
Definition: sch_label.h:93
@ L_BIDI
Definition: sch_label.h:96
@ L_TRISTATE
Definition: sch_label.h:97
@ L_UNSPECIFIED
Definition: sch_label.h:98
@ L_OUTPUT
Definition: sch_label.h:95
@ L_INPUT
Definition: sch_label.h:94
LABEL_SHAPE
Definition: sch_label.h:111
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
Definition: string_utils.h:53
void ConvertMarkdown2Html(const wxString &aMarkdownInput, wxString &aHtmlOutput)
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
wxString replaceString
bool m_PDFPropertyPopups
Definition: sch_plotter.h:91
constexpr 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:174
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:228
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:128
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:171
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:198
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:190
@ SCH_LABEL_LOCATE_WIRE_T
Definition: typeinfo.h:191
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:173
@ SCH_LABEL_LOCATE_BUS_T
Definition: typeinfo.h:192
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:118
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588