dialog_build_BOM.cpp 19.8 KB
Newer Older
1 2 3
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
4
 * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */
24

25 26 27
/**
 * @file dialog_build_BOM.cpp
 */
28

29 30 31 32 33 34 35 36
#include <fctsys.h>
#include <appl_wxstruct.h>
#include <confirm.h>
#include <gestfich.h>
#include <kicad_string.h>
#include <class_sch_screen.h>
#include <wxstruct.h>
#include <build_version.h>
37

38 39 40 41 42
#include <netlist.h>
#include <template_fieldnames.h>
#include <sch_component.h>
#include <sch_sheet.h>
#include <class_library.h>
43

44
#include <wx/valgen.h>
45

46
#include <dialog_build_BOM.h>
47
#include <BOM_lister.h>
48 49


50
/* Local variables */
51 52
static bool     s_ListByRef    = true;
static bool     s_ListByValue  = true;
53 54
static bool     s_ListWithSubCmponents;
static bool     s_ListHierarchicalPinByName;
55
static bool     s_ListHierarchicalPinBySheet;
56 57 58
static bool     s_BrowseCreatedList;
static int      s_OutputFormOpt;
static int      s_OutputSeparatorOpt;
59
static bool     s_Add_Location = false;
60
static bool     s_Add_FpField_state = true;
61
static bool     s_Add_DatasheetField_state;
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
static bool     s_Add_F1_state;
static bool     s_Add_F2_state;
static bool     s_Add_F3_state;
static bool     s_Add_F4_state;
static bool     s_Add_F5_state;
static bool     s_Add_F6_state;
static bool     s_Add_F7_state;
static bool     s_Add_F8_state;
static bool     s_Add_Alls_state;
static char     s_ExportSeparatorSymbol;


static bool*    s_AddFieldList[] =
{
    &s_Add_FpField_state,
    &s_Add_F1_state,
    &s_Add_F2_state,
    &s_Add_F3_state,
    &s_Add_F4_state,
    &s_Add_F5_state,
    &s_Add_F6_state,
    &s_Add_F7_state,
    &s_Add_F8_state,
    &s_Add_Alls_state,
86
    &s_Add_DatasheetField_state,
87 88 89 90
    NULL
};


91 92 93 94 95 96 97 98 99 100 101
const wxString OPTION_BOM_LIST_REF( wxT("BomListPerRef") );
const wxString OPTION_BOM_LIST_VALUE( wxT("BomListPerValue") );
const wxString OPTION_BOM_LIST_HPINS( wxT("BomListPerHPins") );
const wxString OPTION_BOM_LIST_HPINS_BY_SHEET( wxT("BomListHPinsPerSheet") );
const wxString OPTION_BOM_LIST_HPINS_BY_NAME_( wxT("BomListHPinsPerName") );
const wxString OPTION_BOM_LIST_SUB_CMP( wxT("BomListSubCmps") );

const wxString OPTION_BOM_FORMAT( wxT("BomFormat") );
const wxString OPTION_BOM_LAUNCH_BROWSER( wxT("BomLaunchBrowser") );
const wxString OPTION_BOM_SEPARATOR( wxT("BomExportSeparator") );
const wxString OPTION_BOM_ADD_FIELD ( wxT("BomAddField") );
102
const wxString OPTION_BOM_ADD_LOCATION ( wxT("BomAddLocation") );
103 104 105 106 107 108 109 110 111 112 113

/* list of separators used in bom export to spreadsheet
 * (selected by s_OutputSeparatorOpt, and s_OutputSeparatorOpt radiobox)
 */
static char s_ExportSeparator[] = ("\t;,.");

/*!
 * DIALOG_BUILD_BOM dialog type definition
 */


114
DIALOG_BUILD_BOM::DIALOG_BUILD_BOM( EDA_DRAW_FRAME* parent ) :
115 116
    DIALOG_BUILD_BOM_BASE( parent )
{
117 118
    m_config = wxGetApp().GetSettings();
    wxASSERT( m_config != NULL );
119

120
    m_parent = parent;
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

    Init();

    if( GetSizer() )
    {
        GetSizer()->SetSizeHints( this );
    }
    Centre();
}


