KiCad PCB EDA Suite
dialog_symbol_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) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <memory>
27
28#include <bitmaps.h>
29#include <wx/tooltip.h>
30#include <grid_tricks.h>
31#include <confirm.h>
32#include <kiface_base.h>
33#include <pin_numbers.h>
34#include <string_utils.h>
35#include <menus_helpers.h>
36#include <kiplatform/ui.h>
41#include <ee_collectors.h>
42#include <symbol_library.h>
43#include <fields_grid_table.h>
44#include <sch_edit_frame.h>
45#include <sch_reference_list.h>
46#include <schematic.h>
47#include <tool/tool_manager.h>
48#include <tool/actions.h>
49#include <math/vector2d.h>
50
51#ifdef KICAD_SPICE
52#include <dialog_sim_model.h>
53#endif /* KICAD_SPICE */
54
55
56wxDEFINE_EVENT( SYMBOL_DELAY_FOCUS, wxCommandEvent );
57wxDEFINE_EVENT( SYMBOL_DELAY_SELECTION, wxCommandEvent );
58
60{
66
67 COL_COUNT // keep as last
68};
69
70
71class SCH_PIN_TABLE_DATA_MODEL : public wxGridTableBase, public std::vector<SCH_PIN>
72{
73protected:
74 std::vector<wxGridCellAttr*> m_nameAttrs;
75 wxGridCellAttr* m_readOnlyAttr;
76 wxGridCellAttr* m_typeAttr;
77 wxGridCellAttr* m_shapeAttr;
78
79public:
81 m_readOnlyAttr( nullptr ),
82 m_typeAttr( nullptr ),
83 m_shapeAttr( nullptr )
84 {
85 }
86
88 {
89 for( wxGridCellAttr* attr : m_nameAttrs )
90 attr->DecRef();
91
92 m_readOnlyAttr->DecRef();
93 m_typeAttr->DecRef();
94 m_shapeAttr->DecRef();
95 }
96
98 {
99 for( wxGridCellAttr* attr : m_nameAttrs )
100 attr->DecRef();
101
102 m_nameAttrs.clear();
103
104 if( m_readOnlyAttr )
105 m_readOnlyAttr->DecRef();
106
107 m_readOnlyAttr = new wxGridCellAttr;
108 m_readOnlyAttr->SetReadOnly( true );
109
110 for( const SCH_PIN& pin : *this )
111 {
112 LIB_PIN* lib_pin = pin.GetLibPin();
113 wxGridCellAttr* attr = nullptr;
114
115 if( lib_pin->GetAlternates().empty() )
116 {
117 attr = new wxGridCellAttr;
118 attr->SetReadOnly( true );
119 }
120 else
121 {
122 wxArrayString choices;
123 choices.push_back( lib_pin->GetName() );
124
125 for( const std::pair<const wxString, LIB_PIN::ALT>& alt : lib_pin->GetAlternates() )
126 choices.push_back( alt.first );
127
128 attr = new wxGridCellAttr();
129 attr->SetEditor( new GRID_CELL_COMBOBOX( choices ) );
130 }
131
132 m_nameAttrs.push_back( attr );
133 }
134
135 if( m_typeAttr )
136 m_typeAttr->DecRef();
137
138 m_typeAttr = new wxGridCellAttr;
140 PinTypeNames() ) );
141 m_typeAttr->SetReadOnly( true );
142
143 if( m_shapeAttr )
144 m_shapeAttr->DecRef();
145
146 m_shapeAttr = new wxGridCellAttr;
148 PinShapeNames() ) );
149 m_shapeAttr->SetReadOnly( true );
150 }
151
152 int GetNumberRows() override { return (int) size(); }
153 int GetNumberCols() override { return COL_COUNT; }
154
155 wxString GetColLabelValue( int aCol ) override
156 {
157 switch( aCol )
158 {
159 case COL_NUMBER: return _( "Number" );
160 case COL_BASE_NAME: return _( "Base Name" );
161 case COL_ALT_NAME: return _( "Alternate Assignment" );
162 case COL_TYPE: return _( "Electrical Type" );
163 case COL_SHAPE: return _( "Graphic Style" );
164 default: wxFAIL; return wxEmptyString;
165 }
166 }
167
168 bool IsEmptyCell( int row, int col ) override
169 {
170 return false; // don't allow adjacent cell overflow, even if we are actually empty
171 }
172
173 wxString GetValue( int aRow, int aCol ) override
174 {
175 return GetValue( at( aRow ), aCol );
176 }
177
178 static wxString GetValue( const SCH_PIN& aPin, int aCol )
179 {
180 switch( aCol )
181 {
182 case COL_NUMBER: return aPin.GetNumber();
183 case COL_BASE_NAME: return aPin.GetLibPin()->GetName();
184 case COL_ALT_NAME: return aPin.GetAlt();
185 case COL_TYPE: return PinTypeNames()[static_cast<int>( aPin.GetType() )];
186 case COL_SHAPE: return PinShapeNames()[static_cast<int>( aPin.GetShape() )];
187 default: wxFAIL; return wxEmptyString;
188 }
189 }
190
191 wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind ) override
192 {
193 switch( aCol )
194 {
195 case COL_NUMBER:
196 case COL_BASE_NAME:
197 m_readOnlyAttr->IncRef();
198 return m_readOnlyAttr;
199
200 case COL_ALT_NAME:
201 m_nameAttrs[ aRow ]->IncRef();
202 return m_nameAttrs[ aRow ];
203
204 case COL_TYPE:
205 m_typeAttr->IncRef();
206 return m_typeAttr;
207
208 case COL_SHAPE:
209 m_shapeAttr->IncRef();
210 return m_shapeAttr;
211
212 default:
213 wxFAIL;
214 return nullptr;
215 }
216 }
217
218 void SetValue( int aRow, int aCol, const wxString &aValue ) override
219 {
220 switch( aCol )
221 {
222 case COL_ALT_NAME:
223 if( aValue == at( aRow ).GetLibPin()->GetName() )
224 at( aRow ).SetAlt( wxEmptyString );
225 else
226 at( aRow ).SetAlt( aValue );
227 break;
228
229 case COL_NUMBER:
230 case COL_BASE_NAME:
231 case COL_TYPE:
232 case COL_SHAPE:
233 // Read-only.
234 break;
235
236 default:
237 wxFAIL;
238 break;
239 }
240 }
241
242 static bool compare( const SCH_PIN& lhs, const SCH_PIN& rhs, int sortCol, bool ascending )
243 {
244 wxString lhStr = GetValue( lhs, sortCol );
245 wxString rhStr = GetValue( rhs, sortCol );
246
247 if( lhStr == rhStr )
248 {
249 // Secondary sort key is always COL_NUMBER
250 sortCol = COL_NUMBER;
251 lhStr = GetValue( lhs, sortCol );
252 rhStr = GetValue( rhs, sortCol );
253 }
254
255 bool res;
256
257 // N.B. To meet the iterator sort conditions, we cannot simply invert the truth
258 // to get the opposite sort. i.e. ~(a<b) != (a>b)
259 auto cmp = [ ascending ]( const auto a, const auto b )
260 {
261 if( ascending )
262 return a < b;
263 else
264 return b < a;
265 };
266
267 switch( sortCol )
268 {
269 case COL_NUMBER:
270 case COL_BASE_NAME:
271 case COL_ALT_NAME:
272 res = cmp( PIN_NUMBERS::Compare( lhStr, rhStr ), 0 );
273 break;
274 case COL_TYPE:
275 case COL_SHAPE:
276 res = cmp( lhStr.CmpNoCase( rhStr ), 0 );
277 break;
278 default:
279 res = cmp( StrNumCmp( lhStr, rhStr ), 0 );
280 break;
281 }
282
283 return res;
284 }
285
286 void SortRows( int aSortCol, bool ascending )
287 {
288 std::sort( begin(), end(),
289 [ aSortCol, ascending ]( const SCH_PIN& lhs, const SCH_PIN& rhs ) -> bool
290 {
291 return compare( lhs, rhs, aSortCol, ascending );
292 } );
293 }
294};
295
296
298 SCH_SYMBOL* aSymbol ) :
300 m_symbol( nullptr ),
301 m_part( nullptr ),
302 m_fieldsSize( 0, 0 ),
303 m_lastRequestedSize( 0, 0 ),
304 m_editorShown( false ),
305 m_fields( nullptr ),
306 m_dataModel( nullptr )
307{
308 m_symbol = aSymbol;
310
311 // GetLibSymbolRef() now points to the cached part in the schematic, which should always be
312 // there for usual cases, but can be null when opening old schematics not storing the part
313 // so we need to handle m_part == nullptr
314 // wxASSERT( m_part );
315
317
318#ifndef KICAD_SPICE
319 m_cbExcludeFromSim->Hide();
320 m_spiceFieldsButton->Hide();
321#endif /* not KICAD_SPICE */
322
323 // Give a bit more room for combobox editors
324 m_fieldsGrid->SetDefaultRowSize( m_fieldsGrid->GetDefaultRowSize() + 4 );
325 m_pinGrid->SetDefaultRowSize( m_pinGrid->GetDefaultRowSize() + 4 );
326
328 m_fieldsGrid->PushEventHandler( new FIELDS_GRID_TRICKS( m_fieldsGrid, this,
329 [&]( wxCommandEvent& aEvent )
330 {
331 OnAddField( aEvent );
332 } ) );
333 m_fieldsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
334
335 // Show/hide columns according to user's preference
336 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
337
338 if( cfg )
339 {
342 }
343
344 if( m_part && m_part->HasConversion() )
345 {
346 // DeMorgan conversions are a subclass of alternate pin assignments, so don't allow
347 // free-form alternate assignments as well. (We won't know how to map the alternates
348 // back and forth when the conversion is changed.)
349 m_pinTablePage->Disable();
350 m_pinTablePage->SetToolTip( _( "Alternate pin assignments are not available for De Morgan "
351 "symbols." ) );
352 }
353 else
354 {
356
357 // Make a copy of the pins for editing
358 for( const std::unique_ptr<SCH_PIN>& pin : m_symbol->GetRawPins() )
359 m_dataModel->push_back( *pin );
360
363
365 }
366
367 m_pinGrid->PushEventHandler( new GRID_TRICKS( m_pinGrid ) );
368 m_pinGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
369
370 wxToolTip::Enable( true );
372
373 // Configure button logos
378
379 // wxFormBuilder doesn't include this event...
380 m_fieldsGrid->Bind( wxEVT_GRID_CELL_CHANGING, &DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging,
381 this );
382 m_pinGrid->Bind( wxEVT_GRID_COL_SORT, &DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort, this );
383 Bind( SYMBOL_DELAY_FOCUS, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedFocus, this );
384 Bind( SYMBOL_DELAY_SELECTION, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedSelection, this );
385
386 QueueEvent( new wxCommandEvent( SYMBOL_DELAY_SELECTION ) );
387 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
388 evt->SetClientData( new VECTOR2I( REFERENCE_FIELD, FDC_VALUE ) );
389 QueueEvent( evt );
390
392}
393
394
396{
397 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
398
399 if( cfg )
400 {
402 cfg->m_Appearance.edit_symbol_width = GetSize().x;
403 cfg->m_Appearance.edit_symbol_height = GetSize().y;
404 }
405
406 // Prevents crash bug in wxGrid's d'tor
408
409 if( m_dataModel )
411
412 m_fieldsGrid->Unbind( wxEVT_GRID_CELL_CHANGING, &DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging,
413 this );
414 m_pinGrid->Unbind( wxEVT_GRID_COL_SORT, &DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort, this );
415 Unbind( SYMBOL_DELAY_FOCUS, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedFocus, this );
416 Unbind( SYMBOL_DELAY_SELECTION, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedSelection, this );
417
418 // Delete the GRID_TRICKS.
419 m_fieldsGrid->PopEventHandler( true );
420 m_pinGrid->PopEventHandler( true );
421}
422
423
425{
426 return dynamic_cast<SCH_EDIT_FRAME*>( wxDialog::GetParent() );
427}
428
429
431{
432 if( !wxDialog::TransferDataToWindow() )
433 return false;
434
435 std::set<wxString> defined;
436
437 // Push a copy of each field into m_updateFields
438 for( int i = 0; i < m_symbol->GetFieldCount(); ++i )
439 {
440 SCH_FIELD field( m_symbol->GetFields()[i] );
441
442 // change offset to be symbol-relative
443 field.Offset( -m_symbol->GetPosition() );
444
445 defined.insert( field.GetName() );
446 m_fields->push_back( field );
447 }
448
449 // Add in any template fieldnames not yet defined:
450 for( const TEMPLATE_FIELDNAME& templateFieldname :
451 GetParent()->Schematic().Settings().m_TemplateFieldNames.GetTemplateFieldNames() )
452 {
453 if( defined.count( templateFieldname.m_Name ) <= 0 )
454 {
455 SCH_FIELD field( VECTOR2I( 0, 0 ), -1, m_symbol, templateFieldname.m_Name );
456 field.SetVisible( templateFieldname.m_Visible );
457 m_fields->push_back( field );
458 }
459 }
460
461 // notify the grid
462 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->size() );
463 m_fieldsGrid->ProcessTableMessage( msg );
465
466 // If a multi-unit symbol, set up the unit selector and interchangeable checkbox.
467 if( m_symbol->GetUnitCount() > 1 )
468 {
469 // Ensure symbol unit is the currently selected unit (mandatory in complex hierarchies)
470 // from the current sheet path, because it can be modified by previous calculations
471 m_symbol->UpdateUnit( m_symbol->GetUnitSelection( &GetParent()->GetCurrentSheet() ) );
472
473 for( int ii = 1; ii <= m_symbol->GetUnitCount(); ii++ )
474 {
475 if( m_symbol->HasUnitDisplayName( ii ) )
476 m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii ) );
477 else
478 m_unitChoice->Append( LIB_SYMBOL::SubReference( ii, false ) );
479 }
480
481 if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
482 m_unitChoice->SetSelection( m_symbol->GetUnit() - 1 );
483 }
484 else
485 {
486 m_unitLabel->Enable( false );
487 m_unitChoice->Enable( false );
488 }
489
490 if( m_part && m_part->HasConversion() )
491 {
492 if( m_symbol->GetConvert() > LIB_ITEM::LIB_CONVERT::BASE )
493 m_cbAlternateSymbol->SetValue( true );
494 }
495 else
496 {
497 m_cbAlternateSymbol->Enable( false );
498 }
499
500 // Set the symbol orientation and mirroring.
501 int orientation = m_symbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
502
503 switch( orientation )
504 {
505 default:
506 case SYM_ORIENT_0: m_orientationCtrl->SetSelection( 0 ); break;
507 case SYM_ORIENT_90: m_orientationCtrl->SetSelection( 1 ); break;
508 case SYM_ORIENT_270: m_orientationCtrl->SetSelection( 2 ); break;
509 case SYM_ORIENT_180: m_orientationCtrl->SetSelection( 3 ); break;
510 }
511
512 int mirror = m_symbol->GetOrientation() & ( SYM_MIRROR_X | SYM_MIRROR_Y );
513
514 switch( mirror )
515 {
516 default: m_mirrorCtrl->SetSelection( 0 ) ; break;
517 case SYM_MIRROR_X: m_mirrorCtrl->SetSelection( 1 ); break;
518 case SYM_MIRROR_Y: m_mirrorCtrl->SetSelection( 2 ); break;
519 }
520
521#ifdef KICAD_SPICE
522 m_cbExcludeFromSim->SetValue( m_symbol->GetFieldText( SIM_ENABLE_FIELD ) == wxS( "0" ) );
523#endif
526 m_cbDNP->SetValue( m_symbol->GetDNP() );
527
528 if( m_part )
529 {
530 m_ShowPinNumButt->SetValue( m_part->ShowPinNumbers() );
531 m_ShowPinNameButt->SetValue( m_part->ShowPinNames() );
532 }
533
534 // Set the symbol's library name.
536
537 Layout();
538 m_fieldsGrid->Layout();
539 wxSafeYield();
540
541 return true;
542}
543
544
546{
547#ifdef KICAD_SPICE
548 int simEnableFieldRow = -1;
549
550 for( int ii = MANDATORY_FIELDS; ii < m_fieldsGrid->GetNumberRows(); ++ii )
551 {
552 if( m_fieldsGrid->GetCellValue( ii, FDC_NAME ) == SIM_ENABLE_FIELD )
553 simEnableFieldRow = ii;
554 }
555
556 if( event.IsChecked() )
557 {
558 if( simEnableFieldRow == -1 )
559 {
560 simEnableFieldRow = (int) m_fields->size();
561 m_fields->emplace_back( VECTOR2I( 0, 0 ), simEnableFieldRow, m_symbol, SIM_ENABLE_FIELD );
562
563 // notify the grid
564 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
565 m_fieldsGrid->ProcessTableMessage( msg );
566 }
567
568 m_fieldsGrid->SetCellValue( simEnableFieldRow, FDC_VALUE, wxT( "0" ) );
569 m_fieldsGrid->SetCellValue( simEnableFieldRow, FDC_SHOWN, wxT( "0" ) );
570 m_fieldsGrid->SetCellValue( simEnableFieldRow, FDC_SHOW_NAME, wxT( "0" ) );
571 }
572 else if( simEnableFieldRow >= 0 )
573 {
574 m_fields->erase( m_fields->begin() + simEnableFieldRow );
575
576 // notify the grid
577 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, simEnableFieldRow, 1 );
578 m_fieldsGrid->ProcessTableMessage( msg );
579 }
580
581 OnModify();
582#endif
583}
584
585
587{
588#ifdef KICAD_SPICE
590 return;
591
592 std::vector<SCH_FIELD> fields;
593
594 for( const SCH_FIELD& field : *m_fields )
595 fields.emplace_back( field );
596
597 DIALOG_SIM_MODEL dialog( this, *m_symbol, fields );
598
599 if( dialog.ShowModal() != wxID_OK )
600 return;
601
602 // Add in any new fields
603 for( const SCH_FIELD& editedField : fields )
604 {
605 bool found = false;
606
607 for( SCH_FIELD& existingField : *m_fields )
608 {
609 if( existingField.GetName() == editedField.GetName() )
610 {
611 found = true;
612 existingField.SetText( editedField.GetText() );
613 break;
614 }
615 }
616
617 if( !found )
618 {
619 m_fields->emplace_back( editedField );
620 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
621 m_fieldsGrid->ProcessTableMessage( msg );
622 }
623 }
624
625 // Remove any deleted fields
626 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
627 {
628 SCH_FIELD& existingField = m_fields->at( ii );
629 bool found = false;
630
631 for( SCH_FIELD& editedField : fields )
632 {
633 if( editedField.GetName() == existingField.GetName() )
634 {
635 found = true;
636 break;
637 }
638 }
639
640 if( !found )
641 {
642 m_fields->erase( m_fields->begin() + ii );
643 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
644 m_fieldsGrid->ClearSelection();
645 m_fieldsGrid->ProcessTableMessage( msg );
646 }
647 }
648
649 OnModify();
650 m_fieldsGrid->ForceRefresh();
651#endif /* KICAD_SPICE */
652}
653
654
656{
657 // Running the Footprint Browser gums up the works and causes the automatic cancel
658 // stuff to no longer work. So we do it here ourselves.
659 EndQuasiModal( wxID_CANCEL );
660}
661
662
664{
665 LIB_ID id;
666
667 if( !m_fieldsGrid->CommitPendingChanges() || !m_fieldsGrid->Validate() )
668 return false;
669
671 {
672 DisplayErrorMessage( this, _( "References must start with a letter." ) );
673
674 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
675 evt->SetClientData( new VECTOR2I( REFERENCE_FIELD, FDC_VALUE ) );
676 QueueEvent( evt );
677
678 return false;
679 }
680
681 // Check for missing field names.
682 for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
683 {
684 SCH_FIELD& field = m_fields->at( i );
685 wxString fieldName = field.GetName( false );
686
687 if( fieldName.IsEmpty() )
688 {
689 DisplayErrorMessage( this, _( "Fields must have a name." ) );
690
691 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
692 evt->SetClientData( new VECTOR2I( i, FDC_VALUE ) );
693 QueueEvent( evt );
694
695 return false;
696 }
697 }
698
699 return true;
700}
701
702
704{
705 if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
706 return false;
707
709 return false;
710
712 return false;
713
714 SCH_SCREEN* currentScreen = GetParent()->GetScreen();
715 wxCHECK( currentScreen, false );
716
717 // This needs to be done before the LIB_ID is changed to prevent stale library symbols in
718 // the schematic file.
719 currentScreen->Remove( m_symbol );
720
721 // save old cmp in undo list if not already in edit, or moving ...
722 if( m_symbol->GetEditFlags() == 0 )
723 GetParent()->SaveCopyInUndoList( currentScreen, m_symbol, UNDO_REDO::CHANGED, false );
724
725 // Save current flags which could be modified by next change settings
727
728 // For symbols with multiple shapes (De Morgan representation) Set the selected shape:
729 if( m_cbAlternateSymbol->IsEnabled() && m_cbAlternateSymbol->GetValue() )
730 m_symbol->SetConvert( LIB_ITEM::LIB_CONVERT::DEMORGAN );
731 else
732 m_symbol->SetConvert( LIB_ITEM::LIB_CONVERT::BASE );
733
734 //Set the part selection in multiple part per package
735 int unit_selection = m_unitChoice->IsEnabled() ? m_unitChoice->GetSelection() + 1 : 1;
736 m_symbol->SetUnitSelection( &GetParent()->GetCurrentSheet(), unit_selection );
737 m_symbol->SetUnit( unit_selection );
738
739 switch( m_orientationCtrl->GetSelection() )
740 {
741 case 0: m_symbol->SetOrientation( SYM_ORIENT_0 ); break;
742 case 1: m_symbol->SetOrientation( SYM_ORIENT_90 ); break;
743 case 2: m_symbol->SetOrientation( SYM_ORIENT_270 ); break;
744 case 3: m_symbol->SetOrientation( SYM_ORIENT_180 ); break;
745 }
746
747 switch( m_mirrorCtrl->GetSelection() )
748 {
749 case 0: break;
750 case 1: m_symbol->SetOrientation( SYM_MIRROR_X ); break;
751 case 2: m_symbol->SetOrientation( SYM_MIRROR_Y ); break;
752 }
753
754 if( m_part )
755 {
758 }
759
760 // Restore m_Flag modified by SetUnit() and other change settings from the dialog
762 m_symbol->SetFlags( flags );
763
764 // change all field positions from relative to absolute
765 for( unsigned i = 0; i < m_fields->size(); ++i )
766 m_fields->at( i ).Offset( m_symbol->GetPosition() );
767
768 SCH_FIELDS& fields = m_symbol->GetFields();
769
770 fields.clear();
771
772 for( size_t i = 0; i < m_fields->size(); ++i )
773 fields.push_back( m_fields->at( i ) );
774
775 // Reference has a specific initialization, depending on the current active sheet
776 // because for a given symbol, in a complex hierarchy, there are more than one
777 // reference.
778 m_symbol->SetRef( &GetParent()->GetCurrentSheet(), m_fields->at( REFERENCE_FIELD ).GetText() );
779
780 // Similar for Value and Footprint, except that the GUI behaviour is that they are kept
781 // in sync between multiple instances.
782 m_symbol->SetValueFieldText( m_fields->at( VALUE_FIELD ).GetText() );
784
787 m_symbol->SetDNP( m_cbDNP->IsChecked() );
788
789 // Update any assignments
790 if( m_dataModel )
791 {
792 for( const SCH_PIN& model_pin : *m_dataModel )
793 {
794 // map from the edited copy back to the "real" pin in the symbol.
795 SCH_PIN* src_pin = m_symbol->GetPin( model_pin.GetNumber() );
796
797 if( src_pin )
798 src_pin->SetAlt( model_pin.GetAlt() );
799 }
800 }
801
802 // Keep fields other than the reference, include/exclude flags, and alternate pin assignements
803 // in sync in multi-unit parts.
804 if( m_symbol->GetUnitCount() > 1 && m_symbol->IsAnnotated( &GetParent()->GetCurrentSheet() ) )
805 {
806 wxString ref = m_symbol->GetRef( &GetParent()->GetCurrentSheet() );
807 int unit = m_symbol->GetUnit();
808 LIB_ID libId = m_symbol->GetLibId();
809
810 for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() )
811 {
812 SCH_SCREEN* screen = sheet.LastScreen();
813 std::vector<SCH_SYMBOL*> otherUnits;
814 constexpr bool appendUndo = true;
815
816 CollectOtherUnits( ref, unit, libId, sheet, &otherUnits );
817
818 for( SCH_SYMBOL* otherUnit : otherUnits )
819 {
820 GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED,
821 appendUndo );
822 otherUnit->SetValueFieldText( m_fields->at( VALUE_FIELD ).GetText() );
823 otherUnit->SetFootprintFieldText( m_fields->at( FOOTPRINT_FIELD ).GetText() );
824
825 for( size_t ii = DATASHEET_FIELD; ii < m_fields->size(); ++ii )
826 {
827 SCH_FIELD* otherField = otherUnit->FindField( m_fields->at( ii ).GetName() );
828
829 if( otherField )
830 {
831 otherField->SetText( m_fields->at( ii ).GetText() );
832 }
833 else
834 {
835 SCH_FIELD newField( m_fields->at( ii ) );
836 const_cast<KIID&>( newField.m_Uuid ) = KIID();
837
838 newField.Offset( -m_symbol->GetPosition() );
839 newField.Offset( otherUnit->GetPosition() );
840
841 newField.SetParent( otherUnit );
842 otherUnit->AddField( newField );
843 }
844 }
845
846 for( size_t ii = otherUnit->GetFields().size() - 1; ii > DATASHEET_FIELD; ii-- )
847 {
848 SCH_FIELD& otherField = otherUnit->GetFields().at( ii );
849
850 if( !m_symbol->FindField( otherField.GetName() ) )
851 otherUnit->GetFields().erase( otherUnit->GetFields().begin() + ii );
852 }
853
854 otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() );
855 otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() );
856 otherUnit->SetDNP( m_cbDNP->IsChecked() );
857
858 if( m_dataModel )
859 {
860 for( const SCH_PIN& model_pin : *m_dataModel )
861 {
862 SCH_PIN* src_pin = otherUnit->GetPin( model_pin.GetNumber() );
863
864 if( src_pin )
865 src_pin->SetAlt( model_pin.GetAlt() );
866 }
867 }
868
869 GetParent()->UpdateItem( otherUnit, false, true );
870 }
871 }
872 }
873
874 currentScreen->Append( m_symbol );
876 GetParent()->UpdateItem( m_symbol, false, true );
877 GetParent()->OnModify();
878
879 // This must go after OnModify() so that the connectivity graph will have been updated.
881
882 return true;
883}
884
885
887{
888 wxGridCellEditor* editor = m_fieldsGrid->GetCellEditor( event.GetRow(), event.GetCol() );
889 wxControl* control = editor->GetControl();
890
891 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
892 {
893 event.Veto();
894 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
895 evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
896 QueueEvent( evt );
897 }
898 else if( event.GetCol() == FDC_NAME )
899 {
900 wxString newName = event.GetString();
901
902 for( int i = 0; i < m_fieldsGrid->GetNumberRows(); ++i )
903 {
904 if( i == event.GetRow() )
905 continue;
906
907 if( newName.CmpNoCase( m_fieldsGrid->GetCellValue( i, FDC_NAME ) ) == 0 )
908 {
909 DisplayError( this, wxString::Format( _( "Field name '%s' already in use." ),
910 newName ) );
911 event.Veto();
912 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
913 evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
914 QueueEvent( evt );
915 }
916 }
917 }
918
919 editor->DecRef();
920}
921
922
924{
925 if( aEvent.GetRow() == REFERENCE_FIELD && aEvent.GetCol() == FDC_VALUE )
926 QueueEvent( new wxCommandEvent( SYMBOL_DELAY_SELECTION ) );
927
928 m_editorShown = true;
929}
930
931
933{
934 m_editorShown = false;
935}
936
937
938void DIALOG_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
939{
941 return;
942
944 int fieldID = (int) m_fields->size();
945 SCH_FIELD newField( VECTOR2I( 0, 0 ), fieldID, m_symbol,
947
948 newField.SetTextAngle( m_fields->at( REFERENCE_FIELD ).GetTextAngle() );
949 newField.SetTextSize( VECTOR2I( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
950
951 m_fields->push_back( newField );
952
953 // notify the grid
954 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
955 m_fieldsGrid->ProcessTableMessage( msg );
956
957 m_fieldsGrid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
958 m_fieldsGrid->SetGridCursor( (int) m_fields->size() - 1, 0 );
959
960 m_fieldsGrid->EnableCellEditControl();
961 m_fieldsGrid->ShowCellEditControl();
962
963 OnModify();
964}
965
966
967void DIALOG_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
968{
969 wxArrayInt selectedRows = m_fieldsGrid->GetSelectedRows();
970
971 if( selectedRows.empty() && m_fieldsGrid->GetGridCursorRow() >= 0 )
972 selectedRows.push_back( m_fieldsGrid->GetGridCursorRow() );
973
974 if( selectedRows.empty() )
975 return;
976
977 for( int row : selectedRows )
978 {
979 if( row < MANDATORY_FIELDS )
980 {
981 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
983 return;
984 }
985 }
986
987 m_fieldsGrid->CommitPendingChanges( true /* quiet mode */ );
988 m_fieldsGrid->ClearSelection();
989
990 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
991 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
992
993 for( int row : selectedRows )
994 {
995 m_fields->erase( m_fields->begin() + row );
996
997 // notify the grid
998 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
999 m_fieldsGrid->ProcessTableMessage( msg );
1000
1001 if( m_fieldsGrid->GetNumberRows() > 0 )
1002 {
1003 m_fieldsGrid->MakeCellVisible( std::max( 0, row-1 ), m_fieldsGrid->GetGridCursorCol() );
1004 m_fieldsGrid->SetGridCursor( std::max( 0, row-1 ), m_fieldsGrid->GetGridCursorCol() );
1005 }
1006 }
1007
1008 OnModify();
1009}
1010
1011
1012void DIALOG_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
1013{
1015 return;
1016
1017 int i = m_fieldsGrid->GetGridCursorRow();
1018
1019 if( i > MANDATORY_FIELDS )
1020 {
1021 SCH_FIELD tmp = m_fields->at( (unsigned) i );
1022 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
1023 m_fields->insert( m_fields->begin() + i - 1, tmp );
1024 m_fieldsGrid->ForceRefresh();
1025
1026 m_fieldsGrid->SetGridCursor( i - 1, m_fieldsGrid->GetGridCursorCol() );
1027 m_fieldsGrid->MakeCellVisible( m_fieldsGrid->GetGridCursorRow(),
1028 m_fieldsGrid->GetGridCursorCol() );
1029
1030 OnModify();
1031 }
1032 else
1033 {
1034 wxBell();
1035 }
1036}
1037
1038
1039void DIALOG_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
1040{
1042 return;
1043
1044 int i = m_fieldsGrid->GetGridCursorRow();
1045
1046 if( i >= MANDATORY_FIELDS && i < m_fieldsGrid->GetNumberRows() - 1 )
1047 {
1048 SCH_FIELD tmp = m_fields->at( (unsigned) i );
1049 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
1050 m_fields->insert( m_fields->begin() + i + 1, tmp );
1051 m_fieldsGrid->ForceRefresh();
1052
1053 m_fieldsGrid->SetGridCursor( i + 1, m_fieldsGrid->GetGridCursorCol() );
1054 m_fieldsGrid->MakeCellVisible( m_fieldsGrid->GetGridCursorRow(),
1055 m_fieldsGrid->GetGridCursorCol() );
1056
1057 OnModify();
1058 }
1059 else
1060 {
1061 wxBell();
1062 }
1063}
1064
1065
1067{
1070}
1071
1072
1074{
1077}
1078
1079
1081{
1084}
1085
1086
1088{
1091}
1092
1093
1095{
1096 int row = aEvent.GetRow();
1097
1098 if( m_pinGrid->GetCellValue( row, COL_ALT_NAME )
1099 == m_dataModel->GetValue( row, COL_BASE_NAME ) )
1100 {
1101 m_dataModel->SetValue( row, COL_ALT_NAME, wxEmptyString );
1102 }
1103
1104 // These are just to get the cells refreshed
1107
1108 OnModify();
1109}
1110
1111
1113{
1114 int sortCol = aEvent.GetCol();
1115 bool ascending;
1116
1117 // This is bonkers, but wxWidgets doesn't tell us ascending/descending in the
1118 // event, and if we ask it will give us pre-event info.
1119 if( m_pinGrid->IsSortingBy( sortCol ) )
1120 // same column; invert ascending
1121 ascending = !m_pinGrid->IsSortOrderAscending();
1122 else
1123 // different column; start with ascending
1124 ascending = true;
1125
1126 m_dataModel->SortRows( sortCol, ascending );
1128}
1129
1130
1132{
1133 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_fieldsGrid );
1134
1135 // Account for scroll bars
1136 int fieldsWidth = KIPLATFORM::UI::GetUnobscuredSize( m_fieldsGrid ).x;
1137
1138 m_fieldsGrid->AutoSizeColumn( 0 );
1139 m_fieldsGrid->SetColSize( 0, std::max( 72, m_fieldsGrid->GetColSize( 0 ) ) );
1140
1141 int fixedColsWidth = m_fieldsGrid->GetColSize( 0 );
1142
1143 for( int i = 2; i < m_fieldsGrid->GetNumberCols(); i++ )
1144 fixedColsWidth += m_fieldsGrid->GetColSize( i );
1145
1146 m_fieldsGrid->SetColSize( 1, std::max( 120, fieldsWidth - fixedColsWidth ) );
1147}
1148
1149
1151{
1152 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinGrid );
1153
1154 // Account for scroll bars
1155 int pinTblWidth = KIPLATFORM::UI::GetUnobscuredSize( m_pinGrid ).x;
1156
1157 // Stretch the Base Name and Alternate Assignment columns to fit.
1158 for( int i = 0; i < COL_COUNT; ++i )
1159 {
1160 if( i != COL_BASE_NAME && i != COL_ALT_NAME )
1161 pinTblWidth -= m_pinGrid->GetColSize( i );
1162 }
1163
1164 m_pinGrid->SetColSize( COL_BASE_NAME, pinTblWidth / 2 );
1165 m_pinGrid->SetColSize( COL_ALT_NAME, pinTblWidth / 2 );
1166}
1167
1168
1169void DIALOG_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1170{
1171 wxString shownColumns = m_fieldsGrid->GetShownColumns();
1172
1173 if( shownColumns != m_shownColumns )
1174 {
1175 m_shownColumns = shownColumns;
1176
1177 if( !m_fieldsGrid->IsCellEditControlShown() )
1179 }
1180
1181#ifdef KICAD_SPICE
1182 wxString simEnable;
1183
1184 for( int ii = MANDATORY_FIELDS; ii < m_fieldsGrid->GetNumberRows(); ++ii )
1185 {
1186 if( m_fieldsGrid->GetCellValue( ii, FDC_NAME ) == SIM_ENABLE_FIELD )
1187 {
1188 simEnable = m_fieldsGrid->GetCellValue( ii, FDC_VALUE );
1189 break;
1190 }
1191 }
1192
1193 m_cbExcludeFromSim->SetValue( simEnable == wxS( "0" ) );
1194#endif
1195}
1196
1197
1199{
1200 VECTOR2I *loc = static_cast<VECTOR2I*>( event.GetClientData() );
1201
1202 wxCHECK_RET( loc, wxT( "Missing focus cell location" ) );
1203
1204 // Handle a delayed focus
1205
1206 m_fieldsGrid->SetFocus();
1207 m_fieldsGrid->MakeCellVisible( loc->x, loc->y );
1208 m_fieldsGrid->SetGridCursor( loc->x, loc->y );
1209
1210 m_fieldsGrid->EnableCellEditControl( true );
1211 m_fieldsGrid->ShowCellEditControl();
1212
1213 delete loc;
1214}
1215
1216
1218{
1219 // Handle a delayed selection
1220 wxGridCellEditor* cellEditor = m_fieldsGrid->GetCellEditor( REFERENCE_FIELD, FDC_VALUE );
1221
1222 if( wxTextEntry* txt = dynamic_cast<wxTextEntry*>( cellEditor->GetControl() ) )
1224
1225 cellEditor->DecRef(); // we're done; must release
1226}
1227
1229{
1230 wxSize new_size = event.GetSize();
1231
1232 if( ( !m_editorShown || m_lastRequestedSize != new_size ) && m_fieldsSize != new_size )
1233 {
1234 m_fieldsSize = new_size;
1235
1237 }
1238
1239 // We store this value to check whether the dialog is changing size. This might indicate
1240 // that the user is scaling the dialog with an editor shown. Some editors do not close
1241 // (at least on GTK) when the user drags a dialog corner
1242 m_lastRequestedSize = new_size;
1243
1244 // Always propagate for a grid repaint (needed if the height changes, as well as width)
1245 event.Skip();
1246}
1247
1248
1250{
1251 wxSize new_size = event.GetSize();
1252
1253 if( m_pinsSize != new_size )
1254 {
1255 m_pinsSize = new_size;
1256
1258 }
1259
1260 // Always propagate for a grid repaint (needed if the height changes, as well as width)
1261 event.Skip();
1262}
1263
1264
1265void DIALOG_SYMBOL_PROPERTIES::OnInitDlg( wxInitDialogEvent& event )
1266{
1268
1269 // Now all widgets have the size fixed, call FinishDialogSettings
1271
1272 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
1273
1274 if( cfg && cfg->m_Appearance.edit_symbol_width > 0 && cfg->m_Appearance.edit_symbol_height > 0 )
1276}
1277
1278
1279void DIALOG_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
1280{
1281 OnModify();
1282}
1283
1284
1285void DIALOG_SYMBOL_PROPERTIES::OnUnitChoice( wxCommandEvent& event )
1286{
1287 if( m_dataModel )
1288 {
1289 EDA_ITEM_FLAGS flags = m_symbol->GetFlags();
1290
1291 int unit_selection = m_unitChoice->GetSelection() + 1;
1292
1293 // We need to select a new unit to build the new unit pin list
1294 // but we should not change the symbol, so the initial unit will be selected
1295 // after rebuilding the pin list
1296 int old_unit = m_symbol->GetUnit();
1297 m_symbol->SetUnit( unit_selection );
1298
1299 // Rebuild a copy of the pins of the new unit for editing
1300 m_dataModel->clear();
1301
1302 for( const std::unique_ptr<SCH_PIN>& pin : m_symbol->GetRawPins() )
1303 m_dataModel->push_back( *pin );
1304
1307
1308 m_symbol->SetUnit( old_unit );
1309
1310 // Restore m_Flag modified by SetUnit()
1312 m_symbol->SetFlags( flags );
1313 }
1314
1315 OnModify();
1316}
1317
1318
1320{
1321 event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
1322}
1323
1324
1326{
1327 event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
1328}
1329
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
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void EndQuasiModal(int retCode)
void OnModify()
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Class DIALOG_SYMBOL_PROPERTIES_BASE.
void OnSizePinsGrid(wxSizeEvent &event) override
void OnPinTableCellEdited(wxGridEvent &event) override
void OnGridEditorShown(wxGridEvent &event) override
void OnUpdateUI(wxUpdateUIEvent &event) override
void OnEditSymbol(wxCommandEvent &) override
void OnCancelButtonClick(wxCommandEvent &event) override
virtual void onUpdateEditLibrarySymbol(wxUpdateUIEvent &event) override
SCH_PIN_TABLE_DATA_MODEL * m_dataModel
void OnExcludeFromSimulation(wxCommandEvent &event) override
void OnMoveDown(wxCommandEvent &event) override
void OnSizeFieldsGrid(wxSizeEvent &event) override
void OnPinTableColSort(wxGridEvent &aEvent)
void OnMoveUp(wxCommandEvent &event) override
void OnDeleteField(wxCommandEvent &event) override
void OnInitDlg(wxInitDialogEvent &event) override
void OnAddField(wxCommandEvent &event) override
void OnGridEditorHidden(wxGridEvent &event) override
void OnUnitChoice(wxCommandEvent &event) override
void OnEditSpiceModel(wxCommandEvent &event) override
DIALOG_SYMBOL_PROPERTIES(SCH_EDIT_FRAME *aParent, SCH_SYMBOL *aSymbol)
void HandleDelayedFocus(wxCommandEvent &event)
void HandleDelayedSelection(wxCommandEvent &event)
void OnCheckBox(wxCommandEvent &event) override
void OnGridCellChanging(wxGridEvent &event)
void OnEditLibrarySymbol(wxCommandEvent &) override
void OnUpdateSymbol(wxCommandEvent &) override
FIELDS_GRID_TABLE< SCH_FIELD > * m_fields
void OnExchangeSymbol(wxCommandEvent &) override
virtual void onUpdateEditSymbol(wxUpdateUIEvent &event) override
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:145
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:139
const KIID m_Uuid
Definition: eda_item.h:492
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:141
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:142
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:391
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:219
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:349
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:165
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:195
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:214
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
Definition: kiid.h:48
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
UTF8 Format() const
Definition: lib_id.cpp:117
std::map< wxString, ALT > & GetAlternates()
Definition: lib_pin.h:138
const wxString & GetName() const
Definition: lib_pin.h:112
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
Definition: lib_symbol.h:624
bool ShowPinNames() const
Definition: lib_symbol.h:625
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:632
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:581
bool HasConversion() const
Test if symbol has more than one body conversion type (DeMorgan).
bool ShowPinNumbers() const
Definition: lib_symbol.h:633
static int Compare(const wxString &lhs, const wxString &rhs)
These settings were stored in SCH_BASE_FRAME previously.
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:205
Schematic editor (Eeschema) main window.
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
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.
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false) override
Mark an item for refresh.
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:804
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:112
bool IsEmptyCell(int row, int col) override
wxString GetValue(int aRow, int aCol) override
std::vector< wxGridCellAttr * > m_nameAttrs
static bool compare(const SCH_PIN &lhs, const SCH_PIN &rhs, int sortCol, bool ascending)
void SortRows(int aSortCol, bool ascending)
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind) override
static wxString GetValue(const SCH_PIN &aPin, int aCol)
wxString GetColLabelValue(int aCol) override
void SetValue(int aRow, int aCol, const wxString &aValue) override
void SetAlt(const wxString &aAlt)
Definition: sch_pin.h:65
wxString GetAlt() const
Definition: sch_pin.h:64
LIB_PIN * GetLibPin() const
Definition: sch_pin.h:59
wxString GetNumber() const
Definition: sch_pin.h:140
GRAPHIC_PINSHAPE GetShape() const
Definition: sch_pin.cpp:126
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:117
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:145
bool Remove(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:307
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition: sch_symbol.h:81
int GetUnitCount() const
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:427
void SetConvert(int aConvert)
Definition: sch_symbol.cpp:404
std::vector< std::unique_ptr< SCH_PIN > > & GetRawPins()
Definition: sch_symbol.h:547
int GetUnit() const
Definition: sch_symbol.h:228
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:486
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true)
Search for a SCH_FIELD with aFieldName.
Definition: sch_symbol.cpp:938
void SetDNP(bool aDNP)
Definition: sch_symbol.h:754
void UpdateUnit(int aUnit)
Change the unit number to aUnit without setting any internal flags.
Definition: sch_symbol.cpp:398
void SetIncludeOnBoard(bool aIncludeOnBoard)
Definition: sch_symbol.h:751
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:710
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:844
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:674
bool GetIncludeOnBoard() const
Definition: sch_symbol.h:750
bool GetIncludeInBom() const
Definition: sch_symbol.h:747
int GetConvert() const
Definition: sch_symbol.h:270
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
Definition: sch_symbol.cpp:716
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
void SetFootprintFieldText(const wxString &aFootprint)
Definition: sch_symbol.cpp:859
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:712
bool HasUnitDisplayName(int aUnit)
Return true if the given unit aUnit has a display name set.
Definition: sch_symbol.cpp:444
int GetOrientation() const
Get the display symbol orientation.
bool IsAnnotated(const SCH_SHEET_PATH *aSheet)
Check if the symbol has a valid annotation (reference) for the given sheet path.
Definition: sch_symbol.cpp:752
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:793
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:388
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:175
wxString GetUnitDisplayName(int aUnit)
Return the display name for a given unit aUnit.
Definition: sch_symbol.cpp:436
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:901
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:809
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:192
wxString GetFieldText(const wxString &aFieldName) const
Search for a field named aFieldName and returns text associated with this field.
Definition: sch_symbol.cpp:889
void SetIncludeInBom(bool aIncludeInBom)
Definition: sch_symbol.h:748
bool GetDNP() const
Definition: sch_symbol.h:753
void SetBitmap(const wxBitmap &aBmp)
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
Definition: wx_grid.cpp:295
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 GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:276
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:423
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:300
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:325
This file is part of the common library.
wxDEFINE_EVENT(SYMBOL_DELAY_FOCUS, wxCommandEvent)
@ SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL
@ SYMBOL_PROPS_WANT_EXCHANGE_SYMBOL
@ SYMBOL_PROPS_WANT_UPDATE_SYMBOL
@ SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL
#define _(s)
std::uint32_t EDA_ITEM_FLAGS
void CollectOtherUnits(const wxString &aRef, int aUnit, const LIB_ID &aLibId, SCH_SHEET_PATH &aSheet, std::vector< SCH_SYMBOL * > *otherUnits)
@ FDC_SHOW_NAME
@ FDC_NAME
@ FDC_SHOWN
@ FDC_VALUE
Macros and inline functions to create menus items in menubars or popup menus.
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: gtk/ui.cpp:133
void SelectReferenceNumber(wxTextEntry *aTextEntry)
Select the number (or "?") in a reference for ease of editing.
Definition: ui_common.cpp:230
must_if< error >::control< Rule > control
const std::vector< BITMAPS > & PinTypeIcons()
Definition: pin_type.cpp:195
const wxArrayString & PinTypeNames()
Definition: pin_type.cpp:186
const wxArrayString & PinShapeNames()
Definition: pin_type.cpp:204
const std::vector< BITMAPS > & PinShapeIcons()
Definition: pin_type.cpp:213
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
@ SYM_ORIENT_270
@ SYM_MIRROR_Y
@ SYM_ORIENT_180
@ SYM_MIRROR_X
@ SYM_ORIENT_90
@ SYM_ORIENT_0
std::vector< SCH_FIELD > SCH_FIELDS
A container for several SCH_FIELD items.
Definition: sch_symbol.h:69
#define SIM_ENABLE_FIELD
Definition: sim_model.h:56
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString UnescapeString(const wxString &aSource)
Hold a name of a symbol's field, field value, and default visibility.
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslateForHI=false)
Return a default symbol field name for field aFieldNdx for all components.
Definition for symbol library class.
#define DO_TRANSLATE
@ DATASHEET_FIELD
name of datasheet
@ FOOTPRINT_FIELD
Field Name Module PCB, i.e. "16DIP300".
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ MANDATORY_FIELDS
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
VECTOR3I res
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590