ioascii.cpp.notused 36.2 KB
Newer Older
1 2
 /**
 * @file ioascii.cpp
3
 * @brief Routines for reading and saving of structures in ASCII file common to Pcbnew and CvPcb.
4
 */
5

6 7 8 9 10 11 12 13
#include <fctsys.h>
#include <confirm.h>
#include <kicad_string.h>
#include <build_version.h>
#include <wxPcbStruct.h>
#include <richio.h>
#include <macros.h>
#include <pcbcommon.h>
14

15 16 17 18
/**
 * @todo Fix having to recompile the same file with a different defintion.  This is
 *       what C++ derivation was designed to solve.
 */
19
#ifdef PCBNEW
20
#include <zones.h>
21 22 23
#endif

#ifdef CVPCB
24
#include <cvpcb.h>
25 26
#endif

27 28 29 30 31 32 33 34
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_pcb_text.h>
#include <class_zone.h>
#include <class_dimension.h>
#include <class_drawsegment.h>
#include <class_mire.h>
35

36 37 38 39
#include <pcbnew.h>
#include <pcbnew_id.h>
#include <autorout.h>
#include <pcb_plot_params.h>
40

41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
/* ASCII format of structures:
 *
 * Structure PAD:
 *
 * $PAD
 * Sh "name" form DIMVA dimH dV dH East: general form dV, dH = delta size
 * Dr. diam dV dH: drill: diameter drilling offsets
 * At Type S / N layers: standard, cms, conn, hole, meca.,
 *    Stack / Normal, 32-bit hexadecimal: occupation layers
 * Nm net_code netname
 * Po posrefX posrefy: reFX position, Y (0 = east position / anchor)
 * $EndPAD
 *
 * Module Structure
 *
 * $MODULE namelib
 * Po ax ay east layer masquelayer m_TimeCode
 *    ax ay ord = anchor (position module)
 *    east = east to 0.1 degree
 *    layer = layer number
 *    masquelayer = silkscreen layer for
 *    m_TimeCode internal use (groups)
 * Li <namelib>
 *
 * Cd <text> description of the component (Component Doc)
 * Kw <text> List of key words
 *
 * Sc schematic timestamp, reference schematic
 *
 * Op rot90 rot180 placement Options Auto (court rot 90, 180)
 *    rot90 is about 2x4-bit:
 *    lsb = cost rot 90, rot court msb = -90;
 *
 * Tn px py DIMVA dimh East thickness mirror visible "text"
 *    n = type (0 = ref, val = 1,> 1 = qcq
 *    Texts POS x, y / anchor and orient module 0
 *    DIMVA dimh East
 *    mirror thickness (Normal / Mirror)
 *    Visible V / I
 * DS ox oy fx fy w
 *    Edge: coord segment ox, oy has fx, fy, on
 *    was the anchor and orient 0
 *    thickness w
 * DC ox oy fx fy w descr circle (center, 1 point, thickness)
 * $PAD
 * $EndPAD section pads if available
 * $Endmodule
 */
90

91 92 93
/// Get the length of a string constant, at compile time
#define SZ( x )         (sizeof(x)-1)

94
static int NbDraw, NbTrack, NbZone, NbMod, NbNets;
95

96
static const char delims[] = " =\n\r";
97

98

99 100
/** Read a list of segments (Tracks, zones)
 * @return items count or - count if no end block ($End...) found.
101
 */
102 103 104 105
int PCB_BASE_FRAME::ReadListeSegmentDescr( LINE_READER* aReader,
                                           TRACK* insertBeforeMe,
                                           int    StructType,
                                           int    NumSegm )
106
{
107
    int    shape, width, drill, layer, type, flags, net_code;
108 109
    int    tempStartX, tempStartY;
    int    tempEndX, tempEndY;
110
    int    ii = 0;
dickelbeck's avatar
dickelbeck committed
111

112
    TRACK* newTrack;
113

114
    while( aReader->ReadLine() )
115
    {
116 117 118
        char*           line = aReader->Line();
        int             makeType;
        unsigned long   timeStamp;
dickelbeck's avatar
dickelbeck committed
119

120
        if( line[0] == '$' )
121
        {
122
            return ii;      // end of segmentlist: OK
123 124
        }

125 126 127 128 129
        int arg_count = sscanf( line + 2, " %d %d %d %d %d %d %d", &shape,
                                &tempStartX, &tempStartY,
                                &tempEndX, &tempEndY, &width,
                                &drill );

dickelbeck's avatar
dickelbeck committed
130
        // Read the 2nd line to determine the exact type, one of:
131 132 133
        // PCB_TRACE_T, PCB_VIA_T, or PCB_ZONE_T.  The type field in 2nd line
        // differentiates between PCB_TRACE_T and PCB_VIA_T.  With virtual
        // functions in use, it is critical to instantiate the PCB_VIA_T
134
        // exactly.
135
        if( !aReader->ReadLine() )
dickelbeck's avatar
dickelbeck committed
136
            break;
dickelbeck's avatar
dickelbeck committed
137

138 139 140
        line = aReader->Line();

        if( line[0] == '$' )
dickelbeck's avatar
dickelbeck committed
141 142 143
            break;

        // parse the 2nd line first to determine the type of object
144
        sscanf( line + 2, " %d %d %d %lX %X", &layer, &type, &net_code,
dickelbeck's avatar
dickelbeck committed
145 146
                &timeStamp, &flags );

147 148
        if( StructType==PCB_TRACE_T && type==1 )
            makeType = PCB_VIA_T;
dickelbeck's avatar
dickelbeck committed
149 150
        else
            makeType = StructType;
dickelbeck's avatar
dickelbeck committed
151

dickelbeck's avatar
dickelbeck committed
152
        switch( makeType )
153 154
        {
        default:
155
        case PCB_TRACE_T:
156 157
            newTrack = new TRACK( GetBoard() );
            GetBoard()->m_Track.Insert( newTrack, insertBeforeMe );
158 159
            break;

160
        case PCB_VIA_T:
161 162
            newTrack = new SEGVIA( GetBoard() );
            GetBoard()->m_Track.Insert( newTrack, insertBeforeMe );
163 164
            break;

165
        case PCB_ZONE_T:     // this is now deprecated, but exist in old boards
166
            newTrack = new SEGZONE( GetBoard() );
167
            GetBoard()->m_Zone.Insert( (SEGZONE*) newTrack, (SEGZONE*) insertBeforeMe );
168 169 170
            break;
        }

Dick Hollenbeck's avatar
Dick Hollenbeck committed
171
        newTrack->SetTimeStamp( timeStamp );
172

173 174 175 176
        newTrack->m_Start.x = tempStartX;
        newTrack->m_Start.y = tempStartY;
        newTrack->m_End.x = tempEndX;
        newTrack->m_End.y = tempEndY;
177

178 179
        newTrack->m_Width = width;
        newTrack->m_Shape = shape;
g_harland's avatar
g_harland committed
180

181
        if( arg_count < 7 || drill <= 0 )
182
            newTrack->SetDrillDefault();
dickelbeck's avatar
dickelbeck committed
183
        else
Dick Hollenbeck's avatar
Dick Hollenbeck committed
184
            newTrack->SetDrill( drill );
185

186
        newTrack->SetLayer( layer );
charras's avatar
charras committed
187

188
        if( makeType == PCB_VIA_T ) // Ensure layers are OK when possible:
189
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
190
            if( newTrack->GetShape() == VIA_THROUGH )
191
                ( (SEGVIA*) newTrack )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK );
charras's avatar
charras committed
192 193
        }

