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 The 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 // change all field positions from relative to absolute
466 for( SCH_FIELD& field : *m_fields )
467 {
468 field.Offset( m_currentLabel->GetPosition() );
469
470 if( field.GetCanonicalName() == wxT( "Netclass" ) )
471 {
472 field.SetLayer( LAYER_NETCLASS_REFS );
473 }
474 else if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
475 {
476 if( field.IsVisible() != m_Parent->Schematic().Settings().m_IntersheetRefsShow )
477 {
478 DisplayInfoMessage( this, _( "Intersheet reference visibility is "
479 "controlled globally from "
480 "Schematic Setup > General > Formatting" ) );
481 }
482
483 field.SetLayer( LAYER_INTERSHEET_REFS );
484 }
485 else
486 {
487 field.SetLayer( LAYER_FIELDS );
488 }
489 }
490
493
494 for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
495 {
496 SCH_FIELD& field = m_fields->at( ii );
497 const wxString& fieldName = field.GetCanonicalName();
498 const wxString& fieldText = field.GetText();
499
500 if( fieldName.IsEmpty() && fieldText.IsEmpty() )
501 {
502 // delete empty, unnamed fields
503 m_fields->erase( m_fields->begin() + ii );
504 }
505 else if( fieldName == wxT( "Netclass" ) && fieldText.IsEmpty() )
506 {
507 // delete empty Netclass fields if there are other Netclass fields present
508 int netclassFieldCount = 0;
509
510 for( int jj = 0; jj < m_fields->GetNumberRows(); ++jj )
511 {
512 if( m_fields->at( jj ).GetCanonicalName() == wxT( "Netclass" ) )
513 netclassFieldCount++;
514 }
515
516 if( netclassFieldCount > 1 )
517 m_fields->erase( m_fields->begin() + ii );
518 }
519 else if( fieldName.IsEmpty() )
520 {
521 // give non-empty, unnamed fields a name
522 field.SetName( _( "untitled" ) );
523 }
524 }
525
527
528 if( m_shapeSizer->AreAnyItemsShown() )
529 {
530 if( m_bidirectional->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
531 else if( m_input->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
532 else if( m_output->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
533 else if( m_triState->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_TRISTATE );
534 else if( m_passive->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::L_UNSPECIFIED );
535 else if( m_dot->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DOT );
536 else if( m_circle->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_ROUND );
537 else if( m_diamond->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_DIAMOND );
538 else if( m_rectangle->GetValue() ) m_currentLabel->SetShape( LABEL_FLAG_SHAPE::F_RECTANGLE );
539 }
540
542 {
544 m_italic->IsChecked() ) );
545 }
546
548 static_cast<SCH_DIRECTIVE_LABEL*>( m_currentLabel )->SetPinLength( m_textSize.GetIntValue() );
551
552 // Must come after SetTextSize()
555
557
558 SPIN_STYLE selectedSpinStyle= SPIN_STYLE::LEFT;
559
560 if( m_spin0->IsChecked() ) selectedSpinStyle = SPIN_STYLE::RIGHT;
561 else if( m_spin1->IsChecked() ) selectedSpinStyle = SPIN_STYLE::LEFT;
562 else if( m_spin2->IsChecked() ) selectedSpinStyle = SPIN_STYLE::UP;
563 else if( m_spin3->IsChecked() ) selectedSpinStyle = SPIN_STYLE::BOTTOM;
564
566 {
567 SCH_EDIT_FRAME* frame = static_cast<SCH_EDIT_FRAME*>( m_parentFrame );
569 frame->AutoRotateItem( frame->GetScreen(), m_currentLabel );
570 }
571 else
572 {
574 }
575
577 && m_currentLabel->GetSpinStyle() != selectedSpinStyle )
578 {
579 m_currentLabel->SetSpinStyle( selectedSpinStyle );
580 }
581
583
584 if( fieldsAutoplaced == AUTOPLACE_AUTO || fieldsAutoplaced == AUTOPLACE_MANUAL )
585 m_currentLabel->AutoplaceFields( m_Parent->GetScreen(), fieldsAutoplaced );
586
587 if( !commit.Empty() )
588 commit.Push( _( "Edit Label Properties" ) );
589
590 return true;
591}
592
593
594void DIALOG_LABEL_PROPERTIES::onSpinButton( wxCommandEvent& aEvent )
595{
596 for( BITMAP_BUTTON* btn : { m_spin0, m_spin1, m_spin2, m_spin3 } )
597 {
598 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
599 btn->Check( false );
600 }
601}
602
603
604void DIALOG_LABEL_PROPERTIES::OnFormattingHelp( wxHyperlinkEvent& aEvent )
605{
607}
608
609
610void DIALOG_LABEL_PROPERTIES::OnAddField( wxCommandEvent& event )
611{
613 return;
614
615 int fieldID = (int) m_fields->size();
616 wxString fieldName;
617
618 if( (int) fieldID == m_currentLabel->GetMandatoryFieldCount()
619 || m_fields->at( m_fields->size()-1 ).GetCanonicalName() == wxT( "Netclass" ) )
620 {
621 fieldName = wxT( "Netclass" );
622 }
623 else
624 {
625 fieldName = SCH_LABEL_BASE::GetDefaultFieldName( fieldName, true );
626 }
627
628 SCH_FIELD newField( VECTOR2I( 0, 0 ), fieldID, m_currentLabel, fieldName );
629
630 if( m_fields->size() > 0 )
631 {
632 newField.SetVisible( m_fields->at( m_fields->size() - 1 ).IsVisible() );
633 newField.SetTextAngle( m_fields->at( m_fields->size() - 1 ).GetTextAngle() );
634 newField.SetItalic( m_fields->at( m_fields->size() - 1 ).IsItalic() );
635 newField.SetBold( m_fields->at( m_fields->size() - 1 ).IsBold() );
636 }
637 else
638 {
639 newField.SetVisible( true );
640 newField.SetItalic( true );
641 }
642
643 m_fields->push_back( newField );
644
645 // notify the grid
646 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
647 m_grid->ProcessTableMessage( msg );
648
649 m_grid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
650 m_grid->SetGridCursor( (int) m_fields->size() - 1, 0 );
651
652 m_grid->EnableCellEditControl();
653 m_grid->ShowCellEditControl();
654}
655
656
657void DIALOG_LABEL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
658{
659 wxArrayInt selectedRows = m_grid->GetSelectedRows();
660
661 if( selectedRows.empty() && m_grid->GetGridCursorRow() >= 0 )
662 selectedRows.push_back( m_grid->GetGridCursorRow() );
663
664 if( selectedRows.empty() )
665 return;
666
667 for( int row : selectedRows )
668 {
669 if( row < m_currentLabel->GetMandatoryFieldCount() )
670 {
671 DisplayError( this, _( "The first field is mandatory." ) );
672 return;
673 }
674 }
675
676 m_grid->CommitPendingChanges( true /* quiet mode */ );
677
678 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
679 selectedRows.Sort( []( int* first, int* second )
680 {
681 return *second - *first;
682 } );
683
684 for( int row : selectedRows )
685 {
686 //avoids an assert if we deselect early here
687 m_grid->DeselectRow( row );
688 m_fields->erase( m_fields->begin() + row );
689
690 // notify the grid
691 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
692 m_grid->ProcessTableMessage( msg );
693
694 if( m_grid->GetNumberRows() > 0 )
695 {
696 m_grid->MakeCellVisible( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
697 m_grid->SetGridCursor( std::max( 0, row-1 ), m_grid->GetGridCursorCol() );
698 }
699 }
700}
701
702
703void DIALOG_LABEL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
704{
706 return;
707
708 int i = m_grid->GetGridCursorRow();
709
711 {
712 SCH_FIELD tmp = m_fields->at( (unsigned) i );
713 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
714 m_fields->insert( m_fields->begin() + i - 1, tmp );
715 m_grid->ForceRefresh();
716
717 m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() );
718 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
719 }
720 else
721 {
722 wxBell();
723 }
724}
725
726
727void DIALOG_LABEL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
728{
730 return;
731
732 int i = m_grid->GetGridCursorRow();
733
734 if( i >= m_currentLabel->GetMandatoryFieldCount() && i < m_grid->GetNumberRows() - 1 )
735 {
736 SCH_FIELD tmp = m_fields->at( (unsigned) i );
737 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
738 m_fields->insert( m_fields->begin() + i + 1, tmp );
739 m_grid->ForceRefresh();
740
741 m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() );
742 m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() );
743 }
744 else
745 {
746 wxBell();
747 }
748}
749
750
752{
753 m_width = aWidth;
754 // Account for scroll bars
755 aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
756
757 m_grid->AutoSizeColumn( 0 );
758 m_grid->SetColSize( 0, std::max( 72, m_grid->GetColSize( 0 ) ) );
759
760 int fixedColsWidth = m_grid->GetColSize( 0 );
761
762 for( int i = 2; i < m_grid->GetNumberCols(); i++ )
763 fixedColsWidth += m_grid->GetColSize( i );
764
765 m_grid->SetColSize( 1, std::max( 120, aWidth - fixedColsWidth ) );
766}
767
768
769void DIALOG_LABEL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
770{
771 std::bitset<64> shownColumns = m_grid->GetShownColumns();
772
773 if( shownColumns != m_shownColumns )
774 {
775 m_shownColumns = shownColumns;
776
777 if( !m_grid->IsCellEditControlShown() )
778 AdjustGridColumns( m_grid->GetRect().GetWidth() );
779 }
780
781 // Handle a delayed focus
782 if( m_delayedFocusRow >= 0 && m_delayedFocusRow < m_grid->GetNumberRows() )
783 {
784 m_grid->SetFocus();
785 m_grid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
787 }
788
791}
792
793
794void DIALOG_LABEL_PROPERTIES::OnSizeGrid( wxSizeEvent& event )
795{
796 int new_size = event.GetSize().GetX();
797
798 if( m_width != new_size )
799 AdjustGridColumns( new_size );
800
801 // Always propagate for a grid repaint (needed if the height changes, as well as width)
802 event.Skip();
803}
804
805
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)
Modify a given item in the model.
Definition: commit.h:108
bool Empty() const
Definition: commit.h:150
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:222
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:240
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:256
COLOR4D GetTextColor() const
Definition: eda_text.h:257
bool IsItalic() const
Definition: eda_text.h:156
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:134
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:524
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:234
int GetTextWidth() const
Definition: eda_text.h:251
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:587
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:187
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:377
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
Definition: eda_text.cpp:326
bool IsBold() const
Definition: eda_text.h:171
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition: eda_text.h:190
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:268
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:290
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
Definition: eda_text.cpp:298
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:490
int GetNumberRows() override
void SetFontSelection(KIFONT::FONT *aFont, bool aSilentMode=false)
Set the selection in wxChoice widget.
Definition: font_choice.cpp:73
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic, bool aForDrawingSheet=false) const
bool HaveFontSelection() const
Definition: font_choice.cpp:95
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:312
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:581
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:511
SCH_SHEET & Root() const
Definition: schematic.h:125
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
Execute the changes.
Definition: sch_commit.cpp:432
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:1486
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:1253
void SetName(const wxString &aName)
Definition: sch_field.cpp:1203
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:167
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
void SetFieldsAutoplaced(AUTOPLACE_ALGO aAlgo)
Definition: sch_item.h:550
AUTOPLACE_ALGO GetFieldsAutoplaced() const
Return whether the fields have been automatically placed.
Definition: sch_item.h:549
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:1400
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:331
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:1406
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:202
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
Definition: sch_label.cpp:560
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:296
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:712
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
Schematic symbol object.
Definition: sch_symbol.h:77
bool IsSymbolLikePowerGlobalLabel() const
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:905
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:2155
VECTOR2I GetPosition() const override
Definition: sch_text.h:141
void SetBitmap(const wxBitmapBundle &aBmp)
int GetIntValue()
Definition: unit_binder.h:129
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:487
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:270
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:443
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:457
std::bitset< 64 > GetShownColumns()
Definition: wx_grid.cpp:476
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:637
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:414
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:416
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:440
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:415
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
AUTOPLACE_ALGO
Definition: sch_item.h:68
@ AUTOPLACE_MANUAL
Definition: sch_item.h:71
@ AUTOPLACE_NONE
Definition: sch_item.h:69
@ AUTOPLACE_AUTO
Definition: sch_item.h:70
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:398
@ 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:695