dialog_netlist.cpp 25.4 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@wanadoo.fr
5
 * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
6
 * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * 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
 */

26
/**
Wayne Stambaugh's avatar
Wayne Stambaugh committed
27
 * @file eeschema/dialogs/dialog_netlist.cpp
28 29
 * @brief Dialog box for creating netlists.
 */
30

31
/* Functions relative to the dialog creating the netlist for Pcbnew.
32
 * The dialog is a notebook with 4 fixed netlist format:
33
 * Pcbnew ORCADPCB2 CADSTAR and SPICE
34 35 36
 * and up to CUSTOMPANEL_COUNTMAX (see netlist.h) user programmable format
 * calling an external converter with convert an intermediate format to the
 * user specific format.
37
 * these external converters are referred there as plugins,
38 39 40
 * but there are not really plugins, there are only external binaries
 */

41 42 43 44 45
#include <fctsys.h>
#include <appl_wxstruct.h>
#include <confirm.h>
#include <gestfich.h>
#include <wxEeschemaStruct.h>
46

47 48 49 50 51
#include <general.h>
#include <netlist.h>
#include <protos.h>
#include <sch_sheet.h>
#include <dialog_helpers.h>
52
#include <dialog_netlist.h>
53
#include <dialogs/annotate_dialog.h>
54 55
#include <wildcards_and_files_ext.h>
#include <wildcards_and_files_ext.h>
56

57 58 59 60 61 62 63 64 65
#include <eeschema_id.h>

/* Event id for notebook page buttons: */
enum id_netlist {
    ID_CREATE_NETLIST = ID_END_EESCHEMA_ID_LIST + 1,
    ID_CURRENT_FORMAT_IS_DEFAULT,
    ID_RUN_SIMULATOR,
    ID_ADD_SUBCIRCUIT_PREFIX
};
66

67
//Imported function:
68
int TestDuplicateSheetNames( bool aCreateMarker );
69

70
// ID for configuration:
71 72
#define CUSTOM_NETLIST_TITLE   wxT( "CustomNetlistTitle" )
#define CUSTOM_NETLIST_COMMAND wxT( "CustomNetlistCommand" )
73
#define NETLIST_USE_DEFAULT_NETNAME wxT( "NetlistUseDefaultNetname" )
74
#define NETLIST_PSPICE_USE_NETNAME  wxT( "SpiceUseNetNames" )
75

76 77
#define NETLIST_PCBNEW_LEGACY wxT("LegacyPcbnew" )
#define NETLIST_PCBNEW_NEWFMT wxT("PcbnewAdvanced" )
78 79


80
BEGIN_EVENT_TABLE( NETLIST_DIALOG, NETLIST_DIALOG_BASE )
81
    EVT_BUTTON( ID_CREATE_NETLIST, NETLIST_DIALOG::GenNetlist )
82
    EVT_CHECKBOX( ID_CURRENT_FORMAT_IS_DEFAULT,
83
                  NETLIST_DIALOG::SelectDefaultNetlistType )
84 85
    EVT_CHECKBOX( ID_ADD_SUBCIRCUIT_PREFIX,
                  NETLIST_DIALOG::EnableSubcircuitPrefix )
86
    EVT_BUTTON( ID_RUN_SIMULATOR, NETLIST_DIALOG::RunSimulator )
87 88 89 90 91 92 93 94
END_EVENT_TABLE()


/*******************************/
/* Functions for these classes */
/*******************************/


95
/* Contructor to create a setup page for one netlist format.
96 97
 * Used in Netlist format Dialog box creation
 */
98
NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook*     parent,
99
                                          const wxString& title,
100
                                          NETLIST_TYPE_ID id_NetType ) :
101 102
    wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize,
             wxTAB_TRAVERSAL | wxBORDER_SUNKEN )
