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, nullptr,
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, (int) 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.GetIntValue() );
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 )
682 {
683 return *second - *first;
684 } );
685
686 for( int row : selectedRows )
687 {
688 //avoids an assert if we deselect early here
689 m_grid->DeselectRow( row );
690 m_fields->erase( m_fields->begin() + row );
691
692 // notify the grid
693 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
694 m_grid->ProcessTableMessage( msg );
695
696 if( m_grid->GetNumberRows() > 0 )
697 {
698 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
699 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
700 }
701 }
702}
703
704
705void DIALOG_LABEL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
706{
708 return;
709
710 int i = m_grid->GetGridCursorRow();
711
713 {
714 SCH_FIELD tmp = m_fields->at( (unsigned) i );
715 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
716 m_fields->insert( m_fields->begin() + i - 1, tmp );
717 m_grid->ForceRefresh();
718
719 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
720 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
721 }
722 else
723 {
724 wxBell();
725 }
726}
727
728
729void DIALOG_LABEL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
730{
732 return;
733
734 int i = m_grid->GetGridCursorRow();
735
736 if( i >= m_currentLabel->GetMandatoryFieldCount() && i < m_grid->GetNumberRows() - 1 )
737 {
738 SCH_FIELD tmp = m_fields->at( (unsigned) i );
739 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
740 m_fields->insert( m_fields->begin() + i + 1, tmp );
741 m_grid->ForceRefresh();
742
743 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
744 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
745 }
746 else
747 {
748 wxBell();
749 }
750}
751
752
754{
755 m_width = aWidth;
756 // Account for scroll bars
757 aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
758
759 m_grid->AutoSizeColumn( 0 );
760 m_grid->SetColSize( 0, std::max( 72, m_grid->GetColSize( 0 ) ) );
761
762 int fixedColsWidth = m_grid->GetColSize( 0 );
763
764 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
765 fixedColsWidth += m_grid->GetColSize( i );
766
767 m_grid->SetColSize( 1, std::max( 120, aWidth - fixedColsWidth ) );
768}
769
770
771void DIALOG_LABEL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
772{
773 std::bitset<64> shownColumns = m_grid->GetShownColumns();
774
775 if( shownColumns != m_shownColumns )
776 {
777 m_shownColumns = shownColumns;
778
779 if( !m_grid->IsCellEditControlShown() )
780 AdjustGridColumns( m_grid->GetRect().GetWidth() );
781 }
782
783 // Handle a delayed focus
784 if( m_delayedFocusRow >= 0 && m_delayedFocusRow < m_grid->GetNumberRows() )
785 {
786 m_grid->SetFocus();
787 m_grid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
789 }
790
793}
794
795
796void DIALOG_LABEL_PROPERTIES::OnSizeGrid( wxSizeEvent& event )
797{
798 int new_size = event.GetSize().GetX();
799
800 if( m_width != new_size )
801 AdjustGridColumns( new_size );
802
803 // Always propagate for a grid repaint (needed if the height changes, as well as width)
804 event.Skip();
805}
806
807
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:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
std::string m_hash_key
Definition: dialog_shim.h:210
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:228
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:133
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
bool IsNew() const
Definition: eda_item.h:107
void SetTextColor(const COLOR4D &aColor)
Definition: eda_text.h:226
COLOR4D GetTextColor() const
Definition: eda_text.h:227
bool IsItalic() const
Definition: eda_text.h:140
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:130
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:373
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
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:436
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:160
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:244
void SetBold(bool aBold)
Definition: eda_text.cpp:220
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:182
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:204
void SetItalic(bool aItalic)
Definition: eda_text.cpp:212
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:357
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:297
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:555
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:488
SCH_SHEET & Root() const
Definition: schematic.h:113
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:406
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:1462
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:1229
void SetName(const wxString &aName)
Definition: sch_field.cpp:1179
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
void ClearFieldsAutoplaced()
Definition: sch_item.h:551
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:560
void SetFields(const std::vector< SCH_FIELD > &aFields)
Set multiple schematic fields.
Definition: sch_label.h:209
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1429
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:383
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:178
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:177
virtual bool AutoRotateOnPlacementSupported() const =0
AutoRotateOnPlacementSupported.
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1435
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:254
virtual int GetMandatoryFieldCount()
Definition: sch_label.h:199
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:201
virtual wxString GetClass() const override=0
Return the class name.
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:348
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:710
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
Schematic symbol object.
Definition: sch_symbol.h:105
bool IsSymbolLikePowerGlobalLabel() const
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:919
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:2185
VECTOR2I GetPosition() const override
Definition: sch_text.h:141
void SetBitmap(const wxBitmapBundle &aBmp)
int GetIntValue()
Definition: unit_binder.h:127
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:444
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:267
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:400
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:414
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:433
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:594
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:222
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:367
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:369
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:392
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:368
#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< int32_t > VECTOR2I
Definition: vector2d.h:673