194 195
        newTrack->SetNet( net_code );
        newTrack->SetState( flags, ON );
196 197 198 199 200
    }

    DisplayError( this, _( "Error: Unexpected end of file !" ) );
    return -ii;
}
201 202


203
int PCB_BASE_FRAME::ReadGeneralDescrPcb( LINE_READER* aReader )
204
{
205
    while( aReader->ReadLine() )
206
    {
207 208
        char* line = aReader->Line();
        char* data = strtok( line, delims );
209

210 211 212
        if( strnicmp( data, "$EndGENERAL", 10 ) == 0 )
            break;

213 214
        if( stricmp( data, "EnabledLayers" ) == 0 )
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
215
            int enabledLayers = 0;
216 217

            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
218
            sscanf( data, "%X", &enabledLayers );
219

220
            // layer usage
Dick Hollenbeck's avatar
Dick Hollenbeck committed
221
            GetBoard()->SetEnabledLayers( enabledLayers );
222 223

            // layer visibility equals layer usage, unless overridden later via "VisibleLayers"
Dick Hollenbeck's avatar
Dick Hollenbeck committed
224
            GetBoard()->SetVisibleLayers( enabledLayers );
225 226 227
            continue;
        }

228 229 230 231 232 233 234 235 236 237 238
        if( stricmp( data, "VisibleLayers" ) == 0 )
        {
            int visibleLayers = -1;

            data = strtok( NULL, delims );
            sscanf( data, "%X", &visibleLayers );

            GetBoard()->SetVisibleLayers( visibleLayers );
            continue;
        }

239 240 241
        if( strncmp( data, "Ly", 2 ) == 0 )    // Old format for Layer count
        {
            int Masque_Layer = 1, ii;
242 243

            data = strtok( NULL, delims );
244 245 246
            sscanf( data, "%X", &Masque_Layer );

            // Setup layer count
charras's avatar
charras committed
247
            int layer_count = 0;
248

249 250 251
            for( ii = 0; ii < NB_COPPER_LAYERS; ii++ )
            {
                if( Masque_Layer & 1 )
charras's avatar
charras committed
252
                    layer_count++;
253

254 255
                Masque_Layer >>= 1;
            }
256

257
            GetBoard()->SetCopperLayerCount( layer_count );
258 259 260

            continue;
        }
261

262
        if( stricmp( data, "BoardThickness" ) == 0 )
263
        {
264
            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
265
            GetBoard()->GetDesignSettings().m_BoardThickness = atoi( data );
266 267
            continue;
        }
268 269 270

        if( strnicmp( data, "Links", 5 ) == 0 )
        {
271
            // Info only, do nothing
272 273 274 275 276
            continue;
        }

        if( strnicmp( data, "NoConn", 6 ) == 0 )
        {
277
            data = strtok( NULL, delims );
278
            GetBoard()->m_NbNoconnect = atoi( data );
279 280 281 282 283
            continue;
        }

        if( strnicmp( data, "Di", 2 ) == 0 )
        {
284
            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
285
            int x1 = atoi( data );
286 287

            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
288
            int y1 = atoi( data );
289 290

            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
291
            int x2 = atoi( data );
292 293

            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
294 295
            int y2 = atoi( data );

296
            EDA_RECT bbbox( wxPoint( x1, y1 ), wxSize( x2-x1, y2-y1 ) );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
297 298

            GetBoard()->SetBoundingBox( bbbox );
299

300 301 302
            continue;
        }

303
        // Read the number of segments of type DRAW, TRACK, ZONE
304 305
        if( stricmp( data, "Ndraw" ) == 0 )
        {
306
            data   = strtok( NULL, delims );
307
            NbDraw = atoi( data );
308 309 310 311 312
            continue;
        }

        if( stricmp( data, "Ntrack" ) == 0 )
        {
313
            data    = strtok( NULL, delims );
314 315 316 317 318 319
            NbTrack = atoi( data );
            continue;
        }

        if( stricmp( data, "Nzone" ) == 0 )
        {
320
            data   = strtok( NULL, delims );
321 322 323 324 325 326
            NbZone = atoi( data );
            continue;
        }

        if( stricmp( data, "Nmodule" ) == 0 )
        {
327
            data  = strtok( NULL, delims );
328 329 330 331 332 333
            NbMod = atoi( data );
            continue;
        }

        if( stricmp( data, "Nnets" ) == 0 )
        {
334
            data   = strtok( NULL, delims );
335 336 337 338 339 340
            NbNets = atoi( data );
            continue;
        }
    }

    return 1;
341 342 343
}