103
{
104
    m_IdNetType = id_NetType;
105
    m_pageNetFmtName = title;
106
    m_CommandStringCtrl = NULL;
107 108
    m_TitleStringCtrl   = NULL;
    m_IsCurrentFormat   = NULL;
109
    m_AddSubPrefix = NULL;
110
    m_ButtonCancel = NULL;
111
    m_NetOption = NULL;
112

113
    wxString netfmtName = ((NETLIST_DIALOG*)parent->GetParent())->m_NetFmtName;
114
    int fmtOption = 1;  // Default Pcbnew netlist fmt is advanced fmt
115 116 117 118 119 120

    bool selected = m_pageNetFmtName == netfmtName;

    // PCBNEW Format is a special type:
    if( id_NetType == NET_TYPE_PCBNEW )
    {
121
        if( netfmtName.IsEmpty() || netfmtName == NETLIST_PCBNEW_NEWFMT )
122
            selected = true;
123
        if( netfmtName == NETLIST_PCBNEW_LEGACY )
124 125
        {
            selected = true;
126
            fmtOption = 0;
127 128 129
        }
    }

130

131
    parent->AddPage( this, title, selected );
132

133 134 135 136 137 138
    wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxVERTICAL );
    SetSizer( MainBoxSizer );
    wxBoxSizer* UpperBoxSizer = new wxBoxSizer( wxHORIZONTAL );
    m_LowBoxSizer = new wxBoxSizer( wxVERTICAL );
    MainBoxSizer->Add( UpperBoxSizer, 0, wxGROW | wxALL, 5 );
    MainBoxSizer->Add( m_LowBoxSizer, 0, wxGROW | wxALL, 5 );
139

140 141 142 143 144
    m_LeftBoxSizer  = new wxBoxSizer( wxVERTICAL );
    m_RightBoxSizer = new wxBoxSizer( wxVERTICAL );
    m_RightOptionsBoxSizer = new wxBoxSizer( wxVERTICAL );
    UpperBoxSizer->Add( m_LeftBoxSizer, 0, wxGROW | wxALL, 5 );
    UpperBoxSizer->Add( m_RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
145
    UpperBoxSizer->Add( m_RightOptionsBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
146

147 148
    wxStaticText* text = new wxStaticText( this, -1, _( "Options:" ) );
    m_LeftBoxSizer->Add( text, 0, wxGROW | wxALL, 5 );
149

150 151 152 153
    m_IsCurrentFormat = new wxCheckBox( this, ID_CURRENT_FORMAT_IS_DEFAULT,
                                        _( "Default format" ) );
    m_LeftBoxSizer->Add( m_IsCurrentFormat, 0, wxGROW | wxALL, 5 );
    m_IsCurrentFormat->SetValue( selected );
154

155 156
    if( id_NetType == NET_TYPE_PCBNEW )
    {
157
        wxString netlist_opt[2] = { _( "Legacy Format" ), _( "Advanced Format" ) };
158 159 160 161
        m_NetOption = new wxRadioBox( this, -1, _( "Netlist Options:" ),
                                      wxDefaultPosition, wxDefaultSize,
                                      2, netlist_opt, 1,
                                      wxRA_SPECIFY_COLS );
162
        m_NetOption->SetSelection( fmtOption );
163 164
        m_LeftBoxSizer->Add( m_NetOption, 0, wxGROW | wxALL, 5 );
    }
165 166
}

167 168 169 170 171 172
const wxString NETLIST_PAGE_DIALOG::GetPageNetFmtName()
{
    // PCBNEW Format is a special type:
    if( m_IdNetType == NET_TYPE_PCBNEW )
    {
        if( m_NetOption->GetSelection() )
173
            return NETLIST_PCBNEW_NEWFMT;
174
        else
175
            return NETLIST_PCBNEW_LEGACY;
176
    }
177

178 179 180
    return m_pageNetFmtName;
}

181

182
NETLIST_DIALOG::NETLIST_DIALOG( SCH_EDIT_FRAME* parent ) :
183
    NETLIST_DIALOG_BASE( parent )
184
{
185
    m_Parent = parent;
186
    m_config = wxGetApp().GetSettings();
187 188

    long tmp;
189
    m_config->Read( NETLIST_USE_DEFAULT_NETNAME, &tmp, 0l );
190
    m_cbUseDefaultNetlistName->SetValue( tmp );
191
    m_NetFmtName = m_Parent->GetNetListFormatName();
192

193
    for( int ii = 0; ii < PANELCUSTOMBASE + CUSTOMPANEL_COUNTMAX; ii++ )
194 195 196
    {
        m_PanelNetType[ii] = NULL;
    }
197

198
    // Add notebook pages:
199 200

    // Add Panel FORMAT PCBNEW
201
    m_PanelNetType[PANELPCBNEW] =
202 203
        new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Pcbnew" ),
                                 NET_TYPE_PCBNEW );
204 205

    // Add Panel FORMAT ORCADPCB2
206
    m_PanelNetType[PANELORCADPCB2] =
207 208
        new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "OrcadPCB2" ),
                                 NET_TYPE_ORCADPCB2 );
