KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_label_properties.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) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2013 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 1992-2023 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
27#include <widgets/font_choice.h>
31#include <sch_edit_frame.h>
32#include <tool/tool_manager.h>
33#include <gr_text.h>
34#include <confirm.h>
35#include <schematic.h>
38#include <string_utils.h>
39#include <kiface_base.h>
40#include <sch_label.h>
41#include <sch_commit.h>
42
43
46 m_Parent( aParent ),
47 m_currentLabel( aLabel ),
48 m_activeTextEntry( nullptr ),
49 m_netNameValidator( true ),
50 m_fields( nullptr ),
51 m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false ),
52 m_helpWindow( nullptr )
53{
54 COLOR_SETTINGS* colorSettings = m_Parent->GetColorSettings();
55 COLOR4D schematicBackground = colorSettings->GetColor( LAYER_SCHEMATIC_BACKGROUND );
56
58 m_width = 100; // Will be later set to a better value
61
63 {
66
67 m_labelSingleLine->Show( false );
68 m_valueSingleLine->Show( false );
69
70 m_valueCombo->SetValidator( m_netNameValidator );
71 }
72 else if( m_currentLabel->Type() == SCH_HIER_LABEL_T )
73 {
76
77 m_labelCombo->Show( false );
78 m_valueCombo->Show( false );
79
81 }
83 {
86
87 m_labelSingleLine->Show( false );
88 m_valueSingleLine->Show( false );
89 m_labelCombo->Show( false );
90 m_valueCombo->Show( false );
91 m_syntaxHelp->Show( false );
92 m_textEntrySizer->Show( false );
93
94 m_textSizeLabel->SetLabel( _( "Pin length:" ) );
95 }
96
97 switch( m_currentLabel->Type() )
98 {
99 case SCH_GLOBAL_LABEL_T: SetTitle( _( "Global Label Properties" ) ); break;
100 case SCH_HIER_LABEL_T: SetTitle( _( "Hierarchical Label Properties" ) ); break;
101 case SCH_LABEL_T: SetTitle( _( "Label Properties" ) ); break;
102 case SCH_DIRECTIVE_LABEL_T: SetTitle( _( "Directive Label Properties" ) ); break;
103 case SCH_SHEET_PIN_T: SetTitle( _( "Hierarchical Sheet Pin Properties" ) ); break;
104 default: UNIMPLEMENTED_FOR( m_currentLabel->GetClass() ); break;
105 }
106
107 // Give a bit more room for combobox editors
108 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
109
111 m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this,
112 [&]( wxCommandEvent& aEvent )
113 {
114 OnAddField( aEvent );
115 } ) );
116 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
117
118 // Show/hide columns according to user's preference
119 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
120 {
121 m_grid->ShowHideColumns( cfg->m_Appearance.edit_label_visible_columns );
123 }
124
125 // Configure button logos
126 m_bpAdd->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
127 m_bpDelete->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
128 m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
129 m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
130
132
134 m_bold->SetBitmap( KiBitmapBundle( BITMAPS::text_bold ) );
136 m_italic->SetBitmap( KiBitmapBundle( BITMAPS::text_italic ) );
137
139
144
146
147 m_textColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
148 m_textColorSwatch->SetSwatchBackground( schematicBackground );
149
150 // Show/hide relevant controls
152 {
153 m_dot->Hide();
154 m_circle->Hide();
155 m_diamond->Hide();
156 m_rectangle->Hide();
157
158 m_spin0->SetBitmap( KiBitmapBundle( BITMAPS::label_align_left ) );
159 m_spin1->SetBitmap( KiBitmapBundle( BITMAPS::label_align_right ) );
160 m_spin2->SetBitmap( KiBitmapBundle( BITMAPS::label_align_bottom ) );
161 m_spin3->SetBitmap( KiBitmapBundle( BITMAPS::label_align_top ) );
162 }
164 {
165 m_input->Hide();
166 m_output->Hide();
167 m_bidirectional->Hide();
168 m_triState->Hide();
169 m_passive->Hide();
170
171 m_fontLabel->SetLabel( _( "Orientation:" ) );
172 m_fontCtrl->Hide();
173 m_separator1->Hide();
174 m_bold->Hide();
175 m_italic->Hide();
176 m_separator2->Hide();
177 m_spin0->SetBitmap( KiBitmapBundle( BITMAPS::pinorient_down ) );
178 m_spin1->SetBitmap( KiBitmapBundle( BITMAPS::pinorient_up ) );
179 m_spin2->SetBitmap( KiBitmapBundle( BITMAPS::pinorient_right ) );
180 m_spin3->SetBitmap( KiBitmapBundle( BITMAPS::pinorient_left ) );
181 m_separator3->Hide();
182
183 m_formattingGB->Detach( m_fontCtrl );
184 m_formattingGB->Detach( m_iconBar );
185 m_formattingGB->Add( m_iconBar, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxRIGHT, 5 );
186 }
187 else
188 {
189 m_shapeSizer->Show( false );
190
191 m_spin0->SetBitmap( KiBitmapBundle( BITMAPS::text_align_left ) );
192 m_spin1->SetBitmap( KiBitmapBundle( BITMAPS::text_align_right ) );
193 m_spin2->SetBitmap( KiBitmapBundle( BITMAPS::text_align_bottom ) );
194 m_spin3->SetBitmap( KiBitmapBundle( BITMAPS::text_align_top ) );
195 }
196
198 {
199 m_autoRotate->Hide();
200 wxSizer* parentSizer = m_autoRotate->GetContainingSizer();
201 parentSizer->Detach( m_autoRotate );
202 parentSizer->Layout();
203 }
204
206
207 // DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
208 // various versions have different controls so we want to store sizes for each version.
209 m_hash_key = TO_UTF8( GetTitle() );
210
211 m_spin0->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
212 m_spin1->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
213 m_spin2->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
214 m_spin3->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
215
216 // Now all widgets have the size fixed, call FinishDialogSettings
218
219 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
220 {
221 if( cfg->m_Appearance.edit_label_width > 0 && cfg->m_Appearance.edit_label_height > 0 )
222 SetSize( cfg->m_Appearance.edit_label_width, cfg->m_Appearance.edit_label_height );
223 }
224}
225
226
228{
229 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
230 {
231 cfg->m_Appearance.edit_label_visible_columns = m_grid->GetShownColumnsAsString();
232 cfg->m_Appearance.edit_label_width = GetSize().x;
233 cfg->m_Appearance.edit_label_height = GetSize().y;
234 }
235
236 // Prevents crash bug in wxGrid's d'tor
238
239 // Delete the GRID_TRICKS.
240 m_grid->PopEventHandler( true );
241
242 if( m_helpWindow )
243 m_helpWindow->Destroy();
244}
245
246
248{
249 if( !wxDialog::TransferDataToWindow() )
250 return false;
251
253 {
254 // show control characters in a human-readable format
255 wxString text = UnescapeString( m_currentLabel->GetText() );
256
257 // show text variable cross-references in a human-readable format
259
260 m_activeTextEntry->SetValue( text );
261 }
262
264 {
265 // Load the combobox with the existing labels of the same type
266 std::set<wxString> existingLabels;
267 std::vector<std::shared_ptr<BUS_ALIAS>> busAliases;
268 SCH_SCREENS allScreens( m_Parent->Schematic().Root() );
269
270 for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
271 {
272 for( SCH_ITEM* item : screen->Items().OfType( m_currentLabel->Type() ) )
273 {
274 const SCH_LABEL_BASE* label = static_cast<const SCH_LABEL_BASE*>( item );
275 existingLabels.insert( UnescapeString( label->GetText() ) );
276 }
277
278 // Add global power labels from power symbols
280 {
281 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_LOCATE_POWER_T ) )
282 {
283 const SCH_SYMBOL* power = static_cast<const SCH_SYMBOL*>( item );
284
285 // Ensure the symbol has the Power (i.e. equivalent to a global label
286 // before adding its value in list
287 if( power->IsSymbolLikePowerGlobalLabel() )
288 existingLabels.insert( UnescapeString( power->GetField( VALUE_FIELD )->GetText() ) );
289 }
290 }
291
292 auto& sheetAliases = screen->GetBusAliases();
293 busAliases.insert( busAliases.end(), sheetAliases.begin(), sheetAliases.end() );
294 }
295
296 // Add bus aliases to label list
297 for( const std::shared_ptr<BUS_ALIAS>& busAlias : busAliases )
298 existingLabels.insert( wxT( "{" ) + busAlias->GetName() + wxT( "}" ) );
299
300 wxArrayString existingLabelArray;
301
302 for( const wxString& label : existingLabels )
303 existingLabelArray.push_back( label );
304
305 m_valueCombo->Append( existingLabelArray );
306 }
307
308 // Push a copy of each field into m_updateFields
309 for( SCH_FIELD& field : m_currentLabel->GetFields() )
310 {
311 SCH_FIELD field_copy( field );
312
313 // change offset to be symbol-relative
314 field_copy.Offset( -m_currentLabel->GetPosition() );
315
316 m_fields->push_back( field_copy );
317 }
318
319 // notify the grid
320 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->size() );
321 m_grid->ProcessTableMessage( msg );
322 AdjustGridColumns( m_grid->GetRect().GetWidth() );
323
324 if( m_shapeSizer->AreAnyItemsShown() )
325 {
326 switch( m_currentLabel->GetShape() )
327 {
328 case LABEL_FLAG_SHAPE::L_INPUT: m_input->SetValue( true ); break;
329 case LABEL_FLAG_SHAPE::L_OUTPUT: m_output->SetValue( true ); break;
330 case LABEL_FLAG_SHAPE::L_BIDI: m_bidirectional->SetValue( true ); break;
331 case LABEL_FLAG_SHAPE::L_TRISTATE: m_triState->SetValue( true ); break;
332 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: m_passive->SetValue( true ); break;
333 case LABEL_FLAG_SHAPE::F_DOT: m_dot->SetValue( true ); break;
334 case LABEL_FLAG_SHAPE::F_ROUND: m_circle->SetValue( true ); break;
335 case LABEL_FLAG_SHAPE::F_DIAMOND: m_diamond->SetValue( true ); break;
336 case LABEL_FLAG_SHAPE::F_RECTANGLE: m_rectangle->SetValue( true ); break;
337 }
338 }
339
341
343 m_textSize.SetValue( static_cast<SCH_DIRECTIVE_LABEL*>( m_currentLabel )->GetPinLength() );
344 else
346
350
351 switch( m_currentLabel->GetSpinStyle() )
352 {
353 case SPIN_STYLE::RIGHT: m_spin0->Check( true ); break;
354 case SPIN_STYLE::LEFT: m_spin1->Check( true ); break;
355 case SPIN_STYLE::UP: m_spin2->Check( true ); break;
356 case SPIN_STYLE::BOTTOM: m_spin3->Check( true ); break;
357 }
358
361
362 return true;
363}
364
365
369void DIALOG_LABEL_PROPERTIES::OnEnterKey( wxCommandEvent& aEvent )
370{
371 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
372}
373
374
376{
377 if( aEvent.GetKeyCode() == WXK_TAB )
378 {
379 if( aEvent.ShiftDown() )
380 {
381 m_textSizeCtrl->SetFocusFromKbd();
382 }
383 else if( !m_fields->empty() )
384 {
385 m_grid->SetFocusFromKbd();
386 m_grid->MakeCellVisible( 0, 0 );
387 m_grid->SetGridCursor( 0, 0 );
388 }
389 else
390 {
391 m_textSizeCtrl->SetFocusFromKbd();
392 }
393 }
394 else
395 {
396 aEvent.Skip();
397 }
398}
399
400
401static bool positioningChanged( const SCH_FIELD& a, const SCH_FIELD& b )
402{
403 return a.GetPosition() != b.GetPosition()
404 || a.GetHorizJustify() != b.GetHorizJustify()
405 || a.GetVertJustify() != b.GetVertJustify()
406 || a.GetTextAngle() != b.GetTextAngle();
407}
408
409
410static bool positioningChanged( FIELDS_GRID_TABLE<SCH_FIELD>* a, std::vector<SCH_FIELD>& b )
411{
412 for( size_t i = 0; i < a->size() && i < b.size(); ++i )
413 {
414 if( positioningChanged( a->at( i ), b.at( i ) ) )
415 return true;
416 }
417
418 return false;
419}
420
421
423{
425 return false;
426
427 if( !wxDialog::TransferDataFromWindow() )
428 return false;
429
430 // Don't allow text to disappear; it can be difficult to correct if you can't select it
431 if( !m_textSize.Validate( 0.01, 1000.0, EDA_UNITS::MILLIMETRES ) )
432 return false;
433
434 SCH_COMMIT commit( m_Parent );
435 wxString text;
436
437 /* save old text in undo list if not already in edit */
438 if( m_currentLabel->GetEditFlags() == 0 )
440
442
444 {
445 // labels need escaping
447
448 // convert any text variable cross-references to their UUIDs
450
451#ifdef __WXMAC__
452 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting
453 text.Replace( wxS( "\r" ), wxS( "\n" ) );
454#endif
455
456 if( text.IsEmpty() && !m_currentLabel->IsNew() )
457 {
458 DisplayError( this, _( "Label can not be empty." ) );
459 return false;
460 }
461
463 }
464
465 bool doAutoplace = false;
466
467 // change all field positions from relative to absolute
468 for( SCH_FIELD& field : *m_fields )
469 {
470 field.Offset( m_currentLabel->GetPosition() );
471
472 if( field.GetCanonicalName() == wxT( "Netclass" ) )
473 {
474 field.SetLayer( LAYER_NETCLASS_REFS );
475 }
476 else if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
477 {
478 if( field.IsVisible() != m_Parent->Schematic().Settings().m_IntersheetRefsShow )
479 {
480 DisplayInfoMessage( this, _( "Intersheet reference visibility is "
481 "controlled globally from "
482 "Schematic Setup > General > Formatting" ) );
483 }
484
485 field.SetLayer( LAYER_INTERSHEET_REFS );
486 }
487 else
488 {
489 field.SetLayer( LAYER_FIELDS );
490 }
491 }
492
495 else
496 doAutoplace = true;
497
498 for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
499 {
500 SCH_FIELD& field = m_fields->at( ii );
501 const wxString& fieldName = field.GetCanonicalName();
502 const wxString& fieldText = field.GetText();
503
504 if( fieldName.IsEmpty() && fieldText.IsEmpty() )
505 m_fields->erase( m_fields->begin() + ii );
506 else if( fieldName == wxT( "Netclass" ) && fieldText.IsEmpty() )
507 m_fields->erase( m_fields->begin() + ii );
508 else if( fieldName.IsEmpty() )
509 field.SetName( _( "untitled" ) );
510 }
511
513
514 if( m_shapeSizer->AreAnyItemsShown() )
515 {
516 if( m_bidirectional->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
517 else if( m_input->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
518 else if( m_output->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
519 else if( m_triState->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
520 else if( m_passive->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
521 else if( m_dot->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DOT );
522 else if( m_circle->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
523 else if( m_diamond->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
524 else if( m_rectangle->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
525 }
526
528 {
530 m_italic->IsChecked() ) );
531 }
532
534 static_cast<SCH_DIRECTIVE_LABEL*>( m_currentLabel )->SetPinLength( m_textSize.GetValue() );
537
539 {
540 if( m_bold->IsChecked() )
541 {
542 m_currentLabel->SetBold( true );
544 }
545 else
546 {
547 m_currentLabel->SetBold( false );
548 m_currentLabel->SetTextThickness( 0 ); // Use default pen width
549 }
550 }
551
553
555
556 SPIN_STYLE selectedSpinStyle= SPIN_STYLE::LEFT;
557
558 if( m_spin0->IsChecked() ) selectedSpinStyle = SPIN_STYLE::RIGHT;
559 else if( m_spin1->IsChecked() ) selectedSpinStyle = SPIN_STYLE::LEFT;
560 else if( m_spin2->IsChecked() ) selectedSpinStyle = SPIN_STYLE::UP;
561 else if( m_spin3->IsChecked() ) selectedSpinStyle = SPIN_STYLE::BOTTOM;
562
564 {
565 SCH_EDIT_FRAME* frame = static_cast<SCH_EDIT_FRAME*>( m_parentFrame );
567 frame->AutoRotateItem( frame->GetScreen(), m_currentLabel );
568 }
569 else
570 {
572 }
573
575 && m_currentLabel->GetSpinStyle() != selectedSpinStyle )
576 {
577 m_currentLabel->SetSpinStyle( selectedSpinStyle );
578 }
579
580 if( doAutoplace )
582
583 if( !commit.Empty() )
584 commit.Push( _( "Edit Label" ), SKIP_CONNECTIVITY );
585
586 return true;
587}
588
589
590void DIALOG_LABEL_PROPERTIES::onSpinButton( wxCommandEvent& aEvent )
591{
592 for( BITMAP_BUTTON* btn : { m_spin0, m_spin1, m_spin2, m_spin3 } )
593 {
594 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
595 btn->Check( false );
596 }
597}
598
599
600void DIALOG_LABEL_PROPERTIES::OnFormattingHelp( wxHyperlinkEvent& aEvent )
601{
603}
604
605
606void DIALOG_LABEL_PROPERTIES::OnAddField( wxCommandEvent& event )
607{
609 return;
610
611 int fieldID = (int) m_fields->size();
612 wxString fieldName;
613
614 if( (int) fieldID == m_currentLabel->GetMandatoryFieldCount()
615 || m_fields->at( m_fields->size()-1 ).GetCanonicalName() == wxT( "Netclass" ) )
616 {
617 fieldName = wxT( "Netclass" );
618 }
619 else
620 {
621 fieldName = SCH_LABEL_BASE::GetDefaultFieldName( fieldName, true );
622 }
623
624 SCH_FIELD newField( VECTOR2I( 0, 0 ), fieldID, m_currentLabel, fieldName );
625
626 if( m_fields->size() > 0 )
627 {
628 newField.SetVisible( m_fields->at( m_fields->size() - 1 ).IsVisible() );
629 newField.SetTextAngle( m_fields->at( m_fields->size() - 1 ).GetTextAngle() );
630 newField.SetItalic( m_fields->at( m_fields->size() - 1 ).IsItalic() );
631 newField.SetBold( m_fields->at( m_fields->size() - 1 ).IsBold() );
632 }
633 else
634 {
635 newField.SetVisible( true );
636 newField.SetItalic( true );
637 }
638
639 m_fields->push_back( newField );
640
641 // notify the grid
642 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
643 m_grid->ProcessTableMessage( msg );
644
645 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
646 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
647
648 m_grid->EnableCellEditControl();
649 m_grid->ShowCellEditControl();
650}
651
652
653void DIALOG_LABEL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
654{
655 wxArrayInt selectedRows = m_grid->GetSelectedRows();
656
657 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
658 selectedRows.push_back( m_grid->GetGridCursorRow() );
659
660 if( selectedRows.empty() )
661 return;
662
663 for( int row : selectedRows )
664 {
665 if( row < m_currentLabel->GetMandatoryFieldCount() )
666 {
667 DisplayError( this, _( "The first field is mandatory." ) );
668 return;
669 }
670 }
671
672 m_grid->CommitPendingChanges( true /* quiet mode */ );
673
674 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
675 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
676
677 for( int row : selectedRows )
678 {
679 m_fields->erase( m_fields->begin() + row );
680
681 // notify the grid
682 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
683 m_grid->ProcessTableMessage( msg );
684
685 if( m_grid->GetNumberRows() > 0 )
686 {
687 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
688 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
689 }
690 }
691}
692
693
694void DIALOG_LABEL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
695{
697 return;
698
699 int i = m_grid->GetGridCursorRow();
700
702 {
703 SCH_FIELD tmp = m_fields->at( (unsigned) i );
704 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
705 m_fields->insert( m_fields->begin() + i - 1, tmp );
706 m_grid->ForceRefresh();
707
708 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
709 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
710 }
711 else
712 {
713 wxBell();
714 }
715}
716
717
718void DIALOG_LABEL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
719{
721 return;
722
723 int i = m_grid->GetGridCursorRow();
724
725 if( i >= m_currentLabel->GetMandatoryFieldCount() && i < m_grid->GetNumberRows() - 1 )
726 {
727 SCH_FIELD tmp = m_fields->at( (unsigned) i );
728 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
729 m_fields->insert( m_fields->begin() + i + 1, tmp );
730 m_grid->ForceRefresh();
731
732 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
733 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
734 }
735 else
736 {
737 wxBell();
738 }
739}
740
741
743{
744 m_width = aWidth;
745 // Account for scroll bars
746 aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
747
748 m_grid->AutoSizeColumn( 0 );
749 m_grid->SetColSize( 0, std::max( 72, m_grid->GetColSize( 0 ) ) );
750
751 int fixedColsWidth = m_grid->GetColSize( 0 );
752
753 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
754 fixedColsWidth += m_grid->GetColSize( i );
755
756 m_grid->SetColSize( 1, std::max( 120, aWidth - fixedColsWidth ) );
757}
758
759
760void DIALOG_LABEL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
761{
762 std::bitset<64> shownColumns = m_grid->GetShownColumns();
763
764 if( shownColumns != m_shownColumns )
765 {
766 m_shownColumns = shownColumns;
767
768 if( !m_grid->IsCellEditControlShown() )
769 AdjustGridColumns( m_grid->GetRect().GetWidth() );
770 }
771
772 // Handle a delayed focus
773 if( m_delayedFocusRow >= 0 && m_delayedFocusRow < m_grid->GetNumberRows() )
774 {
775 m_grid->SetFocus();
776 m_grid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
778 }
779
782}
783
784
785void DIALOG_LABEL_PROPERTIES::OnSizeGrid( wxSizeEvent& event )
786{
787 int new_size = event.GetSize().GetX();
788
789 if( m_width != new_size )
790 AdjustGridColumns( new_size );
791
792 // Always propagate for a grid repaint (needed if the height changes, as well as width)
793 event.Skip();
794}
795
796
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
Definition: bitmap_button.h:41
void SetIsRadioButton()
bool IsChecked() const
void Check(bool aCheck=true)
Check the control.
void SetIsSeparator()
Render button as a toolbar separator.
void SetIsCheckButton()
Setup the control as a two-state button (checked or unchecked).
void SetBitmap(const wxBitmapBundle &aBmp)
Set the bitmap shown when the button is enabled.
Color settings are a bit different than most of the settings objects in that there can be more than o...
COLOR4D GetColor(int aLayer) const
void SetSwatchColor(const KIGFX::COLOR4D &aColor, bool aSendEvent)
Set the current swatch color directly.
KIGFX::COLOR4D GetSwatchColor() const
void SetDefaultColor(const KIGFX::COLOR4D &aColor)
Sets the color that will be chosen with the "Reset to Default" button in the chooser.
void SetSwatchBackground(const KIGFX::COLOR4D &aBackground)
Set the swatch background color.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
bool Empty() const
Returns status of an item.
Definition: commit.h:142
Class DIALOG_LABEL_PROPERTIES_BASE.
void OnSizeGrid(wxSizeEvent &event) override
void OnMoveUp(wxCommandEvent &event) override
void OnMoveDown(wxCommandEvent &event) override
void OnEnterKey(wxCommandEvent &aEvent) override
void OnAddField(wxCommandEvent &event) override
SCH_NETNAME_VALIDATOR m_netNameValidator
void OnFormattingHelp(wxHyperlinkEvent &aEvent) override
FIELDS_GRID_TABLE< SCH_FIELD > * m_fields
DIALOG_LABEL_PROPERTIES(SCH_EDIT_FRAME *parent, SCH_LABEL_BASE *aLabel)
void OnUpdateUI(wxUpdateUIEvent &event) override
void onSpinButton(wxCommandEvent &aEvent)
void OnDeleteField(wxCommandEvent &event) override
void OnValueCharHook(wxKeyEvent &aEvent) override
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
void SetupStandardButtons(std::map< int, wxString > aLabels={})
std::string m_hash_key
Definition: dialog_shim.h:205
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_BASE_FRAME * m_parentFrame
Definition: dialog_shim.h:223
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:129
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
bool IsNew() const
Definition: eda_item.h:103
void SetTextColor(const COLOR4D &aColor)
Definition: eda_text.h:226
COLOR4D GetTextColor() const
Definition: eda_text.h:227
void SetTextSize(VECTOR2I aNewSize)
Definition: eda_text.cpp:358
bool IsItalic() const
Definition: eda_text.h:141
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:131
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
KIFONT::FONT * GetFont() const
Definition: eda_text.h:207
int GetTextWidth() const
Definition: eda_text.h:221
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:419
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:160
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:229
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:197
void SetBold(bool aBold)
Definition: eda_text.cpp:221
bool IsBold() const
Definition: eda_text.h:144
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:163
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:205
void SetItalic(bool aItalic)
Definition: eda_text.cpp:213
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:342
int GetNumberRows() override
bool HaveFontSelection() const
Definition: font_choice.cpp:94
void SetFontSelection(KIFONT::FONT *aFont)
Definition: font_choice.cpp:73
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic) const
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:287
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:537
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:469
SCH_SHEET & Root() const
Definition: schematic.h:105
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Returns a pointer to the active color theme settings.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:353
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCHEMATIC & Schematic() const
void AutoRotateItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
Automatically set the rotation of an item (if the item supports it)
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:52
VECTOR2I GetPosition() const override
Definition: sch_field.cpp:1261
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:1032
void SetName(const wxString &aName)
Definition: sch_field.cpp:979
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:151
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
void ClearFieldsAutoplaced()
Definition: sch_item.h:456
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:465
void SetFields(const std::vector< SCH_FIELD > &aFields)
Set multiple schematic fields.
Definition: sch_label.h:199
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1377
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:372
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:168
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:167
virtual bool AutoRotateOnPlacementSupported() const =0
AutoRotateOnPlacementSupported.
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1382
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:246
virtual int GetMandatoryFieldCount()
Definition: sch_label.h:189
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:191
virtual wxString GetClass() const override=0
Return the class name.
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:337
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:688
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
Schematic symbol object.
Definition: sch_symbol.h:81
bool IsSymbolLikePowerGlobalLabel() const
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:940
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:2050
VECTOR2I GetPosition() const override
Definition: sch_text.h:134
void SetBitmap(const wxBitmapBundle &aBmp)
virtual long long int GetValue()
Return the current value in Internal Units.
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:298
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:156
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
Definition: wx_grid.cpp:254
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:268
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:287
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:448
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:332
This file is part of the common library.
static bool positioningChanged(const SCH_FIELD &a, const SCH_FIELD &b)
#define _(s)
@ FDC_VALUE
int GetPenSizeForBold(int aTextSize)
Definition: gr_text.cpp:40
@ LAYER_FIELDS
Definition: layer_ids.h:359
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:361
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:382
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:360
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
#define SKIP_CONNECTIVITY
Definition: sch_commit.h:43
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:...
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:391
@ CTX_NETNAME
Definition: string_utils.h:53
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:154
@ SCH_LABEL_T
Definition: typeinfo.h:151
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:153
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:157
@ SCH_SYMBOL_LOCATE_POWER_T
Definition: typeinfo.h:180
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:152
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588