/*!
 * Init Controls for DIALOG_BUILD_BOM
 */

void DIALOG_BUILD_BOM::Init()
{
    SetFocus();

    /* Get options */
141 142 143 144 145 146 147 148 149 150 151
    m_config->Read( OPTION_BOM_LIST_REF, &s_ListByRef );
    m_config->Read( OPTION_BOM_LIST_VALUE , &s_ListByValue );
    m_config->Read( OPTION_BOM_LIST_HPINS, &s_ListHierarchicalPinByName );
    m_config->Read( OPTION_BOM_LIST_HPINS_BY_SHEET, &s_ListWithSubCmponents );
    m_config->Read( OPTION_BOM_LIST_HPINS_BY_NAME_, &s_ListWithSubCmponents );
    m_config->Read( OPTION_BOM_LIST_SUB_CMP, &s_ListWithSubCmponents );
    m_config->Read( OPTION_BOM_LIST_HPINS_BY_SHEET, &s_ListHierarchicalPinBySheet );
    m_config->Read( OPTION_BOM_LIST_HPINS_BY_NAME_, &s_ListHierarchicalPinByName );
    s_OutputFormOpt = m_config->Read( OPTION_BOM_FORMAT, 0l );
    m_config->Read( OPTION_BOM_LAUNCH_BROWSER, &s_BrowseCreatedList );
    s_OutputSeparatorOpt   = m_config->Read( OPTION_BOM_SEPARATOR, 0l );
152
    m_config->Read( OPTION_BOM_ADD_LOCATION, &s_Add_Location );
153

154
    long addfields = m_config->Read( OPTION_BOM_ADD_FIELD, 0l );
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    for( int ii = 0, bitmask = 1; s_AddFieldList[ii] != NULL; ii++ )
    {
        if( (addfields & bitmask) )
            *s_AddFieldList[ii] = true;
        else
            *s_AddFieldList[ii] = false;

        bitmask <<= 1;
    }

    // Set validators
    m_ListCmpbyRefItems->SetValidator( wxGenericValidator( &s_ListByRef ) );
    m_ListSubCmpItems->SetValidator( wxGenericValidator( &s_ListWithSubCmponents ) );
    m_ListCmpbyValItems->SetValidator( wxGenericValidator( &s_ListByValue ) );
    m_GenListLabelsbyVal->SetValidator( wxGenericValidator( &s_ListHierarchicalPinByName ) );
170
    m_GenListLabelsbySheet->SetValidator( wxGenericValidator( &s_ListHierarchicalPinBySheet ) );
171 172 173
    m_OutputFormCtrl->SetValidator( wxGenericValidator( &s_OutputFormOpt ) );
    m_OutputSeparatorCtrl->SetValidator( wxGenericValidator( &s_OutputSeparatorOpt ) );
    m_GetListBrowser->SetValidator( wxGenericValidator( &s_BrowseCreatedList ) );
174 175

    m_AddLocationField->SetValidator( wxGenericValidator( &s_Add_Location ) );
176
    m_AddFootprintField->SetValidator( wxGenericValidator( &s_Add_FpField_state ) );
177
    m_AddDatasheetField->SetValidator( wxGenericValidator( &s_Add_DatasheetField_state ) );
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
    m_AddField1->SetValidator( wxGenericValidator( &s_Add_F1_state ) );
    m_AddField2->SetValidator( wxGenericValidator( &s_Add_F2_state ) );
    m_AddField3->SetValidator( wxGenericValidator( &s_Add_F3_state ) );
    m_AddField4->SetValidator( wxGenericValidator( &s_Add_F4_state ) );
    m_AddField5->SetValidator( wxGenericValidator( &s_Add_F5_state ) );
    m_AddField6->SetValidator( wxGenericValidator( &s_Add_F6_state ) );
    m_AddField7->SetValidator( wxGenericValidator( &s_Add_F7_state ) );
    m_AddField8->SetValidator( wxGenericValidator( &s_Add_F8_state ) );
    m_AddAllFields->SetValidator( wxGenericValidator( &s_Add_Alls_state ) );

    m_OutputFormCtrl->SetSelection( s_OutputFormOpt );
    m_OutputSeparatorCtrl->SetSelection( s_OutputSeparatorOpt );

    // Enable/disable options:
    wxCommandEvent dummy;
    OnRadioboxSelectFormatSelected( dummy );
}