344
int PCB_BASE_FRAME::ReadSetup( LINE_READER* aReader )
345
{
346
    char*     data;
347

348
    NETCLASS* netclass_default = GetBoard()->m_NetClasses.GetDefault();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
349
    ZONE_SETTINGS zoneInfo = GetBoard()->GetZoneSettings();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
350
    BOARD_DESIGN_SETTINGS bds = GetBoard()->GetDesignSettings();
351

352
    while( aReader->ReadLine() )
353
    {
354
        char* line = aReader->Line();
355

356
        if( strnicmp( line, "PcbPlotParams", 13 ) == 0 )
357
        {
358
            PCB_PLOT_PARAMS plot_opts;
359
            PCB_PLOT_PARAMS_PARSER parser( &line[13], aReader->GetSource() );
360 361 362

            try
            {
363
                plot_opts.Parse( &parser );
364 365 366 367
            }
            catch( IO_ERROR& e )
            {
                wxString msg;
368
                msg.Printf( _( "Error reading PcbPlotParams from %s:\n%s" ),
369 370
                            aReader->GetSource().GetData(),
                            e.errorText.GetData() );
371
                wxMessageBox( msg, _( "Open Board File" ), wxOK | wxICON_ERROR );
372 373
            }

374 375
            GetBoard()->SetPlotOptions( plot_opts );

376 377 378
            continue;
        }

379 380
        strtok( line, delims );
        data = strtok( NULL, delims );
381

382
        if( stricmp( line, "$EndSETUP" ) == 0 )
383
        {
384 385 386 387 388 389 390 391 392
            // 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.
            //
393
            // @todo: I expect that at some point we can remove said global
394 395 396 397 398
            //        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.
399 400
            GetBoard()->m_NetClasses.GetDefault()->SetParams();

401 402
            GetBoard()->SetDesignSettings( bds );

Dick Hollenbeck's avatar
Dick Hollenbeck committed
403 404
            GetBoard()->SetZoneSettings( zoneInfo );

405 406 407
            return 0;
        }

408
        if( stricmp( line, "AuxiliaryAxisOrg" ) == 0 )
409 410 411
        {
            int gx = 0, gy = 0;
            gx   = atoi( data );
412
            data = strtok( NULL, delims );
413

414 415
            if( data )
                gy = atoi( data );
416

417
            SetOriginAxisPosition( wxPoint( gx, gy ) );
418 419
            continue;
        }
420

421
#ifdef PCBNEW
422

423
        if( stricmp( line, "Layers" ) == 0 )
424 425 426
        {
            int tmp;
            sscanf( data, "%d", &tmp );
427
            GetBoard()->SetCopperLayerCount( tmp );
428 429 430
            continue;
        }

431
        const int LAYERKEYZ = sizeof("Layer[") - 1;
dickelbeck's avatar
dickelbeck committed
432

433
        if( strncmp( line, "Layer[", LAYERKEYZ ) == 0 )
dickelbeck's avatar
dickelbeck committed
434
        {
dickelbeck's avatar
dickelbeck committed
435
            // parse:
436
            // Layer[n]  <a_Layer_name_with_no_spaces> <LAYER_T>
dickelbeck's avatar
dickelbeck committed
437

438
            char* cp    = line + LAYERKEYZ;
439
            int   layer = atoi( cp );
dickelbeck's avatar
dickelbeck committed
440

dickelbeck's avatar
dickelbeck committed
441 442
            if( data )
            {
443
                wxString layerName = FROM_UTF8( data );
444
                GetBoard()->SetLayerName( layer, layerName );
dickelbeck's avatar
dickelbeck committed
445

446
                data = strtok( NULL, " \n\r" );
447

dickelbeck's avatar
dickelbeck committed
448 449 450
                if( data )
                {
                    LAYER_T type = LAYER::ParseType( data );
451
                    GetBoard()->SetLayerType( layer, type );
dickelbeck's avatar
dickelbeck committed
452 453
                }
            }
454

dickelbeck's avatar
dickelbeck committed
455 456 457
            continue;
        }

458
        if( stricmp( line, "TrackWidth" ) == 0 )    // no more used
459 460 461 462
        {
            continue;
        }

463
        if( stricmp( line, "TrackWidthList" ) == 0 )
464
        {
465 466
            int tmp = atoi( data );
            GetBoard()->m_TrackWidthList.push_back( tmp );
467 468 469
            continue;
        }

470
        if( stricmp( line, "TrackClearence" ) == 0 )
471
        {
472
            netclass_default->SetClearance( atoi( data ) );
473 474 475
            continue;
        }

476
        if( stricmp( line, "TrackMinWidth" ) == 0 )
477
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
478
            bds.m_TrackMinWidth = atoi( data );
479 480
            continue;
        }
481

482
        if( stricmp( line, "ZoneClearence" ) == 0 )
483
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
484
            zoneInfo.m_ZoneClearance = atoi( data );
485 486 487
            continue;
        }

488
        if( stricmp( line, "DrawSegmWidth" ) == 0 )
489
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
490
            bds.m_DrawSegmentWidth = atoi( data );
491 492 493
            continue;
        }

494
        if( stricmp( line, "EdgeSegmWidth" ) == 0 )
495
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
496
            bds.m_EdgeSegmentWidth = atoi( data );
497 498 499
            continue;
        }

500
        if( stricmp( line, "ViaSize" ) == 0 )    // no more used
501 502 503 504
        {
            continue;
        }

505
        if( stricmp( line, "ViaMinSize" ) == 0 )
506
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
507
            bds.m_ViasMinSize = atoi( data );
508 509
            continue;
        }
510

511
        if( stricmp( line, "MicroViaSize" ) == 0 )  // Not used
512 513 514 515
        {
            continue;
        }

516
        if( stricmp( line, "MicroViaMinSize" ) == 0 )
517
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
518
            bds.m_MicroViasMinSize = atoi( data );
519 520 521
            continue;
        }

522
        if( stricmp( line, "ViaSizeList" ) == 0 )
