SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibTree( const SCHLIB_FILTER* aFilter, std::vector<COMPONENT_SELECTION>& aHistoryList, bool aAllowBrowser, int aUnit, int aConvert, bool aShowFootprints, const LIB_ID* aHighlight, bool aAllowFields ) { std::unique_lock<std::mutex> dialogLock( DIALOG_CHOOSE_COMPONENT::g_Mutex, std::defer_lock ); wxString dialogTitle; SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable(); // One CHOOSE_COMPONENT dialog at a time. User probaby can't handle more anyway. if( !dialogLock.try_lock() ) return COMPONENT_SELECTION(); auto adapterPtr( SYMBOL_TREE_MODEL_ADAPTER::Create( libs ) ); auto adapter = static_cast<SYMBOL_TREE_MODEL_ADAPTER*>( adapterPtr.get() ); bool loaded = false; if( aFilter ) { const wxArrayString& liblist = aFilter->GetAllowedLibList(); for( unsigned ii = 0; ii < liblist.GetCount(); ii++ ) { if( libs->HasLibrary( liblist[ii], true ) ) { loaded = true; adapter->AddLibrary( liblist[ii] ); } } adapter->AssignIntrinsicRanks(); if( aFilter->GetFilterPowerParts() ) adapter->SetFilter( SYMBOL_TREE_MODEL_ADAPTER::CMP_FILTER_POWER ); } std::vector< LIB_TREE_ITEM* > history_list; for( auto const& i : aHistoryList ) { LIB_ALIAS* alias = GetLibAlias( i.LibId ); if( alias ) history_list.push_back( alias ); } adapter->DoAddLibrary( "-- " + _( "Recently Used" ) + " --", wxEmptyString, history_list, true ); if( !aHistoryList.empty() ) adapter->SetPreselectNode( aHistoryList[0].LibId, aHistoryList[0].Unit ); const std::vector< wxString > libNicknames = libs->GetLogicalLibs(); if( !loaded ) adapter->AddLibraries( libNicknames, this ); if( aHighlight && aHighlight->IsValid() ) adapter->SetPreselectNode( *aHighlight, /* aUnit */ 0 ); if( adapter->GetFilter() == SYMBOL_TREE_MODEL_ADAPTER::CMP_FILTER_POWER ) dialogTitle.Printf( _( "Choose Power Symbol (%d items loaded)" ), adapter->GetItemCount() ); else dialogTitle.Printf( _( "Choose Symbol (%d items loaded)" ), adapter->GetItemCount() ); DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, adapterPtr, aConvert, aAllowFields, aShowFootprints, aAllowBrowser ); if( dlg.ShowQuasiModal() == wxID_CANCEL ) return COMPONENT_SELECTION(); COMPONENT_SELECTION sel; LIB_ID id = dlg.GetSelectedLibId( &sel.Unit ); if( dlg.IsExternalBrowserSelected() ) // User requested component browser. { sel = SelectComponentFromLibBrowser( this, aFilter, id, sel.Unit, sel.Convert ); id = sel.LibId; } if( !id.IsValid() ) // Dialog closed by OK button, // or the selection by lib browser was requested, // but no symbol selected return COMPONENT_SELECTION(); if( sel.Unit == 0 ) sel.Unit = 1; sel.Fields = dlg.GetFields(); sel.LibId = id; if( sel.LibId.IsValid() ) { aHistoryList.erase( std::remove_if( aHistoryList.begin(), aHistoryList.end(), [ &sel ]( COMPONENT_SELECTION const& i ){ return i.LibId == sel.LibId; } ), aHistoryList.end() ); aHistoryList.insert( aHistoryList.begin(), sel ); } return sel; }
SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC* aDC, const SCHLIB_FILTER* aFilter, SCH_BASE_FRAME::HISTORY_LIST& aHistoryList, bool aUseLibBrowser ) { wxString msg; SetRepeatItem( NULL ); m_canvas->SetIgnoreMouseEvents( true ); auto sel = SelectComponentFromLibrary( aFilter, aHistoryList, aUseLibBrowser, 1, 1, m_footprintPreview ); if( !sel.LibId.IsValid() ) { m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); return NULL; } m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); wxString libsource; // the library name to use. If empty, load from any lib if( aFilter ) libsource = aFilter->GetLibSource(); LIB_ID libId = sel.LibId; LIB_PART* part = GetLibPart( libId, true ); if( !part ) return NULL; SCH_COMPONENT* component = new SCH_COMPONENT( *part, m_CurrentSheet, sel.Unit, sel.Convert, GetCrossHairPosition(), true ); // Set the m_ChipName value, from component name in lib, for aliases // Note if part is found, and if name is an alias of a component, // alias exists because its root component was found component->SetLibId( libId ); // Be sure the link to the corresponding LIB_PART is OK: component->Resolve( *Prj().SchSymbolLibTable() ); // Set any fields that have been modified for( auto const& i : sel.Fields ) { auto field = component->GetField( i.first ); if( field ) field->SetText( i.second ); } // Set the component value that can differ from component name in lib, for aliases component->GetField( VALUE )->SetText( sel.LibId.GetLibItemName() ); // If there is no field defined in the component, copy one over from the library // ( from the .dcm file ) // This way the Datasheet field will not be empty and can be changed from the schematic if( component->GetField( DATASHEET )->GetText().IsEmpty() ) { LIB_ALIAS* entry = GetLibAlias( component->GetLibId(), true, true ); if( entry && !!entry->GetDocFileName() ) component->GetField( DATASHEET )->SetText( entry->GetDocFileName() ); } MSG_PANEL_ITEMS items; component->SetCurrentSheetPath( &GetCurrentSheet() ); component->GetMsgPanelInfo( items ); SetMsgPanel( items ); component->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode ); component->SetFlags( IS_NEW ); if( m_autoplaceFields ) component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); PrepareMoveItem( (SCH_ITEM*) component, aDC ); return component; }