/********************************************************************/ /* Routines de lecture et sauvegarde des structures en format ASCii */ /* Fichier common a PCBNEW et CVPCB */ /********************************************************************/ /* ioascii.cpp */ #include "fctsys.h" #include "common.h" #include "confirm.h" #include "kicad_string.h" #include "pcbnew.h" #include "wxPcbStruct.h" #ifdef PCBNEW #include "autorout.h" #include "zones.h" #endif #ifdef CVPCB #include "cvpcb.h" #endif #include "pcbnew_id.h" /* Format des structures de sauvegarde type ASCII : Structure PAD: $PAD Sh "name" forme dimv dimH dV dH orient :forme generale dV, dH = delta dimensions Dr diam, dV dH :drill : diametre offsets de percage At type S/N layers : type standard,cms,conn,hole,meca., Stack/Normal, Hexadecimal 32 bits: occupation des couches Nm net_code netname Po posrefX posrefy : position refX,Y (= position orient 0 / ancre) $EndPAD ****** Structure module *********** $MODULE namelib Po ax ay orient layer masquelayer m_TimeCode ax ay = coord ancre (position module) orient = orient en 0.1 degre layer = numero de couche masquelayer = couche pour serigraphie m_TimeCode a usage interne (groupements) Li Cd Description du composant (Composant Doc) Kw Liste des mots cle Sc schematimestamp de reference schematique Op rot90 rot180 Options de placement auto (cout rot 90, 180 ) rot90 est sur 2x4 bits: lsb = cout rot 90, msb = cout rot -90; Tn px py dimv dimh orient epaisseur miroir visible "texte" n = type (0 = ref, 1 = val, > 1 =qcq Textes POS x,y / ancre et orient module 0 dimv dimh orient epaisseur miroir (Normal/miroir) visible V/I DS ox oy fx fy w edge: segment coord ox,oy a fx,fy, relatives a l'ancre et orient 0 epaisseur w DC ox oy fx fy w descr cercle (centre, 1 point, epaisseur) $PAD $EndPAD section pads s'il y en a $EndMODULE */ /* Local Variables */ int NbDraw, NbTrack, NbZone, NbMod, NbNets; /**********************************************************************/ int WinEDA_BasePcbFrame::ReadListeSegmentDescr( FILE* File, TRACK* insertBeforeMe, int StructType, int* LineNum, int NumSegm ) /**********************************************************************/ /** Read a list of segments (Tracks, zones) * @return items count or - count if no end block ($End...) found. */ { int shape, width, drill, layer, type, flags, net_code; int ii = 0; char line1[256]; char line2[256]; TRACK* newTrack; while( GetLine( File, line1, LineNum ) ) { int makeType; unsigned long timeStamp; if( line1[0] == '$' ) { return ii; /* end of segmentlist: OK */ } // Read the 2nd line to determine the exact type, one of: // TYPE_TRACK, TYPE_VIA, or TYPE_ZONE. The type field in 2nd line // differentiates between TYPE_TRACK and TYPE_VIA. With virtual // functions in use, it is critical to instantiate the TYPE_VIA exactly. if( GetLine( File, line2, LineNum ) == NULL ) break; if( line2[0] == '$' ) break; // parse the 2nd line first to determine the type of object sscanf( line2 + 2, " %d %d %d %lX %X", &layer, &type, &net_code, &timeStamp, &flags ); if( StructType==TYPE_TRACK && type==1 ) makeType = TYPE_VIA; else makeType = StructType; switch( makeType ) { default: case TYPE_TRACK: newTrack = new TRACK( GetBoard() ); GetBoard()->m_Track.Insert( newTrack, insertBeforeMe ); break; case TYPE_VIA: newTrack = new SEGVIA( GetBoard() ); GetBoard()->m_Track.Insert( newTrack, insertBeforeMe ); break; case TYPE_ZONE: // this is now deprecated, but exits in old boards newTrack = new SEGZONE( GetBoard() ); GetBoard()->m_Zone.Insert( (SEGZONE*)newTrack, (SEGZONE*)insertBeforeMe ); break; } newTrack->m_TimeStamp = timeStamp; int arg_count = sscanf( line1 + 2, " %d %d %d %d %d %d %d", &shape, &newTrack->m_Start.x, &newTrack->m_Start.y, &newTrack->m_End.x, &newTrack->m_End.y, &width, &drill ); newTrack->m_Width = width; newTrack->m_Shape = shape; if( arg_count < 7 || drill <= 0 ) newTrack->SetDrillDefault(); else newTrack->SetDrillValue(drill); newTrack->SetLayer( layer ); if ( makeType == TYPE_VIA ) { // Ensure layers are OK when possible: if( newTrack->Shape() == VIA_THROUGH ) ((SEGVIA*)newTrack)->SetLayerPair( LAYER_CMP_N, COPPER_LAYER_N ); } newTrack->SetNet( net_code ); newTrack->SetState( flags, ON ); } DisplayError( this, _( "Error: Unexpected end of file !" ) ); return -ii; } /**********************************************************************************/ int WinEDA_BasePcbFrame::ReadGeneralDescrPcb( FILE* File, int* LineNum ) /**********************************************************************************/ { char Line[1024], * data; while( GetLine( File, Line, LineNum ) != NULL ) { data = strtok( Line, " =\n\r" ); if( strnicmp( data, "$EndGENERAL", 10 ) == 0 ) break; if( strncmp( data, "Ly", 2 ) == 0 ) // Old format for Layer count { int Masque_Layer = 1, ii; data = strtok( NULL, " =\n\r" ); sscanf( data, "%X", &Masque_Layer ); // Setup layer count GetBoard()->m_BoardSettings->m_CopperLayerCount = 0; for( ii = 0; ii < NB_COPPER_LAYERS; ii++ ) { if( Masque_Layer & 1 ) GetBoard()->m_BoardSettings->m_CopperLayerCount++; Masque_Layer >>= 1; } continue; } if( stricmp( data, "LayerThickness" ) == 0 ) { data = strtok( NULL, " =\n\r" ); GetBoard()->m_BoardSettings->m_LayerThickness = atoi( data );; continue; } if( strnicmp( data, "Links", 5 ) == 0 ) { // Info only, do nothing continue; } if( strnicmp( data, "NoConn", 6 ) == 0 ) { data = strtok( NULL, " =\n\r" ); GetBoard()->m_NbNoconnect = atoi( data ); continue; } if( strnicmp( data, "Di", 2 ) == 0 ) { wxSize pcbsize, screensize; data = strtok( NULL, " =\n\r" ); GetBoard()->m_BoundaryBox.SetX( atoi( data ) ); data = strtok( NULL, " =\n\r" ); GetBoard()->m_BoundaryBox.SetY( atoi( data ) ); data = strtok( NULL, " =\n\r" ); GetBoard()->m_BoundaryBox.SetWidth( atoi( data ) - GetBoard()->m_BoundaryBox.GetX() ); data = strtok( NULL, " =\n\r" ); GetBoard()->m_BoundaryBox.SetHeight( atoi( data ) - GetBoard()->m_BoundaryBox.GetY() ); continue; } /* Lecture du nombre de segments type DRAW , TRACT, ZONE */ if( stricmp( data, "Ndraw" ) == 0 ) { data = strtok( NULL, " =\n\r" ); NbDraw = atoi( data );; continue; } if( stricmp( data, "Ntrack" ) == 0 ) { data = strtok( NULL, " =\n\r" ); NbTrack = atoi( data ); continue; } if( stricmp( data, "Nzone" ) == 0 ) { data = strtok( NULL, " =\n\r" ); NbZone = atoi( data ); continue; } if( stricmp( data, "Nmodule" ) == 0 ) { data = strtok( NULL, " =\n\r" ); NbMod = atoi( data ); continue; } if( stricmp( data, "Nnets" ) == 0 ) { data = strtok( NULL, " =\n\r" ); NbNets = atoi( data ); continue; } } return 1; } /*************************************************************/ int WinEDA_BasePcbFrame::ReadSetup( FILE* File, int* LineNum ) /*************************************************************/ { char Line[1024]; char* data; while( GetLine( File, Line, LineNum ) != NULL ) { strtok( Line, " =\n\r" ); data = strtok( NULL, " =\n\r" ); if( stricmp( Line, "$EndSETUP" ) == 0 ) { // Until such time as the *.brd file does not have the global parameters: // "TrackWidth", "TrackMinWidth", "ViaSize", "ViaDrill", "ViaMinSize", and "TrackClearence", // put those same global values into the default NETCLASS until later board load // code should override them. *.brd files which have been saved with knowledge of // NETCLASSes will override these defaults, old boards will not. // @todo: I expect that at some point we can remove said global // parameters from the *.brd file since the ones in the default // netclass serve the same purpose. If needed at all, the global defaults should go into // a preferences file instead so they are there to start new board projects. GetBoard()->m_NetClasses.GetDefault()->SetParams(); return 0; } if( stricmp( Line, "AuxiliaryAxisOrg" ) == 0 ) { int gx = 0, gy = 0; gx = atoi( data ); data = strtok( NULL, " =\n\r" ); if( data ) gy = atoi( data ); m_Auxiliary_Axis_Position.x = gx; m_Auxiliary_Axis_Position.y = gy; continue; } #ifdef PCBNEW if( stricmp( Line, "Layers" ) == 0 ) { int tmp; sscanf( data, "%d", &tmp ); GetBoard()->m_BoardSettings->m_CopperLayerCount = tmp; continue; } const int LAYERKEYZ = sizeof("Layer[")-1; if( strncmp( Line, "Layer[", LAYERKEYZ ) == 0 ) { // parse: // Layer[n] char* cp = Line + LAYERKEYZ; int layer = atoi(cp); if( data ) { wxString layerName = CONV_FROM_UTF8( data ); GetBoard()->SetLayerName( layer, layerName ); data = strtok( NULL, " " ); if( data ) { LAYER_T type = LAYER::ParseType( data ); GetBoard()->SetLayerType( layer, type ); } } continue; } if( stricmp( Line, "TrackWidth" ) == 0 ) { g_DesignSettings.m_CurrentTrackWidth = atoi( data ); continue; } if( stricmp( Line, "TrackWidthList" ) == 0 ) { int tmp = atoi( data ); GetBoard()->m_TrackWidthList.push_back( tmp ); continue; } if( stricmp( Line, "TrackClearence" ) == 0 ) { g_DesignSettings.m_TrackClearance = atoi( data ); continue; } if( stricmp( Line, "TrackMinWidth" ) == 0 ) { g_DesignSettings.m_TrackMinWidth = atoi( data ); continue; } if( stricmp( Line, "ZoneClearence" ) == 0 ) { g_Zone_Default_Setting.m_ZoneClearance = atoi( data ); continue; } if( stricmp( Line, "ZoneGridSize" ) == 0 ) { g_GridRoutingSize = atoi( data ); continue; } if( stricmp( Line, "DrawSegmWidth" ) == 0 ) { g_DesignSettings.m_DrawSegmentWidth = atoi( data ); continue; } if( stricmp( Line, "EdgeSegmWidth" ) == 0 ) { g_DesignSettings.m_EdgeSegmentWidth = atoi( data ); continue; } if( stricmp( Line, "ViaSize" ) == 0 ) { g_DesignSettings.m_CurrentViaSize = atoi( data ); continue; } if( stricmp( Line, "ViaMinSize" ) == 0 ) { g_DesignSettings.m_ViasMinSize = atoi( data ); continue; } if( stricmp( Line, "MicroViaSize" ) == 0 ) { g_DesignSettings.m_CurrentMicroViaSize = atoi( data ); continue; } if( stricmp( Line, "MicroViaMinSize" ) == 0 ) { g_DesignSettings.m_MicroViasMinSize = atoi( data ); continue; } if( stricmp( Line, "ViaSizeList" ) == 0 ) { int tmp = atoi( data ); GetBoard()->m_ViaSizeList.push_back( tmp ); continue; } if( stricmp( Line, "ViaDrill" ) == 0 ) { g_DesignSettings.m_ViaDrill = atoi( data ); continue; } if( stricmp( Line, "ViaAltDrill" ) == 0 ) { g_DesignSettings.m_ViaDrillCustomValue = atoi( data ); continue; } if( stricmp( Line, "MicroViaDrill" ) == 0 ) { g_DesignSettings.m_MicroViaDrill = atoi( data ); continue; } if( stricmp( Line, "MicroViasAllowed" ) == 0 ) { g_DesignSettings.m_MicroViasAllowed = atoi( data ); continue; } if( stricmp( Line, "TextPcbWidth" ) == 0 ) { g_DesignSettings.m_PcbTextWidth = atoi( data ); continue; } if( stricmp( Line, "TextPcbSize" ) == 0 ) { g_DesignSettings.m_PcbTextSize.x = atoi( data ); data = strtok( NULL, " =\n\r" ); g_DesignSettings.m_PcbTextSize.y = atoi( data ); continue; } if( stricmp( Line, "EdgeModWidth" ) == 0 ) { ModuleSegmentWidth = atoi( data ); continue; } if( stricmp( Line, "TextModWidth" ) == 0 ) { ModuleTextWidth = atoi( data ); continue; } if( stricmp( Line, "TextModSize" ) == 0 ) { ModuleTextSize.x = atoi( data ); data = strtok( NULL, " =\n\r" ); ModuleTextSize.y = atoi( data ); continue; } if( stricmp( Line, "PadSize" ) == 0 ) { g_Pad_Master.m_Size.x = atoi( data ); data = strtok( NULL, " =\n\r" ); g_Pad_Master.m_Size.y = atoi( data ); continue; } if( stricmp( Line, "PadDrill" ) == 0 ) { g_Pad_Master.m_Drill.x = atoi( data ); g_Pad_Master.m_Drill.y = g_Pad_Master.m_Drill.x; continue; } if( stricmp( Line, "Pad2MaskClearance" ) == 0 ) { g_DesignSettings.m_MaskMargin = atoi( data ); continue; } #endif } /* Ensure tracks and vias sizes lists are ok: * Sort lists by by increasing value and remove duplicates * (the first value is not tested, because it is the netclass value */ sort( GetBoard()->m_ViaSizeList.begin()+1, GetBoard()->m_ViaSizeList.end() ); sort( GetBoard()->m_TrackWidthList.begin()+1, GetBoard()->m_TrackWidthList.end() ); for( unsigned ii = 1; ii < GetBoard()->m_ViaSizeList.size()-1; ii++ ) { if( GetBoard()->m_ViaSizeList[ii] == GetBoard()->m_ViaSizeList[ii+1] ) { GetBoard()->m_ViaSizeList.erase(GetBoard()->m_ViaSizeList.begin()+ii); ii--; } } for( unsigned ii = 1; ii < GetBoard()->m_TrackWidthList.size()-1; ii++ ) { if( GetBoard()->m_TrackWidthList[ii] == GetBoard()->m_TrackWidthList[ii+1] ) { GetBoard()->m_TrackWidthList.erase(GetBoard()->m_TrackWidthList.begin()+ii); ii--; } } return 1; } #ifdef PCBNEW /******************************************************************************/ static int WriteSetup( FILE* aFile, WinEDA_BasePcbFrame* aFrame, BOARD* aBoard ) /******************************************************************************/ { char text[1024]; fprintf( aFile, "$SETUP\n" ); sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT ); fprintf( aFile, "%s", text ); fprintf( aFile, "ZoneGridSize %d\n", g_GridRoutingSize ); fprintf( aFile, "Layers %d\n", aBoard->GetCopperLayerCount() ); unsigned layerMask = g_TabAllCopperLayerMask[aBoard->GetCopperLayerCount()-1]; for( int layer=0; layerMask; ++layer, layerMask>>=1 ) { if( layerMask & 1 ) { fprintf( aFile, "Layer[%d] %s %s\n", layer, CONV_TO_UTF8( aBoard->GetLayerName(layer) ), LAYER::ShowType( aBoard->GetLayerType( layer ) ) ); } } fprintf( aFile, "TrackWidth %d\n", g_DesignSettings.m_CurrentTrackWidth ); // Save custom tracks width list (the first is not saved here: this is the netclass value for( unsigned ii = 1; ii < aBoard->m_TrackWidthList.size(); ii++ ) fprintf( aFile, "TrackWidthList %d\n", aBoard->m_TrackWidthList[ii] ); fprintf( aFile, "TrackClearence %d\n", g_DesignSettings.m_TrackClearance ); fprintf( aFile, "ZoneClearence %d\n", g_Zone_Default_Setting.m_ZoneClearance ); fprintf( aFile, "TrackMinWidth %d\n" , g_DesignSettings.m_TrackMinWidth ); fprintf( aFile, "DrawSegmWidth %d\n", g_DesignSettings.m_DrawSegmentWidth ); fprintf( aFile, "EdgeSegmWidth %d\n", g_DesignSettings.m_EdgeSegmentWidth ); fprintf( aFile, "ViaSize %d\n", g_DesignSettings.m_CurrentViaSize ); fprintf( aFile, "ViaDrill %d\n", g_DesignSettings.m_ViaDrill ); fprintf( aFile, "ViaAltDrill %d\n", g_DesignSettings.m_ViaDrillCustomValue ); fprintf( aFile, "ViaMinSize %d\n", g_DesignSettings.m_ViasMinSize ); // Save custom vias diameters list (the first is not saved here: this is the netclass value for( unsigned ii = 1; ii < aBoard->m_ViaSizeList.size(); ii++ ) fprintf( aFile, "ViaSizeList %d\n", aBoard->m_ViaSizeList[ii] ); fprintf( aFile, "MicroViaSize %d\n", g_DesignSettings.m_CurrentMicroViaSize); fprintf( aFile, "MicroViaDrill %d\n", g_DesignSettings.m_MicroViaDrill); fprintf( aFile, "MicroViasAllowed %d\n", g_DesignSettings.m_MicroViasAllowed); fprintf( aFile, "MicroViaMinSize %d\n" , g_DesignSettings.m_MicroViasMinSize ); fprintf( aFile, "TextPcbWidth %d\n", g_DesignSettings.m_PcbTextWidth ); fprintf( aFile, "TextPcbSize %d %d\n", g_DesignSettings.m_PcbTextSize.x, g_DesignSettings.m_PcbTextSize.y ); fprintf( aFile, "EdgeModWidth %d\n", ModuleSegmentWidth ); fprintf( aFile, "TextModSize %d %d\n", ModuleTextSize.x, ModuleTextSize.y ); fprintf( aFile, "TextModWidth %d\n", ModuleTextWidth ); fprintf( aFile, "PadSize %d %d\n", g_Pad_Master.m_Size.x, g_Pad_Master.m_Size.y ); fprintf( aFile, "PadDrill %d\n", g_Pad_Master.m_Drill.x ); fprintf( aFile, "Pad2MaskClearance %d\n", g_DesignSettings.m_MaskMargin ); fprintf( aFile, "AuxiliaryAxisOrg %d %d\n", aFrame->m_Auxiliary_Axis_Position.x, aFrame->m_Auxiliary_Axis_Position.y ); fprintf( aFile, "$EndSETUP\n\n" ); return 1; } #endif /******************************************************/ bool WinEDA_PcbFrame::WriteGeneralDescrPcb( FILE* File ) /******************************************************/ { EDA_BaseStruct* PtStruct = GetBoard()->m_Modules; int NbModules, NbDrawItem, NbLayers; /* Write copper layer count */ NbLayers = GetBoard()->m_BoardSettings->m_CopperLayerCount; fprintf( File, "$GENERAL\n" ); fprintf( File, "LayerCount %d\n", NbLayers ); // Write old format for Layer count (for compatibility with old versions of pcbnew fprintf( File, "Ly %8X\n", g_TabAllCopperLayerMask[NbLayers - 1] | ALL_NO_CU_LAYERS ); // For compatibility with old version of pcbnew fprintf( File, "Links %d\n", GetBoard()->GetRatsnestsCount() ); fprintf( File, "NoConn %d\n", GetBoard()->m_NbNoconnect ); /* Write Bounding box info */ GetBoard()->ComputeBoundaryBox(); fprintf( File, "Di %d %d %d %d\n", GetBoard()->m_BoundaryBox.GetX(), GetBoard()->m_BoundaryBox.GetY(), GetBoard()->m_BoundaryBox.GetRight(), GetBoard()->m_BoundaryBox.GetBottom() ); /* Write segment count for footprints, drawings, track and zones */ /* Calculate the footprint count */ for( NbModules = 0; PtStruct != NULL; PtStruct = PtStruct->Next() ) NbModules++; PtStruct = GetBoard()->m_Drawings; NbDrawItem = 0; for( ; PtStruct != NULL; PtStruct = PtStruct->Next() ) NbDrawItem++; fprintf( File, "Ndraw %d\n", NbDrawItem ); fprintf( File, "Ntrack %d\n", GetBoard()->GetNumSegmTrack() ); fprintf( File, "Nzone %d\n", GetBoard()->GetNumSegmZone() ); fprintf( File, "LayerThickness %d\n", GetBoard()->m_BoardSettings->m_LayerThickness ); fprintf( File, "Nmodule %d\n", NbModules ); fprintf( File, "Nnets %d\n", GetBoard()->m_NetInfo->GetCount() ); fprintf( File, "$EndGENERAL\n\n" ); return TRUE; } /******************************************************/ bool WriteSheetDescr( BASE_SCREEN* screen, FILE* File ) /******************************************************/ /** Function WriteSheetDescr * Save the page information (size, texts, date ..) * @param screen BASE_SCREEN to save * @param File = an openen FILE to write info */ { Ki_PageDescr* sheet = screen->m_CurrentSheetDesc; fprintf( File, "$SHEETDESCR\n" ); fprintf( File, "Sheet %s %d %d\n", CONV_TO_UTF8( sheet->m_Name ), sheet->m_Size.x, sheet->m_Size.y ); fprintf( File, "Title \"%s\"\n", CONV_TO_UTF8( screen->m_Title ) ); fprintf( File, "Date \"%s\"\n", CONV_TO_UTF8( screen->m_Date ) ); fprintf( File, "Rev \"%s\"\n", CONV_TO_UTF8( screen->m_Revision ) ); fprintf( File, "Comp \"%s\"\n", CONV_TO_UTF8( screen->m_Company ) ); fprintf( File, "Comment1 \"%s\"\n", CONV_TO_UTF8( screen->m_Commentaire1 ) ); fprintf( File, "Comment2 \"%s\"\n", CONV_TO_UTF8( screen->m_Commentaire2 ) ); fprintf( File, "Comment3 \"%s\"\n", CONV_TO_UTF8( screen->m_Commentaire3 ) ); fprintf( File, "Comment4 \"%s\"\n", CONV_TO_UTF8( screen->m_Commentaire4 ) ); fprintf( File, "$EndSHEETDESCR\n\n" ); return TRUE; } /***************************************************************************/ static bool ReadSheetDescr( BASE_SCREEN* screen, FILE* File, int* LineNum ) /***************************************************************************/ { char Line[1024], buf[1024], * text; while( GetLine( File, Line, LineNum ) != NULL ) { if( strnicmp( Line, "$End", 4 ) == 0 ) return TRUE; if( strnicmp( Line, "Sheet", 4 ) == 0 ) { text = strtok( Line, " \t\n\r" ); text = strtok( NULL, " \t\n\r" ); Ki_PageDescr* sheet = g_SheetSizeList[0]; int ii; for( ii = 0; sheet != NULL; ii++, sheet = g_SheetSizeList[ii] ) { if( stricmp( CONV_TO_UTF8( sheet->m_Name ), text ) == 0 ) { screen->m_CurrentSheetDesc = sheet; if( sheet == &g_Sheet_user ) { text = strtok( NULL, " \t\n\r" ); if( text ) sheet->m_Size.x = atoi( text ); text = strtok( NULL, " \t\n\r" ); if( text ) sheet->m_Size.y = atoi( text ); } break; } } continue; } if( strnicmp( Line, "Title", 2 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Title = CONV_FROM_UTF8( buf ); continue; } if( strnicmp( Line, "Date", 2 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Date = CONV_FROM_UTF8( buf ); continue; } if( strnicmp( Line, "Rev", 2 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Revision = CONV_FROM_UTF8( buf ); continue; } if( strnicmp( Line, "Comp", 4 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Company = CONV_FROM_UTF8( buf ); continue; } if( strnicmp( Line, "Comment1", 8 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Commentaire1 = CONV_FROM_UTF8( buf ); continue; } if( strnicmp( Line, "Comment2", 8 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Commentaire2 = CONV_FROM_UTF8( buf ); continue; } if( strnicmp( Line, "Comment3", 8 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Commentaire3 = CONV_FROM_UTF8( buf ); continue; } if( strnicmp( Line, "Comment4", 8 ) == 0 ) { ReadDelimitedText( buf, Line, 256 ); screen->m_Commentaire4 = CONV_FROM_UTF8( buf ); continue; } } return FALSE; } /********************************************************************/ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) /********************************************************************/ /** ReadPcbFile * Read a board file .brd * @param Append if 0: a previoulsy loaded board is deleted before loading the file. * else all items of the board file are added to the existing board */ { char Line[1024]; int LineNum = 0; wxBusyCursor dummy; // Switch the locale to standard C (needed to read floating point numbers like 1.3) SetLocaleTo_C_standard(); BOARD* board = GetBoard(); NbDraw = NbTrack = NbZone = NbMod = NbNets = -1; board->m_Status_Pcb = 0; board->m_NetClasses.Clear(); // Put a dollar sign in front, and test for a specific length of characters // The -1 is to omit the trailing \0 which is included in sizeof() on a string. #define TESTLINE(x) (strncmp(Line, "$" x, sizeof("$" x)-1) == 0) while( GetLine( File, Line, &LineNum ) != NULL ) { // put the more frequent ones at the top if( TESTLINE( "MODULE" ) ) { MODULE* Module = new MODULE( board ); if( Module == NULL ) continue; board->Add( Module, ADD_APPEND ); Module->ReadDescr( File, &LineNum ); continue; } if( TESTLINE( "DRAWSEGMENT" ) ) { DRAWSEGMENT* DrawSegm = new DRAWSEGMENT( board ); board->Add( DrawSegm, ADD_APPEND ); DrawSegm->ReadDrawSegmentDescr( File, &LineNum ); continue; } if( TESTLINE( "EQUIPOT" ) ) { NETINFO_ITEM* net = new NETINFO_ITEM( board ); board->m_NetInfo->AppendNet( net ); net->ReadDescr( File, &LineNum ); continue; } if( TESTLINE( "TEXTPCB" ) ) { TEXTE_PCB* pcbtxt = new TEXTE_PCB( board ); board->Add( pcbtxt, ADD_APPEND ); pcbtxt->ReadTextePcbDescr( File, &LineNum ); continue; } if( TESTLINE( "TRACK" ) ) { #ifdef PCBNEW TRACK* insertBeforeMe = Append ? NULL : board->m_Track.GetFirst(); ReadListeSegmentDescr( File, insertBeforeMe, TYPE_TRACK, &LineNum, NbTrack ); #endif continue; } if( TESTLINE( BRD_NETCLASS ) ) { // create an empty NETCLASS without a name. NETCLASS* netclass = new NETCLASS( board, wxEmptyString ); // fill it from the *.brd file, and establish its name. netclass->ReadDescr( File, &LineNum ); if( !board->m_NetClasses.Add( netclass ) ) { // Must have been a name conflict, this is a bad board file. // User may have done a hand edit to the file. // Delete netclass if board could not take ownership of it. delete netclass; // @todo: throw an exception here, this is a bad board file. } continue; } if( TESTLINE( "CZONE_OUTLINE" ) ) { ZONE_CONTAINER * zone_descr = new ZONE_CONTAINER(board); zone_descr->ReadDescr( File, &LineNum ); if ( zone_descr->GetNumCorners( ) > 2 ) // should always occur board->Add(zone_descr); else delete zone_descr; continue; } if( TESTLINE( "COTATION" ) ) { COTATION* Cotation = new COTATION( board ); board->Add( Cotation, ADD_APPEND ); Cotation->ReadCotationDescr( File, &LineNum ); continue; } if( TESTLINE( "MIREPCB" ) ) { MIREPCB* Mire = new MIREPCB( board ); board->Add( Mire, ADD_APPEND ); Mire->ReadMirePcbDescr( File, &LineNum ); continue; } if( TESTLINE( "ZONE" ) ) { #ifdef PCBNEW SEGZONE* insertBeforeMe = Append ? NULL : board->m_Zone.GetFirst(); ReadListeSegmentDescr( File, insertBeforeMe, TYPE_ZONE, &LineNum, NbZone ); #endif continue; } if( TESTLINE( "GENERAL" ) ) { ReadGeneralDescrPcb( File, &LineNum ); continue; } if( TESTLINE( "SHEETDESCR" ) ) { ReadSheetDescr( GetScreen(), File, &LineNum ); continue; } if( TESTLINE( "SETUP" ) ) { if( !Append ) { ReadSetup( File, &LineNum ); } else { while( GetLine( File, Line, &LineNum ) != NULL ) if( TESTLINE( "EndSETUP" ) ) break; } continue; } if( TESTLINE( "EndPCB" ) ) break; } SetLocaleTo_Default( ); // revert to the current locale Affiche_Message( wxEmptyString ); BestZoom(); board->SynchronizeNetsAndNetClasses( ); board->m_Status_Pcb = 0; SetToolbars(); return 1; } #ifdef PCBNEW /***************************************************/ int WinEDA_PcbFrame::SavePcbFormatAscii( FILE* aFile ) /****************************************************/ /* Routine de sauvegarde du PCB courant sous format ASCII * retourne * 1 si OK * 0 si sauvegarde non faite */ { bool rc; char line[256]; GetBoard()->m_Status_Pcb &= ~CONNEXION_OK; wxBeginBusyCursor(); // Switch the locale to standard C (needed to print floating point numbers like 1.3) SetLocaleTo_C_standard( ); /* Ecriture de l'entete PCB : */ fprintf( aFile, "PCBNEW-BOARD Version %d date %s\n\n", g_CurrentVersionPCB, DateAndTime( line ) ); fprintf( aFile, "# Created by Pcbnew%s\n\n", CONV_TO_UTF8( GetBuildVersion() ) ); GetBoard()->SynchronizeNetsAndNetClasses(); // Select default Netclass. Useful to save default values in headers GetBoard()->SetCurrentNetClass( GetBoard()->m_NetClasses.GetDefault()->GetName( )); m_TrackAndViasSizesList_Changed = true; AuxiliaryToolBar_Update_UI(); WriteGeneralDescrPcb( aFile ); WriteSheetDescr( GetScreen(), aFile ); WriteSetup( aFile, this, GetBoard() ); rc = GetBoard()->Save( aFile ); SetLocaleTo_Default( ); // revert to the current locale wxEndBusyCursor(); if( !rc ) DisplayError( this, wxT( "Unable to save PCB file" ) ); else Affiche_Message( wxEmptyString ); return rc; } #endif