197 198 199
/*
 * Called on BOM format selection:
 * Enable/disable options in dialog
200 201 202
 */
void DIALOG_BUILD_BOM::OnRadioboxSelectFormatSelected( wxCommandEvent& event )
{
203
    switch( m_OutputFormCtrl->GetSelection() )
204
    {
205
        case 0:     // Human readable text full report
206 207 208 209 210 211
            m_OutputSeparatorCtrl->Enable( false );
            m_ListCmpbyRefItems->Enable( true );
            m_ListCmpbyValItems->Enable( true );
            m_GenListLabelsbyVal->Enable( true );
            m_GenListLabelsbySheet->Enable( true );
            m_ListSubCmpItems->Enable( true );
212
            m_AddLocationField->Enable( true );
213 214
            break;

215
        case 1:     // Csv format, full list by reference
216 217 218 219 220 221
            m_OutputSeparatorCtrl->Enable( true );
            m_ListCmpbyRefItems->Enable( false );
            m_ListCmpbyValItems->Enable( false );
            m_GenListLabelsbyVal->Enable( false );
            m_GenListLabelsbySheet->Enable( false );
            m_ListSubCmpItems->Enable( true );
222
            m_AddLocationField->Enable( true );
223 224
            break;

225
        case 2:     // Csv format, grouped list by reference
226 227 228 229 230 231
            m_OutputSeparatorCtrl->Enable( true );
            m_ListCmpbyRefItems->Enable( false );
            m_ListCmpbyValItems->Enable( false );
            m_GenListLabelsbyVal->Enable( false );
            m_GenListLabelsbySheet->Enable( false );
            m_ListSubCmpItems->Enable( false );
232
            m_AddLocationField->Enable( false );
233 234
            break;

235
        case 3:     // Csv format, short list by values
236 237 238 239 240 241
            m_OutputSeparatorCtrl->Enable( true );
            m_ListCmpbyRefItems->Enable( false );
            m_ListCmpbyValItems->Enable( false );
            m_GenListLabelsbyVal->Enable( false );
            m_GenListLabelsbySheet->Enable( false );
            m_ListSubCmpItems->Enable( false );
242
            m_AddLocationField->Enable( false );
243
            break;
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
    }
}


/*!
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
 */

void DIALOG_BUILD_BOM::OnOkClick( wxCommandEvent& event )
{
    char ExportSeparatorSymbol = s_ExportSeparator[0];

    if( m_OutputSeparatorCtrl->GetSelection() > 0 )
        ExportSeparatorSymbol = s_ExportSeparator[m_OutputSeparatorCtrl->GetSelection()];

    int ExportFileType = m_OutputFormCtrl->GetSelection();

    SavePreferences();

    Create_BOM_Lists( ExportFileType, m_ListSubCmpItems->GetValue(),
                      ExportSeparatorSymbol, m_GetListBrowser->GetValue() );
}


/*!
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
 */

void DIALOG_BUILD_BOM::OnCancelClick( wxCommandEvent& event )
{
    EndModal( -1 );
}