523
        {
524
            int           tmp = atoi( data );
525
            VIA_DIMENSION via_dim;
526
            via_dim.m_Diameter = tmp;
527
            data = strtok( NULL, " \n\r" );
528

529 530
            if( data )
            {
531 532
                tmp = atoi( data );
                via_dim.m_Drill = tmp > 0 ? tmp : 0;
533
            }
534

535
            GetBoard()->m_ViasDimensionsList.push_back( via_dim );
536 537 538
            continue;
        }

539
        if( stricmp( line, "ViaDrill" ) == 0 )
540
        {
541 542
            int diameter = atoi( data );
            netclass_default->SetViaDrill( diameter );
543 544 545
            continue;
        }

546
        if( stricmp( line, "ViaMinDrill" ) == 0 )
547
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
548
            bds.m_ViasMinDrill = atoi( data );
549 550 551
            continue;
        }

552
        if( stricmp( line, "MicroViaDrill" ) == 0 )
553
        {
554 555
            int diameter = atoi( data );
            netclass_default->SetuViaDrill( diameter );
556 557 558
            continue;
        }

559
        if( stricmp( line, "MicroViaMinDrill" ) == 0 )
560
        {
561
            int diameter = atoi( data );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
562
            bds.m_MicroViasMinDrill = diameter;
563 564 565
            continue;
        }

566
        if( stricmp( line, "MicroViasAllowed" ) == 0 )
567
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
568
            bds.m_MicroViasAllowed = atoi( data );
569 570 571
            continue;
        }

572
        if( stricmp( line, "TextPcbWidth" ) == 0 )
573
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
574
            bds.m_PcbTextWidth = atoi( data );
575 576 577
            continue;
        }

578
        if( stricmp( line, "TextPcbSize" ) == 0 )
579
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
580
            bds.m_PcbTextSize.x = atoi( data );
581
            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
582
            bds.m_PcbTextSize.y = atoi( data );
583 584 585
            continue;
        }

586
        if( stricmp( line, "EdgeModWidth" ) == 0 )
587
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
588
            bds.m_ModuleSegmentWidth = atoi( data );
589 590 591
            continue;
        }

592
        if( stricmp( line, "TextModWidth" ) == 0 )
593
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
594
            bds.m_ModuleTextWidth = atoi( data );
595 596 597
            continue;
        }

598
        if( stricmp( line, "TextModSize" ) == 0 )
599
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
600
            bds.m_ModuleTextSize.x = atoi( data );
601
            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
602
            bds.m_ModuleTextSize.y = atoi( data );
603 604 605
            continue;
        }

606
        if( stricmp( line, "PadSize" ) == 0 )
607
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
608
            int x = atoi( data );
609
            data = strtok( NULL, delims );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
610 611
            int y = atoi( data );
            bds.m_Pad_Master.SetSize( wxSize( x, y ) );
612 613 614
            continue;
        }

615
        if( stricmp( line, "PadDrill" ) == 0 )
616
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
617 618
            int sz = atoi( data );
            bds.m_Pad_Master.SetSize( wxSize( sz, sz ) );
619 620
            continue;
        }
621

622
        if( stricmp( line, "Pad2MaskClearance" ) == 0 )
charras's avatar
charras committed
623
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
624
            bds.m_SolderMaskMargin = atoi( data );
charras's avatar
charras committed
625 626
            continue;
        }
627

628
        if( stricmp( line, "Pad2PasteClearance" ) == 0 )
629
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
630
            bds.m_SolderPasteMargin = atoi( data );
631 632
            continue;
        }
633

634
        if( stricmp( line, "Pad2PasteClearanceRatio" ) == 0 )
635
        {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
636
            bds.m_SolderPasteMarginRatio = atof( data );
637 638 639
            continue;
        }

640
        if( stricmp( line, "GridOrigin" ) == 0 )
641 642 643 644 645
        {
            int Ox = 0;
            int Oy = 0;

            Ox = atoi( data );
646
            data = strtok( NULL, delims );
647 648 649 650 651 652

            if ( data )
                Oy = atoi( data );

            GetScreen()->m_GridOrigin.x = Ox;
            GetScreen()->m_GridOrigin.y = Oy;
653 654
            continue;
        }
655

656 657 658 659
        if( stricmp( line, "VisibleElements" ) == 0 )
        {
            int visibleElements = strtoul( data, 0, 16 );
            bds.SetVisibleElements( visibleElements );
660 661
            continue;
        }
662
#endif
663

664 665
    }

charras's avatar
charras committed
666 667 668
    /* 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
669
     */
670 671 672 673
    sort( GetBoard()->m_ViasDimensionsList.begin() + 1, GetBoard()->m_ViasDimensionsList.end() );
    sort( GetBoard()->m_TrackWidthList.begin() + 1, GetBoard()->m_TrackWidthList.end() );

    for( unsigned ii = 1; ii < GetBoard()->m_ViasDimensionsList.size() - 1; ii++ )
charras's avatar
charras committed
674
    {
675
        if( GetBoard()->m_ViasDimensionsList[ii] == GetBoard()->m_ViasDimensionsList[ii + 1] )
charras's avatar
charras committed
676
        {
677
            GetBoard()->m_ViasDimensionsList.erase( GetBoard()->m_ViasDimensionsList.begin() + ii );
charras's avatar
charras committed
678 679 680
            ii--;
        }
    }
681 682

    for( unsigned ii = 1; ii < GetBoard()->m_TrackWidthList.size() - 1; ii++ )
charras's avatar
charras committed
683
    {
684
        if( GetBoard()->m_TrackWidthList[ii] == GetBoard()->m_TrackWidthList[ii + 1] )
charras's avatar
charras committed
685
        {
686
            GetBoard()->m_TrackWidthList.erase( GetBoard()->m_TrackWidthList.begin() + ii );
charras's avatar
charras committed
687 688 689 690
            ii--;
        }
    }

691
    return 1;
692 693 694 695
}


#ifdef PCBNEW
696 697

static int WriteSetup( FILE* aFile, PCB_EDIT_FRAME* aFrame, BOARD* aBoard )
698
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
699
    const BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
700
    NETCLASS* netclass_default = aBoard->m_NetClasses.GetDefault();
701
    char      text[1024];
702

dickelbeck's avatar
dickelbeck committed
703
    fprintf( aFile, "$SETUP\n" );
