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