34#include <wx/settings.h>
35#include <wx/stattext.h>
36#include <wx/propgrid/advprops.h>
40#if !wxCHECK_VERSION( 3, 3, 0 )
50 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
55 wxPGInitResourceModule();
61 wxPGEditor_TextCtrl =
nullptr;
62 wxPGEditor_Choice =
nullptr;
63 wxPGEditor_ComboBox =
nullptr;
64 wxPGEditor_TextCtrlAndButton =
nullptr;
65 wxPGEditor_CheckBox =
nullptr;
66 wxPGEditor_ChoiceAndButton =
nullptr;
67 wxPGEditor_SpinCtrl =
nullptr;
68 wxPGEditor_DatePickerCtrl =
nullptr;
71 if( !
Pgm().m_PropertyGridInitialized )
78 m_caption =
new wxStaticText(
this, wxID_ANY,
_(
"No objects selected" ) );
79 mainSizer->Add(
m_caption, 0, wxALL | wxEXPAND, 5 );
81 m_grid =
new wxPropertyGrid(
this );
82 m_grid->SetUnspecifiedValueAppearance( wxPGCell( wxT(
"<...>" ) ) );
83 m_grid->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS );
85#if wxCHECK_VERSION( 3, 3, 0 )
86 m_grid->SetValidationFailureBehavior( wxPGVFBFlags::MarkCell );
88 m_grid->SetValidationFailureBehavior( wxPG_VFB_MARK_CELL );
91#if wxCHECK_VERSION( 3, 3, 0 )
92 m_grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_RETURN );
93 m_grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_NUMPAD_ENTER );
94 m_grid->AddActionTrigger( wxPGKeyboardAction::NextProperty, WXK_DOWN );
95 m_grid->AddActionTrigger( wxPGKeyboardAction::PrevProperty, WXK_UP );
96 m_grid->AddActionTrigger( wxPGKeyboardAction::Edit, WXK_SPACE );
98 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
99 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_NUMPAD_ENTER );
100 m_grid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_DOWN );
101 m_grid->AddActionTrigger( wxPG_ACTION_PREV_PROPERTY, WXK_UP );
102 m_grid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_SPACE );
105 m_grid->DedicateKey( WXK_RETURN );
106 m_grid->DedicateKey( WXK_NUMPAD_ENTER );
107 m_grid->DedicateKey( WXK_DOWN );
108 m_grid->DedicateKey( WXK_UP );
109 mainSizer->Add(
m_grid, 1, wxEXPAND, 5 );
111 m_grid->SetCellDisabledTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
115 m_grid->SetCaptionTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_CAPTIONTEXT ) );
120 SetSizer( mainSizer );
130 Bind( wxEVT_PG_COL_END_DRAG,
131 [&]( wxPropertyGridEvent& )
137 [&]( wxSizeEvent& aEvent )
158 if(
m_grid->IsEditorFocused() )
159 m_grid->CommitChangesFromEditor();
176 m_panel->m_SuppressGridChangeEvents++;
181 m_panel->m_SuppressGridChangeEvents--;
196 if(
m_grid->IsEditorFocused() )
197 m_grid->CommitChangesFromEditor();
203 if( aSelection.
Empty() )
205 m_caption->SetLabel(
_(
"No objects selected" ) );
209 else if( aSelection.
Size() == 1 )
215 m_caption->SetLabel( wxString::Format(
_(
"%d objects selected" ), aSelection.
Size() ) );
219 std::set<TYPE_ID> types;
224 wxCHECK( !types.empty(), );
227 std::map<wxString, PROPERTY_BASE*> commonProps;
228 const std::vector<PROPERTY_BASE*>& allProperties = propMgr.
GetProperties( *types.begin() );
231 commonProps.emplace( property->Name(), property );
233 std::map<wxString, int> displayOrder;
235 displayOrder.emplace( entry.first->Name(), entry.second );
238 std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
241 for(
auto itType = std::next( types.begin() ); itType != types.end(); ++itType )
247 if( !groups.count(
group ) )
249 groupDisplayOrder.emplace_back(
group );
250 groups.insert(
group );
254 for(
auto it = commonProps.begin(); it != commonProps.end(); )
257 it = commonProps.erase( it );
269 std::set<wxString> availableProps;
272 for(
auto& [
name, property] : commonProps )
274 if( property->IsHiddenFromPropertiesManager() )
277 if( isLibraryEditor && property->IsHiddenFromLibraryEditors() )
280 if( isDesignEditor && property->IsHiddenFromDesignEditors() )
288 availableProps.insert(
name );
291 bool writeable =
true;
292 std::set<wxString> existingProps;
294 for( wxPropertyGridIterator it =
m_grid->GetIterator(); !it.AtEnd(); it.Next() )
296 wxPGProperty* pgProp = it.GetProperty();
297 wxString
name = pgProp->GetName();
299 if( !availableProps.count(
name ) )
306 pgProp->SetValue( commonVal );
307 pgProp->Enable( writeable );
309 existingProps.insert(
name );
312 if( !existingProps.empty() && existingProps == availableProps )
318 std::map<wxPGProperty*, int> pgPropOrders;
319 std::map<wxString, std::vector<wxPGProperty*>> pgPropGroups;
321 for(
const wxString&
name : availableProps )
333 if( choices.GetCount() )
334 pgProp->SetChoices( choices );
336 pgProp->SetValue( commonVal );
337 pgProp->Enable( writeable );
340 wxASSERT( displayOrder.count(
name ) );
341 pgPropOrders[pgProp] = displayOrder[
name];
342 pgPropGroups[
property->Group()].emplace_back( pgProp );
346 const wxString unspecifiedGroupCaption =
_(
"Basic Properties" );
348 for(
const wxString& groupName : groupDisplayOrder )
350 if( !pgPropGroups.count( groupName ) )
353 std::vector<wxPGProperty*>& properties = pgPropGroups[groupName];
354 wxString groupCaption = wxGetTranslation( groupName );
356 auto groupItem =
new wxPropertyCategory( groupName.IsEmpty() ? unspecifiedGroupCaption
359 m_grid->Append( groupItem );
361 std::sort( properties.begin(), properties.end(),
362 [&]( wxPGProperty*& aFirst, wxPGProperty*& aSecond )
364 return pgPropOrders[aFirst] < pgPropOrders[aSecond];
367 for( wxPGProperty* property : properties )
368 m_grid->Append( property );
377 const wxAny&
any = aItem->
Get( aProperty );
378 bool converted =
false;
384 converted =
any.GetAs<
int>( &tmp );
387 aValue = wxVariant( tmp );
391 converted =
any.GetAs( &aValue );
395 wxString propName = aProperty->
Name();
396 propName.Replace(
' ',
'_' );
397 wxFAIL_MSG( wxString::Format( wxS(
"Could not convert wxAny to wxVariant for %s::%s" ),
407 wxVariant& aValue,
bool& aWritable, wxPGChoices& aChoices )
410 bool different =
false;
425 if( property->IsHiddenFromPropertiesManager() )
428 wxPGChoices choices =
property->
GetChoices( item );
437 wxArrayString labels = choices.GetLabels();
438 wxArrayInt values = choices.GetValuesForStrings( labels );
440 if( labels != aChoices.GetLabels() || values != aChoices.GetValuesForStrings( labels ) )
453 if( !different && !aValue.IsNull() && value != aValue )
458 else if( !different )
476 if( aEvent.IsShown() )
486 if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() )
490 if( wxPGProperty* prop =
m_grid->GetSelectedProperty() )
491 oldValue = prop->GetValue();
493 m_grid->CommitChangesFromEditor();
496 if( wxPGProperty* prop =
m_grid->GetSelectedProperty() )
498 if( prop->GetValue() == oldValue )
505 if( aEvent.GetKeyCode() == WXK_SPACE )
507 if( wxPGProperty* prop =
m_grid->GetSelectedProperty() )
509 if( prop->GetValueType() == wxT(
"bool" ) )
511 m_grid->SetPropertyValue( prop, !prop->GetValue().GetBool() );
517 if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER
518 || aEvent.GetKeyCode() == WXK_DOWN || aEvent.GetKeyCode() == WXK_UP )
520 m_grid->CommitChangesFromEditor();
524 m_grid->SelectProperty(
m_grid->GetSelectedProperty(),
true );
The base frame for deriving all KiCad main window classes.
A base class for most all the KiCad significant classes used in schematics and boards.
virtual wxString GetFriendlyName() const
wxAny Get(PROPERTY_BASE *aProperty) const
virtual wxString GetClass() const =0
Return the class name.
bool m_PropertyGridInitialized
Enhanced renderer to work around some limitations in wxWidgets 3.0 capabilities.
virtual ~PROPERTIES_PANEL()
float m_splitter_key_proportion
Proportion of the grid column splitter that is used for the key column (0.0 - 1.0)
PROPERTIES_PANEL(wxWindow *aParent, EDA_BASE_FRAME *aFrame)
virtual void valueChanging(wxPropertyGridEvent &aEvent)
void RecalculateSplitterPos()
void SetSplitterProportion(float aProportion)
std::vector< PROPERTY_BASE * > m_displayed
int m_SuppressGridChangeEvents
virtual void OnLanguageChanged(wxCommandEvent &aEvent)
virtual void UpdateData()=0
virtual void valueChanged(wxPropertyGridEvent &aEvent)
bool extractValueAndWritability(const SELECTION &aSelection, const wxString &aPropName, wxVariant &aValue, bool &aWritable, wxPGChoices &aChoices)
Processes a selection and determines whether the given property should be available or not and what t...
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.
void onCharHook(wxKeyEvent &aEvent)
virtual wxPGProperty * createPGProperty(const PROPERTY_BASE *aProperty) const =0
void onShow(wxShowEvent &aEvent)
virtual bool HasChoices() const
Return true if this PROPERTY has a limited set of possible values.
wxPGChoices GetChoices(INSPECTABLE *aObject) const
const wxString & Name() const
Provide class metadata.Helper macro to map type hashes to names.
const std::vector< PROPERTY_BASE * > & GetProperties(TYPE_ID aType) const
Return all properties for a specific type.
bool IsWriteableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
bool IsAvailableFor(TYPE_ID aItemClass, PROPERTY_BASE *aProp, INSPECTABLE *aItem)
Checks overriden availability and original availability of a property, returns false if the property ...
const std::map< PROPERTY_BASE *, int > & GetDisplayOrder(TYPE_ID aType) const
const std::vector< wxString > & GetGroupDisplayOrder(TYPE_ID aType) const
int Size() const
Returns the number of selected parts.
bool Empty() const
Checks if there is anything selected.
SUPPRESS_GRID_CHANGED_EVENTS(PROPERTIES_PANEL *aPanel)
~SUPPRESS_GRID_CHANGED_EVENTS()
PROPERTIES_PANEL * m_panel
A type-safe container of any type.
Base window classes and related definitions.
@ FRAME_SCH_SYMBOL_EDITOR
KICOMMON_API wxFont GetDockedPaneFont(wxWindow *aWindow)
PGM_BASE & Pgm()
The global program "get" accessor.
APIIMPORT wxPGGlobalVarsClass * wxPGGlobalVars
size_t TYPE_ID
Unique type identifier.
std::vector< FAB_LAYER_COLOR > dummy