704
    sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT );
705
    fprintf( aFile, "%s", text );
706

dickelbeck's avatar
dickelbeck committed
707
    fprintf( aFile, "Layers %d\n", aBoard->GetCopperLayerCount() );
708

709
    unsigned layerMask = g_TabAllCopperLayerMask[aBoard->GetCopperLayerCount() - 1];
710

711
    for( int layer = 0; layerMask; ++layer, layerMask >>= 1 )
dickelbeck's avatar
dickelbeck committed
712
    {
713 714 715
        if( layerMask & 1 )
        {
            fprintf( aFile, "Layer[%d] %s %s\n", layer,
716
                     TO_UTF8( aBoard->GetLayerName( layer ) ),
717
                     LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
718
        }
dickelbeck's avatar
dickelbeck committed
719 720
    }

721
    // Save current default track width, for compatibility with older Pcbnew version;
722
    fprintf( aFile, "TrackWidth %d\n", aBoard->GetCurrentTrackWidth() );
723

724
    // Save custom tracks width list (the first is not saved here: this is the netclass value
charras's avatar
charras committed
725
    for( unsigned ii = 1; ii < aBoard->m_TrackWidthList.size(); ii++ )
726
        fprintf( aFile, "TrackWidthList %d\n", aBoard->m_TrackWidthList[ii] );
727

728

729
    fprintf( aFile, "TrackClearence %d\n", netclass_default->GetClearance() );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
730
    fprintf( aFile, "ZoneClearence %d\n", aBoard->GetZoneSettings().m_ZoneClearance );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
731
    fprintf( aFile, "TrackMinWidth %d\n", bds.m_TrackMinWidth );
dickelbeck's avatar
dickelbeck committed
732

Dick Hollenbeck's avatar
Dick Hollenbeck committed
733 734
    fprintf( aFile, "DrawSegmWidth %d\n", bds.m_DrawSegmentWidth );
    fprintf( aFile, "EdgeSegmWidth %d\n", bds.m_EdgeSegmentWidth );
735

736
    // Save current default via size, for compatibility with older Pcbnew version;
737 738
    fprintf( aFile, "ViaSize %d\n", netclass_default->GetViaDiameter() );
    fprintf( aFile, "ViaDrill %d\n", netclass_default->GetViaDrill() );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
739 740
    fprintf( aFile, "ViaMinSize %d\n", bds.m_ViasMinSize );
    fprintf( aFile, "ViaMinDrill %d\n", bds.m_ViasMinDrill );
741

742 743
    // Save custom vias diameters list (the first is not saved here: this is
    // the netclass value
744
    for( unsigned ii = 1; ii < aBoard->m_ViasDimensionsList.size(); ii++ )
745 746 747
        fprintf( aFile, "ViaSizeList %d %d\n",
                 aBoard->m_ViasDimensionsList[ii].m_Diameter,
                 aBoard->m_ViasDimensionsList[ii].m_Drill );
748

749
    // for old versions compatibility:
750 751
    fprintf( aFile, "MicroViaSize %d\n", netclass_default->GetuViaDiameter() );
    fprintf( aFile, "MicroViaDrill %d\n", netclass_default->GetuViaDrill() );
752 753
    fprintf( aFile,
             "MicroViasAllowed %d\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
754
             bds.m_MicroViasAllowed );
755
    fprintf( aFile,
756
             "MicroViaMinSize %d\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
757
             bds.m_MicroViasMinSize );
758
    fprintf( aFile,
759
             "MicroViaMinDrill %d\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
760
             bds.m_MicroViasMinDrill );
761

Dick Hollenbeck's avatar
Dick Hollenbeck committed
762
    fprintf( aFile, "TextPcbWidth %d\n", bds.m_PcbTextWidth );
763 764
    fprintf( aFile,
             "TextPcbSize %d %d\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
765 766 767 768 769 770 771 772 773 774 775
             bds.m_PcbTextSize.x,
             bds.m_PcbTextSize.y );

    fprintf( aFile, "EdgeModWidth %d\n", bds.m_ModuleSegmentWidth );
    fprintf( aFile, "TextModSize %d %d\n", bds.m_ModuleTextSize.x, bds.m_ModuleTextSize.y );
    fprintf( aFile, "TextModWidth %d\n", bds.m_ModuleTextWidth );

    fprintf( aFile, "PadSize %d %d\n", bds.m_Pad_Master.GetSize().x,
                                       bds.m_Pad_Master.GetSize().y );

    fprintf( aFile, "PadDrill %d\n", bds.m_Pad_Master.GetDrillSize().x );
776 777
    fprintf( aFile,
             "Pad2MaskClearance %d\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
778
             bds.m_SolderMaskMargin );
779

Dick Hollenbeck's avatar
Dick Hollenbeck committed
780
    if( bds.m_SolderPasteMargin != 0 )
781 782
        fprintf( aFile,
                 "Pad2PasteClearance %d\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
783
                 bds.m_SolderPasteMargin );
784

Dick Hollenbeck's avatar
Dick Hollenbeck committed
785
    if( bds.m_SolderPasteMarginRatio != 0 )
786 787
        fprintf( aFile,
                 "Pad2PasteClearanceRatio %g\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
788
                 bds.m_SolderPasteMarginRatio );
dickelbeck's avatar
dickelbeck committed
789

790 791 792 793 794 795 796 797
    if ( aFrame->GetScreen()->m_GridOrigin != wxPoint( 0, 0 ) )
    {
        fprintf( aFile,
                 "GridOrigin %d %d\n",
                 aFrame->GetScreen()->m_GridOrigin.x,
                 aFrame->GetScreen()->m_GridOrigin.y );
    }

798 799
    fprintf( aFile,
             "AuxiliaryAxisOrg %d %d\n",
800 801
             aFrame->GetOriginAxisPosition().x,
             aFrame->GetOriginAxisPosition().y );
dickelbeck's avatar
dickelbeck committed
802

803 804
    fprintf( aFile, "VisibleElements %X\n", bds.GetVisibleElements() );

805 806
    STRING_FORMATTER sf;

807
    aBoard->GetPlotOptions().Format( &sf, 0 );
808

809
    wxString record = FROM_UTF8( sf.GetString().c_str() );
810 811
    record.Replace( wxT("\n"), wxT(""), true );
    record.Replace( wxT("  "), wxT(" "), true);
812
    fprintf( aFile, "PcbPlotParams %s\n", TO_UTF8( record ) );
dickelbeck's avatar
dickelbeck committed
813
    fprintf( aFile, "$EndSETUP\n\n" );
814
    return 1;
815
}
816

