KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_properties_panel.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) 2020-2023 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 3
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
23
24#include <font/fontconfig.h>
26#include <frame_type.h>
27#include <pgm_base.h>
28#include <pcb_base_edit_frame.h>
29#include <tool/tool_manager.h>
30#include <tools/pcb_actions.h>
34#include <board_commit.h>
36#include <board.h>
38#include <properties/property.h>
39#include <pcb_shape.h>
40#include <pcb_text.h>
41#include <pcb_track.h>
42#include <pcb_generator.h>
44#include <pad.h>
45#include <footprint.h>
46#include <pcb_field.h>
47#include <template_fieldnames.h>
49#include <string_utils.h>
51#include <widgets/ui_common.h>
52
53static const wxString MISSING_FIELD_SENTINEL = wxS( "\uE000" );
54
56{
57public:
58 PCB_FOOTPRINT_FIELD_PROPERTY( const wxString& aName ) :
59 PROPERTY_BASE( aName ),
60 m_name( aName )
61 {
62 }
63
64 size_t OwnerHash() const override { return TYPE_HASH( FOOTPRINT ); }
65 size_t BaseHash() const override { return TYPE_HASH( FOOTPRINT ); }
66 size_t TypeHash() const override { return TYPE_HASH( wxString ); }
67
68 bool Writeable( INSPECTABLE* aObject ) const override
69 {
70 return PROPERTY_BASE::Writeable( aObject );
71 }
72
73 void setter( void* obj, wxAny& v ) override
74 {
75 wxString value;
76
77 if( !v.GetAs( &value ) )
78 return;
79
80 FOOTPRINT* footprint = reinterpret_cast<FOOTPRINT*>( obj );
81 PCB_FIELD* field = footprint->GetField( m_name );
82
83 wxString variantName;
84
85 if( footprint->GetBoard() )
86 variantName = footprint->GetBoard()->GetCurrentVariant();
87
88 if( !variantName.IsEmpty() )
89 {
90 // Store the value as a variant override
91 FOOTPRINT_VARIANT* variant = footprint->AddVariant( variantName );
92
93 if( variant )
94 variant->SetFieldValue( m_name, value );
95 }
96 else
97 {
98 // Set the base field value
99 if( !field )
100 {
101 PCB_FIELD* newField = new PCB_FIELD( footprint, FIELD_T::USER, m_name );
102 newField->SetText( value );
103 footprint->Add( newField );
104 }
105 else
106 {
107 field->SetText( value );
108 }
109 }
110 }
111
112 wxAny getter( const void* obj ) const override
113 {
114 const FOOTPRINT* footprint = reinterpret_cast<const FOOTPRINT*>( obj );
115 PCB_FIELD* field = footprint->GetField( m_name );
116
117 if( field )
118 {
119 wxString variantName;
120
121 if( footprint->GetBoard() )
122 variantName = footprint->GetBoard()->GetCurrentVariant();
123
124 wxString text;
125
126 if( !variantName.IsEmpty() )
127 text = footprint->GetFieldValueForVariant( variantName, m_name );
128 else
129 text = field->GetText();
130
131 return wxAny( text );
132 }
133 else
134 {
135 return wxAny( MISSING_FIELD_SENTINEL );
136 }
137 }
138
139private:
140 wxString m_name;
141};
142
144
145
146class PG_NET_SELECTOR_EDITOR : public wxPGEditor
147{
148public:
149 static const wxString EDITOR_NAME;
150
152 m_frame( aFrame )
153 {
154 }
155
156 void UpdateFrame( PCB_BASE_EDIT_FRAME* aFrame ) { m_frame = aFrame; }
157
158 wxString GetName() const override { return EDITOR_NAME; }
159
160 wxPGWindowList CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty, const wxPoint& aPos,
161 const wxSize& aSize ) const override
162 {
163 NET_SELECTOR* editor = new NET_SELECTOR( aGrid->GetPanel(), wxID_ANY, aPos, aSize, 0 );
164
165 if( BOARD* board = m_frame->GetBoard() )
166 editor->SetNetInfo( &board->GetNetInfo() );
167
168 editor->SetIndeterminateString( INDETERMINATE_STATE );
169 UpdateControl( aProperty, editor );
170
171 editor->Bind( FILTERED_ITEM_SELECTED,
172 [=]( wxCommandEvent& aEvt )
173 {
174 auto& choices = const_cast<wxPGChoices&>( aProperty->GetChoices() );
175 wxString netname = editor->GetSelectedNetname();
176
177 if( choices.Index( netname ) == wxNOT_FOUND )
178 choices.Add( netname, editor->GetSelectedNetcode() );
179
180 wxVariant val( editor->GetSelectedNetcode() );
181 aGrid->ChangePropertyValue( aProperty, val );
182 } );
183
184 return editor;
185 }
186
187 void UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const override
188 {
189 if( NET_SELECTOR* editor = dynamic_cast<NET_SELECTOR*>( aCtrl ) )
190 {
191 if( aProperty->IsValueUnspecified() )
192 editor->SetIndeterminate();
193 else
194 editor->SetSelectedNetcode( (int) aProperty->GetValue().GetLong() );
195 }
196 }
197
198 bool GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty, wxWindow* aCtrl ) const override
199 {
200 NET_SELECTOR* editor = dynamic_cast<NET_SELECTOR*>( aCtrl );
201
202 if( !editor )
203 return false;
204
205 aVariant = static_cast<long>( editor->GetSelectedNetcode() );
206 return true;
207 }
208
209 bool OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aWindow, wxEvent& aEvent ) const override
210 {
211 return false;
212 }
213
214private:
216};
217
218
219const wxString PG_NET_SELECTOR_EDITOR::EDITOR_NAME = wxS( "PG_NET_SELECTOR_EDITOR" );
220
221
222
224 PROPERTIES_PANEL( aParent, aFrame ),
225 m_frame( aFrame ),
226 m_propMgr( PROPERTY_MANAGER::Instance() )
227{
228 m_propMgr.Rebuild();
229 bool found = false;
230
231 wxASSERT( wxPGGlobalVars );
232
233 wxString editorKey = PG_UNIT_EDITOR::BuildEditorName( m_frame );
234
235 auto it = wxPGGlobalVars->m_mapEditorClasses.find( editorKey );
236
237 if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
238 {
239 m_unitEditorInstance = static_cast<PG_UNIT_EDITOR*>( it->second );
240 m_unitEditorInstance->UpdateFrame( m_frame );
241 found = true;
242 }
243
244 if( !found )
245 {
246 PG_UNIT_EDITOR* new_editor = new PG_UNIT_EDITOR( m_frame );
247 m_unitEditorInstance = static_cast<PG_UNIT_EDITOR*>( wxPropertyGrid::RegisterEditorClass( new_editor ) );
248 }
249
250 it = wxPGGlobalVars->m_mapEditorClasses.find( PG_CHECKBOX_EDITOR::EDITOR_NAME );
251
252 if( it == wxPGGlobalVars->m_mapEditorClasses.end() )
253 {
254 PG_CHECKBOX_EDITOR* cbEditor = new PG_CHECKBOX_EDITOR();
255 m_checkboxEditorInstance = static_cast<PG_CHECKBOX_EDITOR*>( wxPropertyGrid::RegisterEditorClass( cbEditor ) );
256 }
257 else
258 {
259 m_checkboxEditorInstance = static_cast<PG_CHECKBOX_EDITOR*>( it->second );
260 }
261
262 it = wxPGGlobalVars->m_mapEditorClasses.find( PG_RATIO_EDITOR::EDITOR_NAME );
263
264 if( it == wxPGGlobalVars->m_mapEditorClasses.end() )
265 {
266 PG_RATIO_EDITOR* ratioEditor = new PG_RATIO_EDITOR();
267 m_ratioEditorInstance = static_cast<PG_RATIO_EDITOR*>( wxPropertyGrid::RegisterEditorClass( ratioEditor ) );
268 }
269 else
270 {
271 m_ratioEditorInstance = static_cast<PG_RATIO_EDITOR*>( it->second );
272 }
273
274 it = wxPGGlobalVars->m_mapEditorClasses.find( PG_NET_SELECTOR_EDITOR::EDITOR_NAME );
275
276 if( it == wxPGGlobalVars->m_mapEditorClasses.end() )
277 {
279 m_netSelectorEditorInstance = static_cast<PG_NET_SELECTOR_EDITOR*>( wxPropertyGrid::RegisterEditorClass( netEditor ) );
280 }
281 else
282 {
283 m_netSelectorEditorInstance = static_cast<PG_NET_SELECTOR_EDITOR*>( it->second );
284 m_netSelectorEditorInstance->UpdateFrame( m_frame );
285 }
286
287 it = wxPGGlobalVars->m_mapEditorClasses.find( PG_FPID_EDITOR::BuildEditorName( m_frame ) );
288
289 if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
290 {
291 m_fpEditorInstance = static_cast<PG_FPID_EDITOR*>( it->second );
292 m_fpEditorInstance->UpdateFrame( m_frame );
293 }
294 else
295 {
296 PG_FPID_EDITOR* fpEditor = new PG_FPID_EDITOR( m_frame,
297 []()
298 {
299 return "";
300 });
301 m_fpEditorInstance = static_cast<PG_FPID_EDITOR*>( wxPropertyGrid::RegisterEditorClass( fpEditor ) );
302 }
303
304 it = wxPGGlobalVars->m_mapEditorClasses.find( PG_URL_EDITOR::BuildEditorName( m_frame ) );
305
306 if( it != wxPGGlobalVars->m_mapEditorClasses.end() )
307 {
308 m_urlEditorInstance = static_cast<PG_URL_EDITOR*>( it->second );
309 m_urlEditorInstance->UpdateFrame( m_frame );
310 }
311 else
312 {
313 PG_URL_EDITOR* urlEditor = new PG_URL_EDITOR( m_frame );
314 m_urlEditorInstance = static_cast<PG_URL_EDITOR*>( wxPropertyGrid::RegisterEditorClass( urlEditor ) );
315 }
316}
317
318
320{
321 m_unitEditorInstance->UpdateFrame( nullptr );
322 m_fpEditorInstance->UpdateFrame( nullptr );
323 m_urlEditorInstance->UpdateFrame( nullptr );
324 m_netSelectorEditorInstance->UpdateFrame( nullptr );
325}
326
327
329{
330 PCB_SELECTION_TOOL* selectionTool = m_frame->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
331 const SELECTION& selection = selectionTool->GetSelection();
332
333 if( selection.Empty() && m_frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
334 {
335 if( BOARD* board = m_frame->GetBoard() )
336 {
337 if( FOOTPRINT* footprint = board->GetFirstFootprint() )
338 {
339 aFallbackSelection.Clear();
340 aFallbackSelection.Add( footprint );
341 return aFallbackSelection;
342 }
343 }
344 }
345
346 return selection;
347}
348
349
351{
352 SELECTION fallbackSelection;
353 const SELECTION& selection = getSelection( fallbackSelection );
354
355 return selection.Empty() ? nullptr : selection.Front();
356}
357
358
360{
361 SELECTION fallbackSelection;
362 const SELECTION& selection = getSelection( fallbackSelection );
363
364 // TODO perhaps it could be called less often? use PROPERTIES_TOOL and catch MODEL_RELOAD?
365 updateLists( static_cast<PCB_EDIT_FRAME*>( m_frame )->GetBoard() );
366
367 // Will actually just be updatePropertyValues() if selection hasn't changed
368 rebuildProperties( selection );
369}
370
371
373{
374 SELECTION fallbackSelection;
375 const SELECTION& selection = getSelection( fallbackSelection );
376
377 rebuildProperties( selection );
378}
379
380
382{
383 m_currentFieldNames.clear();
384
385 for( EDA_ITEM* item : aSelection )
386 {
387 if( item->Type() != PCB_FOOTPRINT_T )
388 continue;
389
390 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
391
392 for( PCB_FIELD* field : footprint->GetFields() )
393 {
394 wxCHECK2( field, continue );
395
396 m_currentFieldNames.insert( field->GetCanonicalName() );
397 }
398 }
399
400 const wxString groupFields = _HKI( "Fields" );
401
402 // Make sure value comes immediately after reference. (Reference is invariant, so was added by
403 // FOOTPRINT_DESC(). We *could* still add it here, but then the whole Fields section comes at
404 // the end, which isn't ideal.)
405 m_propMgr.AddProperty( new PCB_FOOTPRINT_FIELD_PROPERTY( _HKI( "Value" ) ), groupFields );
406
407 for( const wxString& name : m_currentFieldNames )
408 {
409 if( !m_propMgr.GetProperty( TYPE_HASH( FOOTPRINT ), name ) )
410 {
411 m_propMgr.AddProperty( new PCB_FOOTPRINT_FIELD_PROPERTY( name ), groupFields )
412 .SetAvailableFunc( [name]( INSPECTABLE* )
413 {
415 } );
416 }
417 }
418
419 m_propMgr.AddProperty( new PROPERTY<FOOTPRINT, wxString>( _HKI( "Library Link" ),
421 groupFields );
422 m_propMgr.AddProperty( new PROPERTY<FOOTPRINT, wxString>( _HKI( "Library Description" ),
424 groupFields );
425 m_propMgr.AddProperty( new PROPERTY<FOOTPRINT, wxString>( _HKI( "Keywords" ),
427 groupFields );
428
429 // Note: Also used by DRC engine
430 m_propMgr.AddProperty( new PROPERTY<FOOTPRINT, wxString>( _HKI( "Component Class" ),
432 groupFields )
433 .SetIsHiddenFromLibraryEditors();
434
436}
437
438
439wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProperty ) const
440{
441 if( aProperty->TypeHash() == TYPE_HASH( PCB_LAYER_ID ) )
442 {
443 wxASSERT( aProperty->HasChoices() );
444
445 const wxPGChoices& canonicalLayers = aProperty->Choices();
446 wxArrayString boardLayerNames;
447 wxArrayInt boardLayerIDs;
448
449 for( int ii = 0; ii < (int) aProperty->Choices().GetCount(); ++ii )
450 {
451 int layer = canonicalLayers.GetValue( ii );
452
453 boardLayerNames.push_back( m_frame->GetBoard()->GetLayerName( ToLAYER_ID( layer ) ) );
454 boardLayerIDs.push_back( canonicalLayers.GetValue( ii ) );
455 }
456
457 auto ret = new PGPROPERTY_COLORENUM( new wxPGChoices( boardLayerNames, boardLayerIDs ) );
458
459 ret->SetColorFunc(
460 [&]( int aValue ) -> wxColour
461 {
462 return m_frame->GetColorSettings()->GetColor( ToLAYER_ID( aValue ) ).ToColour();
463 } );
464
465 ret->SetLabel( wxGetTranslation( aProperty->Name() ) );
466 ret->SetName( aProperty->Name() );
467 ret->SetHelpString( wxGetTranslation( aProperty->Name() ) );
468 ret->SetClientData( const_cast<PROPERTY_BASE*>( aProperty ) );
469
470 return ret;
471 }
472
473 wxPGProperty* prop = PGPropertyFactory( aProperty, m_frame );
474
475 if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::FOOTPRINT ) )
476 prop->SetEditor( PG_FPID_EDITOR::BuildEditorName( m_frame ) );
477 else if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::DATASHEET ) )
478 prop->SetEditor( PG_URL_EDITOR::BuildEditorName( m_frame ) );
479
480 return prop;
481}
482
483
484PROPERTY_BASE* PCB_PROPERTIES_PANEL::getPropertyFromEvent( const wxPropertyGridEvent& aEvent ) const
485{
486 EDA_ITEM* item = const_cast<PCB_PROPERTIES_PANEL*>( this )->getFrontItem();
487
488 if( !item || !item->IsBOARD_ITEM() )
489 return nullptr;
490
491 BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( item );
492
493 wxCHECK_MSG( firstItem, nullptr, wxT( "getPropertyFromEvent for a property with nothing selected!") );
494
495 PROPERTY_BASE* property = m_propMgr.GetProperty( TYPE_HASH( *firstItem ), aEvent.GetPropertyName() );
496 wxCHECK_MSG( property, nullptr, wxT( "getPropertyFromEvent for a property not found on the selected item!" ) );
497
498 return property;
499}
500
501
502void PCB_PROPERTIES_PANEL::valueChanging( wxPropertyGridEvent& aEvent )
503{
505 return;
506
507 EDA_ITEM* item = getFrontItem();
508
509 PROPERTY_BASE* property = getPropertyFromEvent( aEvent );
510 wxCHECK( property, /* void */ );
511 wxCHECK( item, /* void */ );
512
513 wxVariant newValue = aEvent.GetPropertyValue();
514
515 if( VALIDATOR_RESULT validationFailure = property->Validate( newValue.GetAny(), item ) )
516 {
517 wxString errorMsg = wxString::Format( wxS( "%s: %s" ), wxGetTranslation( property->Name() ),
518 validationFailure->get()->Format( m_frame ) );
519 m_frame->ShowInfoBarError( errorMsg );
520 aEvent.Veto();
521 return;
522 }
523
524 aEvent.Skip();
525}
526
527
528void PCB_PROPERTIES_PANEL::valueChanged( wxPropertyGridEvent& aEvent )
529{
531 return;
532
533 SELECTION fallbackSelection;
534 const SELECTION& selection = getSelection( fallbackSelection );
535
536 wxCHECK( getPropertyFromEvent( aEvent ), /* void */ );
537
538 wxVariant newValue = aEvent.GetPropertyValue();
539 BOARD_COMMIT changes( m_frame );
540
541 PROPERTY_COMMIT_HANDLER handler( &changes );
542
543 for( EDA_ITEM* edaItem : selection )
544 {
545 if( !edaItem->IsBOARD_ITEM() )
546 continue;
547
548 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( edaItem );
549 PROPERTY_BASE* property = m_propMgr.GetProperty( TYPE_HASH( *item ), aEvent.GetPropertyName() );
550 wxCHECK( property, /* void */ );
551
552 if( item->Type() == PCB_TABLECELL_T )
553 changes.Modify( item->GetParent(), nullptr, RECURSE_MODE::NO_RECURSE );
554 else if( item->Type() == PCB_GENERATOR_T )
555 changes.Modify( item, nullptr, RECURSE_MODE::RECURSE );
556 else
557 changes.Modify( item, nullptr, RECURSE_MODE::NO_RECURSE );
558
559 // In the PCB Editor, we generally restrict pad movement to the footprint (like dragging)
560 if( item->Type() == PCB_PAD_T && m_frame
561 && m_frame->IsType( FRAME_PCB_EDITOR )
562 && !m_frame->GetPcbNewSettings()->m_AllowFreePads
563 && ( aEvent.GetPropertyName() == _HKI( "Position X" )
564 || aEvent.GetPropertyName() == _HKI( "Position Y" ) ) )
565 {
566 PAD* pad = static_cast<PAD*>( item );
567 FOOTPRINT* fp = pad->GetParentFootprint();
568
569 if( fp )
570 {
571 VECTOR2I oldPos = pad->GetPosition();
572 VECTOR2I newPos = oldPos;
573
574 if( aEvent.GetPropertyName() == _HKI( "Position X" ) )
575 newPos.x = (int) newValue.GetLong();
576 else
577 newPos.y = (int) newValue.GetLong();
578
579 VECTOR2I delta = newPos - oldPos;
580
581 if( delta.x != 0 || delta.y != 0 )
582 {
583 changes.Modify( fp );
584 fp->Move( delta );
585 }
586 }
587
588 continue;
589 }
590
591 // Handle variant-aware boolean properties for footprints
592 if( item->Type() == PCB_FOOTPRINT_T )
593 {
594 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
595 wxString variantName;
596
597 if( footprint->GetBoard() )
598 variantName = footprint->GetBoard()->GetCurrentVariant();
599
600 if( !variantName.IsEmpty() )
601 {
602 wxString propName = aEvent.GetPropertyName();
603
604 if( propName == _HKI( "Do not Populate" )
605 || propName == _HKI( "Exclude From Bill of Materials" )
606 || propName == _HKI( "Exclude From Position Files" ) )
607 {
608 FOOTPRINT_VARIANT* variant = footprint->GetVariant( variantName );
609
610 if( !variant )
611 variant = footprint->AddVariant( variantName );
612
613 if( variant )
614 {
615 bool boolValue = newValue.GetBool();
616
617 if( propName == _HKI( "Do not Populate" ) )
618 variant->SetDNP( boolValue );
619 else if( propName == _HKI( "Exclude From Bill of Materials" ) )
620 variant->SetExcludedFromBOM( boolValue );
621 else if( propName == _HKI( "Exclude From Position Files" ) )
622 variant->SetExcludedFromPosFiles( boolValue );
623
624 continue;
625 }
626 }
627 }
628 }
629
630 item->Set( property, newValue );
631 }
632
633 changes.Push( _( "Edit Properties" ) );
634
635 m_frame->Refresh();
636
637 // Perform grid updates as necessary based on value change
638 AfterCommit();
639
640 // PointEditor may need to update if locked/unlocked
641 if( aEvent.GetPropertyName() == _HKI( "Locked" ) )
642 m_frame->GetToolManager()->ProcessEvent( EVENTS::SelectedEvent );
643
644 aEvent.Skip();
645}
646
647
649{
650 wxPGChoices layersAll;
651 wxPGChoices layersCu;
652 wxPGChoices nets;
653 wxPGChoices fonts;
654
655 // Regenerate all layers
656 for( PCB_LAYER_ID layer : aBoard->GetEnabledLayers().UIOrder() )
657 layersAll.Add( LSET::Name( layer ), layer );
658
659 for( PCB_LAYER_ID layer : LSET( aBoard->GetEnabledLayers() & LSET::AllCuMask() ).UIOrder() )
660 layersCu.Add( LSET::Name( layer ), layer );
661
662 m_propMgr.GetProperty( TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ) )->SetChoices( layersAll );
663 m_propMgr.GetProperty( TYPE_HASH( PCB_SHAPE ), _HKI( "Layer" ) )->SetChoices( layersAll );
664
665 // Copper only properties
666 m_propMgr.GetProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Layer" ) )->SetChoices( layersCu );
667 m_propMgr.GetProperty( TYPE_HASH( PAD ), _HKI( "Bottom Backdrill Must-Cut" ) )->SetChoices( layersCu );
668 m_propMgr.GetProperty( TYPE_HASH( PAD ), _HKI( "Top Backdrill Must-Cut" ) )->SetChoices( layersCu );
669 m_propMgr.GetProperty( TYPE_HASH( PCB_VIA ), _HKI( "Layer Top" ) )->SetChoices( layersCu );
670 m_propMgr.GetProperty( TYPE_HASH( PCB_VIA ), _HKI( "Layer Bottom" ) )->SetChoices( layersCu );
671 m_propMgr.GetProperty( TYPE_HASH( PCB_VIA ), _HKI( "Bottom Backdrill Must-Cut" ) )->SetChoices( layersCu );
672 m_propMgr.GetProperty( TYPE_HASH( PCB_VIA ), _HKI( "Top Backdrill Must-Cut" ) )->SetChoices( layersCu );
673 m_propMgr.GetProperty( TYPE_HASH( PCB_TUNING_PATTERN ), _HKI( "Layer" ) )->SetChoices( layersCu );
674
675 // Regenerate nets
676
677 std::vector<std::pair<wxString, int>> netNames;
678 netNames.reserve( aBoard->GetNetInfo().NetsByNetcode().size() );
679
680 for( const auto& [ netCode, netInfo ] : aBoard->GetNetInfo().NetsByNetcode() )
681 netNames.emplace_back( UnescapeString( netInfo->GetNetname() ), netCode );
682
683 std::sort( netNames.begin(), netNames.end(),
684 []( const auto& a, const auto& b )
685 {
686 return a.first.CmpNoCase( b.first ) < 0;
687 } );
688
689 for( const auto& [ netName, netCode ] : netNames )
690 nets.Add( netName, netCode );
691
692 auto netProperty = m_propMgr.GetProperty( TYPE_HASH( BOARD_CONNECTED_ITEM ), _HKI( "Net" ) );
693 netProperty->SetChoices( nets );
694
695 auto tuningNet = m_propMgr.GetProperty( TYPE_HASH( PCB_TUNING_PATTERN ), _HKI( "Net" ) );
696 tuningNet->SetChoices( nets );
697}
698
699
700bool PCB_PROPERTIES_PANEL::getItemValue( EDA_ITEM* aItem, PROPERTY_BASE* aProperty, wxVariant& aValue )
701{
702 // For FOOTPRINT variant-aware boolean properties, return variant-specific values
703 if( aItem->Type() == PCB_FOOTPRINT_T )
704 {
705 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( aItem );
706 wxString variantName;
707
708 if( footprint->GetBoard() )
709 variantName = footprint->GetBoard()->GetCurrentVariant();
710
711 if( !variantName.IsEmpty() )
712 {
713 wxString propName = aProperty->Name();
714
715 if( propName == _HKI( "Do not Populate" ) )
716 {
717 aValue = wxVariant( footprint->GetDNPForVariant( variantName ) );
718 return true;
719 }
720 else if( propName == _HKI( "Exclude From Bill of Materials" ) )
721 {
722 aValue = wxVariant( footprint->GetExcludedFromBOMForVariant( variantName ) );
723 return true;
724 }
725 else if( propName == _HKI( "Exclude From Position Files" ) )
726 {
727 aValue = wxVariant( footprint->GetExcludedFromPosFilesForVariant( variantName ) );
728 return true;
729 }
730 }
731 }
732
733 return PROPERTIES_PANEL::getItemValue( aItem, aProperty, aValue );
734}
const char * name
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
BOARD_ITEM_CONTAINER * GetParent() const
Definition board_item.h:215
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
const NETINFO_LIST & GetNetInfo() const
Definition board.h:996
wxString GetCurrentVariant() const
Definition board.h:404
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:967
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
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:99
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:111
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:98
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:284
static const TOOL_EVENT SelectedEvent
Definition actions.h:345
Variant information for a footprint.
Definition footprint.h:146
void SetExcludedFromPosFiles(bool aExclude)
Definition footprint.h:166
void SetDNP(bool aDNP)
Definition footprint.h:160
void SetFieldValue(const wxString &aFieldName, const wxString &aValue)
Set a field value override for this variant.
Definition footprint.h:188
void SetExcludedFromBOM(bool aExclude)
Definition footprint.h:163
wxString GetLibDescription() const
Definition footprint.h:368
const FOOTPRINT_VARIANT * GetVariant(const wxString &aVariantName) const
Get a variant by name.
PCB_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this footprint.
wxString GetFPIDAsString() const
Definition footprint.h:357
wxString GetComponentClassAsString() const
Used for display in the properties panel.
wxString GetFieldValueForVariant(const wxString &aVariantName, const wxString &aFieldName) const
Get a field value for a specific variant.
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
bool GetDNPForVariant(const wxString &aVariantName) const
Get the DNP status for a specific variant.
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
bool GetExcludedFromPosFilesForVariant(const wxString &aVariantName) const
Get the exclude-from-position-files status for a specific variant.
FOOTPRINT_VARIANT * AddVariant(const wxString &aVariantName)
Add a new variant with the given name.
bool GetExcludedFromBOMForVariant(const wxString &aVariantName) const
Get the exclude-from-BOM status for a specific variant.
wxString GetKeywords() const
Definition footprint.h:371
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:38
bool Set(PROPERTY_BASE *aProperty, wxAny &aValue, bool aNotify=true)
bool IsBOARD_ITEM() const
Definition view_item.h:102
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
Definition lset.cpp:743
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition lset.cpp:599
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition lset.cpp:188
const NETCODES_MAP & NetsByNetcode() const
Return the netcode map, at least for python.
Definition netinfo.h:241
Definition pad.h:55
Common, abstract interface for edit frames.
The main frame for Pcbnew.
size_t OwnerHash() const override
Return type-id of the Owner class.
size_t TypeHash() const override
Return type-id of the property type.
void setter(void *obj, wxAny &v) override
size_t BaseHash() const override
Return type-id of the Base class.
PCB_FOOTPRINT_FIELD_PROPERTY(const wxString &aName)
bool Writeable(INSPECTABLE *aObject) const override
wxAny getter(const void *obj) const override
PCB_BASE_EDIT_FRAME * m_frame
PG_NET_SELECTOR_EDITOR * m_netSelectorEditorInstance
void valueChanged(wxPropertyGridEvent &aEvent) override
Regenerates caches storing layer and net names.
PG_UNIT_EDITOR * m_unitEditorInstance
PG_RATIO_EDITOR * m_ratioEditorInstance
wxPGProperty * createPGProperty(const PROPERTY_BASE *aProperty) const override
void rebuildProperties(const SELECTION &aSelection) override
Generates the property grid for a given selection of items.
PCB_PROPERTIES_PANEL(wxWindow *aParent, PCB_BASE_EDIT_FRAME *aFrame)
const SELECTION & getSelection(SELECTION &aFallbackSelection)
Get the current selection from the selection tool.
EDA_ITEM * getFrontItem()
Get the front item of the current selection.
static std::set< wxString > m_currentFieldNames
PROPERTY_BASE * getPropertyFromEvent(const wxPropertyGridEvent &aEvent) const
PROPERTY_MANAGER & m_propMgr
PG_URL_EDITOR * m_urlEditorInstance
PG_CHECKBOX_EDITOR * m_checkboxEditorInstance
void updateLists(const BOARD *aBoard)
void valueChanging(wxPropertyGridEvent &aEvent) override
bool getItemValue(EDA_ITEM *aItem, PROPERTY_BASE *aProperty, wxVariant &aValue) override
Utility to fetch a property value and convert to wxVariant Precondition: aItem is known to have prope...
PG_FPID_EDITOR * m_fpEditorInstance
The selection tool: currently supports:
PCB_SELECTION & GetSelection()
static const wxString EDITOR_NAME
Definition pg_editors.h:75
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
wxPGWindowList CreateControls(wxPropertyGrid *aGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
bool OnEvent(wxPropertyGrid *aGrid, wxPGProperty *aProperty, wxWindow *aWindow, wxEvent &aEvent) const override
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
PCB_BASE_EDIT_FRAME * m_frame
wxString GetName() const override
bool GetValueFromControl(wxVariant &aVariant, wxPGProperty *aProperty, wxWindow *aCtrl) const override
static const wxString EDITOR_NAME
void UpdateFrame(PCB_BASE_EDIT_FRAME *aFrame)
PG_NET_SELECTOR_EDITOR(PCB_BASE_EDIT_FRAME *aFrame)
static const wxString EDITOR_NAME
Definition pg_editors.h:117
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
PROPERTIES_PANEL(wxWindow *aParent, EDA_BASE_FRAME *aFrame)
virtual bool getItemValue(EDA_ITEM *aItem, PROPERTY_BASE *aProperty, wxVariant &aValue)
Utility to fetch a property value and convert to wxVariant Precondition: aItem is known to have prope...
virtual void rebuildProperties(const SELECTION &aSelection)
Generates the property grid for a given selection of items.
virtual size_t TypeHash() const =0
Return type-id of the property type.
PROPERTY_BASE(const wxString &aName, PROPERTY_DISPLAY aDisplay=PT_DEFAULT, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType=ORIGIN_TRANSFORMS::NOT_A_COORD)
< Used to generate unique IDs. Must come up front so it's initialized before ctor.
Definition property.h:201
virtual bool HasChoices() const
Return true if this PROPERTY has a limited set of possible values.
Definition property.h:246
virtual bool Writeable(INSPECTABLE *aObject) const
Definition property.h:282
friend class INSPECTABLE
Definition property.h:459
const wxString & Name() const
Definition property.h:220
virtual const wxPGChoices & Choices() const
Return a limited set of possible values (e.g.
Definition property.h:226
Provide class metadata.Helper macro to map type hashes to names.
virtual void Add(EDA_ITEM *aItem)
Definition selection.cpp:42
EDA_ITEM * Front() const
Definition selection.h:177
virtual void Clear() override
Remove all the stored items from the group.
Definition selection.h:98
bool Empty() const
Checks if there is anything selected.
Definition selection.h:115
#define _(s)
@ RECURSE
Definition eda_item.h:52
@ NO_RECURSE
Definition eda_item.h:53
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:43
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:754
#define _HKI(x)
Definition page_info.cpp:44
static const wxString MISSING_FIELD_SENTINEL
BOARD * GetBoard()
wxPGProperty * PGPropertyFactory(const PROPERTY_BASE *aProperty, EDA_DRAW_FRAME *aFrame)
Customized abstract wxPGProperty class to handle coordinate/size units.
see class PGM_BASE
APIIMPORT wxPGGlobalVarsClass * wxPGGlobalVars
#define TYPE_HASH(x)
Definition property.h:74
#define NO_SETTER(owner, type)
Definition property.h:828
std::optional< std::unique_ptr< VALIDATION_ERROR > > VALIDATOR_RESULT
Null optional means validation succeeded.
static const wxString MISSING_FIELD_SENTINEL
wxString UnescapeString(const wxString &aSource)
@ USER
The field ID hasn't been set yet; field is invalid.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
wxString GetCanonicalFieldName(FIELD_T aFieldType)
int delta
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
Definition typeinfo.h:91
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:95
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition typeinfo.h:86
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:87
Functions to provide common constants and other functions to assist in making a consistent UI.
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition ui_common.h:46
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695