bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName ) { FILE* cmpFile; cmpFile = wxFopen( aFullCmpFileName, wxT( "wt" ) ); if( cmpFile == NULL ) return false; fprintf( cmpFile, "Cmp-Mod V01 Created by PcbNew date = %s\n", TO_UTF8( DateAndTime() ) ); MODULE* module = aBrd->m_Modules; for( ; module != NULL; module = module->Next() ) { fprintf( cmpFile, "\nBeginCmp\n" ); fprintf( cmpFile, "TimeStamp = %8.8lX\n", (unsigned long)module->GetTimeStamp() ); fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath() ) ); fprintf( cmpFile, "Reference = %s;\n", !module->GetReference().IsEmpty() ? TO_UTF8( module->GetReference() ) : "[NoRef]" ); fprintf( cmpFile, "ValeurCmp = %s;\n", !module->GetValue().IsEmpty() ? TO_UTF8( module->GetValue() ) : "[NoVal]" ); fprintf( cmpFile, "IdModule = %s;\n", module->GetFPID().Format().c_str() ); fprintf( cmpFile, "EndCmp\n" ); } fprintf( cmpFile, "\nEndListe\n" ); fclose( cmpFile ); return true; }
// see class_edge_mod.h void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; MODULE* module = (MODULE*) m_Parent; if( !module ) return; BOARD* board = (BOARD*) module->GetParent(); if( !board ) return; aList.push_back( MSG_PANEL_ITEM( _( "Graphic Item" ), wxEmptyString, DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Module" ), module->GetReference(), DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) ); msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() ); aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Mod Layer" ), module->GetLayerName(), RED ) ); aList.push_back( MSG_PANEL_ITEM( _( "Seg Layer" ), GetLayerName(), RED ) ); msg = ::CoordinateToString( m_Width ); aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, BLUE ) ); }
void DIALOG_EXCHANGE_MODULE::init() { SetFocus(); m_CurrentFootprintFPID->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ); m_NewFootprintFPID->AppendText( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ); m_CmpValue->AppendText( m_currentModule->GetValue() ); m_CmpReference->AppendText( m_currentModule->GetReference() ); m_Selection->SetString( 0, wxString::Format( _( "Change footprint of '%s'" ), GetChars( m_currentModule->GetReference() ) ) ); wxString fpname = m_CurrentFootprintFPID->GetValue().AfterLast( ':' ); if( fpname.IsEmpty() ) // Happens for old fp names fpname = m_CurrentFootprintFPID->GetValue(); m_Selection->SetString( 1, wxString::Format( _( "Change footprints '%s'" ), GetChars( fpname.Left( 12 ) ) ) ); m_Selection->SetSelection( m_selectionMode ); // Enable/disable widgets: wxCommandEvent event; OnSelectionClicked( event ); }
void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery ) { if( aPad == NULL ) return; MODULE* module = (MODULE*) aPad->GetParent(); module->SetLastEditTime(); // aQuery = true to prompt for confirmation, false to delete silently if( aQuery ) { wxString msg; msg.Printf( _( "Delete Pad (footprint %s %s) ?" ), GetChars( module->GetReference() ), GetChars( module->GetValue() ) ); if( !IsOK( this, msg ) ) return; } m_Pcb->m_Status_Pcb = 0; aPad->DeleteStructure(); // Refresh the modified screen area, using the initial bounding box // which is perhaps larger than the new bounding box m_canvas->RefreshDrawingRect( module->GetBoundingBox() ); // Update the bounding box module->CalculateBoundingBox(); OnModify(); }
void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery ) { if( aPad == NULL ) return; MODULE* module = aPad->GetParent(); module->SetLastEditTime(); // aQuery = true to prompt for confirmation, false to delete silently if( aQuery ) { wxString msg = wxString::Format( _( "Delete pad (footprint %s %s)?" ), module->GetReference(), module->GetValue() ); if( !IsOK( this, msg ) ) return; } // Stores the initial bounding box to refresh the old area EDA_RECT bbox = module->GetBoundingBox(); m_Pcb->m_Status_Pcb = 0; GetBoard()->PadDelete( aPad ); // Update the bounding box module->CalculateBoundingBox(); // Refresh the modified screen area, using the initial bounding box // which is perhaps larger than the new bounding box m_canvas->RefreshDrawingRect( bbox ); OnModify(); }
/* Creates the section $DEVICES * This is a list of footprints properties * ( Shapes are in section $SHAPE ) */ static void CreateDevicesSection( FILE* aFile, BOARD* aPcb ) { MODULE* module; fputs( "$DEVICES\n", aFile ); for( module = aPcb->m_Modules; module; module = module->Next() ) { fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) ); fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) ); fprintf( aFile, "PACKAGE \"%s\"\n", module->GetFPID().Format().c_str() ); // The TYPE attribute is almost freeform const char* ty = "TH"; if( module->GetAttributes() & MOD_CMS ) ty = "SMD"; if( module->GetAttributes() & MOD_VIRTUAL ) ty = "VIRTUAL"; fprintf( aFile, "TYPE %s\n", ty ); } fputs( "$ENDDEVICES\n\n", aFile ); }
// see class_edge_mod.h void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; MODULE* module = (MODULE*) m_Parent; if( !module ) return; BOARD* board = (BOARD*) module->GetParent(); if( !board ) return; aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) ); msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() ); aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Footprint Layer" ), module->GetLayerName(), RED ) ); // append the features shared with the base class DRAWSEGMENT::GetMsgPanelInfo( aList ); }
void DialogEditModuleText::initDlg( ) { SetFocus(); wxString msg; if( m_module ) { wxString format = m_ModuleInfoText->GetLabel(); msg.Printf( format, GetChars( m_module->GetReference() ), GetChars( m_module->GetValue() ), m_module->GetOrientation() / 10.0 ); } else { msg.Empty(); } m_ModuleInfoText->SetLabel( msg ); switch( m_currentText->GetType() ) { case TEXTE_MODULE::TEXT_is_VALUE: m_TextDataTitle->SetLabel( _( "Value:" ) ); break; case TEXTE_MODULE::TEXT_is_DIVERS: m_TextDataTitle->SetLabel( _( "Text:" ) ); break; default: m_TextDataTitle->SetLabel( _( "Reference:" ) ); break; } m_Name->SetValue( m_currentText->GetText() ); m_Style->SetSelection( m_currentText->IsItalic() ? 1 : 0 ); AddUnitSymbol( *m_SizeXTitle ); PutValueInLocalUnits( *m_TxtSizeCtrlX, m_currentText->GetSize().x ); AddUnitSymbol( *m_SizeYTitle ); PutValueInLocalUnits( *m_TxtSizeCtrlY, m_currentText->GetSize().y ); AddUnitSymbol( *m_PosXTitle ); PutValueInLocalUnits( *m_TxtPosCtrlX, m_currentText->GetPos0().x ); AddUnitSymbol( *m_PosYTitle ); PutValueInLocalUnits( *m_TxtPosCtrlY, m_currentText->GetPos0().y ); AddUnitSymbol( *m_WidthTitle ); PutValueInLocalUnits( *m_TxtWidthCtlr, m_currentText->GetThickness() ); double text_orient = m_currentText->GetOrientation(); NORMALIZE_ANGLE_90( text_orient ); if( (text_orient != 0) ) m_Orient->SetSelection( 1 ); if( !m_currentText->IsVisible() ) m_Show->SetSelection( 1 );; }
bool DIALOG_EXCHANGE_MODULE::changeSameFootprints( bool aUseValue ) { wxString msg; MODULE* Module; MODULE* PtBack; bool change = false; wxString newmodulename = m_NewFootprintFPID->GetValue(); wxString value; LIB_ID lib_reference; bool check_module_value = false; int ShowErr = 3; // Post 3 error messages max. if( m_parent->GetBoard()->m_Modules == NULL ) return false; if( newmodulename == wxEmptyString ) return false; lib_reference = m_currentModule->GetFPID(); if( aUseValue ) { check_module_value = true; value = m_currentModule->GetValue(); msg.Printf( _( "Change footprint %s -> %s (for value = %s)?" ), GetChars( FROM_UTF8( m_currentModule->GetFPID().Format().c_str() ) ), GetChars( newmodulename ), GetChars( m_currentModule->GetValue() ) ); } else { msg.Printf( _( "Change footprint %s -> %s ?" ), GetChars( FROM_UTF8( lib_reference.Format().c_str() ) ), GetChars( newmodulename ) ); } if( !IsOK( this, msg ) ) return false; /* The change is done from the last module because * change_1_Module () modifies the last item in the list. * * note: for the first module in chain (the last here), Module->Back() * points the board or is NULL */ Module = m_parent->GetBoard()->m_Modules.GetLast(); for( ; Module && ( Module->Type() == PCB_MODULE_T ); Module = PtBack ) { PtBack = Module->Back(); if( lib_reference != Module->GetFPID() ) continue; if( check_module_value ) { if( value.CmpNoCase( Module->GetValue() ) != 0 ) continue; } if( change_1_Module( Module, newmodulename, ShowErr ) ) change = true; else if( ShowErr ) ShowErr--; } return change; }
void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) { wxFileName fn; FILE* fp_bom; MODULE* module = GetBoard()->m_Modules; wxString msg; if( module == NULL ) { DisplayError( this, _( "Cannot export BOM: there are no footprints in the PCB" ) ); return; } /* Set the file extension: */ fn = GetBoard()->GetFileName(); fn.SetExt( CsvFileExtension ); wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); wxFileDialog dlg( this, _( "Save Bill of Materials" ), pro_dir, fn.GetFullName(), CsvFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() == wxID_CANCEL ) return; fn = dlg.GetPath(); fp_bom = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); if( fp_bom == NULL ) { msg.Printf( _( "Unable to create file \"%s\"" ), GetChars( fn.GetFullPath() ) ); DisplayError( this, msg ); return; } // Write header: msg = wxT( "\"" ); msg << _( "Id" ) << wxT( "\";\"" ); msg << _( "Designator" ) << wxT( "\";\"" ); msg << _( "Package" ) << wxT( "\";\"" ); msg << _( "Quantity" ) << wxT( "\";\"" ); msg << _( "Designation" ) << wxT( "\";\"" ); msg << _( "Supplier and ref" ) << wxT( "\";\n" ); fprintf( fp_bom, "%s", TO_UTF8( msg ) ); // Build list CmpList list; cmp* comp = NULL; CmpList::iterator iter; int i = 1; while( module != NULL ) { bool valExist = false; // try to find component in existing list for( iter = list.begin(); iter != list.end(); ++iter ) { cmp* current = *iter; if( (current->m_Val == module->GetValue()) && (current->m_fpid == module->GetFPID()) ) { current->m_Ref.Append( wxT( ", " ), 1 ); current->m_Ref.Append( module->GetReference() ); current->m_CmpCount++; valExist = true; break; } } // If component does not exist yet, create new one and append it to the list. if( valExist == false ) { comp = new cmp(); comp->m_Id = i++; comp->m_Val = module->GetValue(); comp->m_Ref = module->GetReference(); comp->m_fpid = module->GetFPID(); comp->m_CmpCount = 1; list.Append( comp ); } // increment module module = module->Next(); } // Print list. Also delete temporary created objects. for( size_t ii = list.GetCount(); ii > 0; ii-- ) { cmp* current = *list.begin(); // Because the first object will be removed // from list, all objects will be get here msg.Empty(); msg << current->m_Id << wxT( ";\"" ); msg << current->m_Ref << wxT( "\";\"" ); msg << FROM_UTF8( current->m_fpid.GetLibItemName().c_str() ) << wxT( "\";" ); msg << current->m_CmpCount << wxT( ";\"" ); msg << current->m_Val << wxT( "\";;;\n" ); fprintf( fp_bom, "%s", TO_UTF8( msg ) ); // We do not need this object, now: remove it from list and delete it list.DeleteObject( current ); delete (current); } fclose( fp_bom ); }
/* Creates the section $COMPONENTS (Footprints placement) * Bottom side components are difficult to handle: shapes must be mirrored or * flipped, silk layers need to be handled correctly and so on. Also it seems * that *noone* follows the specs... */ static void CreateComponentsSection( FILE* aFile, BOARD* aPcb ) { fputs( "$COMPONENTS\n", aFile ); int cu_count = aPcb->GetCopperLayerCount(); for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { const char* mirror; const char* flip; double fp_orient = module->GetOrientation(); if( module->GetFlag() ) { mirror = "0"; flip = "FLIP"; NEGATE_AND_NORMALIZE_ANGLE_POS( fp_orient ); } else { mirror = "0"; flip = "0"; } fprintf( aFile, "\nCOMPONENT %s\n", TO_UTF8( module->GetReference() ) ); fprintf( aFile, "DEVICE %s_%s\n", TO_UTF8( module->GetReference() ), TO_UTF8( module->GetValue() ) ); fprintf( aFile, "PLACE %g %g\n", MapXTo( module->GetPosition().x ), MapYTo( module->GetPosition().y ) ); fprintf( aFile, "LAYER %s\n", (module->GetFlag()) ? "BOTTOM" : "TOP" ); fprintf( aFile, "ROTATION %g\n", fp_orient / 10.0 ); fprintf( aFile, "SHAPE %s %s %s\n", TO_UTF8( module->GetReference() ), mirror, flip ); // Text on silk layer: RefDes and value (are they actually useful?) TEXTE_MODULE *textmod = &module->Reference(); for( int ii = 0; ii < 2; ii++ ) { double txt_orient = textmod->GetOrientation(); std::string layer = GenCADLayerName( cu_count, module->GetFlag() ? B_SilkS : F_SilkS ); fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"", textmod->GetPos0().x / SCALE_FACTOR, -textmod->GetPos0().y / SCALE_FACTOR, textmod->GetSize().x / SCALE_FACTOR, txt_orient / 10.0, mirror, layer.c_str(), TO_UTF8( textmod->GetText() ) ); // Please note, the width is approx fprintf( aFile, " 0 0 %g %g\n", ( textmod->GetSize().x * textmod->GetLength() ) / SCALE_FACTOR, textmod->GetSize().y / SCALE_FACTOR ); textmod = &module->Value(); // Dirty trick for the second iteration } // The SHEET is a 'generic description' for referencing the component fprintf( aFile, "SHEET \"RefDes: %s, Value: %s\"\n", TO_UTF8( module->GetReference() ), TO_UTF8( module->GetValue() ) ); } fputs( "$ENDCOMPONENTS\n\n", aFile ); }
void DIALOG_NETLIST::OnTestFootprintsClick( wxCommandEvent& event ) { if( m_parent->GetBoard()->m_Modules == NULL ) { DisplayInfoMessage( this, _( "No footprints" ) ); return; } // Lists of duplicates, missing references and not in netlist footprints: std::vector <MODULE*> duplicate; wxArrayString missing; std::vector <MODULE*> notInNetlist; wxString netlistFilename = m_NetlistFilenameCtrl->GetValue(); if( !verifyFootprints( netlistFilename, wxEmptyString, duplicate, missing, notInNetlist ) ) return; #define ERR_CNT_MAX 100 // Max number of errors to output in dialog // to avoid a too long message list wxString list; // The messages to display m_parent->SetLastNetListRead( netlistFilename ); int err_cnt = 0; // Search for duplicate footprints. if( duplicate.size() == 0 ) list << wxT("<p><b>") << _( "No duplicate." ) << wxT("</b></p>"); else { list << wxT("<p><b>") << _( "Duplicates:" ) << wxT("</b></p>"); for( unsigned ii = 0; ii < duplicate.size(); ii++ ) { MODULE* module = duplicate[ii]; if( module->GetReference().IsEmpty() ) list << wxT("<br>") << wxT("[noref)"); else list << wxT("<br>") << module->GetReference(); list << wxT(" (<i>") << module->GetValue() << wxT("</i>)"); list << wxT(" @ "); list << CoordinateToString( module->GetPosition().x ), list << wxT(", ") << CoordinateToString( module->GetPosition().y ), err_cnt++; if( ERR_CNT_MAX < err_cnt ) break; } } // Search for missing modules on board. if( missing.size() == 0 ) list << wxT("<p><b>") << _( "No missing footprints." ) << wxT("</b></p>"); else { list << wxT("<p><b>") << _( "Missing:" ) << wxT("</b></p>"); for( unsigned ii = 0; ii < missing.size(); ii += 2 ) { list << wxT("<br>") << missing[ii]; list << wxT(" (<i>") << missing[ii+1] << wxT("</i>)"); err_cnt++; if( ERR_CNT_MAX < err_cnt ) break; } } // Search for modules found on board but not in net list. if( notInNetlist.size() == 0 ) list << wxT( "<p><b>" ) << _( "No extra footprints." ) << wxT( "</b></p>" ); else { list << wxT( "<p><b>" ) << _( "Not in Netlist:" ) << wxT( "</b></p>" ); for( unsigned ii = 0; ii < notInNetlist.size(); ii++ ) { MODULE* module = notInNetlist[ii]; if( module->GetReference().IsEmpty() ) list << wxT( "<br>" ) << wxT( "[noref)" ); else list << wxT( "<br>" ) << module->GetReference() ; list << wxT( " (<i>" ) << module->GetValue() << wxT( "</i>)" ); list << wxT( " @ " ); list << CoordinateToString( module->GetPosition().x ), list << wxT( ", " ) << CoordinateToString( module->GetPosition().y ), err_cnt++; if( ERR_CNT_MAX < err_cnt ) break; } } if( ERR_CNT_MAX < err_cnt ) { list << wxT( "<p><b>" ) << _( "Too many errors: some are skipped" ) << wxT( "</b></p>" ); } HTML_MESSAGE_BOX dlg( this, _( "Check footprints" ) ); dlg.AddHTML_Text( list ); dlg.ShowModal(); }
bool DIALOG_TEXT_PROPERTIES::TransferDataToWindow() { if( m_SingleLineText->IsShown() ) { m_SingleLineText->SetValue( m_edaText->GetText() ); if( m_modText && m_modText->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) SelectReferenceNumber( static_cast<wxTextEntry*>( m_SingleLineText ) ); else m_SingleLineText->SetSelection( -1, -1 ); } else if( m_MultiLineText->IsShown() ) { m_MultiLineText->SetValue( m_edaText->GetText() ); m_MultiLineText->SetSelection( -1, -1 ); } else if (m_DimensionText->IsShown() ) { m_DimensionText->SetValue( m_edaText->GetText() ); m_DimensionText->SetSelection( -1, -1 ); DIMENSION* dimension = (DIMENSION*) m_item; EDA_UNITS_T units; bool useMils; dimension->GetUnits( units, useMils ); m_DimensionUnitsOpt->SetSelection( units == MILLIMETRES ? 2 : useMils ? 1 : 0 ); } if( m_item->Type() == PCB_MODULE_TEXT_T && m_modText ) { MODULE* module = dynamic_cast<MODULE*>( m_modText->GetParent() ); wxString msg; if( module ) { msg.Printf( _("Footprint %s (%s), %s, rotated %.1f deg"), module->GetReference(), module->GetValue(), module->IsFlipped() ? _( "back side (mirrored)" ) : _( "front side" ), module->GetOrientation() / 10.0 ); } m_statusLine->SetLabel( msg ); } else { m_statusLine->Show( false ); } if( m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ) < 0 ) { wxMessageBox( _( "This item was on a non-existing or forbidden layer.\n" "It has been moved to the first allowed layer." ) ); m_LayerSelectionCtrl->SetSelection( 0 ); } m_textWidth.SetValue( m_edaText->GetTextSize().x ); m_textHeight.SetValue( m_edaText->GetTextSize().y ); m_thickness.SetValue( m_edaText->GetThickness() ); m_posX.SetValue( m_edaText->GetTextPos().x ); m_posY.SetValue( m_edaText->GetTextPos().y ); m_Visible->SetValue( m_edaText->IsVisible() ); m_Italic->SetValue( m_edaText->IsItalic() ); EDA_TEXT_HJUSTIFY_T hJustify = m_edaText->GetHorizJustify(); m_JustifyChoice->SetSelection( (int) hJustify + 1 ); m_OrientValue = m_edaText->GetTextAngleDegrees(); m_Mirrored->SetValue( m_edaText->IsMirrored() ); if( m_modText ) m_KeepUpright->SetValue( m_modText->IsKeepUpright() ); return DIALOG_TEXT_PROPERTIES_BASE::TransferDataToWindow(); }