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 <sch_validators.h>
33#include <tool/tool_manager.h>
34#include <gr_text.h>
35#include <confirm.h>
36#include <schematic.h>
39#include <string_utils.h>
42#include <kiface_base.h>
43#include <sch_label.h>
44
45
48 m_Parent( aParent ),
49 m_currentLabel( aLabel ),
50 m_activeTextEntry( nullptr ),
51 m_netNameValidator( true ),
52 m_fields( nullptr ),
53 m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false ),
54 m_helpWindow( nullptr )
55{
56 COLOR_SETTINGS* colorSettings = m_Parent->GetColorSettings();
57 COLOR4D schematicBackground = colorSettings->GetColor( LAYER_SCHEMATIC_BACKGROUND );
58
60 m_width = 100; // Will be later set to a better value
63
65 {
68
69 m_labelSingleLine->Show( false );
70 m_valueSingleLine->Show( false );
71
72 m_valueCombo->SetValidator( m_netNameValidator );
73 }
74 else if( m_currentLabel->Type() == SCH_HIER_LABEL_T )
75 {
78
79 m_labelCombo->Show( false );
80 m_valueCombo->Show( false );
81
83 }
85 {
88
89 m_labelSingleLine->Show( false );
90 m_valueSingleLine->Show( false );
91 m_labelCombo->Show( false );
92 m_valueCombo->Show( false );
93 m_syntaxHelp->Show( false );
94 m_textEntrySizer->Show( false );
95
96 m_textSizeLabel->SetLabel( _( "Pin length:" ) );
97 }
98
99 switch( m_currentLabel->Type() )
100 {
101 case SCH_GLOBAL_LABEL_T: SetTitle( _( "Global Label Properties" ) ); break;
102 case SCH_HIER_LABEL_T: SetTitle( _( "Hierarchical Label Properties" ) ); break;
103 case SCH_LABEL_T: SetTitle( _( "Label Properties" ) ); break;
104 case SCH_DIRECTIVE_LABEL_T: SetTitle( _( "Directive Label Properties" ) ); break;
105 case SCH_SHEET_PIN_T: SetTitle( _( "Hierarchical Sheet Pin Properties" ) ); break;
106 default: UNIMPLEMENTED_FOR( m_currentLabel->GetClass() ); break;
107 }
108
109 // Give a bit more room for combobox editors
110 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
111
113 m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this,
114 [&]( wxCommandEvent& aEvent )
115 {
116 OnAddField( aEvent );
117 } ) );
118 m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
119
120 // Show/hide columns according to user's preference
121 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
122 {
123 m_grid->ShowHideColumns( cfg->m_Appearance.edit_label_visible_columns );
125 }
126
127 // Configure button logos
128 m_bpAdd->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
129 m_bpDelete->SetBitmap( KiBitmap( BITMAPS::small_trash ) );
130 m_bpMoveUp->SetBitmap( KiBitmap( BITMAPS::small_up ) );
131 m_bpMoveDown->SetBitmap( KiBitmap( BITMAPS::small_down ) );
132
134
136 m_bold->SetBitmap( KiBitmap( BITMAPS::text_bold ) );
138 m_italic->SetBitmap( KiBitmap( BITMAPS::text_italic ) );
139
141
146
148
149 m_textColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
150 m_textColorSwatch->SetSwatchBackground( schematicBackground );
151
152 // Show/hide relevant controls
154 {
155 m_dot->Hide();
156 m_circle->Hide();
157 m_diamond->Hide();
158 m_rectangle->Hide();
159
160 m_spin0->SetBitmap( KiBitmap( BITMAPS::label_align_left ) );
161 m_spin1->SetBitmap( KiBitmap( BITMAPS::label_align_right ) );
162 m_spin2->SetBitmap( KiBitmap( BITMAPS::label_align_bottom ) );
163 m_spin3->SetBitmap( KiBitmap( BITMAPS::label_align_top ) );
164 }
166 {
167 m_input->Hide();
168 m_output->Hide();
169 m_bidirectional->Hide();
170 m_triState->Hide();
171 m_passive->Hide();
172
173 m_fontLabel->SetLabel( _( "Orientation:" ) );
174 m_fontCtrl->Hide();
175 m_separator1->Hide();
176 m_bold->Hide();
177 m_italic->Hide();
178 m_separator2->Hide();
179 m_spin0->SetBitmap( KiBitmap( BITMAPS::pinorient_down ) );
180 m_spin1->SetBitmap( KiBitmap( BITMAPS::pinorient_up ) );
181 m_spin2->SetBitmap( KiBitmap( BITMAPS::pinorient_right ) );
182 m_spin3->SetBitmap( KiBitmap( BITMAPS::pinorient_left ) );
183 m_separator3->Hide();
184
185 m_formattingGB->Detach( m_fontCtrl );
186 m_formattingGB->Detach( m_iconBar );
187 m_formattingGB->Add( m_iconBar, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxRIGHT, 5 );
188 }
189 else
190 {
191 m_shapeSizer->Show( false );
192
193 m_spin0->SetBitmap( KiBitmap( BITMAPS::text_align_left ) );
194 m_spin1->SetBitmap( KiBitmap( BITMAPS::text_align_right ) );
195 m_spin2->SetBitmap( KiBitmap( BITMAPS::text_align_bottom ) );
196 m_spin3->SetBitmap( KiBitmap( BITMAPS::text_align_top ) );
197 }
198
200 {
201 m_autoRotate->Hide();
202 wxSizer* parentSizer = m_autoRotate->GetContainingSizer();
203 parentSizer->Detach( m_autoRotate );
204 parentSizer->Layout();
205 }
206
208
209 // DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
210 // various versions have different controls so we want to store sizes for each version.
211 m_hash_key = TO_UTF8( GetTitle() );
212
213 m_spin0->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
214 m_spin1->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
215 m_spin2->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
216 m_spin3->Bind( wxEVT_BUTTON, &DIALOG_LABEL_PROPERTIES::onSpinButton, this );
217
218 // Now all widgets have the size fixed, call FinishDialogSettings
220
221 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
222 {
223 if( cfg->m_Appearance.edit_label_width > 0 && cfg->m_Appearance.edit_label_height > 0 )
224 SetSize( cfg->m_Appearance.edit_label_width, cfg->m_Appearance.edit_label_height );
225 }
226}
227
228
230{
231 if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
232 {
233 cfg->m_Appearance.edit_label_visible_columns = m_grid->GetShownColumnsAsString();
234 cfg->m_Appearance.edit_label_width = GetSize().x;
235 cfg->m_Appearance.edit_label_height = GetSize().y;
236 }
237
238 // Prevents crash bug in wxGrid's d'tor
240
241 // Delete the GRID_TRICKS.
242 m_grid->PopEventHandler( true );
243
244 if( m_helpWindow )
245 m_helpWindow->Destroy();
246}
247
248
250{
251 if( !wxDialog::TransferDataToWindow() )
252 return false;
253
255 {
256 // show control characters in a human-readable format
257 wxString text = UnescapeString( m_currentLabel->GetText() );
258
259 // show text variable cross-references in a human-readable format
261
262 m_activeTextEntry->SetValue( text );
263 }
264
266 {
267 // Load the combobox with the existing labels of the same type
268 std::set<wxString> existingLabels;
269 std::vector<std::shared_ptr<BUS_ALIAS>> busAliases;
270 SCH_SCREENS allScreens( m_Parent->Schematic().Root() );
271
272 for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
273 {
274 for( SCH_ITEM* item : screen->Items().OfType( m_currentLabel->Type() ) )
275 {
276 const SCH_LABEL_BASE* label = static_cast<const SCH_LABEL_BASE*>( item );
277 existingLabels.insert( UnescapeString( label->GetText() ) );
278 }
279
280 // Add global power labels from power symbols
282 {
283 for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_LOCATE_POWER_T ) )
284 {
285 const SCH_SYMBOL* power = static_cast<const SCH_SYMBOL*>( item );
286
287 // Ensure the symbol has the Power (i.e. equivalent to a global label
288 // before adding its value in list
289 if( power->IsSymbolLikePowerGlobalLabel() )
290 existingLabels.insert( UnescapeString( power->GetField( VALUE_FIELD )->GetText() ) );
291 }
292 }
293
294 std::set<std::shared_ptr<BUS_ALIAS>> sheetAliases = screen->GetBusAliases();
295 busAliases.insert( busAliases.end(), sheetAliases.begin(), sheetAliases.end() );
296 }
297
298 // Add bus aliases to label list
299 for( const std::shared_ptr<BUS_ALIAS>& busAlias : busAliases )
300 existingLabels.insert( wxT( "{" ) + busAlias->GetName() + wxT( "}" ) );
301
302 wxArrayString existingLabelArray;
303
304 for( const wxString& label : existingLabels )
305 existingLabelArray.push_back( label );
306
307 m_valueCombo->Append( existingLabelArray );
308 }
309
310 // Push a copy of each field into m_updateFields
311 for( SCH_FIELD& field : m_currentLabel->GetFields() )
312 {
313 SCH_FIELD field_copy( field );
314
315 // change offset to be symbol-relative
316 field_copy.Offset( -m_currentLabel->GetPosition() );
317
318 m_fields->push_back( field_copy );
319 }
320
321 // notify the grid
322 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->size() );
323 m_grid->ProcessTableMessage( msg );
324 AdjustGridColumns( m_grid->GetRect().GetWidth() );
325
326 if( m_shapeSizer->AreAnyItemsShown() )
327 {
328 switch( m_currentLabel->GetShape() )
329 {
330 case LABEL_FLAG_SHAPE::L_INPUT: m_input->SetValue( true ); break;
331 case LABEL_FLAG_SHAPE::L_OUTPUT: m_output->SetValue( true ); break;
332 case LABEL_FLAG_SHAPE::L_BIDI: m_bidirectional->SetValue( true ); break;
333 case LABEL_FLAG_SHAPE::L_TRISTATE: m_triState->SetValue( true ); break;
334 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: m_passive->SetValue( true ); break;
335 case LABEL_FLAG_SHAPE::F_DOT: m_dot->SetValue( true ); break;
336 case LABEL_FLAG_SHAPE::F_ROUND: m_circle->SetValue( true ); break;
337 case LABEL_FLAG_SHAPE::F_DIAMOND: m_diamond->SetValue( true ); break;
338 case LABEL_FLAG_SHAPE::F_RECTANGLE: m_rectangle->SetValue( true ); break;
339 }
340 }
341
343
345 m_textSize.SetValue( static_cast<SCH_DIRECTIVE_LABEL*>( m_currentLabel )->GetPinLength() );
346 else
348
352
354 {
355 case TEXT_SPIN_STYLE::RIGHT: m_spin0->Check( true ); break;
356 case TEXT_SPIN_STYLE::LEFT: m_spin1->Check( true ); break;
357 case TEXT_SPIN_STYLE::UP: m_spin2->Check( true ); break;
358 case TEXT_SPIN_STYLE::BOTTOM: m_spin3->Check( true ); break;
359 }
360
363
364 return true;
365}
366
367
371void DIALOG_LABEL_PROPERTIES::OnEnterKey( wxCommandEvent& aEvent )
372{
373 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
374}
375
376
378{
379 if( aEvent.GetKeyCode() == WXK_TAB )
380 {
381 if( aEvent.ShiftDown() )
382 {
383 m_textSizeCtrl->SetFocusFromKbd();
384 }
385 else if( !m_fields->empty() )
386 {
387 m_grid->SetFocusFromKbd();
388 m_grid->MakeCellVisible( 0, 0 );
389 m_grid->SetGridCursor( 0, 0 );
390 }
391 else
392 {
393 m_textSizeCtrl->SetFocusFromKbd();
394 }
395 }
396 else
397 {
398 aEvent.Skip();
399 }
400}
401
402
403static bool positioningChanged( const SCH_FIELD& a, const SCH_FIELD& b )
404{
405 return a.GetPosition() != b.GetPosition()
406 || a.GetHorizJustify() != b.GetHorizJustify()
407 || a.GetVertJustify() != b.GetVertJustify()
408 || a.GetTextAngle() != b.GetTextAngle();
409}
410
411
412static bool positioningChanged( FIELDS_GRID_TABLE<SCH_FIELD>* a, std::vector<SCH_FIELD>& b )
413{
414 for( size_t i = 0; i < a->size() && i < b.size(); ++i )
415 {
416 if( positioningChanged( a->at( i ), b.at( i ) ) )
417 return true;
418 }
419
420 return false;
421}
422
423
425{
427 return false;
428
429 if( !wxDialog::TransferDataFromWindow() )
430 return false;
431
432 // Don't allow text to disappear; it can be difficult to correct if you can't select it
433 if( !m_textSize.Validate( 0.01, 1000.0, EDA_UNITS::MILLIMETRES ) )
434 return false;
435
436 wxString text;
437
438 /* save old text in undo list if not already in edit */
439 if( m_currentLabel->GetEditFlags() == 0 )
440 {
442 false );
443 }
444
446
448 {
449 // labels need escaping
451
452 // convert any text variable cross-references to their UUIDs
454
455#ifdef __WXMAC__
456 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting
457 text.Replace( wxS( "\r" ), wxS( "\n" ) );
458#endif
459
460 if( text.IsEmpty() && !m_currentLabel->IsNew() )
461 {
462 DisplayError( this, _( "Label can not be empty." ) );
463 return false;
464 }
465
467 }
468
469 bool doAutoplace = false;
470
471 // change all field positions from relative to absolute
472 for( SCH_FIELD& field : *m_fields )
473 {
474 field.Offset( m_currentLabel->GetPosition() );
475
476 if( field.GetCanonicalName() == wxT( "Netclass" ) )
477 {
478 field.SetLayer( LAYER_NETCLASS_REFS );
479 }
480 else if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
481 {
482 if( field.IsVisible() != m_Parent->Schematic().Settings().m_IntersheetRefsShow )
483 {
484 DisplayInfoMessage( this, _( "Intersheet reference visibility is "
485 "controlled globally from "
486 "Schematic Setup > General > Formatting" ) );
487 }
488
489 field.SetLayer( LAYER_INTERSHEET_REFS );
490 }
491 else
492 {
493 field.SetLayer( LAYER_FIELDS );
494 }
495 }
496
499 else
500 doAutoplace = true;
501
502 for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
503 {
504 SCH_FIELD& field = m_fields->at( ii );
505 const wxString& fieldName = field.GetCanonicalName();
506 const wxString& fieldText = field.GetText();
507
508 if( fieldName.IsEmpty() && fieldText.IsEmpty() )
509 m_fields->erase( m_fields->begin() + ii );
510 else if( fieldName == wxT( "Netclass" ) && fieldText.IsEmpty() )
511 m_fields->erase( m_fields->begin() + ii );
512 else if( fieldName.IsEmpty() )
513 field.SetName( _( "untitled" ) );
514 }
515
517
518 if( m_shapeSizer->AreAnyItemsShown() )
519 {
520 if( m_input->GetValue() )
521 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
522 else if( m_output->GetValue() )
523 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
524 else if( m_bidirectional->GetValue() )
525 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
526 else if( m_triState->GetValue() )
527 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
528 else if( m_passive->GetValue() )
529 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
530 else if( m_dot->GetValue() )
531 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DOT );
532 else if( m_circle->GetValue() )
533 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
534 else if( m_diamond->GetValue() )
535 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
536 else if( m_rectangle->GetValue() )
537 m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
538 }
539
541 {
543 m_italic->IsChecked() ) );
544 }
545
547 static_cast<SCH_DIRECTIVE_LABEL*>( m_currentLabel )->SetPinLength( m_textSize.GetValue() );
550
552 {
553 if( m_bold->IsChecked() )
554 {
555 m_currentLabel->SetBold( true );
557 }
558 else
559 {
560 m_currentLabel->SetBold( false );
561 m_currentLabel->SetTextThickness( 0 ); // Use default pen width
562 }
563 }
564
566
568
569 TEXT_SPIN_STYLE selectedSpinStyle= TEXT_SPIN_STYLE::LEFT;
570
571 if( m_spin0->IsChecked() )
572 selectedSpinStyle = TEXT_SPIN_STYLE::RIGHT;
573 else if( m_spin1->IsChecked() )
574 selectedSpinStyle = TEXT_SPIN_STYLE::LEFT;
575 else if( m_spin2->IsChecked() )
576 selectedSpinStyle = TEXT_SPIN_STYLE::UP;
577 else if( m_spin3->IsChecked() )
578 selectedSpinStyle = TEXT_SPIN_STYLE::BOTTOM;
579
581 {
582 SCH_EDIT_FRAME* frame = static_cast<SCH_EDIT_FRAME*>( m_parentFrame );
584 frame->AutoRotateItem( frame->GetScreen(), m_currentLabel );
585 }
586 else
588
590 && m_currentLabel->GetTextSpinStyle() != selectedSpinStyle )
591 m_currentLabel->SetTextSpinStyle( selectedSpinStyle );
592
593 if( doAutoplace )
595
598
599 return true;
600}
601
602
603void DIALOG_LABEL_PROPERTIES::onSpinButton( wxCommandEvent& aEvent )
604{
605 for( BITMAP_BUTTON* btn : { m_spin0, m_spin1, m_spin2, m_spin3 } )
606 {
607 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
608 btn->Check( false );
609 }
610}
611
612
613void DIALOG_LABEL_PROPERTIES::OnFormattingHelp( wxHyperlinkEvent& aEvent )
614{
616}
617
618
619void DIALOG_LABEL_PROPERTIES::OnAddField( wxCommandEvent& event )
620{
622 return;
623
624 int fieldID = (int) m_fields->size();
625 wxString fieldName;
626
627 if( (int) fieldID == m_currentLabel->GetMandatoryFieldCount()
628 || m_fields->at( m_fields->size()-1 ).GetCanonicalName() == wxT( "Netclass" ) )
629 {
630 fieldName = wxT( "Netclass" );
631 }
632 else
633 {
634 fieldName = SCH_LABEL_BASE::GetDefaultFieldName( fieldName, true );
635 }
636
637 SCH_FIELD newField( VECTOR2I( 0, 0 ), fieldID, m_currentLabel, fieldName );
638
639 if( m_fields->size() > 0 )
640 {
641 newField.SetVisible( m_fields->at( m_fields->size() - 1 ).IsVisible() );
642 newField.SetTextAngle( m_fields->at( m_fields->size() - 1 ).GetTextAngle() );
643 newField.SetItalic( m_fields->at( m_fields->size() - 1 ).IsItalic() );
644 newField.SetBold( m_fields->at( m_fields->size() - 1 ).IsBold() );
645 }
646 else
647 {
648 newField.SetVisible( true );
649 newField.SetItalic( true );
650 }
651
652 m_fields->push_back( newField );
653
654 // notify the grid
655 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
656 m_grid->ProcessTableMessage( msg );
657
658 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
659 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
660
661 m_grid->EnableCellEditControl();
662 m_grid->ShowCellEditControl();
663}
664
665
666void DIALOG_LABEL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
667{
668 wxArrayInt selectedRows = m_grid->GetSelectedRows();
669
670 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
671 selectedRows.push_back( m_grid->GetGridCursorRow() );
672
673 if( selectedRows.empty() )
674 return;
675
676 for( int row : selectedRows )
677 {
678 if( row < m_currentLabel->GetMandatoryFieldCount() )
679 {
680 DisplayError( this, _( "The first field is mandatory." ) );
681 return;
682 }
683 }
684
685 m_grid->CommitPendingChanges( true /* quiet mode */ );
686
687 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
688 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
689
690 for( int row : selectedRows )
691 {
692 m_fields->erase( m_fields->begin() + row );
693
694 // notify the grid
695 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
696 m_grid->ProcessTableMessage( msg );
697
698 if( m_grid->GetNumberRows() > 0 )
699 {
700 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
701 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
702 }
703 }
704}
705
706
707void DIALOG_LABEL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
708{
710 return;
711
712 int i = m_grid->GetGridCursorRow();
713
715 {
716 SCH_FIELD tmp = m_fields->at( (unsigned) i );
717 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
718 m_fields->insert( m_fields->begin() + i - 1, tmp );
719 m_grid->ForceRefresh();
720
721 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
722 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
723 }
724 else
725 {
726 wxBell();
727 }
728}
729
730
731void DIALOG_LABEL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
732{
734 return;
735
736 int i = m_grid->GetGridCursorRow();
737
738 if( i >= m_currentLabel->GetMandatoryFieldCount() && i < m_grid->GetNumberRows() - 1 )
739 {
740 SCH_FIELD tmp = m_fields->at( (unsigned) i );
741 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
742 m_fields->insert( m_fields->begin() + i + 1, tmp );
743 m_grid->ForceRefresh();
744
745 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
746 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
747 }
748 else
749 {
750 wxBell();
751 }
752}
753
754
756{
757 m_width = aWidth;
758 // Account for scroll bars
759 aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
760
761 m_grid->AutoSizeColumn( 0 );
762 m_grid->SetColSize( 0, std::max( 72, m_grid->GetColSize( 0 ) ) );
763
764 int fixedColsWidth = m_grid->GetColSize( 0 );
765
766 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
767 fixedColsWidth += m_grid->GetColSize( i );
768
769 m_grid->SetColSize( 1, std::max( 120, aWidth - fixedColsWidth ) );
770}
771
772
773void DIALOG_LABEL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
774{
775 std::bitset<64> shownColumns = m_grid->GetShownColumns();
776
777 if( shownColumns != m_shownColumns )
778 {
779 m_shownColumns = shownColumns;
780
781 if( !m_grid->IsCellEditControlShown() )
782 AdjustGridColumns( m_grid->GetRect().GetWidth() );
783 }
784
785 // Handle a delayed focus
786 if( m_delayedFocusRow >= 0 && m_delayedFocusRow < m_grid->GetNumberRows() )
787 {
788 m_grid->SetFocus();
789 m_grid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
791 }
792
795}
796
797
798void DIALOG_LABEL_PROPERTIES::OnSizeGrid( wxSizeEvent& event )
799{
800 int new_size = event.GetSize().GetX();
801
802 if( m_width != new_size )
803 AdjustGridColumns( new_size );
804
805 // Always propagate for a grid repaint (needed if the height changes, as well as width)
806 event.Skip();
807}
808
809
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:106
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.
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:204
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:221
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:212
COLOR4D GetTextColor() const
Definition: eda_text.h:213
bool IsItalic() const
Definition: eda_text.h:138
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:128
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:92
KIFONT::FONT * GetFont() const
Definition: eda_text.h:196
int GetTextWidth() const
Definition: eda_text.h:207
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:411
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:157
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:141
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:160
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:359
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:175
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:343
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:103
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:205
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:453
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:385
SCH_SHEET & Root() const
Definition: schematic.h:102
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.
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend, bool aDirtyConnectivity=true)
Create a copy of the current schematic item, and put it in the undo list.
SCHEMATIC & Schematic() const
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
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:1094
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:862
void SetName(const wxString &aName)
Definition: sch_field.h:117
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
void ClearFieldsAutoplaced()
Definition: sch_item.h:433
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:442
void SetFields(const std::vector< SCH_FIELD > &aFields)
Set multiple schematic fields.
Definition: sch_label.h:98
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1141
virtual bool AutoRotateOnPlacementSupported() const =0
AutoRotateOnPlacementSupported.
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1146
void SetShape(LABEL_FLAG_SHAPE aShape) override
Definition: sch_label.h:74
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:184
LABEL_FLAG_SHAPE GetShape() const override
Definition: sch_label.h:73
virtual int GetMandatoryFieldCount()
Definition: sch_label.h:88
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:90
virtual wxString GetClass() const override=0
Return the class name.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:662
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:891
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:1804
VECTOR2I GetPosition() const override
Definition: sch_text.h:212
TEXT_SPIN_STYLE GetTextSpinStyle() const
Definition: sch_text.h:157
virtual void SetTextSpinStyle(TEXT_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:193
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:306
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:164
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:262
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:276
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:295
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:474
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:283
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:335
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:358
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:360
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:380
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:359
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:120
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
Definitions of control validators for schematic dialogs.
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_NETNAME
Definition: string_utils.h:54
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:144
@ SCH_LABEL_T
Definition: typeinfo.h:141
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:143
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:147
@ SCH_SYMBOL_LOCATE_POWER_T
Definition: typeinfo.h:170
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:142
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588