void DIALOG_BUILD_BOM::SavePreferences()
{
    // Determine current settings of "List items" and "Options" checkboxes
    s_ListByRef = m_ListCmpbyRefItems->GetValue();
    s_ListWithSubCmponents = m_ListSubCmpItems->GetValue();
    s_ListByValue = m_ListCmpbyValItems->GetValue();
    s_ListHierarchicalPinByName = m_GenListLabelsbyVal->GetValue();
285
    s_ListHierarchicalPinBySheet = m_GenListLabelsbySheet->GetValue();
286 287
    s_BrowseCreatedList = m_GetListBrowser->GetValue();

288
    // (saved in config ):
289 290 291 292

    // Determine current settings of both radiobutton groups
    s_OutputFormOpt = m_OutputFormCtrl->GetSelection();
    s_OutputSeparatorOpt = m_OutputSeparatorCtrl->GetSelection();
293

294 295 296 297
    if( s_OutputSeparatorOpt < 0 )
        s_OutputSeparatorOpt = 0;

    // Determine current settings of all "Fields to add" checkboxes
298
    s_Add_Location = m_AddLocationField->GetValue();
299
    s_Add_FpField_state = m_AddFootprintField->GetValue();
300
    s_Add_DatasheetField_state = m_AddDatasheetField->GetValue();
301 302 303 304 305 306 307 308 309 310 311
    s_Add_F1_state     = m_AddField1->GetValue();
    s_Add_F2_state     = m_AddField2->GetValue();
    s_Add_F3_state     = m_AddField3->GetValue();
    s_Add_F4_state     = m_AddField4->GetValue();
    s_Add_F5_state     = m_AddField5->GetValue();
    s_Add_F6_state     = m_AddField6->GetValue();
    s_Add_F7_state     = m_AddField7->GetValue();
    s_Add_F8_state     = m_AddField8->GetValue();
    s_Add_Alls_state   = m_AddAllFields->GetValue();

    // Now save current settings of both radiobutton groups
312 313 314 315 316 317
    m_config->Write( OPTION_BOM_LIST_REF, s_ListByRef );
    m_config->Write( OPTION_BOM_LIST_VALUE , s_ListByValue );
    m_config->Write( OPTION_BOM_LIST_HPINS, s_ListHierarchicalPinByName );
    m_config->Write( OPTION_BOM_LIST_HPINS_BY_SHEET, s_ListHierarchicalPinBySheet );
    m_config->Write( OPTION_BOM_LIST_HPINS_BY_NAME_, s_ListHierarchicalPinByName );
    m_config->Write( OPTION_BOM_LIST_SUB_CMP, s_ListWithSubCmponents );
318

319 320 321
    m_config->Write( OPTION_BOM_FORMAT, (long) s_OutputFormOpt );
    m_config->Write( OPTION_BOM_SEPARATOR, (long) s_OutputSeparatorOpt );
    m_config->Write( OPTION_BOM_LAUNCH_BROWSER, (long) s_BrowseCreatedList );
322 323

    // Now save current settings of all "Fields to add" checkboxes
324
    m_config->Write( OPTION_BOM_ADD_LOCATION, s_Add_Location );
325

326
    long addfields = 0;
327 328 329 330
    for( int ii = 0, bitmask = 1; s_AddFieldList[ii] != NULL; ii++ )
    {
        if( *s_AddFieldList[ii] )
            addfields |= bitmask;
331

332 333 334
        bitmask <<= 1;
    }

335
    m_config->Write( OPTION_BOM_ADD_FIELD, addfields );
336 337 338 339 340 341 342 343 344 345 346 347
}


void DIALOG_BUILD_BOM::Create_BOM_Lists( int  aTypeFile,
                                         bool aIncludeSubComponents,
                                         char aExportSeparatorSymbol,
                                         bool aRunBrowser )
{
    wxString    wildcard;

    static wxFileName fn;

348
    wxFileName  current = g_RootSheet->GetScreen()->GetFileName();
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379

    s_ExportSeparatorSymbol = aExportSeparatorSymbol;

    if( !fn.HasName() || fn.GetName()==NAMELESS_PROJECT )
    {
        fn.SetName( current.GetName() );
    }
    // else use a previous run's name, because fn was set before and user
    // is probably just iteratively refining the BOM.

    if( fn.GetPath().IsEmpty() )
    {
        fn.SetPath( current.GetPath() );
    }
    // else use a previous run's path, because fn was set before and user
    // is probably just iteratively refining the BOM.

    wxString bomDesc = _( "Bill of Materials" );    // translate once, use twice.

    if( aTypeFile == 0 )
    {
        fn.SetExt( wxT( "lst" ) );
        wildcard = bomDesc + wxT( " (*.lst)|*.lst" );
    }
    else
    {
        fn.SetExt( wxT( "csv" ) );
        wildcard = bomDesc + wxT( " (*.csv)|*.csv" );
    }

    wxFileDialog dlg( this, bomDesc, fn.GetPath(),
380
                      fn.GetFullName(), wildcard, wxFD_SAVE );
381 382 383 384 385 386

    if( dlg.ShowModal() == wxID_CANCEL )
        return;

    fn = dlg.GetPath();        // remember path+filename+ext for subsequent runs.

387
    m_listFileName = dlg.GetPath();
388 389 390 391 392 393

    // Close dialog, then show the list (if so requested)

    switch( aTypeFile )
    {
    case 0: // list
394
        CreatePartsAndLabelsFullList( aIncludeSubComponents );
395 396
        break;

397
    case 1: // spreadsheet, Single Part per line
398 399 400 401 402
        CreateSpreadSheetPartsFullList( aIncludeSubComponents, s_Add_Location, false );
        break;

    case 2: // spreadsheet, group Part with same fields per line
        CreateSpreadSheetPartsFullList( aIncludeSubComponents, s_Add_Location, true );
403 404
        break;

405 406
    case 3: // spreadsheet, one value per line and no sub-component
        CreateSpreadSheetPartsShortList();
407 408 409 410 411 412 413 414
        break;
    }

    EndModal( 1 );

    if( aRunBrowser )
    {
        wxString editorname = wxGetApp().GetEditorName();
415
        wxString filename   = m_listFileName;
416 417 418 419 420 421 422
        AddDelimiterString( filename );
        ExecuteFile( this, editorname, filename );
    }
}

