int CVPCB_MAINFRAME::ReadSchematicNetlist( const std::string& aNetlist ) { STRING_LINE_READER* strrdr = new STRING_LINE_READER( aNetlist, "Eeschema via Kiway" ); KICAD_NETLIST_READER netrdr( strrdr, &m_netlist ); m_netlist.Clear(); try { netrdr.LoadNetlist(); } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); return 1; } // We also remove footprint name if it is "$noname" because this is a dummy name, // not the actual name of the footprint. for( unsigned ii = 0; ii < m_netlist.GetCount(); ii++ ) { if( m_netlist.GetComponent( ii )->GetFPID().GetFootprintName() == std::string( "$noname" ) ) m_netlist.GetComponent( ii )->SetFPID( FPID( wxEmptyString ) ); } // Sort components by reference: m_netlist.SortByReference(); return 0; }
MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName ) { MODULE* module; wxString moduleName; wxPoint newpos; moduleName = aModuleName; // Ask for the new module reference if( moduleName.IsEmpty() ) { wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName ); dlg.SetTextValidator( FOOTPRINT_NAME_VALIDATOR( &moduleName ) ); if( dlg.ShowModal() != wxID_OK ) return NULL; //Aborted by user } moduleName.Trim( true ); moduleName.Trim( false ); if( moduleName.IsEmpty() ) { DisplayInfoMessage( this, FMT_NO_REF_ABORTED ); return NULL; } // Creates the new module and add it to the head of the linked list of modules module = new MODULE( GetBoard() ); GetBoard()->Add( module ); // Update parameters: position, timestamp ... newpos = GetCrossHairPosition(); module->SetPosition( newpos ); module->SetLastEditTime(); // Update its name in lib module->SetFPID( FPID( moduleName ) ); // Update reference: module->SetReference( moduleName ); module->Reference().SetThickness( GetDesignSettings().m_ModuleTextWidth ); module->Reference().SetSize( GetDesignSettings().m_ModuleTextSize ); // Set the value field to a default value module->SetValue( wxT( "VAL**" ) ); module->Value().SetThickness( GetDesignSettings().m_ModuleTextWidth ); module->Value().SetSize( GetDesignSettings().m_ModuleTextSize ); module->SetPosition( wxPoint( 0, 0 ) ); SetMsgPanel( module ); return module; }
void GPCB_FPL_CACHE::Load() { wxDir dir( m_lib_path.GetPath() ); if( !dir.IsOpened() ) { THROW_IO_ERROR( wxString::Format( _( "footprint library path '%s' does not exist" ), m_lib_path.GetPath().GetData() ) ); } wxString fpFileName; wxString wildcard = wxT( "*." ) + GedaPcbFootprintLibFileExtension; if( !dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) ) return; do { wxFileName fn( m_lib_path.GetPath(), fpFileName ); // reader now owns fp, will close on exception or return FILE_LINE_READER reader( fn.GetFullPath() ); std::string name = TO_UTF8( fn.GetName() ); MODULE* footprint = parseMODULE( &reader ); // The footprint name is the file name without the extension. footprint->SetFPID( FPID( fn.GetName() ) ); m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) ); } while( dir.GetNext( &fpFileName ) ); // Remember the file modification time of library file when the // cache snapshot was made, so that in a networked environment we will // reload the cache as needed. m_mod_time = GetLibModificationTime(); }
MODULE* PCB_BASE_FRAME::CreateNewModule( const wxString& aModuleName ) { // Creates a new footprint at position 0,0 which contains the minimal items: // the reference and the value. // Value : initialized to the footprint name. // put on fab layer (front side) // Reference : initialized to a default value (REF**). // put on silkscreen layer (front side) wxString moduleName = aModuleName; // Ask for the new module name if( moduleName.IsEmpty() ) { wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName ); dlg.SetTextValidator( FILE_NAME_CHAR_VALIDATOR( &moduleName ) ); if( dlg.ShowModal() != wxID_OK ) return NULL; //Aborted by user } moduleName.Trim( true ); moduleName.Trim( false ); if( moduleName.IsEmpty() ) { DisplayInfoMessage( this, FMT_NO_REF_ABORTED ); return NULL; } // Creates the new module and add it to the head of the linked list of modules MODULE* module = new MODULE( GetBoard() ); GetBoard()->Add( module ); // Update parameters: timestamp ... module->SetLastEditTime(); // Update its name in lib module->SetFPID( FPID( moduleName ) ); wxPoint default_pos; BOARD_DESIGN_SETTINGS& settings = GetDesignSettings(); // Update reference: if( settings.m_RefDefaultText.IsEmpty() ) module->SetReference( moduleName ); else module->SetReference( settings.m_RefDefaultText ); module->Reference().SetThickness( settings.m_ModuleTextWidth ); module->Reference().SetSize( settings.m_ModuleTextSize ); default_pos.y = GetDesignSettings().m_ModuleTextSize.y / 2; module->Reference().SetPosition( default_pos ); module->Reference().SetLayer( ToLAYER_ID( settings.m_RefDefaultlayer ) ); module->Reference().SetVisible( settings.m_RefDefaultVisibility ); // Set the value field to a default value if( settings.m_ValueDefaultText.IsEmpty() ) module->SetValue( moduleName ); else module->SetValue( settings.m_ValueDefaultText ); module->Value().SetThickness( GetDesignSettings().m_ModuleTextWidth ); module->Value().SetSize( GetDesignSettings().m_ModuleTextSize ); default_pos.y = -default_pos.y; module->Value().SetPosition( default_pos ); module->Value().SetLayer( ToLAYER_ID( settings.m_ValueDefaultlayer ) ); module->Value().SetVisible( settings.m_ValueDefaultVisibility ); SetMsgPanel( module ); return module; }
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 DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event ) { // First, test for invalid chars in module name wxString footprintName = m_FootprintNameCtrl->GetValue(); if( ! footprintName.IsEmpty() ) { if( ! MODULE::IsLibNameValid( footprintName ) ) { wxString msg; msg.Printf( _( "Error:\none of invalid chars <%s> found\nin <%s>" ), MODULE::StringLibNameInvalidChars( true ), GetChars( footprintName ) ); DisplayError( NULL, msg ); return; } } m_parent->SaveCopyInUndoList( m_currentModule, UR_MODEDIT ); m_currentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 ); switch( m_AttributsCtrl->GetSelection() ) { case 0: m_currentModule->SetAttributes( 0 ); break; case 1: m_currentModule->SetAttributes( MOD_CMS ); break; case 2: m_currentModule->SetAttributes( MOD_VIRTUAL ); break; } m_currentModule->SetPlacementCost90( m_CostRot90Ctrl->GetValue() ); m_currentModule->SetPlacementCost180( m_CostRot180Ctrl->GetValue() ); m_currentModule->SetDescription( m_DocCtrl->GetValue() ); m_currentModule->SetKeywords( m_KeywordCtrl->GetValue() ); // Init footprint name in library if( ! footprintName.IsEmpty() ) m_currentModule->SetFPID( FPID( footprintName ) ); // Init Fields: m_currentModule->Reference().Copy( m_referenceCopy ); m_currentModule->Value().Copy( m_valueCopy ); // Initialize masks clearances m_currentModule->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) ); m_currentModule->SetLocalSolderMaskMargin( ValueFromTextCtrl( *m_SolderMaskMarginCtrl ) ); m_currentModule->SetLocalSolderPasteMargin( ValueFromTextCtrl( *m_SolderPasteMarginCtrl ) ); double dtmp; wxString msg = m_SolderPasteMarginRatioCtrl->GetValue(); msg.ToDouble( &dtmp ); // A -50% margin ratio means no paste on a pad, the ratio must be >= -50 % if( dtmp < -50.0 ) dtmp = -50.0; // A margin ratio is always <= 0 if( dtmp > 0.0 ) dtmp = 0.0; m_currentModule->SetLocalSolderPasteMarginRatio( dtmp / 100 ); // Update 3D shape list int ii = m_3D_ShapeNameListBox->GetSelection(); if ( ii >= 0 ) TransfertDisplayTo3DValues( ii ); S3D_MASTER* draw3D = m_currentModule->Models(); for( unsigned ii = 0; ii < m_shapes3D_list.size(); ii++ ) { S3D_MASTER* draw3DCopy = m_shapes3D_list[ii]; if( draw3DCopy->GetShape3DName().IsEmpty() ) continue; if( draw3D == NULL ) { draw3D = new S3D_MASTER( draw3D ); m_currentModule->Models().Append( draw3D ); } draw3D->SetShape3DName( draw3DCopy->GetShape3DName() ); draw3D->m_MatScale = draw3DCopy->m_MatScale; draw3D->m_MatRotation = draw3DCopy->m_MatRotation; draw3D->m_MatPosition = draw3DCopy->m_MatPosition; draw3D = draw3D->Next(); } // Remove old extra 3D shapes S3D_MASTER* nextdraw3D; for( ; draw3D != NULL; draw3D = nextdraw3D ) { nextdraw3D = (S3D_MASTER*) draw3D->Next(); delete m_currentModule->Models().Remove( draw3D ); } // Fill shape list with one void entry, if no entry if( m_currentModule->Models() == NULL ) m_currentModule->Models().PushBack( new S3D_MASTER( m_currentModule ) ); m_currentModule->CalculateBoundingBox(); m_parent->OnModify(); EndModal( 1 ); }
bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary, MODULE* aModule, bool aOverwrite, bool aDisplayDialog ) { if( aModule == NULL ) return false; SetMsgPanel( aModule ); // 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 { MODULE* m = FootprintLibs()->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. FootprintLibs()->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; }
MODULE* PCB_EDIT_FRAME::Genere_Self( wxDC* DC ) { D_PAD* pad; int ll; wxString msg; m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); if( s_inductor_pattern.m_Flag == false ) { DisplayError( this, wxT( "Starting point not init.." ) ); return NULL; } s_inductor_pattern.m_Flag = false; s_inductor_pattern.m_End = GetCrossHairPosition(); wxPoint pt = s_inductor_pattern.m_End - s_inductor_pattern.m_Start; int min_len = KiROUND( EuclideanNorm( pt ) ); s_inductor_pattern.m_lenght = min_len; // Enter the desired length. msg = StringFromValue( g_UserUnit, s_inductor_pattern.m_lenght ); wxTextEntryDialog dlg( this, wxEmptyString, _( "Length of Trace:" ), msg ); if( dlg.ShowModal() != wxID_OK ) return NULL; // canceled by user msg = dlg.GetValue(); s_inductor_pattern.m_lenght = ValueFromString( g_UserUnit, msg ); // Control values (ii = minimum length) if( s_inductor_pattern.m_lenght < min_len ) { DisplayError( this, _( "Requested length < minimum length" ) ); return NULL; } // Calculate the elements. s_inductor_pattern.m_Width = GetDesignSettings().GetCurrentTrackWidth(); std::vector <wxPoint> buffer; ll = BuildCornersList_S_Shape( buffer, s_inductor_pattern.m_Start, s_inductor_pattern.m_End, s_inductor_pattern.m_lenght, s_inductor_pattern.m_Width ); if( !ll ) { DisplayError( this, _( "Requested length too large" ) ); return NULL; } // Generate footprint. the value is also used as footprint name. msg.Empty(); wxTextEntryDialog cmpdlg( this, wxEmptyString, _( "Component Value:" ), msg ); cmpdlg.SetTextValidator( FILE_NAME_CHAR_VALIDATOR( &msg ) ); if( ( cmpdlg.ShowModal() != wxID_OK ) || msg.IsEmpty() ) return NULL; // Aborted by user MODULE* module = CreateNewModule( msg ); // here the module is already in the BOARD, CreateNewModule() does that. module->SetFPID( FPID( std::string( "mw_inductor" ) ) ); module->SetAttributes( MOD_VIRTUAL | MOD_CMS ); module->ClearFlags(); module->SetPosition( s_inductor_pattern.m_End ); // Generate segments for( unsigned jj = 1; jj < buffer.size(); jj++ ) { EDGE_MODULE* PtSegm; PtSegm = new EDGE_MODULE( module ); PtSegm->SetStart( buffer[jj - 1] ); PtSegm->SetEnd( buffer[jj] ); PtSegm->SetWidth( s_inductor_pattern.m_Width ); PtSegm->SetLayer( module->GetLayer() ); PtSegm->SetShape( S_SEGMENT ); PtSegm->SetStart0( PtSegm->GetStart() - module->GetPosition() ); PtSegm->SetEnd0( PtSegm->GetEnd() - module->GetPosition() ); module->GraphicalItems().PushBack( PtSegm ); } // Place a pad on each end of coil. pad = new D_PAD( module ); module->Pads().PushFront( pad ); pad->SetPadName( wxT( "1" ) ); pad->SetPosition( s_inductor_pattern.m_End ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); pad->SetSize( wxSize( s_inductor_pattern.m_Width, s_inductor_pattern.m_Width ) ); pad->SetLayerSet( LSET( module->GetLayer() ) ); pad->SetAttribute( PAD_ATTRIB_SMD ); pad->SetShape( PAD_SHAPE_CIRCLE ); D_PAD* newpad = new D_PAD( *pad ); module->Pads().Insert( newpad, pad->Next() ); pad = newpad; pad->SetPadName( wxT( "2" ) ); pad->SetPosition( s_inductor_pattern.m_Start ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); // Modify text positions. SetMsgPanel( module ); wxPoint refPos( ( s_inductor_pattern.m_Start.x + s_inductor_pattern.m_End.x ) / 2, ( s_inductor_pattern.m_Start.y + s_inductor_pattern.m_End.y ) / 2 ); wxPoint valPos = refPos; refPos.y -= module->Reference().GetSize().y; module->Reference().SetPosition( refPos ); valPos.y += module->Value().GetSize().y; module->Value().SetPosition( valPos ); module->CalculateBoundingBox(); module->Draw( m_canvas, DC, GR_OR ); return module; }
MODULE* PCB_EDIT_FRAME::Genere_Self( wxDC* DC ) { D_PAD* pad; int ll; wxString msg; m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); if( Self_On == 0 ) { DisplayError( this, wxT( "Starting point not init.." ) ); return NULL; } Self_On = 0; Mself.m_End = GetCrossHairPosition(); wxPoint pt = Mself.m_End - Mself.m_Start; int min_len = KiROUND( EuclideanNorm( pt ) ); Mself.lng = min_len; // Enter the desired length. msg = StringFromValue( g_UserUnit, Mself.lng ); wxTextEntryDialog dlg( this, _( "Length:" ), _( "Length" ), msg ); if( dlg.ShowModal() != wxID_OK ) return NULL; // canceled by user msg = dlg.GetValue(); Mself.lng = ValueFromString( g_UserUnit, msg ); // Control values (ii = minimum length) if( Mself.lng < min_len ) { DisplayError( this, _( "Requested length < minimum length" ) ); return NULL; } // Calculate the elements. Mself.m_Width = GetBoard()->GetCurrentTrackWidth(); std::vector <wxPoint> buffer; ll = BuildCornersList_S_Shape( buffer, Mself.m_Start, Mself.m_End, Mself.lng, Mself.m_Width ); if( !ll ) { DisplayError( this, _( "Requested length too large" ) ); return NULL; } // Generate module. MODULE* module; module = Create_1_Module( wxEmptyString ); if( module == NULL ) return NULL; // here the module is already in the BOARD, Create_1_Module() does that. module->SetFPID( FPID( std::string( "MuSelf" ) ) ); module->SetAttributes( MOD_VIRTUAL | MOD_CMS ); module->ClearFlags(); module->SetPosition( Mself.m_End ); // Generate segments for( unsigned jj = 1; jj < buffer.size(); jj++ ) { EDGE_MODULE* PtSegm; PtSegm = new EDGE_MODULE( module ); PtSegm->SetStart( buffer[jj - 1] ); PtSegm->SetEnd( buffer[jj] ); PtSegm->SetWidth( Mself.m_Width ); PtSegm->SetLayer( module->GetLayer() ); PtSegm->SetShape( S_SEGMENT ); PtSegm->SetStart0( PtSegm->GetStart() - module->GetPosition() ); PtSegm->SetEnd0( PtSegm->GetEnd() - module->GetPosition() ); module->GraphicalItems().PushBack( PtSegm ); } // Place a pad on each end of coil. pad = new D_PAD( module ); module->Pads().PushFront( pad ); pad->SetPadName( wxT( "1" ) ); pad->SetPosition( Mself.m_End ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); pad->SetSize( wxSize( Mself.m_Width, Mself.m_Width ) ); pad->SetLayerMask( GetLayerMask( module->GetLayer() ) ); pad->SetAttribute( PAD_SMD ); pad->SetShape( PAD_CIRCLE ); D_PAD* newpad = new D_PAD( *pad ); module->Pads().Insert( newpad, pad->Next() ); pad = newpad; pad->SetPadName( wxT( "2" ) ); pad->SetPosition( Mself.m_Start ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); // Modify text positions. SetMsgPanel( module ); wxPoint refPos( ( Mself.m_Start.x + Mself.m_End.x ) / 2, ( Mself.m_Start.y + Mself.m_End.y ) / 2 ); wxPoint valPos = refPos; refPos.y -= module->Reference().GetSize().y; module->Reference().SetTextPosition( refPos ); valPos.y += module->Value().GetSize().y; module->Value().SetTextPosition( valPos ); module->Reference().SetPos0( module->Reference().GetTextPosition() - module->GetPosition() ); module->Value().SetPos0( module->Value().GetTextPosition() - module->GetPosition() ); module->CalculateBoundingBox(); module->Draw( m_canvas, DC, GR_OR ); return module; }