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