200 lines
5.4 KiB
C++
200 lines
5.4 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <eda_draw_frame.h>
|
|
#include <kiway.h>
|
|
#include <kiface_ids.h>
|
|
#include <widgets/footprint_choice.h>
|
|
#include <widgets/footprint_select_widget.h>
|
|
#include <json_common.h>
|
|
#include <wx/wupdlock.h>
|
|
|
|
|
|
wxDEFINE_EVENT( EVT_FOOTPRINT_SELECTED, wxCommandEvent );
|
|
|
|
FOOTPRINT_SELECT_WIDGET::FOOTPRINT_SELECT_WIDGET( EDA_DRAW_FRAME* aFrame, wxWindow* aParent,
|
|
int aMaxItems ) :
|
|
wxPanel( aParent ),
|
|
m_max_items( aMaxItems ),
|
|
m_pin_count( 0 ),
|
|
m_zero_filter( true ),
|
|
m_kiway( nullptr )
|
|
{
|
|
m_sizer = new wxBoxSizer( wxVERTICAL );
|
|
m_fp_sel_ctrl = new FOOTPRINT_CHOICE( this, wxID_ANY );
|
|
m_sizer->Add( m_fp_sel_ctrl, 1, wxEXPAND, 5 );
|
|
|
|
SetSizer( m_sizer );
|
|
Layout();
|
|
m_sizer->Fit( this );
|
|
|
|
m_fp_sel_ctrl->Bind( wxEVT_COMBOBOX, &FOOTPRINT_SELECT_WIDGET::OnComboBox, this );
|
|
}
|
|
|
|
|
|
void FOOTPRINT_SELECT_WIDGET::Load( KIWAY& aKiway, PROJECT& aProject )
|
|
{
|
|
m_kiway = &aKiway;
|
|
}
|
|
|
|
|
|
void FOOTPRINT_SELECT_WIDGET::OnComboBox( wxCommandEvent& aEvent )
|
|
{
|
|
wxCommandEvent evt( EVT_FOOTPRINT_SELECTED );
|
|
int sel = m_fp_sel_ctrl->GetSelection();
|
|
|
|
if( sel == wxNOT_FOUND )
|
|
return;
|
|
|
|
wxStringClientData* clientdata =
|
|
static_cast<wxStringClientData*>( m_fp_sel_ctrl->GetClientObject( sel ) );
|
|
wxASSERT( clientdata );
|
|
|
|
evt.SetString( clientdata->GetData() );
|
|
wxPostEvent( this, evt );
|
|
}
|
|
|
|
|
|
void FOOTPRINT_SELECT_WIDGET::ClearFilters()
|
|
{
|
|
m_pin_count = 0;
|
|
m_filters.Clear();
|
|
m_default_footprint.Clear();
|
|
m_zero_filter = false;
|
|
}
|
|
|
|
|
|
void FOOTPRINT_SELECT_WIDGET::FilterByPinCount( int aPinCount )
|
|
{
|
|
m_pin_count = aPinCount;
|
|
}
|
|
|
|
|
|
void FOOTPRINT_SELECT_WIDGET::FilterByFootprintFilters( wxArrayString const& aFilters,
|
|
bool aZeroFilters )
|
|
{
|
|
m_zero_filter = ( aZeroFilters && aFilters.size() == 0 );
|
|
m_filters = aFilters;
|
|
}
|
|
|
|
|
|
void FOOTPRINT_SELECT_WIDGET::SetDefaultFootprint( wxString const& aFp )
|
|
{
|
|
m_default_footprint = aFp;
|
|
}
|
|
|
|
|
|
bool FOOTPRINT_SELECT_WIDGET::UpdateList()
|
|
{
|
|
if( !m_kiway )
|
|
return false;
|
|
|
|
wxWindowUpdateLocker lock( m_fp_sel_ctrl );
|
|
m_fp_sel_ctrl->Clear();
|
|
|
|
// Add the default footprint entry at the top
|
|
wxString defaultLabel = m_default_footprint.IsEmpty()
|
|
? _( "No default footprint" )
|
|
: wxS( "[" ) + _( "Default" ) + wxS( "] " ) + m_default_footprint;
|
|
|
|
m_fp_sel_ctrl->Append( defaultLabel, new wxStringClientData( m_default_footprint ) );
|
|
|
|
// If zero_filter is set and we have no filters, show no footprints
|
|
if( m_zero_filter && m_filters.IsEmpty() && m_pin_count == 0 )
|
|
{
|
|
SelectDefault();
|
|
return true;
|
|
}
|
|
|
|
// Build JSON request for pcbnew
|
|
using json = nlohmann::json;
|
|
json request;
|
|
request["pin_count"] = m_pin_count;
|
|
request["zero_filters"] = m_zero_filter;
|
|
request["max_results"] = m_max_items;
|
|
|
|
json filtersArray = json::array();
|
|
|
|
for( const wxString& filter : m_filters )
|
|
filtersArray.push_back( filter.ToStdString() );
|
|
|
|
request["filters"] = filtersArray;
|
|
|
|
// Get the filter function from pcbnew via KIWAY
|
|
try
|
|
{
|
|
KIFACE* kiface = m_kiway->KiFACE( KIWAY::FACE_PCB );
|
|
|
|
if( !kiface )
|
|
{
|
|
SelectDefault();
|
|
return true;
|
|
}
|
|
|
|
void* funcPtr = kiface->IfaceOrAddress( KIFACE_FILTER_FOOTPRINTS );
|
|
|
|
if( !funcPtr )
|
|
{
|
|
SelectDefault();
|
|
return true;
|
|
}
|
|
|
|
// Call the filter function
|
|
using FilterFunc = wxString ( * )( const wxString& );
|
|
FilterFunc filterFootprints = reinterpret_cast<FilterFunc>( funcPtr );
|
|
|
|
wxString requestStr = wxString::FromUTF8( request.dump() );
|
|
wxString responseStr = filterFootprints( requestStr );
|
|
|
|
// Parse the response
|
|
json response = json::parse( responseStr.ToStdString() );
|
|
|
|
if( response.is_array() )
|
|
{
|
|
for( const auto& item : response )
|
|
{
|
|
if( item.is_string() )
|
|
{
|
|
wxString fpName = wxString::FromUTF8( item.get<std::string>() );
|
|
m_fp_sel_ctrl->Append( fpName, new wxStringClientData( fpName ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch( const std::exception& e )
|
|
{
|
|
// JSON parsing or other error - just show default
|
|
}
|
|
|
|
SelectDefault();
|
|
return true;
|
|
}
|
|
|
|
|
|
void FOOTPRINT_SELECT_WIDGET::SelectDefault()
|
|
{
|
|
m_fp_sel_ctrl->SetSelection( 0 );
|
|
}
|
|
|
|
|
|
bool FOOTPRINT_SELECT_WIDGET::Enable( bool aEnable )
|
|
{
|
|
return m_fp_sel_ctrl->Enable( aEnable );
|
|
}
|