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>
40#include <ee_collectors.h>
41#include <symbol_library.h>
42#include <fields_grid_table.h>
43#include <sch_edit_frame.h>
44#include <sch_reference_list.h>
45#include <schematic.h>
46#include <tool/tool_manager.h>
47#include <tool/actions.h>
48#include <math/vector2d.h>
49
50#ifdef KICAD_SPICE
51#include <dialog_sim_model.h>
52#endif /* KICAD_SPICE */
53
54
55wxDEFINE_EVENT( SYMBOL_DELAY_FOCUS, wxCommandEvent );
56wxDEFINE_EVENT( SYMBOL_DELAY_SELECTION, wxCommandEvent );
57
59{
65
66 COL_COUNT // keep as last
67};
68
69
70class SCH_PIN_TABLE_DATA_MODEL : public wxGridTableBase, public std::vector<SCH_PIN>
71{
72protected:
73 std::vector<wxGridCellAttr*> m_nameAttrs;
74 wxGridCellAttr* m_readOnlyAttr;
75 wxGridCellAttr* m_typeAttr;
76 wxGridCellAttr* m_shapeAttr;
77
78public:
80 m_readOnlyAttr( nullptr ),
81 m_typeAttr( nullptr ),
82 m_shapeAttr( nullptr )
83 {
84 }
85
87 {
88 for( wxGridCellAttr* attr : m_nameAttrs )
89 attr->DecRef();
90
91 m_readOnlyAttr->DecRef();
92 m_typeAttr->DecRef();
93 m_shapeAttr->DecRef();
94 }
95
97 {
98 for( wxGridCellAttr* attr : m_nameAttrs )
99 attr->DecRef();
100
101 m_nameAttrs.clear();
102
103 if( m_readOnlyAttr )
104 m_readOnlyAttr->DecRef();
105
106 m_readOnlyAttr = new wxGridCellAttr;
107 m_readOnlyAttr->SetReadOnly( true );
108
109 for( const SCH_PIN& pin : *this )
110 {
111 LIB_PIN* lib_pin = pin.GetLibPin();
112 wxGridCellAttr* attr = nullptr;
113
114 if( lib_pin->GetAlternates().empty() )
115 {
116 attr = new wxGridCellAttr;
117 attr->SetReadOnly( true );
118 }
119 else
120 {
121 wxArrayString choices;
122 choices.push_back( lib_pin->GetName() );
123
124 for( const std::pair<const wxString, LIB_PIN::ALT>& alt : lib_pin->GetAlternates() )
125 choices.push_back( alt.first );
126
127 attr = new wxGridCellAttr();
128 attr->SetEditor( new GRID_CELL_COMBOBOX( choices ) );
129 }
130
131 m_nameAttrs.push_back( attr );
132 }
133
134 if( m_typeAttr )
135 m_typeAttr->DecRef();
136
137 m_typeAttr = new wxGridCellAttr;
139 PinTypeNames() ) );
140 m_typeAttr->SetReadOnly( true );
141
142 if( m_shapeAttr )
143 m_shapeAttr->DecRef();
144
145 m_shapeAttr = new wxGridCellAttr;
147 PinShapeNames() ) );
148 m_shapeAttr->SetReadOnly( true );
149 }
150
151 int GetNumberRows() override { return (int) size(); }
152 int GetNumberCols() override { return COL_COUNT; }
153
154 wxString GetColLabelValue( int aCol ) override
155 {
156 switch( aCol )
157 {
158 case COL_NUMBER: return _( "Number" );
159 case COL_BASE_NAME: return _( "Base Name" );
160 case COL_ALT_NAME: return _( "Alternate Assignment" );
161 case COL_TYPE: return _( "Electrical Type" );
162 case COL_SHAPE: return _( "Graphic Style" );
163 default: wxFAIL; return wxEmptyString;
164 }
165 }
166
167 bool IsEmptyCell( int row, int col ) override
168 {
169 return false; // don't allow adjacent cell overflow, even if we are actually empty
170 }
171
172 wxString GetValue( int aRow, int aCol ) override
173 {
174 return GetValue( at( aRow ), aCol );
175 }
176
177 static wxString GetValue( const SCH_PIN& aPin, int aCol )
178 {
179 switch( aCol )
180 {
181 case COL_NUMBER: return aPin.GetNumber();
182 case COL_BASE_NAME: return aPin.GetLibPin()->GetName();
183 case COL_ALT_NAME: return aPin.GetAlt();
184 case COL_TYPE: return PinTypeNames()[static_cast<int>( aPin.GetType() )];
185 case COL_SHAPE: return PinShapeNames()[static_cast<int>( aPin.GetShape() )];
186 default: wxFAIL; return wxEmptyString;
187 }
188 }
189
190 wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind ) override
191 {
192 switch( aCol )
193 {
194 case COL_NUMBER:
195 case COL_BASE_NAME:
196 m_readOnlyAttr->IncRef();
197 return m_readOnlyAttr;
198
199 case COL_ALT_NAME:
200 m_nameAttrs[ aRow ]->IncRef();
201 return m_nameAttrs[ aRow ];
202
203 case COL_TYPE:
204 m_typeAttr->IncRef();
205 return m_typeAttr;
206
207 case COL_SHAPE:
208 m_shapeAttr->IncRef();
209 return m_shapeAttr;
210
211 default:
212 wxFAIL;
213 return nullptr;
214 }
215 }
216
217 void SetValue( int aRow, int aCol, const wxString &aValue ) override
218 {
219 switch( aCol )
220 {
221 case COL_ALT_NAME:
222 if( aValue == at( aRow ).GetLibPin()->GetName() )
223 at( aRow ).SetAlt( wxEmptyString );
224 else
225 at( aRow ).SetAlt( aValue );
226 break;
227
228 case COL_NUMBER:
229 case COL_BASE_NAME:
230 case COL_TYPE:
231 case COL_SHAPE:
232 // Read-only.
233 break;
234
235 default:
236 wxFAIL;
237 break;
238 }
239 }
240
241 static bool compare( const SCH_PIN& lhs, const SCH_PIN& rhs, int sortCol, bool ascending )
242 {
243 wxString lhStr = GetValue( lhs, sortCol );
244 wxString rhStr = GetValue( rhs, sortCol );
245
246 if( lhStr == rhStr )
247 {
248 // Secondary sort key is always COL_NUMBER
249 sortCol = COL_NUMBER;
250 lhStr = GetValue( lhs, sortCol );
251 rhStr = GetValue( rhs, sortCol );
252 }
253
254 bool res;
255
256 // N.B. To meet the iterator sort conditions, we cannot simply invert the truth
257 // to get the opposite sort. i.e. ~(a<b) != (a>b)
258 auto cmp = [ ascending ]( const auto a, const auto b )
259 {
260 if( ascending )
261 return a < b;
262 else
263 return b < a;
264 };
265
266 switch( sortCol )
267 {
268 case COL_NUMBER:
269 case COL_BASE_NAME:
270 case COL_ALT_NAME:
271 res = cmp( PIN_NUMBERS::Compare( lhStr, rhStr ), 0 );
272 break;
273 case COL_TYPE:
274 case COL_SHAPE:
275 res = cmp( lhStr.CmpNoCase( rhStr ), 0 );
276 break;
277 default:
278 res = cmp( StrNumCmp( lhStr, rhStr ), 0 );
279 break;
280 }
281
282 return res;
283 }
284
285 void SortRows( int aSortCol, bool ascending )
286 {
287 std::sort( begin(), end(),
288 [ aSortCol, ascending ]( const SCH_PIN& lhs, const SCH_PIN& rhs ) -> bool
289 {
290 return compare( lhs, rhs, aSortCol, ascending );
291 } );
292 }
293};
294
295
297 SCH_SYMBOL* aSymbol ) :
299 m_symbol( nullptr ),
300 m_part( nullptr ),
301 m_fieldsSize( 0, 0 ),
302 m_lastRequestedSize( 0, 0 ),
303 m_editorShown( false ),
304 m_fields( nullptr ),
305 m_dataModel( nullptr )
306{
307 m_symbol = aSymbol;
309
310 // GetLibSymbolRef() now points to the cached part in the schematic, which should always be
311 // there for usual cases, but can be null when opening old schematics not storing the part
312 // so we need to handle m_part == nullptr
313 // wxASSERT( m_part );
314
316
317#ifndef KICAD_SPICE
318 m_spiceFieldsButton->Hide();
319#endif /* not KICAD_SPICE */
320
321 // disable some options inside the edit dialog which can cause problems while dragging
322 if( m_symbol->IsDragging() )
323 {
324 m_orientationLabel->Disable();
325 m_orientationCtrl->Disable();
326 m_mirrorLabel->Disable();
327 m_mirrorCtrl->Disable();
328 }
329
330 // Give a bit more room for combobox editors
331 m_fieldsGrid->SetDefaultRowSize( m_fieldsGrid->GetDefaultRowSize() + 4 );
332 m_pinGrid->SetDefaultRowSize( m_pinGrid->GetDefaultRowSize() + 4 );
333
335 m_fieldsGrid->PushEventHandler( new FIELDS_GRID_TRICKS( m_fieldsGrid, this ) );
336 m_fieldsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
337
338 // Show/hide columns according to user's preference
339 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
340
341 if( cfg )
342 {
345 }
346
347 if( m_part && m_part->HasConversion() )
348 {
349 // DeMorgan conversions are a subclass of alternate pin assignments, so don't allow
350 // free-form alternate assignments as well. (We won't know how to map the alternates
351 // back and forth when the conversion is changed.)
352 m_pinTablePage->Disable();
353 m_pinTablePage->SetToolTip( _( "Alternate pin assignments are not available for De Morgan "
354 "symbols." ) );
355 }
356 else
357 {
359
360 // Make a copy of the pins for editing
361 for( const std::unique_ptr<SCH_PIN>& pin : m_symbol->GetRawPins() )
362 m_dataModel->push_back( *pin );
363
366
368 }
369
370 m_pinGrid->PushEventHandler( new GRID_TRICKS( m_pinGrid ) );
371 m_pinGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
372
373 wxToolTip::Enable( true );
375
376 // Configure button logos
377 m_bpAdd->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
379 m_bpMoveUp->SetBitmap( KiBitmap( BITMAPS::small_up ) );
381
382 // wxFormBuilder doesn't include this event...
383 m_fieldsGrid->Connect( wxEVT_GRID_CELL_CHANGING,
385 nullptr, this );
386
387 m_pinGrid->Connect( wxEVT_GRID_COL_SORT,
389 nullptr, this );
390
391 Connect( SYMBOL_DELAY_FOCUS,
392 wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES::HandleDelayedFocus ), nullptr, this );
393 Connect( SYMBOL_DELAY_SELECTION,
394 wxCommandEventHandler( DIALOG_SYMBOL_PROPERTIES::HandleDelayedSelection ), nullptr,
395 this );
396
397 QueueEvent( new wxCommandEvent( SYMBOL_DELAY_SELECTION ) );
398 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
399 evt->SetClientData( new VECTOR2I( REFERENCE_FIELD, FDC_VALUE ) );
400 QueueEvent( evt );
401
403}
404
405
407{
408 EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
409
410 if( cfg )
412
413 // Prevents crash bug in wxGrid's d'tor
415
416 if( m_dataModel )
418
419 m_fieldsGrid->Disconnect( wxEVT_GRID_CELL_CHANGING,
421 nullptr, this );
422
423 m_pinGrid->Disconnect( wxEVT_GRID_COL_SORT,
425 nullptr, this );
426
427 // Delete the GRID_TRICKS.
428 m_fieldsGrid->PopEventHandler( true );
429 m_pinGrid->PopEventHandler( true );
430}
431
432
434{
435 return dynamic_cast<SCH_EDIT_FRAME*>( wxDialog::GetParent() );
436}
437
438
440{
441 if( !wxDialog::TransferDataToWindow() )
442 return false;
443
444 std::set<wxString> defined;
445
446 // Push a copy of each field into m_updateFields
447 for( int i = 0; i < m_symbol->GetFieldCount(); ++i )
448 {
449 SCH_FIELD field( m_symbol->GetFields()[i] );
450
451 // change offset to be symbol-relative
452 field.Offset( -m_symbol->GetPosition() );
453
454 defined.insert( field.GetName() );
455 m_fields->push_back( field );
456 }
457
458 // Add in any template fieldnames not yet defined:
459 for( const TEMPLATE_FIELDNAME& templateFieldname :
460 GetParent()->Schematic().Settings().m_TemplateFieldNames.GetTemplateFieldNames() )
461 {
462 if( defined.count( templateFieldname.m_Name ) <= 0 )
463 {
464 SCH_FIELD field( wxPoint( 0, 0 ), -1, m_symbol, templateFieldname.m_Name );
465 field.SetVisible( templateFieldname.m_Visible );
466 m_fields->push_back( field );
467 }
468 }
469
470 // notify the grid
471 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->size() );
472 m_fieldsGrid->ProcessTableMessage( msg );
474
475 // If a multi-unit symbol, set up the unit selector and interchangeable checkbox.
476 if( m_symbol->GetUnitCount() > 1 )
477 {
478 // Ensure symbol unit is the currently selected unit (mandatory in complex hierarchies)
479 // from the current sheet path, because it can be modified by previous calculations
480 m_symbol->UpdateUnit( m_symbol->GetUnitSelection( &GetParent()->GetCurrentSheet() ) );
481
482 for( int ii = 1; ii <= m_symbol->GetUnitCount(); ii++ )
483 {
484 if( m_symbol->HasUnitDisplayName( ii ) )
485 m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii ) );
486 else
487 m_unitChoice->Append( LIB_SYMBOL::SubReference( ii, false ) );
488 }
489
490 if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
491 m_unitChoice->SetSelection( m_symbol->GetUnit() - 1 );
492 }
493 else
494 {
495 m_unitLabel->Enable( false );
496 m_unitChoice->Enable( false );
497 }
498
499 if( m_part && m_part->HasConversion() )
500 {
501 if( m_symbol->GetConvert() > LIB_ITEM::LIB_CONVERT::BASE )
502 m_cbAlternateSymbol->SetValue( true );
503 }
504 else
505 {
506 m_cbAlternateSymbol->Enable( false );
507 }
508
509 // Set the symbol orientation and mirroring.
510 int orientation = m_symbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
511
512 switch( orientation )
513 {
514 default:
515 case SYM_ORIENT_0: m_orientationCtrl->SetSelection( 0 ); break;
516 case SYM_ORIENT_90: m_orientationCtrl->SetSelection( 1 ); break;
517 case SYM_ORIENT_270: m_orientationCtrl->SetSelection( 2 ); break;
518 case SYM_ORIENT_180: m_orientationCtrl->SetSelection( 3 ); break;
519 }
520
521 int mirror = m_symbol->GetOrientation() & ( SYM_MIRROR_X | SYM_MIRROR_Y );
522
523 switch( mirror )
524 {
525 default: m_mirrorCtrl->SetSelection( 0 ) ; break;
526 case SYM_MIRROR_X: m_mirrorCtrl->SetSelection( 1 ); break;
527 case SYM_MIRROR_Y: m_mirrorCtrl->SetSelection( 2 ); break;
528 }
529
532 m_cbDNP->SetValue( m_symbol->GetDNP() );
533
534 if( m_part )
535 {
536 m_ShowPinNumButt->SetValue( m_part->ShowPinNumbers() );
537 m_ShowPinNameButt->SetValue( m_part->ShowPinNames() );
538 }
539
540 // Set the symbol's library name.
542
543 Layout();
544 m_fieldsGrid->Layout();
545 wxSafeYield();
546
547 return true;
548}
549
550
552{
553#ifdef KICAD_SPICE
555 return;
556
557 int diff = m_fields->size();
558
559 DIALOG_SIM_MODEL dialog( this, *m_symbol, *m_fields );
560
561 if( dialog.ShowModal() != wxID_OK )
562 return;
563
564 diff = (int) m_fields->size() - diff;
565
566 if( diff > 0 )
567 {
568 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, diff );
569 m_fieldsGrid->ProcessTableMessage( msg );
570 }
571 else if( diff < 0 )
572 {
573 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, -diff );
574 m_fieldsGrid->ProcessTableMessage( msg );
575 }
576
577 OnModify();
578 m_fieldsGrid->ForceRefresh();
579#endif /* KICAD_SPICE */
580}
581
582
584{
585 // Running the Footprint Browser gums up the works and causes the automatic cancel
586 // stuff to no longer work. So we do it here ourselves.
587 EndQuasiModal( wxID_CANCEL );
588}
589
590
592{
593 LIB_ID id;
594
595 if( !m_fieldsGrid->CommitPendingChanges() || !m_fieldsGrid->Validate() )
596 return false;
597
599 {
600 DisplayErrorMessage( this, _( "References must start with a letter." ) );
601
602 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
603 evt->SetClientData( new VECTOR2I( REFERENCE_FIELD, FDC_VALUE ) );
604 QueueEvent( evt );
605
606 return false;
607 }
608
609 // Check for missing field names.
610 for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
611 {
612 SCH_FIELD& field = m_fields->at( i );
613 wxString fieldName = field.GetName( false );
614
615 if( fieldName.IsEmpty() )
616 {
617 DisplayErrorMessage( this, _( "Fields must have a name." ) );
618
619 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
620 evt->SetClientData( new VECTOR2I( i, FDC_VALUE ) );
621 QueueEvent( evt );
622
623 return false;
624 }
625 }
626
627 return true;
628}
629
630
632{
633 if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
634 return false;
635
637 return false;
638
640 return false;
641
642 SCH_SCREEN* currentScreen = GetParent()->GetScreen();
643 wxCHECK( currentScreen, false );
644
645 // This needs to be done before the LIB_ID is changed to prevent stale library symbols in
646 // the schematic file.
647 currentScreen->Remove( m_symbol );
648
649 // save old cmp in undo list if not already in edit, or moving ...
650 if( m_symbol->GetEditFlags() == 0 )
651 GetParent()->SaveCopyInUndoList( currentScreen, m_symbol, UNDO_REDO::CHANGED, false );
652
653 // Save current flags which could be modified by next change settings
655
656 // For symbols with multiple shapes (De Morgan representation) Set the selected shape:
657 if( m_cbAlternateSymbol->IsEnabled() && m_cbAlternateSymbol->GetValue() )
658 m_symbol->SetConvert( LIB_ITEM::LIB_CONVERT::DEMORGAN );
659 else
660 m_symbol->SetConvert( LIB_ITEM::LIB_CONVERT::BASE );
661
662 //Set the part selection in multiple part per package
663 int unit_selection = m_unitChoice->IsEnabled() ? m_unitChoice->GetSelection() + 1 : 1;
664 m_symbol->SetUnitSelection( &GetParent()->GetCurrentSheet(), unit_selection );
665 m_symbol->SetUnit( unit_selection );
666
667 switch( m_orientationCtrl->GetSelection() )
668 {
669 case 0: m_symbol->SetOrientation( SYM_ORIENT_0 ); break;
670 case 1: m_symbol->SetOrientation( SYM_ORIENT_90 ); break;
671 case 2: m_symbol->SetOrientation( SYM_ORIENT_270 ); break;
672 case 3: m_symbol->SetOrientation( SYM_ORIENT_180 ); break;
673 }
674
675 switch( m_mirrorCtrl->GetSelection() )
676 {
677 case 0: break;
678 case 1: m_symbol->SetOrientation( SYM_MIRROR_X ); break;
679 case 2: m_symbol->SetOrientation( SYM_MIRROR_Y ); break;
680 }
681
682 if( m_part )
683 {
686 }
687
688 // Restore m_Flag modified by SetUnit() and other change settings from the dialog
690 m_symbol->SetFlags( flags );
691
692 // change all field positions from relative to absolute
693 for( unsigned i = 0; i < m_fields->size(); ++i )
694 m_fields->at( i ).Offset( m_symbol->GetPosition() );
695
696 SCH_FIELDS& fields = m_symbol->GetFields();
697
698 fields.clear();
699
700 for( size_t i = 0; i < m_fields->size(); ++i )
701 fields.push_back( m_fields->at( i ) );
702
703 // Reference has a specific initialization, depending on the current active sheet
704 // because for a given symbol, in a complex hierarchy, there are more than one
705 // reference.
706 m_symbol->SetRef( &GetParent()->GetCurrentSheet(), m_fields->at( REFERENCE_FIELD ).GetText() );
707
708 // Similar for Value and Footprint, except that the GUI behaviour is that they are kept
709 // in sync between multiple instances.
710 m_symbol->SetValueFieldText( m_fields->at( VALUE_FIELD ).GetText() );
712
715 m_symbol->SetDNP( m_cbDNP->IsChecked() );
716
717 // Update any assignments
718 if( m_dataModel )
719 {
720 for( const SCH_PIN& model_pin : *m_dataModel )
721 {
722 // map from the edited copy back to the "real" pin in the symbol.
723 SCH_PIN* src_pin = m_symbol->GetPin( model_pin.GetNumber() );
724
725 if( src_pin )
726 src_pin->SetAlt( model_pin.GetAlt() );
727 }
728 }
729
730 // Keep fields other than the reference, include/exclude flags, and alternate pin assignements
731 // in sync in multi-unit parts.
732 if( m_symbol->GetUnitCount() > 1 && m_symbol->IsAnnotated( &GetParent()->GetCurrentSheet() ) )
733 {
734 wxString ref = m_symbol->GetRef( &GetParent()->GetCurrentSheet() );
735 int unit = m_symbol->GetUnit();
736 LIB_ID libId = m_symbol->GetLibId();
737
738 for( SCH_SHEET_PATH& sheet : GetParent()->Schematic().GetSheets() )
739 {
740 SCH_SCREEN* screen = sheet.LastScreen();
741 std::vector<SCH_SYMBOL*> otherUnits;
742 constexpr bool appendUndo = true;
743
744 CollectOtherUnits( ref, unit, libId, sheet, &otherUnits );
745
746 for( SCH_SYMBOL* otherUnit : otherUnits )
747 {
748 GetParent()->SaveCopyInUndoList( screen, otherUnit, UNDO_REDO::CHANGED,
749 appendUndo );
750 otherUnit->SetValueFieldText( m_fields->at( VALUE_FIELD ).GetText() );
751 otherUnit->SetFootprintFieldText( m_fields->at( FOOTPRINT_FIELD ).GetText() );
752
753 for( size_t ii = DATASHEET_FIELD; ii < m_fields->size(); ++ii )
754 {
755 SCH_FIELD* otherField = otherUnit->FindField( m_fields->at( ii ).GetName() );
756
757 if( otherField )
758 {
759 otherField->SetText( m_fields->at( ii ).GetText() );
760 }
761 else
762 {
763 SCH_FIELD newField( m_fields->at( ii ) );
764 const_cast<KIID&>( newField.m_Uuid ) = KIID();
765
766 newField.Offset( -m_symbol->GetPosition() );
767 newField.Offset( otherUnit->GetPosition() );
768
769 newField.SetParent( otherUnit );
770 otherUnit->AddField( newField );
771 }
772 }
773
774 for( size_t ii = otherUnit->GetFields().size() - 1; ii > DATASHEET_FIELD; ii-- )
775 {
776 SCH_FIELD& otherField = otherUnit->GetFields().at( ii );
777
778 if( !m_symbol->FindField( otherField.GetName() ) )
779 otherUnit->GetFields().erase( otherUnit->GetFields().begin() + ii );
780 }
781
782 otherUnit->SetIncludeInBom( !m_cbExcludeFromBom->IsChecked() );
783 otherUnit->SetIncludeOnBoard( !m_cbExcludeFromBoard->IsChecked() );
784 otherUnit->SetDNP( m_cbDNP->IsChecked() );
785
786 if( m_dataModel )
787 {
788 for( const SCH_PIN& model_pin : *m_dataModel )
789 {
790 SCH_PIN* src_pin = otherUnit->GetPin( model_pin.GetNumber() );
791
792 if( src_pin )
793 src_pin->SetAlt( model_pin.GetAlt() );
794 }
795 }
796
797 GetParent()->UpdateItem( otherUnit, false, true );
798 }
799 }
800 }
801
802 currentScreen->Append( m_symbol );
804 GetParent()->UpdateItem( m_symbol, false, true );
805 GetParent()->OnModify();
806
807 // This must go after OnModify() so that the connectivity graph will have been updated.
809
810 return true;
811}
812
813
815{
816 wxGridCellEditor* editor = m_fieldsGrid->GetCellEditor( event.GetRow(), event.GetCol() );
817 wxControl* control = editor->GetControl();
818
819 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
820 {
821 event.Veto();
822 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
823 evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
824 QueueEvent( evt );
825 }
826 else if( event.GetCol() == FDC_NAME )
827 {
828 wxString newName = event.GetString();
829
830 for( int i = 0; i < m_fieldsGrid->GetNumberRows(); ++i )
831 {
832 if( i == event.GetRow() )
833 continue;
834
835 if( newName.CmpNoCase( m_fieldsGrid->GetCellValue( i, FDC_NAME ) ) == 0 )
836 {
837 DisplayError( this, wxString::Format( _( "Field name '%s' already in use." ),
838 newName ) );
839 event.Veto();
840 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
841 evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
842 QueueEvent( evt );
843 }
844 }
845 }
846
847 editor->DecRef();
848}
849
850
852{
853 if( aEvent.GetRow() == REFERENCE_FIELD && aEvent.GetCol() == FDC_VALUE )
854 QueueEvent( new wxCommandEvent( SYMBOL_DELAY_SELECTION ) );
855
856 m_editorShown = true;
857}
858
859
861{
862 m_editorShown = false;
863}
864
865
866void DIALOG_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
867{
869 return;
870
872 int fieldID = m_fields->size();
873 SCH_FIELD newField( wxPoint( 0, 0 ), fieldID, m_symbol,
875
876 newField.SetTextAngle( m_fields->at( REFERENCE_FIELD ).GetTextAngle() );
877 newField.SetTextSize( wxSize( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
878
879 m_fields->push_back( newField );
880
881 // notify the grid
882 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
883 m_fieldsGrid->ProcessTableMessage( msg );
884
885 m_fieldsGrid->MakeCellVisible( (int) m_fields->size() - 1, 0 );
886 m_fieldsGrid->SetGridCursor( (int) m_fields->size() - 1, 0 );
887
888 m_fieldsGrid->EnableCellEditControl();
889 m_fieldsGrid->ShowCellEditControl();
890
891 OnModify();
892}
893
894
895void DIALOG_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
896{
897 wxArrayInt selectedRows = m_fieldsGrid->GetSelectedRows();
898
899 if( selectedRows.empty() && m_fieldsGrid->GetGridCursorRow() >= 0 )
900 selectedRows.push_back( m_fieldsGrid->GetGridCursorRow() );
901
902 if( selectedRows.empty() )
903 return;
904
905 for( int row : selectedRows )
906 {
907 if( row < MANDATORY_FIELDS )
908 {
909 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
911 return;
912 }
913 }
914
915 m_fieldsGrid->CommitPendingChanges( true /* quiet mode */ );
916
917 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
918 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
919
920 for( int row : selectedRows )
921 {
922 m_fields->erase( m_fields->begin() + row );
923
924 // notify the grid
925 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
926 m_fieldsGrid->ProcessTableMessage( msg );
927
928 if( m_fieldsGrid->GetNumberRows() > 0 )
929 {
930 m_fieldsGrid->MakeCellVisible( std::max( 0, row-1 ), m_fieldsGrid->GetGridCursorCol() );
931 m_fieldsGrid->SetGridCursor( std::max( 0, row-1 ), m_fieldsGrid->GetGridCursorCol() );
932 }
933 }
934
935 OnModify();
936}
937
938
939void DIALOG_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
940{
942 return;
943
944 int i = m_fieldsGrid->GetGridCursorRow();
945
946 if( i > MANDATORY_FIELDS )
947 {
948 SCH_FIELD tmp = m_fields->at( (unsigned) i );
949 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
950 m_fields->insert( m_fields->begin() + i - 1, tmp );
951 m_fieldsGrid->ForceRefresh();
952
953 m_fieldsGrid->SetGridCursor( i - 1, m_fieldsGrid->GetGridCursorCol() );
954 m_fieldsGrid->MakeCellVisible( m_fieldsGrid->GetGridCursorRow(),
955 m_fieldsGrid->GetGridCursorCol() );
956
957 OnModify();
958 }
959 else
960 {
961 wxBell();
962 }
963}
964
965
966void DIALOG_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
967{
969 return;
970
971 int i = m_fieldsGrid->GetGridCursorRow();
972
973 if( i >= MANDATORY_FIELDS && i < m_fieldsGrid->GetNumberRows() - 1 )
974 {
975 SCH_FIELD tmp = m_fields->at( (unsigned) i );
976 m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 );
977 m_fields->insert( m_fields->begin() + i + 1, tmp );
978 m_fieldsGrid->ForceRefresh();
979
980 m_fieldsGrid->SetGridCursor( i + 1, m_fieldsGrid->GetGridCursorCol() );
981 m_fieldsGrid->MakeCellVisible( m_fieldsGrid->GetGridCursorRow(),
982 m_fieldsGrid->GetGridCursorCol() );
983
984 OnModify();
985 }
986 else
987 {
988 wxBell();
989 }
990}
991
992
994{
997}
998
999
1001{
1004}
1005
1006
1008{
1011}
1012
1013
1015{
1018}
1019
1020
1022{
1023 int row = aEvent.GetRow();
1024
1025 if( m_pinGrid->GetCellValue( row, COL_ALT_NAME )
1026 == m_dataModel->GetValue( row, COL_BASE_NAME ) )
1027 {
1028 m_dataModel->SetValue( row, COL_ALT_NAME, wxEmptyString );
1029 }
1030
1031 // These are just to get the cells refreshed
1034
1035 OnModify();
1036}
1037
1038
1040{
1041 int sortCol = aEvent.GetCol();
1042 bool ascending;
1043
1044 // This is bonkers, but wxWidgets doesn't tell us ascending/descending in the
1045 // event, and if we ask it will give us pre-event info.
1046 if( m_pinGrid->IsSortingBy( sortCol ) )
1047 // same column; invert ascending
1048 ascending = !m_pinGrid->IsSortOrderAscending();
1049 else
1050 // different column; start with ascending
1051 ascending = true;
1052
1053 m_dataModel->SortRows( sortCol, ascending );
1055}
1056
1057
1059{
1060 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_fieldsGrid );
1061
1062 // Account for scroll bars
1063 int fieldsWidth = KIPLATFORM::UI::GetUnobscuredSize( m_fieldsGrid ).x;
1064
1065 m_fieldsGrid->AutoSizeColumn( 0 );
1066 m_fieldsGrid->SetColSize( 0, std::max( 72, m_fieldsGrid->GetColSize( 0 ) ) );
1067
1068 int fixedColsWidth = m_fieldsGrid->GetColSize( 0 );
1069
1070 for( int i = 2; i < m_fieldsGrid->GetNumberCols(); i++ )
1071 fixedColsWidth += m_fieldsGrid->GetColSize( i );
1072
1073 m_fieldsGrid->SetColSize( 1, std::max( 120, fieldsWidth - fixedColsWidth ) );
1074}
1075
1076
1078{
1079 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinGrid );
1080
1081 // Account for scroll bars
1082 int pinTblWidth = KIPLATFORM::UI::GetUnobscuredSize( m_pinGrid ).x;
1083
1084 // Stretch the Base Name and Alternate Assignment columns to fit.
1085 for( int i = 0; i < COL_COUNT; ++i )
1086 {
1087 if( i != COL_BASE_NAME && i != COL_ALT_NAME )
1088 pinTblWidth -= m_pinGrid->GetColSize( i );
1089 }
1090
1091 m_pinGrid->SetColSize( COL_BASE_NAME, pinTblWidth / 2 );
1092 m_pinGrid->SetColSize( COL_ALT_NAME, pinTblWidth / 2 );
1093}
1094
1095
1096void DIALOG_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1097{
1098 wxString shownColumns = m_fieldsGrid->GetShownColumns();
1099
1100 if( shownColumns != m_shownColumns )
1101 {
1102 m_shownColumns = shownColumns;
1103
1104 if( !m_fieldsGrid->IsCellEditControlShown() )
1106 }
1107}
1108
1109
1111{
1112 VECTOR2I *loc = static_cast<VECTOR2I*>( event.GetClientData() );
1113
1114 wxCHECK_RET( loc, wxT( "Missing focus cell location" ) );
1115
1116 // Handle a delayed focus
1117
1118 m_fieldsGrid->SetFocus();
1119 m_fieldsGrid->MakeCellVisible( loc->x, loc->y );
1120 m_fieldsGrid->SetGridCursor( loc->x, loc->y );
1121
1122 m_fieldsGrid->EnableCellEditControl( true );
1123 m_fieldsGrid->ShowCellEditControl();
1124
1125 delete loc;
1126}
1127
1128
1130{
1131 // Handle a delayed selection
1132 wxGridCellEditor* cellEditor = m_fieldsGrid->GetCellEditor( REFERENCE_FIELD, FDC_VALUE );
1133
1134 if( wxTextEntry* txt = dynamic_cast<wxTextEntry*>( cellEditor->GetControl() ) )
1136
1137 cellEditor->DecRef(); // we're done; must release
1138}
1139
1141{
1142 wxSize new_size = event.GetSize();
1143
1144 if( ( !m_editorShown || m_lastRequestedSize != new_size ) && m_fieldsSize != new_size )
1145 {
1146 m_fieldsSize = new_size;
1147
1149 }
1150
1151 // We store this value to check whether the dialog is changing size. This might indicate
1152 // that the user is scaling the dialog with an editor shown. Some editors do not close
1153 // (at least on GTK) when the user drags a dialog corner
1154 m_lastRequestedSize = new_size;
1155
1156 // Always propagate for a grid repaint (needed if the height changes, as well as width)
1157 event.Skip();
1158}
1159
1160
1162{
1163 wxSize new_size = event.GetSize();
1164
1165 if( m_pinsSize != new_size )
1166 {
1167 m_pinsSize = new_size;
1168
1170 }
1171
1172 // Always propagate for a grid repaint (needed if the height changes, as well as width)
1173 event.Skip();
1174}
1175
1176
1177void DIALOG_SYMBOL_PROPERTIES::OnInitDlg( wxInitDialogEvent& event )
1178{
1180
1181 // Now all widgets have the size fixed, call FinishDialogSettings
1183}
1184
1185
1186void DIALOG_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
1187{
1188 OnModify();
1189}
1190
1191
1192void DIALOG_SYMBOL_PROPERTIES::OnUnitChoice( wxCommandEvent& event )
1193{
1194 if( m_dataModel )
1195 {
1196 EDA_ITEM_FLAGS flags = m_symbol->GetFlags();
1197
1198 int unit_selection = m_unitChoice->GetSelection() + 1;
1199
1200 // We need to select a new unit to build the new unit pin list
1201 // but we should not change the symbol, so the initial unit will be selected
1202 // after rebuilding the pin list
1203 int old_unit = m_symbol->GetUnit();
1204 m_symbol->SetUnit( unit_selection );
1205
1206 // Rebuild a copy of the pins of the new unit for editing
1207 m_dataModel->clear();
1208
1209 for( const std::unique_ptr<SCH_PIN>& pin : m_symbol->GetRawPins() )
1210 m_dataModel->push_back( *pin );
1211
1214
1215 m_symbol->SetUnit(old_unit );
1216
1217 // Restore m_Flag modified by SetUnit()
1219 m_symbol->SetFlags( flags );
1220 }
1221
1222 OnModify();
1223}
1224
1225
1227{
1228 event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
1229}
1230
1231
1233{
1234 event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
1235}
1236
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:105
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 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:147
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
const KIID m_Uuid
Definition: eda_item.h:494
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:143
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
bool IsDragging() const
Definition: eda_item.h:105
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:144
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:389
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:193
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:213
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:93
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:635
bool ShowPinNames() const
Definition: lib_symbol.h:636
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: lib_symbol.h:643
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Definition: lib_symbol.cpp:588
bool HasConversion() const
Test if symbol has more than one body conversion type (DeMorgan).
bool ShowPinNumbers() const
Definition: lib_symbol.h:644
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:172
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:50
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Definition: sch_field.cpp:827
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
bool Remove(SCH_ITEM *aItem)
Remove aItem from the schematic associated with this screen.
Definition: sch_screen.cpp:268
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:141
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:80
int GetUnitCount() const
Return the number of units per package of the symbol.
Definition: sch_symbol.cpp:419
void SetConvert(int aConvert)
Definition: sch_symbol.cpp:396
std::vector< std::unique_ptr< SCH_PIN > > & GetRawPins()
Definition: sch_symbol.h:532
int GetUnit() const
Definition: sch_symbol.h:227
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:478
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true)
Search for a SCH_FIELD with aFieldName.
Definition: sch_symbol.cpp:861
void SetDNP(bool aDNP)
Definition: sch_symbol.h:731
void UpdateUnit(int aUnit)
Change the unit number to aUnit without setting any internal flags.
Definition: sch_symbol.cpp:390
void SetIncludeOnBoard(bool aIncludeOnBoard)
Definition: sch_symbol.h:728
static bool IsReferenceStringValid(const wxString &aReferenceString)
Test for an acceptable reference string.
Definition: sch_symbol.cpp:660
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:767
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:624
bool GetIncludeOnBoard() const
Definition: sch_symbol.h:727
bool GetIncludeInBom() const
Definition: sch_symbol.h:724
int GetConvert() const
Definition: sch_symbol.h:269
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:666
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:782
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:697
bool HasUnitDisplayName(int aUnit)
Return true if the given unit aUnit has a display name set.
Definition: sch_symbol.cpp:436
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:702
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
Definition: sch_symbol.cpp:716
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:380
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:174
wxString GetUnitDisplayName(int aUnit)
Return the display name for a given unit aUnit.
Definition: sch_symbol.cpp:428
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
Definition: sch_symbol.cpp:954
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:824
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
Set the selected unit of this symbol on one sheet.
Definition: sch_symbol.cpp:732
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:191
void SetIncludeInBom(bool aIncludeInBom)
Definition: sch_symbol.h:725
bool GetDNP() const
Definition: sch_symbol.h:730
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:226
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:95
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:193
wxString GetShownColumns()
Get a tokenized string containing the shown column indexes.
Definition: wx_grid.cpp:207
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:280
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:299
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_NAME
@ 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:126
void SelectReferenceNumber(wxTextEntry *aTextEntry)
Select the number (or "?") in a reference for ease of editing.
Definition: ui_common.cpp:218
must_if< error >::control< Rule > control
Definition: sim_serde.h:107
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:68
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".
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618