/* * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2020 CERN * @author Maciej Suminski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "properties_panel.h" #include #include #include #include #include #include #include #include extern APIIMPORT wxPGGlobalVarsClass* wxPGGlobalVars; PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame ) : wxPanel( aParent ), m_frame( aFrame ) { wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL ); // on some platforms wxPGGlobalVars is initialized automatically, // but others need an explicit init if( !wxPGGlobalVars ) wxPGInitResourceModule(); m_caption = new wxStaticText( this, wxID_ANY, _( "No objects selected" ), wxDefaultPosition, wxDefaultSize, 0 ); mainSizer->Add( m_caption, 0, wxALL | wxEXPAND, 5 ); m_grid = new wxPropertyGrid( this, wxID_ANY, wxDefaultPosition, wxSize( 300, 400 ), wxPG_AUTO_SORT | wxPG_DEFAULT_STYLE ); m_grid->SetUnspecifiedValueAppearance( wxPGCell( wxT( "<...>" ) ) ); mainSizer->Add( m_grid, 1, wxALL | wxEXPAND, 5 ); m_grid->SetCellDisabledTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); SetSizer( mainSizer ); Layout(); m_grid->CenterSplitter(); Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ), NULL, this ); Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ), NULL, this ); Connect( wxEVT_SHOW, wxShowEventHandler( PROPERTIES_PANEL::onShow ), NULL, this ); } void PROPERTIES_PANEL::update( const SELECTION& aSelection ) { m_grid->Clear(); m_displayed.clear(); if( aSelection.Empty() ) { m_caption->SetLabel( _( "No objects selected" ) ); return; } // Get all the selected types std::set types; for( EDA_ITEM* item : aSelection ) types.insert( TYPE_HASH( *item ) ); wxCHECK( !types.empty(), /* void */ ); if( aSelection.Size() > 1 ) { m_caption->SetLabel( _( "Multiple objects selected" ) ); } else { m_caption->SetLabel( aSelection.Front()->GetTypeDesc() ); } PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance(); propMgr.SetUnits( m_frame->GetUserUnits() ); std::set commonProps; const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() ); copy( allProperties.begin(), allProperties.end(), inserter( commonProps, commonProps.begin() ) ); // Get all possible properties for( const auto& type : types ) { const PROPERTY_LIST& itemProps = propMgr.GetProperties( type ); for( auto it = commonProps.begin(); it != commonProps.end(); /* ++it in the loop */ ) { if( !binary_search( itemProps.begin(), itemProps.end(), *it ) ) it = commonProps.erase( it ); else ++it; } } // Find a set of properties that is common to all selected items for( const auto& property : commonProps ) { if( !property->Available( aSelection.Front() ) ) continue; // Either determine the common value for a property or "<...>" to indicate multiple values bool available = true; wxVariant commonVal, itemVal; for( EDA_ITEM* item : aSelection ) { if( !property->Available( item ) ) break; // there is an item that does not have this property, so do not display it wxVariant& value = commonVal.IsNull() ? commonVal : itemVal; const wxAny& any = item->Get( property ); bool converted = false; if( property->HasChoices() ) { // handle enums as ints, since there are no default conversion functions for wxAny int tmp; converted = any.GetAs( &tmp ); if( converted ) value = wxVariant( tmp ); } if( !converted ) // all other types converted = any.GetAs( &value ); if( !converted ) { wxFAIL_MSG( "Could not convert wxAny to wxVariant" ); available = false; break; } if( !commonVal.IsNull() && value != commonVal ) { commonVal.MakeNull(); // items have different values for this property break; } } if( available ) { wxPGProperty* pgProp = createPGProperty( property ); if( pgProp ) { pgProp->SetValue( commonVal ); m_grid->Append( pgProp ); m_displayed.push_back( property ); } } } m_grid->FitColumns(); } void PROPERTIES_PANEL::onShow( wxShowEvent& aEvent ) { if( aEvent.IsShown() ) UpdateData(); }