209 210

    // Add Panel FORMAT CADSTAR
211
    m_PanelNetType[PANELCADSTAR] =
212 213
        new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "CadStar" ),
                                 NET_TYPE_CADSTAR );
214

215 216
    // Add Panel spice
    InstallPageSpice();
217

218 219 220
    // Add custom panels:
    InstallCustomPages();

221
    GetSizer()->SetSizeHints( this );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
222

223
    Centre();
224 225 226
}


227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
/**
 * Function ReturnUserNetlistTypeName
 * to retrieve user netlist type names
 * @param first_item = true: return first name of the list, false = return next
 * @return a wxString : name of the type netlist or empty string
 * this function must be called first with "first_item" = true
 * and after with "first_item" = false to get all the other existing netlist names
 */
const wxString NETLIST_DIALOG::ReturnUserNetlistTypeName( bool first_item )
{
    static int index;
    wxString   name, msg;

    if( first_item )
        index = 0;
    else
        index++;

    msg = CUSTOM_NETLIST_TITLE;
    msg << index + 1;

248
    name = m_config->Read( msg );
249 250 251 252

    return name;
}

253
void NETLIST_DIALOG::InstallPageSpice()
254
{
255
    wxButton* Button;
256
    NETLIST_PAGE_DIALOG* page;
257
    wxString title = wxT( "Spice" );
258

259
    page = m_PanelNetType[PANELSPICE] =
260
        new NETLIST_PAGE_DIALOG( m_NoteBook, title, NET_TYPE_SPICE );
261

262 263 264

    page->m_AddSubPrefix = new wxCheckBox( page, ID_ADD_SUBCIRCUIT_PREFIX,
                                           _( "Prefix references 'U' and 'IC' with 'X'" ) );
265
    page->m_AddSubPrefix->SetValue( m_Parent->GetAddReferencePrefix() );
266 267
    page->m_LeftBoxSizer->Add( page->m_AddSubPrefix, 0, wxGROW | wxALL, 5 );

268
    page->m_LowBoxSizer->Add( new wxStaticText( page, -1, _( "Simulator command:" ) ), 0,
269
                              wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
270 271 272 273 274 275 276 277 278

    page->m_CommandStringCtrl = new wxTextCtrl( page, -1, m_Parent->GetSimulatorCommand(),
                                                wxDefaultPosition, wxDefaultSize );

    page->m_CommandStringCtrl->SetInsertionPoint( 1 );
    page->m_LowBoxSizer->Add( page->m_CommandStringCtrl,
                              0,
                              wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM,
                              5 );
279

280
    // Add buttons
281 282
    Button = new wxButton( page, ID_RUN_SIMULATOR, _( "&Run Simulator" ) );
    page->m_RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
283 284
}

285

286
/* create the pages for custom netlist format selection:
287
 */
288
void NETLIST_DIALOG::InstallCustomPages()
289
{
290 291 292
    int               ii;
    wxString          title, msg;
    NETLIST_PAGE_DIALOG* currPage;
293

294
    for( ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
295
    {
296
        title = ReturnUserNetlistTypeName( ii == 0 ? true : false );
297 298

        if( title.IsEmpty() )
299
            break; // No more panel to install
300

301
        // Install a plugin panel
302 303
        msg = CUSTOM_NETLIST_COMMAND;
        msg << ii + 1;
304
        wxString command = m_config->Read( msg );
305

306 307 308
        currPage = AddOneCustomPage( title, command,
                                     (NETLIST_TYPE_ID)(NET_TYPE_CUSTOM1 + ii) );
        m_PanelNetType[PANELCUSTOMBASE + ii] = currPage;
309
    }
310 311
}

312 313 314
NETLIST_PAGE_DIALOG* NETLIST_DIALOG::AddOneCustomPage( const wxString & aTitle,
                                                       const wxString & aCommandString,
                                                       NETLIST_TYPE_ID aNetTypeId )
315
{
316
    NETLIST_PAGE_DIALOG* currPage;
317

318
    currPage = new NETLIST_PAGE_DIALOG( m_NoteBook, aTitle, aNetTypeId );
319

320

321 322 323
    currPage->m_LowBoxSizer->Add( new wxStaticText( currPage,
                                                    -1, _( "Netlist command:" ) ), 0,
                                  wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
324

325 326
    currPage->m_CommandStringCtrl = new wxTextCtrl( currPage, -1, aCommandString,
                                                    wxDefaultPosition, wxDefaultSize );
327

328 329 330 331 332
    currPage->m_CommandStringCtrl->SetInsertionPoint( 1 );
    currPage->m_LowBoxSizer->Add( currPage->m_CommandStringCtrl,
                                  0,
                                  wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM,
                                  5 );
333

334 335 336
    currPage->m_LowBoxSizer->Add( new wxStaticText( currPage,
                                                    -1, _( "Title:" ) ), 0,
                                  wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
337

338 339
    currPage->m_TitleStringCtrl = new wxTextCtrl( currPage, -1, aTitle,
                                                  wxDefaultPosition, wxDefaultSize );
340

341 342 343 344 345 346
    currPage->m_TitleStringCtrl->SetInsertionPoint( 1 );
    currPage->m_LowBoxSizer->Add( currPage->m_TitleStringCtrl,
                                  0,
                                  wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM,
                                  5 );
    return currPage;
347 348 349
}


CHARRAS's avatar
CHARRAS committed
350
/* Called when the check box "default format" is clicked
351
 */
352
void NETLIST_DIALOG::SelectDefaultNetlistType( wxCommandEvent& event )
353
{
354
    int ii;
355
    NETLIST_PAGE_DIALOG* currPage;
356

357 358
    for( ii = 0; ii < PANELCUSTOMBASE + CUSTOMPANEL_COUNTMAX; ii++ )
        if( m_PanelNetType[ii] )
359
            m_PanelNetType[ii]->m_IsCurrentFormat->SetValue( false );
360

361
    currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
362

363
    if( currPage == NULL )
364
        return;
365

366 367
    m_Parent->SetNetListFormatName( currPage->GetPageNetFmtName() );
    currPage->m_IsCurrentFormat->SetValue( true );
368 369
}

370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
/* Called when a netlist type is selected.
 * Enable/disable relevant/irrelevant widgets, and display the default
 * netlist name, for known types
 */
void NETLIST_DIALOG::OnNetlistTypeSelection( wxNotebookEvent& event )
{
    NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
    if( currPage == NULL )
        return;

    m_buttonDelPlugin->Enable( currPage->m_IdNetType >= NET_TYPE_CUSTOM1 );
    m_cbUseDefaultNetlistName->Enable( currPage->m_IdNetType < NET_TYPE_CUSTOM1 );

    wxString fileExt;
    if( ReturnFilenamePrms( currPage->m_IdNetType, &fileExt, NULL ) )
    {
        wxFileName fn = g_RootSheet->GetScreen()->GetFileName();
        fn.SetExt( fileExt );
        m_textCtrlDefaultFileName->SetValue( fn.GetFullName() );
    }
    else
        m_textCtrlDefaultFileName->Clear();
}
393

394 395 396
/* Called when the check box m_AddSubPrefix
 * "default format" is clicked
 * ( Spice format only )
397 398 399 400
 */
void NETLIST_DIALOG::EnableSubcircuitPrefix( wxCommandEvent& event )
{

401
    NETLIST_PAGE_DIALOG* currPage;
402

403
    currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
404

405
    if( currPage == NULL || currPage->m_AddSubPrefix == NULL )
406 407
        return;

408
    m_Parent->SetAddReferencePrefix( currPage->m_AddSubPrefix->IsChecked() );
409 410
}

411
void NETLIST_DIALOG::NetlistUpdateOpt()
412
{
413
    int ii;
414

415
    m_Parent->SetSimulatorCommand( m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->GetValue() );
416
    m_Parent->SetNetListFormatName( wxEmptyString );
417 418 419 420 421

    for( ii = 0; ii < PANELCUSTOMBASE + CUSTOMPANEL_COUNTMAX; ii++ )
    {
        if( m_PanelNetType[ii] == NULL )
            break;
422 423

        if( m_PanelNetType[ii]->m_IsCurrentFormat->GetValue() == true )
424
            m_Parent->SetNetListFormatName( m_PanelNetType[ii]->GetPageNetFmtName() );
425
    }
426 427
}

428

429 430
/**
 * Function GenNetlist
431
 * Create the netlist file:
432
 * calculate the filename with the suitable extensions
433 434
 * and run the netlist creator
 */
435
void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
436
{
437 438 439 440
    wxFileName  fn;
    wxString    fileWildcard;
    wxString    fileExt;
    wxString    title = _( "Save Netlist File" );
441

442
    NetlistUpdateOpt();
443

444 445
    NETLIST_PAGE_DIALOG* currPage;
    currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
446

447 448
    unsigned netlist_opt = 0;

449
    /* Calculate the netlist filename */
450
    fn = g_RootSheet->GetScreen()->GetFileName();
451
    ReturnFilenamePrms( currPage->m_IdNetType, &fileExt, &fileWildcard );
452

453 454
    // Set some parameters
    switch( currPage->m_IdNetType )
455 456
    {
    case NET_TYPE_SPICE:
457
        // Set spice netlist options:
458
        if( currPage->m_AddSubPrefix->GetValue() )
459
            netlist_opt |= NET_USE_X_PREFIX;
460 461 462 463 464
        break;

    case NET_TYPE_CADSTAR:
        break;

465
    case NET_TYPE_PCBNEW:
466
        if( currPage->m_NetOption->GetSelection() != 0 )
467 468 469
            netlist_opt = NET_PCBNEW_USE_NEW_FORMAT;
        break;

470
    case NET_TYPE_ORCADPCB2:
471
        break;
472

473
    default:    // custom, NET_TYPE_CUSTOM1 and greater
474
        title.Printf( _( "%s Export" ), currPage->m_TitleStringCtrl->GetValue().GetData() );
475 476
    }

477
    fn.SetExt( fileExt );
478 479 480 481 482

    if( fn.GetPath().IsEmpty() )
       fn.SetPath( wxGetCwd() );

    wxString fullfilename = fn.GetFullPath();
483

484 485 486
    if( !GetUseDefaultNetlistName() || currPage->m_IdNetType >= NET_TYPE_CUSTOM1 )
    {
        wxFileDialog dlg( this, title, fn.GetPath(),
487
                          fullfilename, fileWildcard,
488
                          wxFD_SAVE );
489

490 491 492
        if( dlg.ShowModal() == wxID_CANCEL )
            return;

493
        fullfilename = dlg.GetPath();
494
    }
495

496
    m_Parent->ClearMsgPanel();
497

498 499
    if( currPage->m_CommandStringCtrl )
        m_Parent->SetNetListerCommand( currPage->m_CommandStringCtrl->GetValue() );
500
    else
501
        m_Parent->SetNetListerCommand( wxEmptyString );
502

503
    m_Parent->CreateNetlist( currPage->m_IdNetType, fullfilename, netlist_opt );
504 505 506

    WriteCurrentNetlistSetup();

507
    EndModal( wxID_OK );
508 509
}

510 511 512 513 514
/**
 * Function ReturnFilenamePrms
 * returns the filename extension and the wildcard string for this curr
 * or a void name if there is no default name
 * @param aNetTypeId = the netlist type ( NET_TYPE_PCBNEW ... )
Wayne Stambaugh's avatar
Wayne Stambaugh committed
515 516
 * @param aExt = a reference to a wxString to return the default  file ext.
 * @param aWildCard =  reference to a wxString to return the default wildcard.
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
 * @return true for known netlist type, false for custom formats
 */
bool NETLIST_DIALOG::ReturnFilenamePrms( NETLIST_TYPE_ID aNetTypeId,
                                         wxString * aExt, wxString * aWildCard )
{
    wxString fileExt;
    wxString fileWildcard;

    bool ret = true;

    switch( aNetTypeId )
    {
    case NET_TYPE_SPICE:
        fileExt = wxT( "cir" );
        fileWildcard = _( "SPICE netlist file (.cir)|*.cir" );
        break;

    case NET_TYPE_CADSTAR:
        fileExt = wxT( "frp" );
        fileWildcard = _( "CadStar netlist file (.frp)|*.frp" );
        break;

    case NET_TYPE_PCBNEW:
    case NET_TYPE_ORCADPCB2:
        fileExt = NetlistFileExtension;
        fileWildcard = NetlistFileWildcard;
        break;

    default:    // custom, NET_TYPE_CUSTOM1 and greater
        fileWildcard = AllFilesWildcard;
        ret = false;
    }

    if( aExt )
        *aExt = fileExt;

    if( aWildCard )
        *aWildCard = fileWildcard;

    return ret;
}
558

559 560 561 562 563 564 565 566
/* Function CreateNetlist
 *  > test for some issues (missing or duplicate references and sheet names)
 *  > build netlist info
 *  > create the netlist file
 * param aFormat = netlist format (NET_TYPE_PCBNEW ...)
 * param aFullFileName = full netlist file name
 * param aNetlistOptions = netlist options using OR'ed bits (see WriteNetListFile).
 * return true if success.
567
 */
568
bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName,
569
                                    unsigned aNetlistOptions )
570
{
571 572
    SCH_SHEET_LIST sheets;
    sheets.AnnotatePowerSymbols();
573 574 575

    // Performs some controls:
    if( CheckAnnotate( NULL, 0 ) )
576
    {
577 578 579
        if( !IsOK( NULL, _( "Some items are not annotated\n\
Do you want to annotate schematic?" ) ) )
            return false;
580

581 582 583
        // Schematic must be annotated: call Annotate dialog:
        wxCommandEvent event;
        OnAnnotate( event );
584

585
        if( CheckAnnotate( NULL, 0 ) )
586
            return false;
587 588
    }

589
    // Test duplicate sheet names:
590
    if( TestDuplicateSheetNames( false ) > 0 )
591
    {
592 593
        if( !IsOK( NULL, _( "Error: duplicate sheet names. Continue?" ) ) )
            return false;
594 595
    }

596
    /* Cleanup the entire hierarchy */
597 598
    SCH_SCREENS screens;
    screens.SchematicCleanUp();
599

600
    BuildNetListBase();
601
    bool success = WriteNetListFile( aFormat, aFullFileName, aNetlistOptions );
602

603
    return success;
604 605 606
}


607
void NETLIST_DIALOG::OnCancelClick( wxCommandEvent& event )
608
{
609
    EndModal( wxID_CANCEL );
610 611 612
}


613
void NETLIST_DIALOG::RunSimulator( wxCommandEvent& event )
614
{
615
    wxFileName fn;
616
    wxString   ExecFile, CommandLine;
617

618 619 620 621 622 623
    wxString tmp = m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->GetValue();
    tmp.Trim( false );
    tmp.Trim( true );
    m_Parent->SetSimulatorCommand( tmp );
    ExecFile = tmp.BeforeFirst( ' ' );
    CommandLine = tmp.AfterFirst( ' ' );
624 625

    /* Calculate the netlist filename */
626
    fn = g_RootSheet->GetScreen()->GetFileName();
627 628
    fn.SetExt( wxT( "cir" ) );
    CommandLine += wxT( " \"" ) + fn.GetFullPath() + wxT( "\"" );
629

630 631
    NETLIST_PAGE_DIALOG* currPage;
    currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
632

633 634
    // Set spice netlist options:
    unsigned netlist_opt = 0;
635

636
    if( currPage->m_AddSubPrefix && currPage->m_AddSubPrefix->GetValue() )
637
        netlist_opt |= NET_USE_X_PREFIX;
638

639
    if( ! m_Parent->CreateNetlist( currPage->m_IdNetType, fn.GetFullPath(),
640
                                   netlist_opt ) )
641 642
        return;

643 644 645 646
    ExecuteFile( this, ExecFile, CommandLine );
}


647 648
/**
 * Function WriteCurrentNetlistSetup
649 650
 * Write the current netlist options setup in the configuration
 */
651
void NETLIST_DIALOG::WriteCurrentNetlistSetup( void )
652
{
653
    wxString  msg, Command;
654

655
    NetlistUpdateOpt();
656

657
    m_config->Write( NETLIST_USE_DEFAULT_NETNAME, GetUseDefaultNetlistName() );
658

659 660 661
    // Update the new titles
    for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
    {
662
        NETLIST_PAGE_DIALOG* currPage = m_PanelNetType[ii + PANELCUSTOMBASE];
663

664
        if( currPage == NULL )
665
            break;
666

667
        msg = wxT( "Custom" );
668
        msg << ii + 1;
669

670
        if( currPage->m_TitleStringCtrl )
671
        {
672 673
            wxString title = currPage->m_TitleStringCtrl->GetValue();
            currPage->SetPageNetFmtName( title );
674

675 676 677 678
            if( msg != title ) // Title has changed, Update config
            {
                msg = CUSTOM_NETLIST_TITLE;
                msg << ii + 1;
679
                m_config->Write( msg, title );
680 681 682
            }
        }

683
        if( currPage->m_CommandStringCtrl )
684
        {
685
            Command = currPage->m_CommandStringCtrl->GetValue();
686
            msg     = CUSTOM_NETLIST_COMMAND;
687
            msg << ii + 1;
688
            m_config->Write( msg, Command );
689 690
        }
    }
691 692
}

693

694
/**
695
 * Function OnDelPlugin
696 697
 * Remove a panel relative to a netlist plugin
 */
698
void NETLIST_DIALOG::OnDelPlugin( wxCommandEvent& event )
699
{
700
    NETLIST_PAGE_DIALOG* currPage = (NETLIST_PAGE_DIALOG*) m_NoteBook->GetCurrentPage();
701

702 703
    currPage->m_CommandStringCtrl->SetValue( wxEmptyString );
    currPage->m_TitleStringCtrl->SetValue( wxEmptyString );
704

705
    if( currPage->m_IsCurrentFormat->IsChecked() )
706
    {
707
        currPage->m_IsCurrentFormat->SetValue( false );
708
        m_PanelNetType[PANELPCBNEW]->m_IsCurrentFormat->SetValue( true );
709
    }
710

711 712 713
    WriteCurrentNetlistSetup();
    EndModal( NET_PLUGIN_CHANGE );
}
714

715
/**
716 717
 * Function OnAddPlugin
 * Add a new panel for a new netlist plugin
718
 */
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
void NETLIST_DIALOG::OnAddPlugin( wxCommandEvent& event )
{
    NETLIST_DIALOG_ADD_PLUGIN dlg( this );
    if( dlg.ShowModal() != wxID_OK )
        return;

    // Creates a new custom plugin page
    wxString title = dlg.GetPluginTitle();

    // Verify it does not exists
    int netTypeId = PANELCUSTOMBASE;    // the first not used type id
    NETLIST_PAGE_DIALOG* currPage;
    for( int ii = 0; ii < CUSTOMPANEL_COUNTMAX; ii++ )
    {
        netTypeId = PANELCUSTOMBASE + ii;
        currPage = m_PanelNetType[ii + PANELCUSTOMBASE];

        if( currPage == NULL )
            break;

        if( currPage->GetPageNetFmtName() == title )
        {
            wxMessageBox( _("This plugin already exists. Abort") );
            return;
        }
    }

    wxString cmd = dlg.GetPluginTCommandLine();
    currPage = AddOneCustomPage( title,cmd, (NETLIST_TYPE_ID)netTypeId );
    m_PanelNetType[netTypeId] = currPage;
    WriteCurrentNetlistSetup();

    // Close and reopen dialog to rebuild the dialog after changes
    EndModal( NET_PLUGIN_CHANGE );
}


NETLIST_DIALOG_ADD_PLUGIN::NETLIST_DIALOG_ADD_PLUGIN( NETLIST_DIALOG* parent ) :
    NETLIST_DIALOG_ADD_PLUGIN_BASE( parent )
758
{
759 760 761
    m_Parent = parent;
    GetSizer()->SetSizeHints( this );
}
762

763 764 765 766 767 768 769
/**
 * Function OnOKClick
 * Validate info relative to a new netlist plugin
 */
void NETLIST_DIALOG_ADD_PLUGIN::OnOKClick( wxCommandEvent& event )
{
    if( m_textCtrlCommand->GetValue() == wxEmptyString )
770
    {
771
        wxMessageBox( _( "Error. You must provide a command String" ) );
772 773
        return;
    }
774

775
    if( m_textCtrlName->GetValue() == wxEmptyString )
776
    {
777
        wxMessageBox( _( "Error. You must provide a Title" ) );
778 779
        return;
    }
780

781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
    EndModal( wxID_OK );
}

void NETLIST_DIALOG_ADD_PLUGIN::OnCancelClick( wxCommandEvent& event )
{
    EndModal( wxID_CANCEL );
}

/*
 * Browse plugin files, and set m_CommandStringCtrl field
 */
void NETLIST_DIALOG_ADD_PLUGIN::OnBrowsePlugins( wxCommandEvent& event )
{
    wxString FullFileName, Mask, Path;

    Mask = wxT( "*" );
    Path = wxGetApp().GetExecutablePath();
    FullFileName = EDA_FileSelector( _( "Plugin files:" ),
                                     Path,
                                     FullFileName,
                                     wxEmptyString,
                                     Mask,
                                     this,
                                     wxFD_OPEN,
                                     true
                                     );
    if( FullFileName.IsEmpty() )
        return;

    // Creates a default command line, suitable for external tool xslproc:
    // try to build a default command line depending on plugin extension
    wxString cmdLine;
    wxFileName fn( FullFileName );
    wxString ext = fn.GetExt();

    if( ext == wxT("xsl" ) )
        cmdLine.Printf(wxT("xsltproc -o \"%%O\" \"%s\" \"%%I\""), GetChars(FullFileName) );
    else if( ext == wxT("exe" ) || ext.IsEmpty() )
        cmdLine.Printf(wxT("\"%s\" > \"%%O\" < \"%%I\""), GetChars(FullFileName) );
    else
        cmdLine.Printf(wxT("\"%s\""), GetChars(FullFileName) );

    m_textCtrlCommand->SetValue( cmdLine );

    /* Get a title for this page */
    wxString title = m_textCtrlName->GetValue();

    if( title.IsEmpty() )
        wxMessageBox( _( "Do not forget to choose a title for this netlist control page" ) );
830
}