/** Helper function IsFieldChecked
 * return the state of the wxCheckbox corresponding to the
423
 * field aFieldId (FOOTPRINT, DATASHEET and FIELD1 to FIELD8
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
 * if the option "All user fields" is checked, return always true
 * for fileds ids >= FIELD1
 * @param aFieldId = the field id : FOOTPRINT to FIELD8
 */
bool DIALOG_BUILD_BOM::IsFieldChecked(int aFieldId)
{
    if( m_AddAllFields->IsChecked() && (aFieldId>= FIELD1) )
        return true;

    switch ( aFieldId )
    {
        case FIELD1:
            return m_AddField1->IsChecked();
        case FIELD2:
            return m_AddField2->IsChecked();
        case FIELD3:
            return m_AddField3->IsChecked();
        case FIELD4:
            return m_AddField4->IsChecked();
        case FIELD5:
            return m_AddField5->IsChecked();
        case FIELD6:
            return m_AddField6->IsChecked();
        case FIELD7:
            return m_AddField7->IsChecked();
        case FIELD8:
            return m_AddField8->IsChecked();
        case FOOTPRINT:
            return m_AddFootprintField->IsChecked();
453 454
        case DATASHEET:
            return m_AddDatasheetField->IsChecked();
455 456 457 458 459 460
    }

    return false;
}


461 462 463 464 465 466 467
/* Prints a list of components, in a form which can be imported by a spreadsheet.
 * components having the same value and the same footprint
 * are grouped on the same line
 * Form is:
 *  value; number of components; list of references; <footprint>; <field1>; ...;
 * list is sorted by values
 */
468
void DIALOG_BUILD_BOM::CreateSpreadSheetPartsShortList( )
469
{
470
    FILE* f;
471

472
    if( ( f = wxFopen( m_listFileName, wxT( "wt" ) ) ) == NULL )
473
    {
474
        wxString msg;
475
        msg.Printf( _( "Failed to open file <%s>" ), GetChars(m_listFileName) );
476 477 478 479
        DisplayError( this, msg );
        return;
    }

480
    BOM_LISTER bom_lister;
481
    bom_lister.SetCvsFormOn( s_ExportSeparatorSymbol );
482

483
    // Set the list of fields to add to list
484
    for( int ii = FOOTPRINT; ii <= FIELD8; ii++ )
485
        if( IsFieldChecked( ii ) )
486
            bom_lister.AddFieldIdToPrintList( ii );
487 488
    // Write the list of components grouped by values:
    bom_lister.CreateCsvBOMListByValues( f );
489 490 491 492 493 494
}