817

818 819 820
#endif


821
bool PCB_EDIT_FRAME::WriteGeneralDescrPcb( FILE* File )
822
{
823 824
    EDA_ITEM* PtStruct = GetBoard()->m_Modules;
    int       NbModules, NbDrawItem, NbLayers;
825

826
    // Write copper layer count
827
    NbLayers = GetBoard()->GetCopperLayerCount();
828
    fprintf( File, "$GENERAL\n" );
829
    fprintf( File, "encoding utf-8\n");
830 831
    fprintf( File, "LayerCount %d\n", NbLayers );

832 833 834 835 836
    // 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 );
837

838
    fprintf( File, "EnabledLayers %08X\n", GetBoard()->GetEnabledLayers() );
839 840 841 842

    if( GetBoard()->GetEnabledLayers() != GetBoard()->GetVisibleLayers() )
        fprintf( File, "VisibleLayers %08X\n", GetBoard()->GetVisibleLayers() );

843
    fprintf( File, "Links %d\n", GetBoard()->GetRatsnestsCount() );
844
    fprintf( File, "NoConn %d\n", GetBoard()->m_NbNoconnect );
845

846
    // Write board's bounding box info
Dick Hollenbeck's avatar
Dick Hollenbeck committed
847
    EDA_RECT bbbox = GetBoard()->ComputeBoundingBox();
848
    fprintf( File, "Di %d %d %d %d\n",
Dick Hollenbeck's avatar
Dick Hollenbeck committed
849 850 851 852
             bbbox.GetX(),
             bbbox.GetY(),
             bbbox.GetRight(),
             bbbox.GetBottom() );
853

854 855
    // Write segment count for footprints, drawings, track and zones
    // Calculate the footprint count
856
    for( NbModules = 0; PtStruct != NULL; PtStruct = PtStruct->Next() )
857 858
        NbModules++;

859
    PtStruct = GetBoard()->m_Drawings; NbDrawItem = 0;
860

861
    for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
862 863 864
        NbDrawItem++;

    fprintf( File, "Ndraw %d\n", NbDrawItem );
865 866
    fprintf( File, "Ntrack %d\n", GetBoard()->GetNumSegmTrack() );
    fprintf( File, "Nzone %d\n", GetBoard()->GetNumSegmZone() );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
867
    fprintf( File, "BoardThickness %d\n", GetBoard()->GetDesignSettings().m_BoardThickness );
868
    fprintf( File, "Nmodule %d\n", NbModules );
869
    fprintf( File, "Nnets %d\n", GetBoard()->GetNetCount() );
870
    fprintf( File, "$EndGENERAL\n\n" );
871
    return true;
872 873
}

874

875 876
/**
 * Function WriteSheetDescr
877
 * Save the page information (size, texts, date ..)
878 879 880
 * @param aPageSettings The page settings to write to \a aFile.
 * @param aTitleBlock The title block information to write to \a aFile.
 * @param aFile An open FILE to write info.
881
 */
882 883
static bool WriteSheetDescr( const PAGE_INFO& aPageSettings, const TITLE_BLOCK& aTitleBlock,
                             FILE* aFile )
884
{
885 886
    fprintf( aFile, "$SHEETDESCR\n" );
    fprintf( aFile, "Sheet %s %d %d%s\n",
887
             TO_UTF8( aPageSettings.GetType() ),
888 889 890
             aPageSettings.GetWidthMils(),
             aPageSettings.GetHeightMils(),
             !aPageSettings.IsCustom() && aPageSettings.IsPortrait() ?
891 892
                " portrait" : ""
             );
893

894 895 896 897 898 899 900 901
    fprintf( aFile, "Title %s\n",        EscapedUTF8( aTitleBlock.GetTitle() ).c_str() );
    fprintf( aFile, "Date %s\n",         EscapedUTF8( aTitleBlock.GetDate() ).c_str() );
    fprintf( aFile, "Rev %s\n",          EscapedUTF8( aTitleBlock.GetRevision() ).c_str() );
    fprintf( aFile, "Comp %s\n",         EscapedUTF8( aTitleBlock.GetCompany() ).c_str() );
    fprintf( aFile, "Comment1 %s\n",     EscapedUTF8( aTitleBlock.GetComment1() ).c_str() );
    fprintf( aFile, "Comment2 %s\n",     EscapedUTF8( aTitleBlock.GetComment2() ).c_str() );
    fprintf( aFile, "Comment3 %s\n",     EscapedUTF8( aTitleBlock.GetComment3() ).c_str() );
    fprintf( aFile, "Comment4 %s\n",     EscapedUTF8( aTitleBlock.GetComment4() ).c_str() );
902

903
    fprintf( aFile, "$EndSHEETDESCR\n\n" );
904
    return true;
905 906 907
}


Dick Hollenbeck's avatar
Dick Hollenbeck committed
908 909
#if !defined( USE_NEW_PCBNEW_LOAD )

