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