/*
 * Print a list of components, in a form which can be imported by a spreadsheet
 * form is:
495 496
 * cmp ref; cmp val; fields;
 * Components are sorted by reference
497 498 499 500 501
 * param aIncludeSubComponents = true to print sub components
 * param aPrintLocation = true to print components location
 *        (only possible when aIncludeSubComponents == true)
 * param aGroupRefs = true to group components references, when other fieds
 *          have the same value
502
 */
503 504 505
void DIALOG_BUILD_BOM::CreateSpreadSheetPartsFullList( bool aIncludeSubComponents,
                                                       bool aPrintLocation,
                                                       bool aGroupRefs )
506 507 508 509
{
    FILE*    f;
    wxString msg;

510
    if( ( f = wxFopen( m_listFileName, wxT( "wt" ) ) ) == NULL )
511
    {
512
        msg.Printf( _( "Failed to open file <%s>" ), GetChars( m_listFileName ) );
513 514 515 516
        DisplayError( this, msg );
        return;
    }

517 518
    BOM_LISTER bom_lister;
    bom_lister.SetCvsFormOn( s_ExportSeparatorSymbol );
519

520 521 522 523
    // Set group refs option (hight priority):
    // Obvioulsy only useful when not including sub-components
    bom_lister.SetGroupReferences( aGroupRefs );
    bom_lister.SetIncludeSubCmp( aIncludeSubComponents && !aGroupRefs );
524

525 526 527 528 529
    // Set print location option:
    // Obvioulsy only possible when including sub components
    // and not grouping references
    bom_lister.SetPrintLocation( aPrintLocation && !aGroupRefs &&
                                 aIncludeSubComponents );
530

531
    // Set the list of fields to add to list
532
    for( int ii = FOOTPRINT; ii <= FIELD8; ii++ )
533 534
        if( IsFieldChecked( ii ) )
            bom_lister.AddFieldIdToPrintList( ii );
535 536

    // create the file
537
    bom_lister.PrintComponentsListByReferenceCsvForm( f );
538 539 540 541 542

    fclose( f );
}


543
/*
544
 * CreatePartsAndLabelsFullList()
545
 * Main function to create the list of components and/or labels
546
 * (global labels, hierarchical labels and pin sheets )
547
 */
548
void DIALOG_BUILD_BOM::CreatePartsAndLabelsFullList( bool aIncludeSubComponents )
549 550 551 552
{
    FILE*    f;
    wxString msg;

553
    if( ( f = wxFopen( m_listFileName, wxT( "wt" ) ) ) == NULL )
554
    {
555
        msg.Printf( _( "Failed to open file <%s>" ), GetChars( m_listFileName ) );
556 557 558 559
        DisplayError( this, msg );
        return;
    }

560 561 562 563 564
    BOM_LISTER bom_lister;
    bom_lister.SetIncludeSubCmp( aIncludeSubComponents );
    bom_lister.SetCvsFormOff();
    bom_lister.SetPrintLocation( s_Add_Location );
    // Set the list of fields to add to list
565
    for( int ii = FOOTPRINT; ii <= FIELD8; ii++ )
566 567
        if( IsFieldChecked( ii ) )
            bom_lister.AddFieldIdToPrintList( ii );
568

569 570
    // creates the list file
    wxString Title = wxGetApp().GetAppName() + wxT( " " ) + GetBuildVersion();
571

572
    fprintf( f, "%s  >> Creation date: %s\n", TO_UTF8( Title ), TO_UTF8( DateAndTime() ) );
573

574 575
    if( m_ListCmpbyRefItems->GetValue() )
        bom_lister.PrintComponentsListByReferenceHumanReadable( f );
576

577 578
    if( m_ListCmpbyValItems->GetValue() )
        bom_lister.PrintComponentsListByValue( f );
579

580
    // Create list of global labels, hierachical labels and pins sheets
581

582 583
    if( m_GenListLabelsbySheet->GetValue() )
        bom_lister.PrintGlobalAndHierarchicalLabelsList( f, true );
584

585 586
    if( m_GenListLabelsbyVal->GetValue() )
        bom_lister.PrintGlobalAndHierarchicalLabelsList( f, false );
587 588

    msg = _( "\n#End List\n" );
589
    fprintf( f, "%s", TO_UTF8( msg ) );
590 591
    fclose( f );
}