910
static bool ReadSheetDescr( BOARD* aBoard, LINE_READER* aReader )
911
{
912 913
    char        buf[1024];
    TITLE_BLOCK tb;
914

915
    while( aReader->ReadLine() )
916
    {
917
        char* line = aReader->Line();
918

919
        if( strnicmp( line, "$End", 4 ) == 0 )
920 921
        {
            aBoard->SetTitleBlock( tb );
922
            return true;
923
        }
924

925
        if( strnicmp( line, "Sheet", 4 ) == 0 )
926
        {
927 928 929 930 931
            // e.g. "Sheet A3 16535 11700"
            // width and height are in 1/1000th of an inch, always

            PAGE_INFO   page;
            char*       sname  = strtok( line + SZ( "Sheet" ), delims );
932

933
            if( sname )
934
            {
935 936
                wxString wname = FROM_UTF8( sname );
                if( !page.SetType( wname ) )
937
                {
938
                    /* this entire file is soon to be deleted.
939 940 941
                    m_error.Printf( _( "Unknown sheet type '%s' on line:%d" ),
                                wname.GetData(), m_reader->LineNumber() );
                    THROW_IO_ERROR( m_error );
942
                    */
943
                }
944

945 946 947 948 949
                char*   width  = strtok( NULL, delims );
                char*   height = strtok( NULL, delims );
                char*   orient = strtok( NULL, delims );

                // only keep width and height if page size is "User"
950
                if( wname == PAGE_INFO::Custom )
951 952 953 954 955
                {
                    if( width && height )
                    {
                        // legacy disk file describes paper in mils
                        // (1/1000th of an inch)
956 957
                        int w = atoi( width );
                        int h = atoi( height );
958

959 960
                        page.SetWidthMils(  w );
                        page.SetHeightMils( h );
961 962
                    }
                }
963

964 965 966 967 968
                if( orient && !strcmp( orient, "portrait" ) )
                {
                    page.SetPortrait( true );
                }

969
                aBoard->SetPageSettings( page );
970 971 972 973 974
            }

            continue;
        }

975
        if( strnicmp( line, "Title", 2 ) == 0 )
976
        {
977
            ReadDelimitedText( buf, line, 256 );
978
            tb.SetTitle( FROM_UTF8( buf ) );
979 980 981
            continue;
        }

982
        if( strnicmp( line, "Date", 2 ) == 0 )
983
        {
984
            ReadDelimitedText( buf, line, 256 );
985
            tb.SetDate( FROM_UTF8( buf ) );
986 987 988
            continue;
        }

989
        if( strnicmp( line, "Rev", 2 ) == 0 )
990
        {
991
            ReadDelimitedText( buf, line, 256 );
992
            tb.SetRevision( FROM_UTF8( buf ) );
993 994 995
            continue;
        }

996
        if( strnicmp( line, "Comp", 4 ) == 0 )
997
        {
998
            ReadDelimitedText( buf, line, 256 );
999
            tb.SetCompany( FROM_UTF8( buf ) );
1000 1001 1002
            continue;
        }

1003
        if( strnicmp( line, "Comment1", 8 ) == 0 )
1004
        {
1005
            ReadDelimitedText( buf, line, 256 );
1006
            tb.SetComment1( FROM_UTF8( buf ) );
1007 1008 1009
            continue;
        }

1010
        if( strnicmp( line, "Comment2", 8 ) == 0 )
1011
        {
1012
            ReadDelimitedText( buf, line, 256 );
1013
            tb.SetComment2( FROM_UTF8( buf ) );
1014 1015 1016
            continue;
        }

1017
        if( strnicmp( line, "Comment3", 8 ) == 0 )
1018
        {
1019
            ReadDelimitedText( buf, line, 256 );
1020
            tb.SetComment3( FROM_UTF8( buf ) );
1021 1022 1023
            continue;
        }

1024
        if( strnicmp( line, "Comment4", 8 ) == 0 )
1025
        {
1026
            ReadDelimitedText( buf, line, 256 );
1027
            tb.SetComment4( FROM_UTF8( buf ) );
1028 1029 1030 1031
            continue;
        }
    }

1032
    return false;
1033 1034
}

1035

