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