KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <memory>
23
24#include <bitmaps.h>
25#include <wx/tooltip.h>
26#include <wx/uiaction.h>
27#include <grid_tricks.h>
28#include <confirm.h>
29#include <kiface_base.h>
30#include <pin_numbers.h>
31#include <string_utils.h>
32#include <kiplatform/ui.h>
37#include <sch_collectors.h>
38#include <fields_grid_table.h>
39#include <sch_edit_frame.h>
40#include <sch_reference_list.h>
41#include <schematic.h>
42#include <sch_commit.h>
43#include <tool/tool_manager.h>
44#include <tool/actions.h>
45
46#include <dialog_sim_model.h>
49
50
51wxDEFINE_EVENT( SYMBOL_DELAY_FOCUS, wxCommandEvent );
52wxDEFINE_EVENT( SYMBOL_DELAY_SELECTION, wxCommandEvent );
53
54
65
66
67class SCH_PIN_TABLE_DATA_MODEL : public WX_GRID_TABLE_BASE, public std::vector<SCH_PIN>
68{
69public:
71 m_readOnlyAttr( nullptr ),
72 m_typeAttr( nullptr ),
73 m_shapeAttr( nullptr )
74 {
75 }
76
78 {
79 for( wxGridCellAttr* attr : m_nameAttrs )
80 attr->DecRef();
81
82 m_readOnlyAttr->DecRef();
83 m_typeAttr->DecRef();
84 m_shapeAttr->DecRef();
85 }
86
88 {
89 for( wxGridCellAttr* attr : m_nameAttrs )
90 attr->DecRef();
91
92 m_nameAttrs.clear();
93
94 if( m_readOnlyAttr )
95 m_readOnlyAttr->DecRef();
96
97 m_readOnlyAttr = new wxGridCellAttr;
98 m_readOnlyAttr->SetReadOnly( true );
99
100 for( const SCH_PIN& pin : *this )
101 {
102 SCH_PIN* lib_pin = pin.GetLibPin();
103 wxGridCellAttr* attr = nullptr;
104
105 if( !lib_pin || lib_pin->GetAlternates().empty() )
106 {
107 attr = new wxGridCellAttr;
108 attr->SetReadOnly( true );
109 attr->SetBackgroundColour( KIPLATFORM::UI::GetDialogBGColour() );
110 }
111 else
112 {
113 wxArrayString choices;
114 choices.push_back( lib_pin->GetName() );
115
116 for( const std::pair<const wxString, SCH_PIN::ALT>& alt : lib_pin->GetAlternates() )
117 choices.push_back( alt.first );
118
119 attr = new wxGridCellAttr();
120 attr->SetEditor( new GRID_CELL_COMBOBOX( choices ) );
121 }
122
123 m_nameAttrs.push_back( attr );
124 }
125
126 if( m_typeAttr )
127 m_typeAttr->DecRef();
128
129 m_typeAttr = new wxGridCellAttr;
131 m_typeAttr->SetReadOnly( true );
132
133 if( m_shapeAttr )
134 m_shapeAttr->DecRef();
135
136 m_shapeAttr = new wxGridCellAttr;
138 m_shapeAttr->SetReadOnly( true );
139 }
140
141 int GetNumberRows() override { return (int) size(); }
142 int GetNumberCols() override { return COL_COUNT; }
143
144 wxString GetColLabelValue( int aCol ) override
145 {
146 switch( aCol )
147 {
148 case COL_NUMBER: return _( "Number" );
149 case COL_BASE_NAME: return _( "Base Name" );
150 case COL_ALT_NAME: return _( "Alternate Assignment" );
151 case COL_TYPE: return _( "Electrical Type" );
152 case COL_SHAPE: return _( "Graphic Style" );
153 default: wxFAIL; return wxEmptyString;
154 }
155 }
156
157 bool IsEmptyCell( int row, int col ) override
158 {
159 return false; // don't allow adjacent cell overflow, even if we are actually empty
160 }
161
162 bool CanSetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
163 {
164 // Don't accept random values; must use the popup to change to a known alternate
165 return false;
166 }
167
168 wxString GetValue( int aRow, int aCol ) override
169 {
170 return GetValue( at( aRow ), aCol );
171 }
172
173 static wxString GetValue( const SCH_PIN& aPin, int aCol )
174 {
175 if( aCol == COL_ALT_NAME )
176 {
177 if( !aPin.GetLibPin() || aPin.GetLibPin()->GetAlternates().empty() )
178 return wxEmptyString;
179 else if( aPin.GetAlt().IsEmpty() )
180 return aPin.GetName();
181 else
182 return aPin.GetAlt();
183 }
184
185 switch( aCol )
186 {
187 case COL_NUMBER: return aPin.GetNumber();
188 case COL_BASE_NAME: return aPin.GetBaseName();
189 case COL_TYPE: return PinTypeNames()[static_cast<int>( aPin.GetType() )];
190 case COL_SHAPE: return PinShapeNames()[static_cast<int>( aPin.GetShape() )];
191 default: wxFAIL; return wxEmptyString;
192 }
193 }
194
195 wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind ) override
196 {
197 switch( aCol )
198 {
199 case COL_NUMBER:
200 case COL_BASE_NAME:
201 m_readOnlyAttr->IncRef();
202 return enhanceAttr( m_readOnlyAttr, aRow, aCol, aKind );
203
204 case COL_ALT_NAME:
205 m_nameAttrs[ aRow ]->IncRef();
206 return enhanceAttr( m_nameAttrs[ aRow ], aRow, aCol, aKind );
207
208 case COL_TYPE:
209 m_typeAttr->IncRef();
210 return enhanceAttr( m_typeAttr, aRow, aCol, aKind );
211
212 case COL_SHAPE:
213 m_shapeAttr->IncRef();
214 return enhanceAttr( m_shapeAttr, aRow, aCol, aKind );
215
216 default:
217 wxFAIL;
218 return nullptr;
219 }
220 }
221
222 void SetValue( int aRow, int aCol, const wxString &aValue ) override
223 {
224 SCH_PIN& pin = at( aRow );
225
226 switch( aCol )
227 {
228 case COL_ALT_NAME:
229 if( pin.GetLibPin() && aValue == pin.GetLibPin()->GetName() )
230 pin.SetAlt( wxEmptyString );
231 else
232 pin.SetAlt( aValue );
233 break;
234
235 case COL_NUMBER:
236 case COL_BASE_NAME:
237 case COL_TYPE:
238 case COL_SHAPE:
239 // Read-only.
240 break;
241
242 default:
243 wxFAIL;
244 break;
245 }
246 }
247
248 static bool compare( const SCH_PIN& lhs, const SCH_PIN& rhs, int sortCol, bool ascending )
249 {
250 wxString lhStr = GetValue( lhs, sortCol );
251 wxString rhStr = GetValue( rhs, sortCol );
252
253 if( lhStr == rhStr )
254 {
255 // Secondary sort key is always COL_NUMBER
256 sortCol = COL_NUMBER;
257 lhStr = GetValue( lhs, sortCol );
258 rhStr = GetValue( rhs, sortCol );
259 }
260
261 bool res;
262
263 // N.B. To meet the iterator sort conditions, we cannot simply invert the truth
264 // to get the opposite sort. i.e. ~(a<b) != (a>b)
265 auto cmp = [ ascending ]( const auto a, const auto b )
266 {
267 if( ascending )
268 return a < b;
269 else
270 return b < a;
271 };
272
273 switch( sortCol )
274 {
275 case COL_NUMBER:
276 case COL_BASE_NAME:
277 case COL_ALT_NAME:
278 res = cmp( PIN_NUMBERS::Compare( lhStr, rhStr ), 0 );
279 break;
280 case COL_TYPE:
281 case COL_SHAPE:
282 res = cmp( lhStr.CmpNoCase( rhStr ), 0 );
283 break;
284 default:
285 res = cmp( StrNumCmp( lhStr, rhStr ), 0 );
286 break;
287 }
288
289 return res;
290 }
291
292 void SortRows( int aSortCol, bool ascending )
293 {
294 std::sort( begin(), end(),
295 [ aSortCol, ascending ]( const SCH_PIN& lhs, const SCH_PIN& rhs ) -> bool
296 {
297 return compare( lhs, rhs, aSortCol, ascending );
298 } );
299 }
300
301protected:
302 std::vector<wxGridCellAttr*> m_nameAttrs;
303 wxGridCellAttr* m_readOnlyAttr;
304 wxGridCellAttr* m_typeAttr;
305 wxGridCellAttr* m_shapeAttr;
306};
307
308
311 m_symbol( nullptr ),
312 m_part( nullptr ),
314 m_editorShown( false ),
315 m_fields( nullptr ),
316 m_dataModel( nullptr ),
317 m_embeddedFiles( nullptr ),
318 m_pinMapPanel( nullptr )
319{
320 m_symbol = aSymbol;
321 m_part = m_symbol->GetLibSymbolRef().get();
322
323 // GetLibSymbolRef() now points to the cached part in the schematic, which should always be
324 // there for usual cases, but can be null when opening old schematics not storing the part
325 // so we need to handle m_part == nullptr
326 // wxASSERT( m_part );
327
328 m_fields = new FIELDS_GRID_TABLE( this, aParent, m_fieldsGrid, m_symbol );
329
330 m_fieldsGrid->SetTable( m_fields );
331 m_fieldsGrid->PushEventHandler( new FIELDS_GRID_TRICKS( m_fieldsGrid, this,
332 { &aParent->Schematic(), m_part },
333 [&]( wxCommandEvent& aEvent )
334 {
335 OnAddField( aEvent );
336 } ) );
337 m_fieldsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
338 m_fieldsGrid->ShowHideColumns( "0 1 2 3 4 5 6 7" );
339 m_fieldsGrid->SetMinSize( wxSize( -1, 160 ) );
340 m_fieldsGrid->OverrideMinSize( 1.0, 1.0 );
341 m_shownColumns = m_fieldsGrid->GetShownColumns();
342
343 if( m_symbol->GetEmbeddedFiles() )
344 {
345 m_embeddedFiles = new PANEL_EMBEDDED_FILES( m_notebook1, m_symbol->GetEmbeddedFiles() );
346 m_notebook1->AddPage( m_embeddedFiles, _( "Embedded Files" ) );
347 }
348
350 bPinMapPageSizer->Add( m_pinMapPanel, 1, wxEXPAND, 5 );
351
352 if( m_part && m_part->IsMultiBodyStyle() )
353 {
354 // Multiple body styles are a superclass of alternate pin assignments, so don't allow
355 // free-form alternate assignments as well. (We won't know how to map the alternates
356 // back and forth when the body style is changed.)
357 m_pinTablePage->Disable();
358 m_pinTablePage->SetToolTip( _( "Alternate pin assignments are not available for symbols with multiple "
359 "body styles." ) );
360 }
361 else
362 {
364
365 // Make a copy of the pins for editing
366 for( const std::unique_ptr<SCH_PIN>& pin : m_symbol->GetRawPins() )
367 m_dataModel->push_back( *pin );
368
369 m_dataModel->SortRows( COL_NUMBER, true );
370 m_dataModel->BuildAttrs();
371
372 m_pinGrid->SetTable( m_dataModel );
373 }
374
375 if( m_part && m_part->IsPower() )
376 m_spiceFieldsButton->Hide();
377
378 m_pinGrid->PushEventHandler( new GRID_TRICKS( m_pinGrid ) );
379 m_pinGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
380
381 wxFont infoFont = KIUI::GetSmallInfoFont( this );
382 m_libraryIDLabel->SetFont( infoFont );
383 m_tcLibraryID->SetFont( infoFont );
384 m_tcLibraryID->SetBackgroundColour( KIPLATFORM::UI::GetDialogBGColour() );
385
386 wxToolTip::Enable( true );
388
389 // Configure button logos
394
395 // wxFormBuilder doesn't include this event...
396 m_fieldsGrid->Bind( wxEVT_GRID_CELL_CHANGING, &DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging, this );
397 m_pinGrid->Bind( wxEVT_GRID_COL_SORT, &DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort, this );
398 Bind( SYMBOL_DELAY_FOCUS, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedFocus, this );
399 Bind( SYMBOL_DELAY_SELECTION, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedSelection, this );
400
401 wxCommandEvent* evt = new wxCommandEvent( SYMBOL_DELAY_SELECTION );
402 evt->SetClientData( new VECTOR2I( 0, FDC_VALUE ) );
403 QueueEvent( evt );
404
405 evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
406 evt->SetClientData( new VECTOR2I( 0, FDC_VALUE ) );
407 QueueEvent( evt );
408
409 // Remind user that they are editing the current variant.
410 if( !aParent->Schematic().GetCurrentVariant().IsEmpty() )
411 SetTitle( GetTitle() + wxS( " - " ) + aParent->Schematic().GetCurrentVariant() + _( " Design Variant" ) );
412
413 Layout();
414 m_fieldsGrid->Layout();
415
416 if( GetSizer() )
417 GetSizer()->Fit( this );
418
420}
421
422
424{
425 // Prevents crash bug in wxGrid's d'tor
426 m_fieldsGrid->DestroyTable( m_fields );
427
428 if( m_dataModel )
429 m_pinGrid->DestroyTable( m_dataModel );
430
431 m_fieldsGrid->Unbind( wxEVT_GRID_CELL_CHANGING, &DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging, this );
432 m_pinGrid->Unbind( wxEVT_GRID_COL_SORT, &DIALOG_SYMBOL_PROPERTIES::OnPinTableColSort, this );
433 Unbind( SYMBOL_DELAY_FOCUS, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedFocus, this );
434 Unbind( SYMBOL_DELAY_SELECTION, &DIALOG_SYMBOL_PROPERTIES::HandleDelayedSelection, this );
435
436 // Delete the GRID_TRICKS.
437 m_fieldsGrid->PopEventHandler( true );
438 m_pinGrid->PopEventHandler( true );
439}
440
441
443{
444 return dynamic_cast<SCH_EDIT_FRAME*>( wxDialog::GetParent() );
445}
446
447
452
453
455{
456 if( !wxDialog::TransferDataToWindow() )
457 return false;
458
459 const SCHEMATIC& schematic = GetParent()->Schematic();
460 SCH_SHEET_PATH& sheetPath = schematic.CurrentSheet();
461 wxString variantName = schematic.GetCurrentVariant();
462 std::optional<SCH_SYMBOL_VARIANT> variant = m_symbol->GetVariant( sheetPath, variantName );
463 std::set<wxString> defined;
464
465 // Push a copy of each field into m_updateFields
466 for( SCH_FIELD& srcField : m_symbol->GetFields() )
467 {
468 SCH_FIELD field( srcField );
469
470 // change offset to be symbol-relative
471 field.Offset( -m_symbol->GetPosition() );
472 field.SetText( schematic.ConvertKIIDsToRefs( m_symbol->GetFieldText( field.GetName(), &sheetPath,
473 variantName ) ) );
474
475 defined.insert( field.GetName() );
476 m_fields->push_back( field );
477 }
478
479 // Add in any template fieldnames not yet defined:
480 for( const TEMPLATE_FIELDNAME& templateFieldname :
481 schematic.Settings().m_TemplateFieldNames.GetTemplateFieldNames() )
482 {
483 if( defined.count( templateFieldname.m_Name ) <= 0 )
484 {
485 SCH_FIELD field( m_symbol, FIELD_T::USER, templateFieldname.m_Name );
486 field.SetVisible( templateFieldname.m_Visible );
487 m_fields->push_back( field );
488 }
489 }
490
491 // notify the grid
492 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
493 m_fieldsGrid->ProcessTableMessage( msg );
494
495 // If a multi-unit symbol, set up the unit selector and interchangeable checkbox.
496 if( m_symbol->IsMultiUnit() )
497 {
498 // Ensure symbol unit is the currently selected unit (mandatory in complex hierarchies)
499 // from the current sheet path, because it can be modified by previous calculations
500 m_symbol->SetUnit( m_symbol->GetUnitSelection( &sheetPath ) );
501
502 for( int ii = 1; ii <= m_symbol->GetUnitCount(); ii++ )
503 m_unitChoice->Append( m_symbol->GetUnitDisplayName( ii, false ) );
504
505 if( m_symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
506 m_unitChoice->SetSelection( m_symbol->GetUnit() - 1 );
507 }
508 else
509 {
510 m_unitLabel->Enable( false );
511 m_unitChoice->Enable( false );
512 }
513
514 if( m_part && m_part->IsMultiBodyStyle() )
515 {
516 if( m_part->HasDeMorganBodyStyles() )
517 {
518 m_bodyStyleChoice->Append( _( "Standard" ) );
519 m_bodyStyleChoice->Append( _( "Alternate" ) );
520 }
521 else
522 {
523 wxASSERT( (int)m_part->GetBodyStyleNames().size() == m_part->GetBodyStyleCount() );
524
525 for( int ii = 0; ii < m_part->GetBodyStyleCount(); ii++ )
526 {
527 try
528 {
529 m_bodyStyleChoice->Append( m_part->GetBodyStyleNames().at( ii ) );
530 }
531 catch( ... )
532 {
533 m_bodyStyleChoice->Append( wxT( "???" ) );
534 }
535 }
536 }
537
538 if( m_symbol->GetBodyStyle() <= (int) m_bodyStyleChoice->GetCount() )
539 m_bodyStyleChoice->SetSelection( m_symbol->GetBodyStyle() - 1 );
540 }
541 else
542 {
543 m_bodyStyle->Enable( false );
544 m_bodyStyleChoice->Enable( false );
545 }
546
547 // Set the symbol orientation and mirroring.
548 int orientation = m_symbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
549
550 switch( orientation )
551 {
552 default:
553 case SYM_ORIENT_0: m_orientationCtrl->SetSelection( 0 ); break;
554 case SYM_ORIENT_90: m_orientationCtrl->SetSelection( 1 ); break;
555 case SYM_ORIENT_270: m_orientationCtrl->SetSelection( 2 ); break;
556 case SYM_ORIENT_180: m_orientationCtrl->SetSelection( 3 ); break;
557 }
558
559 int mirror = m_symbol->GetOrientation() & ( SYM_MIRROR_X | SYM_MIRROR_Y );
560
561 switch( mirror )
562 {
563 default: m_mirrorCtrl->SetSelection( 0 ) ; break;
564 case SYM_MIRROR_X: m_mirrorCtrl->SetSelection( 1 ); break;
565 case SYM_MIRROR_Y: m_mirrorCtrl->SetSelection( 2 ); break;
566 }
567
568 m_cbExcludeFromSim->SetValue( m_symbol->GetExcludedFromSim( &sheetPath, variantName ) );
569 m_cbExcludeFromBom->SetValue( m_symbol->GetExcludedFromBOM( &sheetPath, variantName ) );
570 m_cbExcludeFromBoard->SetValue( m_symbol->GetExcludedFromBoard( &sheetPath, variantName ) );
571 m_cbExcludeFromPosFiles->SetValue( m_symbol->GetExcludedFromPosFiles( &sheetPath, variantName ) );
572 m_cbDNP->SetValue( m_symbol->GetDNP( &sheetPath, variantName ) );
573
574 switch( m_symbol->GetPassthroughMode() )
575 {
576 case SCH_SYMBOL::PASSTHROUGH_MODE::DEFAULT: m_choicePassthrough->SetSelection( 0 ); break;
577 case SCH_SYMBOL::PASSTHROUGH_MODE::BLOCK: m_choicePassthrough->SetSelection( 1 ); break;
578 case SCH_SYMBOL::PASSTHROUGH_MODE::FORCE: m_choicePassthrough->SetSelection( 2 ); break;
579 }
580
581 if( m_part )
582 {
583 m_ShowPinNumButt->SetValue( m_part->GetShowPinNumbers() );
584 m_ShowPinNameButt->SetValue( m_part->GetShowPinNames() );
585 }
586
587 // Set the symbol's library name.
588 m_tcLibraryID->SetValue( UnescapeString( m_symbol->GetLibId().Format() ) );
589
590 if( m_embeddedFiles && !m_embeddedFiles->TransferDataToWindow() )
591 return false;
592
593 m_pinMapPanel->SetSymbol( m_part );
594 m_pinMapPanel->TransferDataToWindow();
595
596 m_fieldsGrid->Layout();
597 Layout();
598 m_fieldsGrid->SetMinVisibleRows( this, 4 );
599
600 // Always open on the General page, unless the caller explicitly asked for the Pin Map
601 // tab (the Edit Pin Map button). This overrides DIALOG_SHIM's remembered-tab restore.
602 int targetPage = 0;
603
605 {
606 for( size_t page = 0; page < m_notebook1->GetPageCount(); ++page )
607 {
608 if( m_notebook1->GetPage( page ) == m_pinMapPage )
609 {
610 targetPage = (int) page;
611 break;
612 }
613 }
614 }
615
616 m_notebook1->ChangeSelection( targetPage );
617
618 return true;
619}
620
621
623{
624 if( !m_fieldsGrid->CommitPendingChanges() )
625 return;
626
627 m_fieldsGrid->ClearSelection();
628
629 std::vector<SCH_FIELD> fields;
630
631 for( const SCH_FIELD& field : *m_fields )
632 fields.emplace_back( field );
633
634 DIALOG_SIM_MODEL dialog( this, m_parentFrame, *m_symbol, fields );
635
636 if( dialog.ShowModal() != wxID_OK )
637 return;
638
639 // Add in any new fields
640 for( const SCH_FIELD& editedField : fields )
641 {
642 bool found = false;
643
644 for( SCH_FIELD& existingField : *m_fields )
645 {
646 if( existingField.GetName() == editedField.GetName() )
647 {
648 found = true;
649 existingField.SetText( editedField.GetText() );
650 break;
651 }
652 }
653
654 if( !found )
655 {
656 m_fields->emplace_back( editedField );
657 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
658 m_fieldsGrid->ProcessTableMessage( msg );
659 }
660 }
661
662 // Remove any deleted fields
663 for( int ii = (int) m_fields->size() - 1; ii >= 0; --ii )
664 {
665 SCH_FIELD& existingField = m_fields->at( ii );
666 bool found = false;
667
668 for( SCH_FIELD& editedField : fields )
669 {
670 if( editedField.GetName() == existingField.GetName() )
671 {
672 found = true;
673 break;
674 }
675 }
676
677 if( !found )
678 {
679 m_fieldsGrid->ClearSelection();
680 m_fields->erase( m_fields->begin() + ii );
681
682 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, ii, 1 );
683 m_fieldsGrid->ProcessTableMessage( msg );
684 }
685 }
686
687 OnModify();
688 m_fieldsGrid->ForceRefresh();
689}
690
691
693{
694 // Running the Footprint Browser gums up the works and causes the automatic cancel
695 // stuff to no longer work. So we do it here ourselves.
696 EndQuasiModal( wxID_CANCEL );
697}
698
699
701{
702 LIB_ID id;
703
704 if( !m_fieldsGrid->CommitPendingChanges() || !m_fieldsGrid->Validate() )
705 return false;
706
707 // Check for missing field names.
708 for( size_t i = 0; i < m_fields->size(); ++i )
709 {
710 SCH_FIELD& field = m_fields->at( i );
711
712 if( field.IsMandatory() )
713 continue;
714
715 wxString fieldName = field.GetName( false );
716
717 if( fieldName.IsEmpty() )
718 {
719 DisplayErrorMessage( this, _( "Fields must have a name." ) );
720
721 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
722 evt->SetClientData( new VECTOR2I( i, FDC_VALUE ) );
723 QueueEvent( evt );
724
725 return false;
726 }
727 }
728
729 return true;
730}
731
732
734{
735 if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
736 return false;
737
738 if( m_embeddedFiles && !m_embeddedFiles->TransferDataFromWindow() )
739 return false;
740
741 if( !m_fieldsGrid->CommitPendingChanges() )
742 return false;
743
744 if( !m_pinGrid->CommitPendingChanges() )
745 return false;
746
747 if( !m_pinMapPanel->CommitPendingChanges() )
748 return false;
749
750 SCH_COMMIT commit( GetParent() );
751 SCH_SCREEN* currentScreen = GetParent()->GetScreen();
752 SCH_SHEET_PATH currentSheet = GetParent()->Schematic().CurrentSheet();
753 wxString currentVariant = GetParent()->Schematic().GetCurrentVariant();
754 bool replaceOnCurrentScreen;
755
756 wxCHECK( currentScreen, false );
757
758 // This needs to be done before the LIB_ID is changed to prevent stale library symbols in
759 // the schematic file.
760 replaceOnCurrentScreen = currentScreen->Remove( m_symbol );
761
762 // save old cmp in undo list if not already in edit, or moving ...
763 if( m_symbol->GetEditFlags() == 0 )
764 commit.Modify( m_symbol, currentScreen );
765
766 // Apply pin-map edits after the undo snapshot so undo restores them (issue #2282).
767 if( m_part )
768 m_pinMapPanel->ApplyToSymbol( m_part );
769
770 // Save current flags which could be modified by next change settings
771 EDA_ITEM_FLAGS flags = m_symbol->GetFlags();
772
773 //Set the part selection in multiple part per package
774 int unit_selection = m_unitChoice->IsEnabled() ? m_unitChoice->GetSelection() + 1 : 1;
775 m_symbol->SetUnitSelection( &GetParent()->GetCurrentSheet(), unit_selection );
776 m_symbol->SetUnit( unit_selection );
777
778 int bodyStyle_selection = m_bodyStyleChoice->IsEnabled() ? m_bodyStyleChoice->GetSelection() + 1 : 1;
779 m_symbol->SetBodyStyle( bodyStyle_selection );
780
781 switch( m_orientationCtrl->GetSelection() )
782 {
783 case 0: m_symbol->SetOrientation( SYM_ORIENT_0 ); break;
784 case 1: m_symbol->SetOrientation( SYM_ORIENT_90 ); break;
785 case 2: m_symbol->SetOrientation( SYM_ORIENT_270 ); break;
786 case 3: m_symbol->SetOrientation( SYM_ORIENT_180 ); break;
787 }
788
789 switch( m_mirrorCtrl->GetSelection() )
790 {
791 case 0: break;
792 case 1: m_symbol->SetOrientation( SYM_MIRROR_X ); break;
793 case 2: m_symbol->SetOrientation( SYM_MIRROR_Y ); break;
794 }
795
796 m_symbol->SetShowPinNames( m_ShowPinNameButt->GetValue() );
797 m_symbol->SetShowPinNumbers( m_ShowPinNumButt->GetValue() );
798
799 // Restore m_Flag modified by SetUnit() and other change settings from the dialog
800 m_symbol->ClearFlags();
801 m_symbol->SetFlags( flags );
802
803 // change all field positions from relative to absolute
804 for( SCH_FIELD& field : *m_fields )
805 field.Offset( m_symbol->GetPosition() );
806
807 int ordinal = 42; // Arbitrarily larger than any mandatory FIELD_T ids.
808
809 for( SCH_FIELD& field : *m_fields )
810 {
811 const wxString& fieldName = field.GetCanonicalName();
812
813 if( fieldName.IsEmpty() && field.GetText().IsEmpty() )
814 continue;
815 else if( fieldName.IsEmpty() )
816 field.SetName( _( "untitled" ) );
817
818 const SCH_FIELD* existingField = m_symbol->GetField( fieldName );
819 SCH_FIELD* tmp;
820
821 if( !existingField )
822 {
823 tmp = m_symbol->AddField( field );
824 tmp->SetParent( m_symbol );
825 }
826 else
827 {
828 wxString defaultText = m_symbol->Schematic()->ConvertRefsToKIIDs( existingField->GetText() );
829 tmp = const_cast<SCH_FIELD*>( existingField );
830
831 *tmp = field;
832
833 if( !currentVariant.IsEmpty() )
834 {
835 // Restore the default field text for existing fields.
836 tmp->SetText( defaultText, &currentSheet );
837
838 wxString variantText = m_symbol->Schematic()->ConvertRefsToKIIDs( field.GetText() );
839 tmp->SetText( variantText, &currentSheet, currentVariant );
840 }
841 }
842
843 if( !field.IsMandatory() )
844 field.SetOrdinal( ordinal++ );
845 }
846
847 for( int ii = (int) m_symbol->GetFields().size() - 1; ii >= 0; ii-- )
848 {
849 SCH_FIELD& symbolField = m_symbol->GetFields()[ii];
850
851 if( symbolField.IsMandatory() )
852 continue;
853
854 bool found = false;
855
856 for( const SCH_FIELD& editedField : *m_fields )
857 {
858 if( editedField.GetName() == symbolField.GetName() )
859 {
860 found = true;
861 break;
862 }
863 }
864
865 if( !found )
866 m_symbol->GetFields().erase( m_symbol->GetFields().begin() + ii );
867 }
868
869 if( currentVariant.IsEmpty() )
870 {
871 // Reference has a specific initialization, depending on the current active sheet
872 // because for a given symbol, in a complex hierarchy, there are more than one
873 // reference.
874 m_symbol->SetRef( &GetParent()->GetCurrentSheet(), m_fields->GetField( FIELD_T::REFERENCE )->GetText() );
875 }
876
877 m_symbol->SetExcludedFromSim( m_cbExcludeFromSim->IsChecked(), &currentSheet, currentVariant );
878 m_symbol->SetExcludedFromBOM( m_cbExcludeFromBom->IsChecked(), &currentSheet, currentVariant );
879 m_symbol->SetExcludedFromBoard( m_cbExcludeFromBoard->IsChecked(), &currentSheet, currentVariant );
880 m_symbol->SetExcludedFromPosFiles( m_cbExcludeFromPosFiles->IsChecked(), &currentSheet, currentVariant );
881 m_symbol->SetDNP( m_cbDNP->IsChecked(), &currentSheet, currentVariant );
882
883 switch( m_choicePassthrough->GetSelection() )
884 {
885 case 0: m_symbol->SetPassthroughMode( SCH_SYMBOL::PASSTHROUGH_MODE::DEFAULT ); break;
886 case 1: m_symbol->SetPassthroughMode( SCH_SYMBOL::PASSTHROUGH_MODE::BLOCK ); break;
887 case 2: m_symbol->SetPassthroughMode( SCH_SYMBOL::PASSTHROUGH_MODE::FORCE ); break;
888 default: break;
889 }
890
891 // Update any assignments
892 if( m_dataModel )
893 {
894 for( const SCH_PIN& model_pin : *m_dataModel )
895 {
896 // map from the edited copy back to the "real" pin(s) in the symbol.
897 for( SCH_PIN* src_pin : m_symbol->GetPinsByNumber( model_pin.GetNumber() ) )
898 src_pin->SetAlt( model_pin.GetAlt() );
899 }
900 }
901
902 // Keep fields other than the reference, include/exclude flags, and alternate pin assignements
903 // in sync in multi-unit parts.
904 m_symbol->SyncOtherUnits( currentSheet, commit, nullptr, currentVariant );
905
906 if( replaceOnCurrentScreen )
907 currentScreen->Append( m_symbol );
908
909 if( !commit.Empty() )
910 commit.Push( _( "Edit Symbol Properties" ) );
911
912 return true;
913}
914
915
917{
918 wxGridCellEditor* editor = m_fieldsGrid->GetCellEditor( event.GetRow(), event.GetCol() );
919 wxControl* control = editor->GetControl();
920
921 if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
922 {
923 event.Veto();
924 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
925 evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
926 QueueEvent( evt );
927 }
928 else if( event.GetCol() == FDC_NAME )
929 {
930 wxString newName = event.GetString();
931
932 for( int i = 0; i < m_fieldsGrid->GetNumberRows(); ++i )
933 {
934 if( i == event.GetRow() )
935 continue;
936
937 if( newName.CmpNoCase( m_fieldsGrid->GetCellValue( i, FDC_NAME ) ) == 0 )
938 {
939 DisplayError( this, wxString::Format( _( "Field name '%s' already in use." ),
940 newName ) );
941 event.Veto();
942 wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
943 evt->SetClientData( new VECTOR2I( event.GetRow(), event.GetCol() ) );
944 QueueEvent( evt );
945 }
946 }
947 }
948
949 editor->DecRef();
950}
951
952
954{
955 if( m_fields->at( aEvent.GetRow() ).GetId() == FIELD_T::REFERENCE
956 && aEvent.GetCol() == FDC_VALUE )
957 {
958 wxCommandEvent* evt = new wxCommandEvent( SYMBOL_DELAY_SELECTION );
959 evt->SetClientData( new VECTOR2I( aEvent.GetRow(), aEvent.GetCol() ) );
960 QueueEvent( evt );
961 }
962
963 m_editorShown = true;
964}
965
966
968{
969 m_editorShown = false;
970}
971
972
973void DIALOG_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
974{
975 m_fieldsGrid->OnAddRow(
976 [&]() -> std::pair<int, int>
977 {
979
980 newField.SetTextAngle( m_fields->GetField( FIELD_T::REFERENCE )->GetTextAngle() );
981 newField.SetVisible( false );
982
983 m_fields->push_back( newField );
984
985 // notify the grid
986 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 );
987 m_fieldsGrid->ProcessTableMessage( msg );
988 OnModify();
989
990 return { m_fields->size() - 1, FDC_NAME };
991 } );
992}
993
994
995void DIALOG_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
996{
997 m_fieldsGrid->OnDeleteRows(
998 [&]( int row )
999 {
1000 if( row < m_fields->GetMandatoryRowCount() )
1001 {
1002 DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ),
1003 m_fields->GetMandatoryRowCount() ) );
1004 return false;
1005 }
1006
1007 return true;
1008 },
1009 [&]( int row )
1010 {
1011 m_fields->erase( m_fields->begin() + row );
1012
1013 // notify the grid
1014 wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, row, 1 );
1015 m_fieldsGrid->ProcessTableMessage( msg );
1016 } );
1017
1018 OnModify();
1019}
1020
1021
1022void DIALOG_SYMBOL_PROPERTIES::OnMoveUp( wxCommandEvent& event )
1023{
1024 m_fieldsGrid->OnMoveRowUp(
1025 [&]( int row )
1026 {
1027 return row > m_fields->GetMandatoryRowCount();
1028 },
1029 [&]( int row )
1030 {
1031 std::swap( *( m_fields->begin() + row ), *( m_fields->begin() + row - 1 ) );
1032 m_fieldsGrid->ForceRefresh();
1033 OnModify();
1034 } );
1035}
1036
1037
1038void DIALOG_SYMBOL_PROPERTIES::OnMoveDown( wxCommandEvent& event )
1039{
1040 m_fieldsGrid->OnMoveRowDown(
1041 [&]( int row )
1042 {
1043 return row >= m_fields->GetMandatoryRowCount();
1044 },
1045 [&]( int row )
1046 {
1047 std::swap( *( m_fields->begin() + row ), *( m_fields->begin() + row + 1 ) );
1048 m_fieldsGrid->ForceRefresh();
1049 OnModify();
1050 } );
1051}
1052
1053
1059
1060
1066
1067
1073
1074
1080
1081
1083{
1084 int row = aEvent.GetRow();
1085
1086 if( m_pinGrid->GetCellValue( row, COL_ALT_NAME ) == m_dataModel->GetValue( row, COL_BASE_NAME ) )
1087 m_dataModel->SetValue( row, COL_ALT_NAME, wxEmptyString );
1088
1089 // These are just to get the cells refreshed
1090 m_dataModel->SetValue( row, COL_TYPE, m_dataModel->GetValue( row, COL_TYPE ) );
1091 m_dataModel->SetValue( row, COL_SHAPE, m_dataModel->GetValue( row, COL_SHAPE ) );
1092
1093 OnModify();
1094}
1095
1096
1098{
1099 int sortCol = aEvent.GetCol();
1100 bool ascending;
1101
1102 // This is bonkers, but wxWidgets doesn't tell us ascending/descending in the
1103 // event, and if we ask it will give us pre-event info.
1104 if( m_pinGrid->IsSortingBy( sortCol ) )
1105 // same column; invert ascending
1106 ascending = !m_pinGrid->IsSortOrderAscending();
1107 else
1108 // different column; start with ascending
1109 ascending = true;
1110
1111 m_dataModel->SortRows( sortCol, ascending );
1112 m_dataModel->BuildAttrs();
1113}
1114
1115
1117{
1118 wxGridUpdateLocker deferRepaintsTillLeavingScope( m_pinGrid );
1119
1120 // Account for scroll bars
1121 int pinTblWidth = KIPLATFORM::UI::GetUnobscuredSize( m_pinGrid ).x;
1122
1123 // Stretch the Base Name and Alternate Assignment columns to fit.
1124 for( int i = 0; i < COL_COUNT; ++i )
1125 {
1126 if( i != COL_BASE_NAME && i != COL_ALT_NAME )
1127 pinTblWidth -= m_pinGrid->GetColSize( i );
1128 }
1129
1130 if( pinTblWidth > 2 )
1131 {
1132 m_pinGrid->SetColSize( COL_BASE_NAME, pinTblWidth / 2 );
1133 m_pinGrid->SetColSize( COL_ALT_NAME, pinTblWidth / 2 );
1134 }
1135}
1136
1137
1138void DIALOG_SYMBOL_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1139{
1140 std::bitset<64> shownColumns = m_fieldsGrid->GetShownColumns();
1141
1142 if( shownColumns != m_shownColumns )
1143 {
1144 m_shownColumns = shownColumns;
1145
1146 if( !m_fieldsGrid->IsCellEditControlShown() )
1147 m_fieldsGrid->SetGridWidthsDirty();
1148 }
1149}
1150
1151
1153{
1154 VECTOR2I *loc = static_cast<VECTOR2I*>( event.GetClientData() );
1155
1156 wxCHECK_RET( loc, wxT( "Missing focus cell location" ) );
1157
1158 // Run the AutoColumnSizer before setting focus (as it will clear any shown cell edit control
1159 // if it has to resize that column).
1160 m_fieldsGrid->RecomputeGridWidths();
1161
1162 // Handle a delayed focus
1163
1164 m_fieldsGrid->SetFocus();
1165 m_fieldsGrid->MakeCellVisible( loc->x, loc->y );
1166 m_fieldsGrid->SetGridCursor( loc->x, loc->y );
1167
1168 delete loc;
1169
1170 CallAfter(
1171 [this]()
1172 {
1173 m_fieldsGrid->EnableCellEditControl( true );
1174 } );
1175}
1176
1177
1179{
1180 VECTOR2I *loc = static_cast<VECTOR2I*>( event.GetClientData() );
1181
1182 wxCHECK_RET( loc, wxT( "Missing focus cell location" ) );
1183
1184 // Handle a delayed selection
1185 wxGridCellEditor* cellEditor = m_fieldsGrid->GetCellEditor( loc->x, loc->y );
1186
1187 if( wxTextEntry* txt = dynamic_cast<wxTextEntry*>( cellEditor->GetControl() ) )
1189
1190 cellEditor->DecRef(); // we're done; must release
1191 delete loc;
1192}
1193
1194
1196{
1197 wxSize new_size = event.GetSize();
1198
1199 if( ( !m_editorShown || m_lastRequestedPinsSize != new_size ) && m_pinsSize != new_size )
1200 {
1201 m_pinsSize = new_size;
1202
1204 }
1205
1206 // We store this value to check whether the dialog is changing size. This might indicate
1207 // that the user is scaling the dialog with a grid-cell-editor shown. Some editors do not
1208 // close (at least on GTK) when the user drags a dialog corner
1209 m_lastRequestedPinsSize = new_size;
1210
1211 // Always propagate for a grid repaint (needed if the height changes, as well as width)
1212 event.Skip();
1213}
1214
1215
1216void DIALOG_SYMBOL_PROPERTIES::OnCheckBox( wxCommandEvent& event )
1217{
1218 OnModify();
1219}
1220
1221
1222void DIALOG_SYMBOL_PROPERTIES::OnUnitChoice( wxCommandEvent& event )
1223{
1224 if( m_dataModel )
1225 {
1226 EDA_ITEM_FLAGS flags = m_symbol->GetFlags();
1227
1228 int unit_selection = m_unitChoice->GetSelection() + 1;
1229
1230 // We need to select a new unit to build the new unit pin list
1231 // but we should not change the symbol, so the initial unit will be selected
1232 // after rebuilding the pin list
1233 int old_unit = m_symbol->GetUnit();
1234 m_symbol->SetUnit( unit_selection );
1235
1236 // Rebuild a copy of the pins of the new unit for editing
1237 m_dataModel->clear();
1238
1239 for( const std::unique_ptr<SCH_PIN>& pin : m_symbol->GetRawPins() )
1240 m_dataModel->push_back( *pin );
1241
1242 m_dataModel->SortRows( COL_NUMBER, true );
1243 m_dataModel->BuildAttrs();
1244
1245 m_symbol->SetUnit( old_unit );
1246
1247 // Restore m_Flag modified by SetUnit()
1248 m_symbol->ClearFlags();
1249 m_symbol->SetFlags( flags );
1250 }
1251
1252 OnModify();
1253}
1254
1255
1257{
1258 event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
1259}
1260
1261
1263{
1264 event.Enable( m_symbol && m_symbol->GetLibSymbolRef() );
1265}
1266
1267
1268void DIALOG_SYMBOL_PROPERTIES::OnPageChanging( wxBookCtrlEvent& aEvent )
1269{
1270 if( !m_fieldsGrid->CommitPendingChanges() )
1271 aEvent.Veto();
1272
1273 if( !m_pinGrid->CommitPendingChanges() )
1274 aEvent.Veto();
1275}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
bool Empty() const
Definition commit.h:134
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void EndQuasiModal(int retCode)
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_BASE_FRAME * m_parentFrame
int ShowModal() override
DIALOG_SYMBOL_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Symbol Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU)
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
PANEL_SYMBOL_PIN_MAP * m_pinMapPanel
SCH_PIN_TABLE_DATA_MODEL * m_dataModel
void OnMoveDown(wxCommandEvent &event) override
void OnPinTableColSort(wxGridEvent &aEvent)
void OnMoveUp(wxCommandEvent &event) override
void OnDeleteField(wxCommandEvent &event) override
void OnAddField(wxCommandEvent &event) override
void OnGridEditorHidden(wxGridEvent &event) override
PANEL_EMBEDDED_FILES * m_embeddedFiles
void OnUnitChoice(wxCommandEvent &event) override
void OnEditSpiceModel(wxCommandEvent &event) override
void OnPageChanging(wxNotebookEvent &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
void SelectPinMapPage()
Select the Pin Map page so the dialog opens directly on the pin-to-pad mapping editor (issue #2282).
void OnExchangeSymbol(wxCommandEvent &) override
virtual void onUpdateEditSymbol(wxUpdateUIEvent &event) override
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:89
virtual void Offset(const VECTOR2I &aOffset)
Definition eda_text.cpp:595
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:381
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:294
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition grid_tricks.h:57
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
Composed widget that edits a symbol's named pin maps and the footprint each is bound to.
static int Compare(const wxString &lhs, const wxString &rhs)
Holds all the data relating to one schematic.
Definition schematic.h:90
wxString GetCurrentVariant() const
Return the current variant being edited.
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:189
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCHEMATIC & Schematic() const
void SetOrdinal(int aOrdinal)
Definition sch_field.h:138
bool IsMandatory() const
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
void SetText(const wxString &aText) override
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)
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) 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
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind) override
const std::map< wxString, ALT > & GetAlternates() const
Definition sch_pin.h:203
ALT GetAlt(const wxString &aAlt)
Definition sch_pin.h:217
SCH_PIN * GetLibPin() const
Definition sch_pin.h:95
const wxString & GetName() const
Definition sch_pin.cpp:499
const wxString & GetBaseName() const
Get the name without any alternates.
Definition sch_pin.cpp:508
const wxString & GetNumber() const
Definition sch_pin.h:130
GRAPHIC_PINSHAPE GetShape() const
Definition sch_pin.cpp:372
ELECTRICAL_PINTYPE GetType() const
Definition sch_pin.cpp:407
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
bool Remove(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Remove aItem from the schematic associated with this screen.
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:69
wxGridCellAttr * enhanceAttr(wxGridCellAttr *aInputAttr, int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind)
Definition wx_grid.cpp:43
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
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
@ FDC_NAME
@ FDC_VALUE
wxColour GetDialogBGColour()
Definition wxgtk/ui.cpp:63
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition wxgtk/ui.cpp:294
KICOMMON_API wxFont GetSmallInfoFont(wxWindow *aWindow)
KICOMMON_API void SelectReferenceNumber(wxTextEntry *aTextEntry)
Select the number (or "?") in a reference for ease of editing.
const std::vector< BITMAPS > & PinTypeIcons()
Definition pin_type.cpp:158
const wxArrayString & PinTypeNames()
Definition pin_type.cpp:149
const wxArrayString & PinShapeNames()
Definition pin_type.cpp:167
const std::vector< BITMAPS > & PinShapeIcons()
Definition pin_type.cpp:176
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.
@ SYM_ORIENT_270
Definition symbol.h:38
@ SYM_MIRROR_Y
Definition symbol.h:40
@ SYM_ORIENT_180
Definition symbol.h:37
@ SYM_MIRROR_X
Definition symbol.h:39
@ SYM_ORIENT_90
Definition symbol.h:36
@ SYM_ORIENT_0
Definition symbol.h:35
wxString GetUserFieldName(int aFieldNdx, bool aTranslateForHI)
#define DO_TRANSLATE
@ USER
The field ID hasn't been set yet; field is invalid.
@ REFERENCE
Field Reference of part, i.e. "IC21".
KIBIS_PIN * pin
VECTOR3I res
VECTOR2I end
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683