1036
int PCB_EDIT_FRAME::ReadPcbFile( LINE_READER* aReader, bool Append )
1037
{
1038
    wxBusyCursor dummy;
1039

1040 1041
    // Switch the locale to standard C (needed to read floating point numbers
    // like 1.3)
dickelbeck's avatar
dickelbeck committed
1042 1043
    SetLocaleTo_C_standard();

1044
    BOARD* board = GetBoard();
1045

dickelbeck's avatar
dickelbeck committed
1046 1047
    board->m_Status_Pcb = 0;
    board->m_NetClasses.Clear();
1048

1049
    // Put a dollar sign in front, and test for a specific length of characters
1050 1051
    // The -1 is to omit the trailing \0 which is included in sizeof() on a
    // string.
1052
#define TESTLINE( x ) (strncmp( line, "$" x, sizeof("$" x) - 1 ) == 0)
1053

1054
    while( aReader->ReadLine() )
1055
    {
1056 1057
        char* line = aReader->Line();

1058
        // put the more frequent ones at the top
1059

1060
        if( TESTLINE( "MODULE" ) )
1061
        {
1062 1063 1064
            MODULE* module = new MODULE( board );
            board->Add( module, ADD_APPEND );
            module->ReadDescr( aReader );
1065 1066 1067
            continue;
        }

1068
        if( TESTLINE( "DRAWSEGMENT" ) )
1069
        {
1070 1071 1072
            DRAWSEGMENT* dseg = new DRAWSEGMENT( board );
            board->Add( dseg, ADD_APPEND );
            dseg->ReadDrawSegmentDescr( aReader );
1073 1074 1075
            continue;
        }

1076
        if( TESTLINE( "EQUIPOT" ) )
1077
        {
dickelbeck's avatar
dickelbeck committed
1078
            NETINFO_ITEM* net = new NETINFO_ITEM( board );
1079
            board->m_NetInfo.AppendNet( net );
1080
            net->ReadDescr( aReader );
1081 1082 1083
            continue;
        }

1084
        if( TESTLINE( "TEXTPCB" ) )
1085
        {
1086 1087
            TEXTE_PCB* pcbtxt = new TEXTE_PCB( board );
            board->Add( pcbtxt, ADD_APPEND );
1088
            pcbtxt->ReadTextePcbDescr( aReader );
1089 1090 1091
            continue;
        }

1092
        if( TESTLINE( "TRACK" ) )
1093
        {
1094

1095 1096
#ifdef PCBNEW
            TRACK* insertBeforeMe = Append ? NULL : board->m_Track.GetFirst();
1097
            ReadListeSegmentDescr( aReader, insertBeforeMe, PCB_TRACE_T, NbTrack );
1098
#endif
1099

dickelbeck's avatar
dickelbeck committed
1100
            continue;
dickelbeck's avatar
dickelbeck committed
1101
        }
1102

1103
        if( TESTLINE( "NCLASS" ) )
1104
        {
1105 1106
            // create an empty NETCLASS without a name.
            NETCLASS* netclass = new NETCLASS( board, wxEmptyString );
1107

1108
            // fill it from the *.brd file, and establish its name.
1109
            netclass->ReadDescr( aReader );
1110

1111 1112 1113 1114 1115 1116 1117 1118 1119
            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.
            }
1120 1121 1122 1123

            continue;
        }

1124
        if( TESTLINE( "CZONE_OUTLINE" ) )
1125
        {
1126
            ZONE_CONTAINER* zone_descr = new ZONE_CONTAINER( board );
1127
            zone_descr->ReadDescr( aReader );
1128 1129 1130 1131
            if( zone_descr->GetNumCorners() > 2 )       // should always occur
                board->Add( zone_descr );
            else
                delete zone_descr;
1132 1133 1134
            continue;
        }

1135
        if( TESTLINE( "COTATION" ) )
1136
        {
1137 1138 1139
            DIMENSION* dim = new DIMENSION( board );
            board->Add( dim, ADD_APPEND );
            dim->ReadDimensionDescr( aReader );
1140 1141 1142
            continue;
        }

1143
        if( TESTLINE( "PCB_TARGET" ) || TESTLINE( "MIREPCB" ) )
1144
        {
1145 1146 1147
            PCB_TARGET* t = new PCB_TARGET( board );
            board->Add( t, ADD_APPEND );
            t->ReadMirePcbDescr( aReader );
1148 1149 1150
            continue;
        }

1151
        if( TESTLINE( "ZONE" ) )
1152
        {
1153
#ifdef PCBNEW
1154 1155
            SEGZONE* insertBeforeMe = Append ? NULL : board->m_Zone.GetFirst();

1156
            ReadListeSegmentDescr( aReader, insertBeforeMe, PCB_ZONE_T, NbZone );
1157
#endif
1158 1159 1160
            continue;
        }

1161
        if( TESTLINE( "GENERAL" ) )
1162
        {
1163
            ReadGeneralDescrPcb( aReader );
1164 1165
            continue;
        }
1166

1167 1168
        if( TESTLINE( "SHEETDESCR" ) )
        {
1169
            ReadSheetDescr( board, aReader );
1170 1171
            continue;
        }
1172 1173 1174 1175 1176

        if( TESTLINE( "SETUP" ) )
        {
            if( !Append )
            {
1177
                ReadSetup( aReader );
1178 1179 1180
            }
            else
            {
1181 1182
                while( aReader->ReadLine() )
                {
1183
                    line = aReader->Line();
1184

1185 1186
                    if( TESTLINE( "EndSETUP" ) )
                        break;
1187
                }
1188
            }
1189

1190 1191 1192 1193 1194
            continue;
        }

        if( TESTLINE( "EndPCB" ) )
            break;
1195
    }
1196

1197
    SetLocaleTo_Default();       // revert to the current  locale
1198

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1199
    board->m_Status_Pcb = 0;
1200

1201
    // Build the net info list
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1202
    board->BuildListOfNets();
1203

1204
    board->SynchronizeNetsAndNetClasses();
1205

1206
    SetStatusText( wxEmptyString );
1207
    BestZoom();
1208
    return 1;
1209 1210
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
1211 1212
#endif

1213 1214

#ifdef PCBNEW
1215

1216 1217 1218 1219
/* Save the current PCB in ASCII format
 * Returns
 * 1 if OK
 * 0 if error occurs saving file.
1220
 */
1221
int PCB_EDIT_FRAME::SavePcbFormatAscii( FILE* aFile )
1222
{
1223
    bool rc;
dickelbeck's avatar
dickelbeck committed
1224

1225
    GetBoard()->m_Status_Pcb &= ~CONNEXION_OK;
1226

dickelbeck's avatar
dickelbeck committed
1227
    wxBeginBusyCursor();
dickelbeck's avatar
dickelbeck committed
1228

1229 1230
    // Switch the locale to standard C (needed to print floating point numbers
    // like 1.3)
Dick Hollenbeck's avatar
Dick Hollenbeck committed
1231
    LOCALE_IO   toggle;
dickelbeck's avatar
dickelbeck committed
1232

1233
    // Writing file header.
1234
    fprintf( aFile, "PCBNEW-BOARD Version %d date %s\n\n", LEGACY_BOARD_FILE_VERSION,
1235
             TO_UTF8( DateAndTime() ) );
1236
    fprintf( aFile, "# Created by Pcbnew%s\n\n", TO_UTF8( GetBuildVersion() ) );
1237

charras's avatar
charras committed
1238
    GetBoard()->SynchronizeNetsAndNetClasses();
1239

1240 1241
    // Select default Netclass before writing file.
    // Useful to save default values in headers
1242
    GetBoard()->SetCurrentNetClass( GetBoard()->m_NetClasses.GetDefault()->GetName() );
charras's avatar
charras committed
1243

dickelbeck's avatar
dickelbeck committed
1244
    WriteGeneralDescrPcb( aFile );
1245
    WriteSheetDescr( GetBoard()->GetPageSettings(), GetBoard()->GetTitleBlock(), aFile );
1246
    WriteSetup( aFile, this, GetBoard() );
1247

1248
    rc = GetBoard()->Save( aFile );
dickelbeck's avatar
dickelbeck committed
1249

dickelbeck's avatar
dickelbeck committed
1250
    wxEndBusyCursor();
dickelbeck's avatar
dickelbeck committed
1251

dickelbeck's avatar
dickelbeck committed
1252 1253 1254
    if( !rc )
        DisplayError( this, wxT( "Unable to save PCB file" ) );
    else
1255
        SetStatusText( wxEmptyString );
dickelbeck's avatar
dickelbeck committed
1256

dickelbeck's avatar
dickelbeck committed
1257
    return rc;
1258 1259
}

1260
#endif