const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRowByURI( const wxString& aURI ) { FP_LIB_TABLE* cur = this; do { cur->ensureIndex(); for( unsigned i = 0; i < cur->rows.size(); i++ ) { wxString uri = cur->rows[i].GetFullURI( true ); if( wxFileName::GetPathSeparator() == wxChar( '\\' ) && uri.Find( wxChar( '/' ) ) >= 0 ) uri.Replace( wxT( "/" ), wxT( "\\" ) ); if( (wxFileName::IsCaseSensitive() && uri == aURI) || (!wxFileName::IsCaseSensitive() && uri.Upper() == aURI.Upper() ) ) { return &cur->rows[i]; // found } } // not found, search fall back table(s), if any } while( ( cur = cur->fallBack ) != 0 ); return 0; // not found }
bool CVPCB_MAINFRAME::LoadFootprintFiles() { FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); // Check if there are footprint libraries in the footprint library table. if( !fptbl || !fptbl->GetLogicalLibs().size() ) { wxMessageBox( _( "No PCB footprint libraries are listed in the current footprint " "library table." ), _( "Configuration Error" ), wxOK | wxICON_ERROR ); return false; } { wxBusyCursor dummy; // Let the user know something is happening. m_FootprintsList.ReadFootprintFiles( fptbl ); } if( m_FootprintsList.GetErrorCount() ) { m_FootprintsList.DisplayErrors( this ); } return true; }
wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting ) { wxArrayString headers; headers.Add( _( "Nickname" ) ); headers.Add( _( "Description" ) ); FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); std::vector< wxArrayString > itemsToDisplay; std::vector< wxString > nicknames = fptbl->GetLogicalLibs(); for( unsigned i = 0; i < nicknames.size(); i++ ) { wxArrayString item; item.Add( nicknames[i] ); item.Add( fptbl->GetDescription( nicknames[i] ) ); itemsToDisplay.push_back( item ); } EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, aNicknameExisting ); if( dlg.ShowModal() != wxID_OK ) return wxEmptyString; wxString nickname = dlg.GetTextSelection(); wxLogDebug( wxT( "Chose footprint library '%s'." ), GetChars( nickname ) ); return nickname; }
FP_LIB_TABLE* PROJECT::PcbFootprintLibs() { // This is a lazy loading function, it loads the project specific table when // that table is asked for, not before. FP_LIB_TABLE* tbl = (FP_LIB_TABLE*) GetElem( ELEM_FPTBL ); // its gotta be NULL or a FP_LIB_TABLE, or a bug. wxASSERT( !tbl || dynamic_cast<FP_LIB_TABLE*>( tbl ) ); if( !tbl ) { // Stack the project specific FP_LIB_TABLE overlay on top of the global table. // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may // stack this way, all using the same global fallback table. tbl = new FP_LIB_TABLE( &GFootprintTable ); SetElem( ELEM_FPTBL, tbl ); wxString projectFpLibTableFileName = FootprintLibTblName(); try { tbl->Load( projectFpLibTableFileName ); } catch( const IO_ERROR& ioe ) { DisplayError( NULL, ioe.errorText ); } } return tbl; }
bool FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR ) { bool tableExists = true; wxFileName fn = GetGlobalTableFileName(); if( !fn.FileExists() ) { tableExists = false; if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) ) { THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ), GetChars( fn.GetPath() ) ) ); } // Attempt to copy the default global file table from the KiCad // template folder to the user's home configuration path. wxString fileName = Kiface().KifaceSearch().FindValidPath( global_tbl_name ); // The fallback is to create an empty global footprint table for the user to populate. if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) ) { FP_LIB_TABLE emptyTable; emptyTable.Save( fn.GetFullPath() ); } } aTable.Load( fn.GetFullPath() ); return tableExists; }
void CVPCB_MAINFRAME::BuildLIBRARY_LISTBOX() { wxFont guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); if( m_libListBox == NULL ) { m_libListBox = new LIBRARY_LISTBOX( this, ID_CVPCB_LIBRARY_LIST, wxDefaultPosition, wxDefaultSize ); m_libListBox->SetFont( wxFont( guiFont.GetPointSize(), wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL ) ); } FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); if( tbl ) { wxArrayString libNames; std::vector< wxString > libNickNames = tbl->GetLogicalLibs(); for( unsigned ii = 0; ii < libNickNames.size(); ii++ ) libNames.Add( libNickNames[ii] ); m_libListBox->SetLibraryList( libNames ); } }
bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule ) { wxString libraryName = aModule->GetFPID().GetLibNickname(); wxString footprintName = aModule->GetFPID().GetLibItemName(); bool nameChanged = m_footprintNameWhenLoaded != footprintName; if( aModule->GetLink() ) { if( SaveFootprintToBoard( false ) ) { m_footprintNameWhenLoaded = footprintName; return true; } else return false; } else if( libraryName.IsEmpty() || footprintName.IsEmpty() ) { if( SaveFootprintAs( aModule ) ) { m_footprintNameWhenLoaded = footprintName; SyncLibraryTree( true ); return true; } else return false; } FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); // Legacy libraries are readable, but modifying legacy format is not allowed // So prompt the user if he try to add/replace a footprint in a legacy lib wxString libfullname = tbl->FindRow( libraryName )->GetFullURI(); if( IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == IO_MGR::LEGACY ) { DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT ); return false; } if( nameChanged ) { LIB_ID oldFPID( libraryName, m_footprintNameWhenLoaded ); DeleteModuleFromLibrary( oldFPID, false ); } if( !saveFootprintInLibrary( aModule, libraryName ) ) return false; if( nameChanged ) { m_footprintNameWhenLoaded = footprintName; SyncLibraryTree( true ); } return true; }
MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId ) throw( IO_ERROR, PARSE_ERROR ) { FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) ); return fptbl->FootprintLoadWithOptionalNickname( aFootprintId ); }
void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller ) { FP_LIB_TABLE* globalTable = &GFootprintTable; wxString globalTablePath = FP_LIB_TABLE::GetGlobalTableFileName(); FP_LIB_TABLE* projectTable = aKiway->Prj().PcbFootprintLibs(); wxString projectTablePath = aKiway->Prj().FootprintLibTblName(); wxString msg; DIALOG_EDIT_LIBRARY_TABLES dlg( aCaller, _( "Footprint Libraries" ) ); dlg.SetKiway( &dlg, aKiway ); dlg.InstallPanel( new PANEL_FP_LIB_TABLE( &dlg, globalTable, globalTablePath, projectTable, projectTablePath, aKiway->Prj().GetProjectPath() ) ); if( dlg.ShowModal() == wxID_CANCEL ) return; if( dlg.m_GlobalTableChanged ) { try { globalTable->Save( globalTablePath ); } catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error saving global library table:\n\n%s" ), ioe.What() ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); } } if( dlg.m_ProjectTableChanged ) { try { projectTable->Save( projectTablePath ); } catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); } } auto editor = (FOOTPRINT_EDIT_FRAME*) aKiway->Player( FRAME_PCB_MODULE_EDITOR, false ); if( editor ) editor->SyncLibraryTree( true ); auto viewer = (FOOTPRINT_VIEWER_FRAME*) aKiway->Player( FRAME_PCB_MODULE_VIEWER, false ); if( viewer ) viewer->ReCreateLibraryList(); }
MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId ) throw( IO_ERROR, PARSE_ERROR, boost::interprocess::lock_exception ) { FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) ); MODULE* module = fptbl->FootprintLoadWithOptionalNickname( aFootprintId ); // If the module is found, clear all net info, // to be sure there is no broken links // to any netinfo list (should be not needed, but it can be edited from // the footprint editor ) if( module ) module->ClearAllNets(); return module; }
FP_LIB_TABLE::ROW* FP_LIB_TABLE::findRow( const wxString& aNickName ) const { FP_LIB_TABLE* cur = (FP_LIB_TABLE*) this; do { cur->ensureIndex(); INDEX_CITER it = cur->nickIndex.find( aNickName ); if( it != cur->nickIndex.end() ) { return &cur->rows[it->second]; // found } // not found, search fall back table(s), if any } while( ( cur = cur->fallBack ) != 0 ); return 0; // not found }
bool CVPCB_MAINFRAME::LoadFootprintFiles() { FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); // Check if there are footprint libraries in the footprint library table. if( !fptbl || !fptbl->GetLogicalLibs().size() ) { wxMessageBox( _( "No PCB footprint libraries are listed in the current footprint " "library table." ), _( "Configuration Error" ), wxOK | wxICON_ERROR ); return false; } m_footprints.ReadFootprintFiles( fptbl ); if( m_footprints.GetErrorCount() ) { m_footprints.DisplayErrors( this ); } return true; }
void FOOTPRINT_VIEWER_FRAME::UpdateTitle() { wxString title; wxString path; title.Printf( _( "Footprint Library Browser" ) + L" \u2014 %s", getCurNickname().size() ? getCurNickname() : _( "no library selected" ) ); // Now, add the full path, for info if( getCurNickname().size() ) { FP_LIB_TABLE* libtable = Prj().PcbFootprintLibs(); const LIB_TABLE_ROW* row = libtable->FindRow( getCurNickname() ); if( row ) title << L" \u2014 " << row->GetFullURI( true ); } SetTitle( title ); }
FP_LIB_TABLE* PROJECT::PcbFootprintLibs( KIWAY& aKiway ) { // This is a lazy loading function, it loads the project specific table when // that table is asked for, not before. FP_LIB_TABLE* tbl = (FP_LIB_TABLE*) GetElem( ELEM_FPTBL ); // its gotta be NULL or a FP_LIB_TABLE, or a bug. wxASSERT( !tbl || dynamic_cast<FP_LIB_TABLE*>( tbl ) ); if( !tbl ) { // Build a new project specific FP_LIB_TABLE with the global table as a fallback. // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may // stack this way, all using the same global fallback table. KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_PCB ); if( kiface ) tbl = (FP_LIB_TABLE*) kiface->IfaceOrAddress( KIFACE_NEW_FOOTPRINT_TABLE ); wxASSERT( tbl ); SetElem( ELEM_FPTBL, tbl ); wxString projectFpLibTableFileName = FootprintLibTblName(); try { tbl->Load( projectFpLibTableFileName ); } catch( const IO_ERROR& ioe ) { DisplayErrorMessage( NULL, _( "Error loading project footprint library table" ), ioe.What() ); } } return tbl; }
void FOOTPRINT_INFO_IMPL::load() { FP_LIB_TABLE* fptable = m_owner->GetTable(); wxASSERT( fptable ); const MODULE* footprint = fptable->GetEnumeratedFootprint( m_nickname, m_fpname ); if( footprint == NULL ) // Should happen only with malformed/broken libraries { m_pad_count = 0; m_unique_pad_count = 0; } else { m_pad_count = footprint->GetPadCount( DO_NOT_INCLUDE_NPTH ); m_unique_pad_count = footprint->GetUniquePadCount( DO_NOT_INCLUDE_NPTH ); m_keywords = footprint->GetKeywords(); m_doc = footprint->GetDescription(); } m_loaded = true; }
void FOOTPRINT_INFO::load() { FP_LIB_TABLE* fptable = m_owner->GetTable(); wxASSERT( fptable ); std::auto_ptr<MODULE> m( fptable->FootprintLoad( m_nickname, m_fpname ) ); if( m.get() == NULL ) // Should happen only with malformed/broken libraries { m_pad_count = 0; m_unique_pad_count = 0; } else { m_pad_count = m->GetPadCount( DO_NOT_INCLUDE_NPTH ); m_unique_pad_count = m->GetUniquePadCount( DO_NOT_INCLUDE_NPTH ); m_keywords = m->GetKeywords(); m_doc = m->GetDescription(); // tell ensure_loaded() I'm loaded. m_loaded = true; } }
bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( const wxString& aLibrary, MODULE* aModule, bool aOverwrite, bool aDisplayDialog ) { if( aModule == NULL ) return false; SetMsgPanel( aModule ); // Legacy libraries are readable, but modifying legacy format is not allowed // So prompt the user if he try to add/replace a footprint in a legacy lib wxString libfullname = Prj().PcbFootprintLibs()->FindRow( aLibrary )->GetFullURI(); IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname ); if( piType == IO_MGR::LEGACY ) { DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT ); return false; } // Ask what to use as the footprint name in the library wxString footprintName = aModule->GetFPID().GetFootprintName(); if( aDisplayDialog ) { wxTextEntryDialog dlg( this, _( "Name:" ), FMT_SAVE_MODULE, footprintName ); if( dlg.ShowModal() != wxID_OK ) return false; // canceled by user footprintName = dlg.GetValue(); footprintName.Trim( true ); footprintName.Trim( false ); if( footprintName.IsEmpty() ) return false; if( ! MODULE::IsLibNameValid( footprintName ) ) { wxString msg = wxString::Format( _("Error:\none of invalid chars '%s' found\nin '%s'" ), MODULE::StringLibNameInvalidChars( true ), GetChars( footprintName ) ); DisplayError( NULL, msg ); return false; } aModule->SetFPID( FPID( footprintName ) ); } // Ensure this footprint has a libname if( footprintName.IsEmpty() ) { footprintName = wxT("noname"); aModule->SetFPID( FPID( footprintName ) ); } bool module_exists = false; try { FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); MODULE* m = tbl->FootprintLoad( aLibrary, footprintName ); if( m ) { delete m; module_exists = true; // an existing footprint is found in current lib if( aDisplayDialog ) { wxString msg = wxString::Format( FMT_MOD_EXISTS, footprintName.GetData(), aLibrary.GetData() ); SetStatusText( msg ); } if( !aOverwrite ) { // Do not save the given footprint: an old one exists return true; } } // this always overwrites any existing footprint, but should yell on its // own if the library or footprint is not writable. tbl->FootprintSave( aLibrary, aModule ); } catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); return false; } if( aDisplayDialog ) { wxString fmt = module_exists ? _( "Component [%s] replaced in '%s'" ) : _( "Component [%s] added in '%s'" ); wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibrary.GetData() ); SetStatusText( msg ); } return true; }
void FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent ) { FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs(); aEvent.Enable( fptbl && !fptbl->IsEmpty() ); }
bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) { switch( (IO_MGR::PCB_FILE_T) aFileType ) { case IO_MGR::EAGLE: if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_EAGLE_BRD ) ) { wxString projectpath = Kiway().Prj().GetProjectPath(); wxFileName newfilename; newfilename.SetPath( Prj().GetProjectPath() ); newfilename.SetName( Prj().GetProjectName() ); newfilename.SetExt( KiCadPcbFileExtension ); GetBoard()->SetFileName( newfilename.GetFullPath() ); UpdateTitle(); OnModify(); // Extract a footprint library from the design and add it to the fp-lib-table wxString newLibPath; ArchiveModulesOnBoard( true, newfilename.GetName(), &newLibPath ); if( newLibPath.Length() > 0 ) { FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs(); const wxString& project_env = PROJECT_VAR_NAME; wxString rel_path, env_path; wxGetEnv( project_env, &env_path ); wxString result( newLibPath ); rel_path = result.Replace( env_path, wxString( "$(" + project_env + ")" ) ) ? result : "" ; if( !rel_path.IsEmpty() ) newLibPath = rel_path; FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(), newLibPath, wxT( "KiCad" ), wxEmptyString ); prjlibtable->InsertRow( row ); } if( !GetBoard()->GetFileName().IsEmpty() ) { wxString tblName = Prj().FootprintLibTblName(); try { Prj().PcbFootprintLibs()->Save( tblName ); } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error occurred saving project specific footprint library " "table:\n\n%s" ), GetChars( ioe.What() ) ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); } } // Update module LIB_IDs to point to the just imported Eagle library for( MODULE* module : GetBoard()->Modules() ) { LIB_ID libId = module->GetFPID(); if( libId.GetLibItemName().empty() ) continue; libId.SetLibNickname( newfilename.GetName() ); module->SetFPID( libId ); } // Store net names for all pads, to create net remap information std::unordered_map<D_PAD*, wxString> netMap; for( const auto& pad : GetBoard()->GetPads() ) { NETINFO_ITEM* netinfo = pad->GetNet(); if( netinfo->GetNet() > 0 && !netinfo->GetNetname().IsEmpty() ) netMap[pad] = netinfo->GetNetname(); } // Two stage netlist update: // - first, assign valid timestamps to footprints (no reannotation) // - second, perform schematic annotation and update footprint references // based on timestamps NETLIST netlist; FetchNetlistFromSchematic( netlist, NO_ANNOTATION ); DoUpdatePCBFromNetlist( netlist, false ); FetchNetlistFromSchematic( netlist, QUIET_ANNOTATION ); DoUpdatePCBFromNetlist( netlist, true ); std::unordered_map<wxString, wxString> netRemap; // Compare the old net names with the new net names and create a net map for( const auto& pad : GetBoard()->GetPads() ) { auto it = netMap.find( pad ); if( it == netMap.end() ) continue; NETINFO_ITEM* netinfo = pad->GetNet(); // Net name has changed, create a remap entry if( netinfo->GetNet() > 0 && netMap[pad] != netinfo->GetNetname() ) netRemap[netMap[pad]] = netinfo->GetNetname(); } if( !netRemap.empty() ) fixEagleNets( netRemap ); return true; } return false; default: return false; } return false; }
bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( MODULE* aModule ) { if( aModule == NULL ) return false; FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs(); SetMsgPanel( aModule ); wxString libraryName = aModule->GetFPID().GetLibNickname(); wxString footprintName = aModule->GetFPID().GetLibItemName(); bool updateValue = ( aModule->GetValue() == footprintName ); wxArrayString headers; std::vector<wxArrayString> itemsToDisplay; std::vector<wxString> nicknames = tbl->GetLogicalLibs(); headers.Add( _( "Nickname" ) ); headers.Add( _( "Description" ) ); for( unsigned i = 0; i < nicknames.size(); i++ ) { wxArrayString item; item.Add( nicknames[i] ); item.Add( tbl->GetDescription( nicknames[i] ) ); itemsToDisplay.push_back( item ); } EDA_LIST_DIALOG dlg( this, FMT_SAVE_MODULE, headers, itemsToDisplay, libraryName, nullptr, nullptr, /* sort */ false, /* show headers */ false ); dlg.SetListLabel( _( "Save in library:" ) ); dlg.SetOKLabel( _( "Save" ) ); wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL ); wxStaticText* label = new wxStaticText( &dlg, wxID_ANY, _( "Name:" ), wxDefaultPosition, wxDefaultSize, 0 ); bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); wxTextCtrl* nameTextCtrl = new wxTextCtrl( &dlg, wxID_ANY, footprintName, wxDefaultPosition, wxDefaultSize, 0 ); bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST ); nameValidator.SetCharExcludes( MODULE::StringLibNameInvalidChars( false ) ); nameTextCtrl->SetValidator( nameValidator ); wxSizer* mainSizer = dlg.GetSizer(); mainSizer->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 ); // Move nameTextCtrl to the head of the tab-order if( dlg.GetChildren().DeleteObject( nameTextCtrl ) ) dlg.GetChildren().Insert( nameTextCtrl ); dlg.SetInitialFocus( nameTextCtrl ); dlg.Layout(); mainSizer->Fit( &dlg ); if( dlg.ShowModal() != wxID_OK ) return false; // canceled by user libraryName = dlg.GetTextSelection(); if( libraryName.IsEmpty() ) { DisplayError( NULL, _( "No library specified. Footprint could not be saved." ) ); return false; } footprintName = nameTextCtrl->GetValue(); footprintName.Trim( true ); footprintName.Trim( false ); if( footprintName.IsEmpty() ) { DisplayError( NULL, _( "No footprint name specified. Footprint could not be saved." ) ); return false; } aModule->SetFPID( LIB_ID( libraryName, footprintName ) ); if( updateValue ) aModule->SetValue( footprintName ); // Legacy libraries are readable, but modifying legacy format is not allowed // So prompt the user if he try to add/replace a footprint in a legacy lib wxString libfullname = Prj().PcbFootprintLibs()->FindRow( libraryName )->GetFullURI(); IO_MGR::PCB_FILE_T piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname ); if( piType == IO_MGR::LEGACY ) { DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT ); return false; } bool module_exists = tbl->FootprintExists( libraryName, footprintName ); if( module_exists ) { wxString msg = wxString::Format( _( "Footprint %s already exists in %s." ), footprintName, libraryName ); KIDIALOG chkdlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); chkdlg.SetOKLabel( _( "Overwrite" ) ); if( chkdlg.ShowModal() == wxID_CANCEL ) return false; } if( !saveFootprintInLibrary( aModule, libraryName ) ) return false; // Once saved-as a board footprint is no longer a board footprint aModule->SetLink( 0 ); wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) : _( "Component \"%s\" added in \"%s\"" ); wxString msg = wxString::Format( fmt, footprintName.GetData(), libraryName.GetData() ); SetStatusText( msg ); updateTitle(); return true; }
void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aStoreInNewLib ) { if( GetBoard()->m_Modules == NULL ) { DisplayInfoMessage( this, _( "No footprints to archive!" ) ); return; } wxString footprintName; if( !aStoreInNewLib ) { // The footprints are saved in an existing .pretty library in the fp lib table PROJECT& prj = Prj(); wxString last_nickname = prj.GetRString( PROJECT::PCB_LIB_NICKNAME ); wxString nickname = SelectLibrary( last_nickname ); if( !nickname ) // Aborted return; prj.SetRString( PROJECT::PCB_LIB_NICKNAME, nickname ); try { FP_LIB_TABLE* tbl = prj.PcbFootprintLibs(); for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() ) { if( !curr_fp->GetFPID().GetFootprintName().empty() ) // Can happen with old boards. tbl->FootprintSave( nickname, curr_fp, false ); } } catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); } } else { // The footprints are saved in a new .pretty library. // If this library already exists, all previous footprints will be deleted wxString libPath = CreateNewLibrary(); if( libPath.IsEmpty() ) // Aborted return; IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD; PLUGIN::RELEASER pi( IO_MGR::PluginFind( piType ) ); for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() ) { try { if( !curr_fp->GetFPID().GetFootprintName().empty() ) // Can happen with old boards. pi->FootprintSave( libPath, curr_fp ); } catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); } } } }