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-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
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
57 m_fields = new FIELDS_GRID_TABLE( this, aParent, m_grid, m_currentLabel );
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* 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 {
506 // delete empty, unnamed fields
507 m_fields->erase( m_fields->begin() + ii );
508 }
509 else if( fieldName == wxT( "Netclass" ) && fieldText.IsEmpty() )
510 {
511 // delete empty Netclass fields if there are other Netclass fields present
512 int netclassFieldCount = 0;
513
514 for( int jj = 0; jj < m_fields->GetNumberRows(); ++jj )
515 {
516 if( m_fields->at( jj ).GetCanonicalName() == wxT( "Netclass" ) )
517 netclassFieldCount++;
518 }
519
520 if( netclassFieldCount > 1 )
521 m_fields->erase( m_fields->begin() + ii );
522 }
523 else if( fieldName.IsEmpty() )
524 {
525 // give non-empty, unnamed fields a name
526 field.SetName( _( "untitled" ) );
527 }
528 }
529
531
532 if( m_shapeSizer->AreAnyItemsShown() )
533 {
534 if( m_bidirectional->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
535 else if( m_input->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
536 else if( m_output->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
537 else if( m_triState->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
538 else if( m_passive->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
539 else if( m_dot->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DOT );
540 else if( m_circle->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
541 else if( m_diamond->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
542 else if( m_rectangle->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
543 }
544
546 {
548 m_italic->IsChecked() ) );
549 }
550
552 static_cast<SCH_DIRECTIVE_LABEL*>( m_currentLabel )->SetPinLength( m_textSize.GetValue() );
555
556 // Must come after SetTextSize()
559
561
562 SPIN_STYLE selectedSpinStyle= SPIN_STYLE::LEFT;
563
564 if( m_spin0->IsChecked() ) selectedSpinStyle = SPIN_STYLE::RIGHT;
565 else if( m_spin1->IsChecked() ) selectedSpinStyle = SPIN_STYLE::LEFT;
566 else if( m_spin2->IsChecked() ) selectedSpinStyle = SPIN_STYLE::UP;
567 else if( m_spin3->IsChecked() ) selectedSpinStyle = SPIN_STYLE::BOTTOM;
568
570 {
571 SCH_EDIT_FRAME* frame = static_cast<SCH_EDIT_FRAME*>( m_parentFrame );
573 frame->AutoRotateItem( frame->GetScreen(), m_currentLabel );
574 }
575 else
576 {
578 }
579
581 && m_currentLabel->GetSpinStyle() != selectedSpinStyle )
582 {
583 m_currentLabel->SetSpinStyle( selectedSpinStyle );
584 }
585
586 if( doAutoplace )
588
589 if( !commit.Empty() )
590 commit.Push( _( "Edit Label Properties" ) );
591
592 return true;
593}
594
595
596void DIALOG_LABEL_PROPERTIES::onSpinButton( wxCommandEvent& aEvent )
597{
598 for( BITMAP_BUTTON* btn : { m_spin0, m_spin1, m_spin2, m_spin3 } )
599 {
600 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
601 btn->Check( false );
602 }
603}
604
605
606void DIALOG_LABEL_PROPERTIES::OnFormattingHelp( wxHyperlinkEvent& aEvent )
607{
609}
610
611
612void DIALOG_LABEL_PROPERTIES::OnAddField( wxCommandEvent& event )
613{
615 return;
616
617 int fieldID = (int) m_fields->size();
618 wxString fieldName;
619
620 if( (int) fieldID == m_currentLabel->GetMandatoryFieldCount()
621 || m_fields->at( m_fields->size()-1 ).GetCanonicalName() == wxT( "Netclass" ) )
622 {
623 fieldName = wxT( "Netclass" );
624 }
625 else
626 {
627 fieldName = SCH_LABEL_BASE::GetDefaultFieldName( fieldName, true );
628 }
629
630 SCH_FIELD newField( VECTOR2I( 0, 0 ), fieldID, m_currentLabel, fieldName );
631
632 if( m_fields->size() > 0 )
633 {
634 newField.SetVisible( m_fields->at( m_fields->size() - 1 ).IsVisible() );
635 newField.SetTextAngle( m_fields->at( m_fields->size() - 1 ).GetTextAngle() );
636 newField.SetItalic( m_fields->at( m_fields->size() - 1 ).IsItalic() );
637 newField.SetBold( m_fields->at( m_fields->size() - 1 ).IsBold() );
638 }
639 else
640 {
641 newField.SetVisible( true );
642 newField.SetItalic( true );
643 }
644
645 m_fields->push_back( newField );
646
647 // notify the grid
648 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
649 m_grid->ProcessTableMessage( msg );
650
651 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
652 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
653
654 m_grid->EnableCellEditControl();
655 m_grid->ShowCellEditControl();
656}
657
658
659void DIALOG_LABEL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
660{
661 wxArrayInt selectedRows = m_grid->GetSelectedRows();
662
663 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
664 selectedRows.push_back( m_grid->GetGridCursorRow() );
665
666 if( selectedRows.empty() )
667 return;
668
669 for( int row : selectedRows )
670 {
671 if( row < m_currentLabel->GetMandatoryFieldCount() )
672 {
673 DisplayError( this, _( "The first field is mandatory." ) );
674 return;
675 }
676 }
677
678 m_grid->CommitPendingChanges( true /* quiet mode */ );
679
680 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
681 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
682
683 for( int row : selectedRows )
684 {
685 //avoids an assert if we deselect early here
686 m_grid->DeselectRow( row );
687 m_fields->erase( m_fields->begin() + row );
688
689 // notify the grid
690 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
691 m_grid->ProcessTableMessage( msg );
692
693 if( m_grid->GetNumberRows() > 0 )
694 {
695 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
696 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
697 }
698 }
699}
700
701
702void DIALOG_LABEL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
703{
705 return;
706
707 int i = m_grid->GetGridCursorRow();
708
710 {
711 SCH_FIELD tmp = m_fields->at( (unsigned) i );
712 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
713 m_fields->insert( m_fields->begin() + i - 1, tmp );
714 m_grid->ForceRefresh();
715
716 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
717 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
718 }
719 else
720 {
721 wxBell();
722 }
723}
724
725
726void DIALOG_LABEL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
727{
729 return;
730
731 int i = m_grid->GetGridCursorRow();
732
733 if( i >= m_currentLabel->GetMandatoryFieldCount() && i < m_grid->GetNumberRows() - 1 )
734 {
735 SCH_FIELD tmp = m_fields->at( (unsigned) i );
736 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
737 m_fields->insert( m_fields->begin() + i + 1, tmp );
738 m_grid->ForceRefresh();
739
740 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
741 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
742 }
743 else
744 {
745 wxBell();
746 }
747}
748
749
751{
752 m_width = aWidth;
753 // Account for scroll bars
754 aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
755
756 m_grid->AutoSizeColumn( 0 );
757 m_grid->SetColSize( 0, std::max( 72, m_grid->GetColSize( 0 ) ) );
758
759 int fixedColsWidth = m_grid->GetColSize( 0 );
760
761 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
762 fixedColsWidth += m_grid->GetColSize( i );
763
764 m_grid->SetColSize( 1, std::max( 120, aWidth - fixedColsWidth ) );
765}
766
767
768void DIALOG_LABEL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
769{
770 std::bitset<64> shownColumns = m_grid->GetShownColumns();
771
772 if( shownColumns != m_shownColumns )
773 {
774 m_shownColumns = shownColumns;
775
776 if( !m_grid->IsCellEditControlShown() )
777 AdjustGridColumns( m_grid->GetRect().GetWidth() );
778 }
779
780 // Handle a delayed focus
781 if( m_delayedFocusRow >= 0 && m_delayedFocusRow < m_grid->GetNumberRows() )
782 {
783 m_grid->SetFocus();
784 m_grid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
786 }
787
790}
791
792
793void DIALOG_LABEL_PROPERTIES::OnSizeGrid( wxSizeEvent& event )
794{
795 int new_size = event.GetSize().GetX();
796
797 if( m_width != new_size )
798 AdjustGridColumns( new_size );
799
800 // Always propagate for a grid repaint (needed if the height changes, as well as width)
801 event.Skip();
802}
803
804
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:42
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:105
bool Empty() const
Returns status of an item.
Definition: commit.h:144
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
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:98
void SetupStandardButtons(std::map< int, wxString > aLabels={})
std::string m_hash_key
Definition: dialog_shim.h:206
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:224
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:132
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
bool IsNew() const
Definition: eda_item.h:106
void SetTextColor(const COLOR4D &aColor)
Definition: eda_text.h:230
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
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:374
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
KIFONT::FONT * GetFont() const
Definition: eda_text.h:211
int GetTextWidth() const
Definition: eda_text.h:225
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:437
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:164
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:245
void SetBold(bool aBold)
Definition: eda_text.cpp:221
bool IsBold() const
Definition: eda_text.h:148
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:167
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:358
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:541
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:473
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:405
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:51
VECTOR2I GetPosition() const override
Definition: sch_field.cpp:1407
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:1174
void SetName(const wxString &aName)
Definition: sch_field.cpp:1128
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:174
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:139
void ClearFieldsAutoplaced()
Definition: sch_item.h:559
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:568
void SetFields(const std::vector< SCH_FIELD > &aFields)
Set multiple schematic fields.
Definition: sch_label.h:204
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1454
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:373
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:173
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:172
virtual bool AutoRotateOnPlacementSupported() const =0
AutoRotateOnPlacementSupported.
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1460
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:247
virtual int GetMandatoryFieldCount()
Definition: sch_label.h:194
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:196
virtual wxString GetClass() const override=0
Return the class name.
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:338
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:704
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
Schematic symbol object.
Definition: sch_symbol.h:108
bool IsSymbolLikePowerGlobalLabel() const
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:910
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:2209
VECTOR2I GetPosition() const override
Definition: sch_text.h:141
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:408
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:231
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:364
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:378
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:397
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:558
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
@ LAYER_FIELDS
Definition: layer_ids.h:366
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:368
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:390
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:367
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
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:171
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:173
@ SCH_SYMBOL_LOCATE_POWER_T
Definition: typeinfo.h:195
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588