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