diff --git a/CMakeModules/Html2C.cmake b/CMakeModules/Html2C.cmake index 2c44322d64..99919b31ce 100644 --- a/CMakeModules/Html2C.cmake +++ b/CMakeModules/Html2C.cmake @@ -8,5 +8,6 @@ file( STRINGS ${inputFile} lines ) file( WRITE ${outputFile} "// Do not edit this file, it is autogenerated by CMake from an HTML file\n" ) foreach( line ${lines} ) - file( APPEND ${outputFile} "\"" ${line} "\"\n" ) + STRING(REGEX REPLACE "\"" "\\\\\"" linem ${line}) + file( APPEND ${outputFile} "\"" ${linem} "\\n\"\n" ) endforeach( line ${lines} ) diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 416b853cf3..6c22e75182 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -14,6 +14,9 @@ set(EESCHEMA_DLGS dialogs/dialog_color_config.cpp dialogs/dialog_annotate.cpp dialogs/dialog_annotate_base.cpp + dialogs/dialog_bom.cpp + dialogs/dialog_bom_base.cpp + dialogs/dialog_bom_cfg_keywords.cpp dialogs/dialog_lib_edit_text.cpp dialogs/dialog_lib_edit_text_base.cpp dialogs/dialog_edit_component_in_lib.cpp @@ -203,6 +206,33 @@ make_lexer( template_fieldnames.h ) +make_lexer( + ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg.keywords + ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_lexer.h + ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_keywords.cpp + T_BOMCFG_T + + # Pass header file with dependency on *_lexer.h as extra_arg + /dialogs/dialog_bom_cfg.h + ) + +# Create a C++ compilable string initializer containing html text into a *.h file: +add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + COMMAND ${CMAKE_COMMAND} + -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html + -DoutputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + -P ${CMAKE_MODULE_PATH}/Html2C.cmake + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html + COMMENT "creating ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + from ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html" + ) + +set_source_files_properties( dialogs/dialog_bom.cpp + PROPERTIES + OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + ) + add_executable(eeschema WIN32 MACOSX_BUNDLE ${EESCHEMA_SRCS} ${EESCHEMA_COMMON_SRCS} diff --git a/eeschema/component_references_lister.cpp b/eeschema/component_references_lister.cpp index df0f97effe..e352f785df 100644 --- a/eeschema/component_references_lister.cpp +++ b/eeschema/component_references_lister.cpp @@ -67,7 +67,6 @@ bool SCH_REFERENCE_LIST::sortByXPosition( const SCH_REFERENCE& item1, return ii < 0; } - bool SCH_REFERENCE_LIST::sortByYPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ) { @@ -106,252 +105,6 @@ bool SCH_REFERENCE_LIST::sortByRefAndValue( const SCH_REFERENCE& item1, return ii < 0; } -bool SCH_REFERENCE_LIST::sortByValueAndRef( const SCH_REFERENCE& item1, - const SCH_REFERENCE& item2 ) -{ - int ii = item1.CompareValue( item2 ); - - if( ii == 0 ) - ii = RefDesStringCompare( item1.GetRef(), item2.GetRef() ); - - if( ii == 0 ) - ii = item1.m_Unit - item2.m_Unit; - - if( ii == 0 ) - ii = item1.m_SheetNum - item2.m_SheetNum; - - if( ii == 0 ) - ii = item1.m_CmpPos.x - item2.m_CmpPos.x; - - if( ii == 0 ) - ii = item1.m_CmpPos.y - item2.m_CmpPos.y; - - if( ii == 0 ) - ii = item1.m_TimeStamp - item2.m_TimeStamp; - - return ii < 0; -} - -/* - * Helper function to calculate in a component value string - * the value, depending on multiplier symbol: - * pico - * nano - * micro (u) - * milli (m) - * kilo (k ou K) - * Mega - * Giga - * Tera - * - * with notations like 1K; 1.5K; 1,5K; 1k5 - * returns true if the string is a value, false if not - * (a value is a string starting by a number) - */ - -static bool engStrToDouble( wxString aStr, double* aDouble ) -{ - // A trick to take care of strings without a multiplier - aStr.Append( wxT( "R" ) ); - - // Regular expression for a value string, e.g., 47k2 -#if defined(KICAD_GOST) - static wxRegEx valueRegEx( wxT( "^([0-9]+)(мк|[pnumRkKMGT.,кнМГ])([0-9]*)(мк*|[pnumRkKMGTкнМГ]*)" ) ); -#else - static wxRegEx valueRegEx( wxT( "^([0-9]+)([pnumRkKMGT.,])([0-9]*)([pnumRkKMGT]*)" ) ); -#endif - - if( !valueRegEx.Matches( aStr ) ) - return false; - - wxString valueStr = wxString( valueRegEx.GetMatch( aStr, 1 ) - + wxT( "." ) - + valueRegEx.GetMatch( aStr, 3 ) ); - wxString multiplierString = valueRegEx.GetMatch( aStr, 2 ); -#if defined(KICAD_GOST) - if ( multiplierString == wxT( "мк" ) ) - multiplierString = wxT( "u" ); - else if ( multiplierString == wxT( "к" ) ) - multiplierString = wxT( "k" ); - else if ( multiplierString == wxT( "н" ) ) - multiplierString = wxT( "n" ); - else if ( multiplierString == wxT( "М" ) ) - multiplierString = wxT( "M" ); - else if ( multiplierString == wxT( "Г" ) ) - multiplierString = wxT( "G" ); -#endif - wxString post_multiplierString = valueRegEx.GetMatch( aStr, 4 ); -#if defined(KICAD_GOST) - if ( post_multiplierString == wxT( "мк" ) ) - multiplierString = wxT( "u" ); - else if ( post_multiplierString == wxT( "к" ) ) - multiplierString = wxT( "k" ); - else if ( post_multiplierString == wxT( "н" ) ) - multiplierString = wxT( "n" ); - else if ( post_multiplierString == wxT( "М" ) ) - multiplierString = wxT( "M" ); - else if ( post_multiplierString == wxT( "Г" ) ) - multiplierString = wxT( "G" ); -#endif - double multiplier; - - switch( (wxChar)multiplierString[0] ) - { - case 'p': - multiplier = 1e-12; - break; - case 'n': - multiplier = 1e-9; - break; - case 'u': - multiplier = 1e-6; - break; - case 'm': - multiplier = 1e-3; - break; - case 'k': - case 'K': - multiplier = 1e3; - break; - case 'M': - multiplier = 1e6; - break; - case 'G': - multiplier = 1e9; - break; - case 'T': - multiplier = 1e12; - break; - case 'R': - case '.': // floating point separator - case ',': // floating point separator (some languages) - default: - multiplier = 1; - break; - } - - switch( (wxChar)post_multiplierString[0] ) - { - case 'p': - multiplier = 1e-12; - break; - case 'n': - multiplier = 1e-9; - break; - case 'u': - multiplier = 1e-6; - break; - case 'm': - multiplier = 1e-3; - break; - case 'k': - case 'K': - multiplier = 1e3; - break; - case 'M': - multiplier = 1e6; - break; - case 'G': - multiplier = 1e9; - break; - case 'T': - multiplier = 1e12; - break; - case 'R': - default: - break; - } - - LOCALE_IO dummy; // set to C floating point standard - valueStr.ToDouble( aDouble ); - *aDouble *= multiplier; - - return true; -} - - -static bool splitRefStr( const wxString& aRef, wxString* aStr, int* aNumber ) -{ - static wxRegEx refRegEx( wxT( "^([a-zA-Z]+)([0-9]+)" ) ); - - if( !refRegEx.Matches( aRef ) ) - return false; - - *aStr = refRegEx.GetMatch( aRef, 1 ); - *aNumber = wxAtoi( refRegEx.GetMatch( aRef, 2 ) ); - return true; -} - -/* sort the list of references by value. - * Components are grouped by type and are sorted by value: - * The value of a component accept multiplier symbols (p, n, K ..) - * groups are made by first letter of reference - */ -bool SCH_REFERENCE_LIST::sortByValueOnly( const SCH_REFERENCE& item1, - const SCH_REFERENCE& item2 ) -{ - // First, group by type according to reference text part (R, C, etc.) - wxString text1 = item1.GetComponent()->GetField( REFERENCE )->GetText(); - wxString text2 = item2.GetComponent()->GetField( REFERENCE )->GetText(); - wxString refNameStr1, refNameStr2; - int refNumber1, refNumber2; - - if( !splitRefStr( text1, &refNameStr1, &refNumber1 ) ) - return false; - - if( !splitRefStr( text2, &refNameStr2, &refNumber2 ) ) - return false; - - int ii = refNameStr1.CmpNoCase( refNameStr2 ); - - if( ii != 0 ) - return ii < 0; - - // We can compare here 2 values relative to components of the same type - // assuming references are correctly chosen - text1 = item1.GetComponent()->GetField( VALUE )->GetText(); - text2 = item2.GetComponent()->GetField( VALUE )->GetText(); - - double value1, value2; - - // Try to convert value to double (4k7 -> 4700 etc.) - bool match1 = engStrToDouble( text1, &value1 ); - bool match2 = engStrToDouble( text2, &value2 ); - - // Values come before other strings - if( match1 && !match2 ) - return true; - - // Values come before other strings - if( !match1 && match2 ) - return false; - - if( match1 && match2 && (value1 != value2) ) - return value1 < value2; - - // Inside a group of components of same value, it could be good to group per footprints - text1 = item1.GetComponent()->GetField( FOOTPRINT )->GetText(); - text2 = item2.GetComponent()->GetField( FOOTPRINT )->GetText(); - ii = text1.CmpNoCase( text2 ); - - if( ii != 0 ) - return ii < 0; - - if( refNumber1 != refNumber2 ) - return refNumber1 < refNumber2; - - // Fall back to normal string compare - ii = text1.CmpNoCase( text2 ); - - if( ii == 0 ) - ii = RefDesStringCompare( item1.GetRef(), item2.GetRef() ); - - if( ii == 0 ) - ii = item1.m_Unit - item2.m_Unit; - - return ii < 0; -} - bool SCH_REFERENCE_LIST::sortByReferenceOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ) @@ -385,7 +138,6 @@ bool SCH_REFERENCE_LIST::sortByTimeStamp( const SCH_REFERENCE& item1, return ii < 0; } - int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit ) { int NumRef; diff --git a/eeschema/dialogs/dialog_bom.cpp b/eeschema/dialogs/dialog_bom.cpp new file mode 100644 index 0000000000..59c4184400 --- /dev/null +++ b/eeschema/dialogs/dialog_bom.cpp @@ -0,0 +1,490 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 Jean-Pierre Charras, jp.charras@wanadoo.fr + * Copyright (C) 1992-2013 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 + */ + +/** + * @file eeschema/dialogs/dialog_bom.cpp + * @brief Dialog box for creating bom and other documents from generic netlist. + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include <../common/dialogs/dialog_display_info_HTML_base.h> + +#define BOM_PLUGINS_KEY wxT("bom_plugins") +#define BOM_PLUGIN_SELECTED_KEY wxT("bom_plugin_selected") + +const char * s_bomHelpInfo = +#include +; + +#include + +using namespace T_BOMCFG_T; + +/** + * Class BOM_CFG_READER_PARSER + * holds data and functions pertinent to parsing a S-expression file + * for a WORKSHEET_LAYOUT. + */ +class BOM_CFG_READER_PARSER : public DIALOG_BOM_CFG_LEXER +{ + wxArrayString* m_pluginsList; + +public: + BOM_CFG_READER_PARSER( wxArrayString* aPlugins, + const char* aData, const wxString& aSource ); + void Parse() throw( PARSE_ERROR, IO_ERROR ); + +private: + void parsePlugin() throw( IO_ERROR, PARSE_ERROR ); + +}; + +// PCB_PLOT_PARAMS_PARSER + +BOM_CFG_READER_PARSER::BOM_CFG_READER_PARSER( wxArrayString* aPlugins, + const char* aLine, + const wxString& aSource ) : + DIALOG_BOM_CFG_LEXER( aLine, aSource ) +{ + m_pluginsList = aPlugins; +} + + +void BOM_CFG_READER_PARSER::Parse() throw( PARSE_ERROR, IO_ERROR ) +{ + T token; + + while( ( token = NextTok() ) != T_RIGHT ) + { + if( token == T_EOF) + break; + + if( token == T_LEFT ) + token = NextTok(); + + if( token == T_plugins ) + continue; + + switch( token ) + { + case T_plugin: // Defines a new plugin + parsePlugin(); + break; + + default: +// Unexpected( CurText() ); + break; + } + } +} + +void BOM_CFG_READER_PARSER::parsePlugin() throw( IO_ERROR, PARSE_ERROR ) +{ + wxString title, command; + + NeedSYMBOLorNUMBER(); + title = FromUTF8(); + + T token; + while( ( token = NextTok() ) != T_RIGHT ) + { + if( token == T_EOF) + break; + + switch( token ) + { + case T_LEFT: + break; + + case T_cmd: + NeedSYMBOLorNUMBER(); + command = FromUTF8(); + NeedRIGHT(); + break; + + case T_opts: + while( ( token = NextTok() ) != T_RIGHT && token != T_EOF ); + break; + + default: + Unexpected( CurText() ); + break; + } + } + + if( ! title.IsEmpty() ) + { + m_pluginsList->Add( title ); + m_pluginsList->Add( command ); + } +} + +// The main dialog frame tu run scripts to build bom +class DIALOG_BOM : public DIALOG_BOM_BASE +{ +private: + SCH_EDIT_FRAME* m_parent; + // The list of scripts (or plugins): + // a script descr uses 2 lines: + // the first is the title + // the second is the command line + wxArrayString m_plugins; + wxConfig* m_config; // to store the "plugins" + +public: + // Constructor and destructor + DIALOG_BOM( SCH_EDIT_FRAME* parent ); + ~DIALOG_BOM(); + +private: + void OnPluginSelected( wxCommandEvent& event ); + void OnRunPlugin( wxCommandEvent& event ); + void OnCancelClick( wxCommandEvent& event ); + void OnHelp( wxCommandEvent& event ); + void OnAddPlugin( wxCommandEvent& event ); + void OnChoosePlugin( wxCommandEvent& event ); + void OnRemovePlugin( wxCommandEvent& event ); + void OnEditPlugin( wxCommandEvent& event ); + void OnCommandLineEdited( wxCommandEvent& event ); + void OnNameEdited( wxCommandEvent& event ); + + void pluginInit(); + void installPluginsList(); +}; + +// Create and show DIALOG_BOM. +int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller ) +{ + DIALOG_BOM dlg( aCaller ); + return dlg.ShowModal(); +} + +DIALOG_BOM::DIALOG_BOM( SCH_EDIT_FRAME* parent ) : + DIALOG_BOM_BASE( parent ) +{ + m_parent = parent; + m_config = wxGetApp().GetSettings(); + installPluginsList(); + + GetSizer()->SetSizeHints( this ); + Centre(); +} + +DIALOG_BOM::~DIALOG_BOM() +{ + wxString list; + + // Save the plugin descriptions in config. + // the config stores only one string. + // plugins are saved inside a S expr: + // ( plugins + // ( plugin "plugin name" (cmd "command line") ) + // .... + // ) + + STRING_FORMATTER writer; + list << wxT("(plugins"); + for( unsigned ii = 0; ii < m_plugins.GetCount(); ii += 2 ) + { + writer.Print( 1, "(plugin %s (cmd %s))", + writer.Quotew( m_plugins[ii] ).c_str(), + writer.Quotew( m_plugins[ii+1] ).c_str() ); + } + + list << writer.GetString(); + list << wxT(")"); + + m_config->Write( BOM_PLUGINS_KEY, list ); + + wxString active_plugin_name = m_lbPlugins->GetStringSelection( ); + m_config->Write( BOM_PLUGIN_SELECTED_KEY, active_plugin_name ); + +} + +/* Read the initialized plugins in config and fill the list + * of names + */ +void DIALOG_BOM::installPluginsList() +{ + wxString list, text, active_plugin_name; + m_config->Read( BOM_PLUGINS_KEY, &list ); + m_config->Read( BOM_PLUGIN_SELECTED_KEY, &active_plugin_name ); + + if( !list.IsEmpty() ) + { + BOM_CFG_READER_PARSER cfg_parser( &m_plugins, list.c_str(), wxT( "plugins" ) ); + try + { + cfg_parser.Parse(); + } + catch( IO_ERROR ioe ) + { +// wxLogMessage( ioe.errorText ); + } + } + + // Populate list box + for( unsigned ii = 0; ii < m_plugins.GetCount(); ii+=2 ) + { + m_lbPlugins->Append( m_plugins[ii] ); + + if( active_plugin_name == m_plugins[ii] ) + m_lbPlugins->SetSelection( ii/2 ); + } + + pluginInit(); +} + +void DIALOG_BOM::OnPluginSelected( wxCommandEvent& event ) +{ + pluginInit(); +} + +void DIALOG_BOM::pluginInit() +{ + int ii = m_lbPlugins->GetSelection(); + + if( ii < 0 ) + { + m_textCtrlName->SetValue( wxEmptyString ); + m_textCtrlCommand->SetValue( wxEmptyString ); + return; + } + + m_textCtrlName->SetValue( m_plugins[2 * ii] ); + m_textCtrlCommand->SetValue( m_plugins[(2 * ii)+1] ); +} + + +/** + * Function RunPlugin + * run the plugin command line + */ +void DIALOG_BOM::OnRunPlugin( wxCommandEvent& event ) +{ + wxFileName fn; + wxString fileWildcard; + wxString title = _( "Save Netlist File" ); + + // Calculate the xml netlist filename + fn = g_RootSheet->GetScreen()->GetFileName(); + + if( fn.GetPath().IsEmpty() ) + fn.SetPath( wxGetCwd() ); + + fn.ClearExt(); + wxString fullfilename = fn.GetFullPath(); + m_parent->ClearMsgPanel(); + + m_parent->SetNetListerCommand( m_textCtrlCommand->GetValue() ); + m_parent->CreateNetlist( -1, fullfilename, 0 ); +} + + +void DIALOG_BOM::OnCancelClick( wxCommandEvent& event ) +{ + EndModal( wxID_CANCEL ); +} + + +/** + * Function OnRemovePlugin + * Remove a plugin from the list + */ +void DIALOG_BOM::OnRemovePlugin( wxCommandEvent& event ) +{ + int ii = m_lbPlugins->GetSelection(); + + if( ii < 0 ) + return; + + m_lbPlugins->Delete( ii ); + + m_plugins.RemoveAt( 2*ii, 2 ); // Remove title and command line + + // Select the next item, if exists + if( (int)m_lbPlugins->GetCount() >= ii ) + ii = m_lbPlugins->GetCount() - 1; + + if( ii >= 0 ) + m_lbPlugins->SetSelection( ii ); + + pluginInit(); +} + +/** + * Function OnAddPlugin + * Add a new panel for a new netlist plugin + */ +void DIALOG_BOM::OnAddPlugin( wxCommandEvent& event ) +{ + // Creates a new plugin entry + wxString name = wxGetTextFromUser( _("Plugin") ); + + if( name.IsEmpty() ) + return; + + // Verify if it does not exists + for( unsigned ii = 0; ii < m_plugins.GetCount(); ii += 2 ) + { + if( name == m_plugins[ii] ) + { + wxMessageBox( _("This plugin already exists. Abort") ); + return; + } + } + + m_plugins.Add( name ); + m_plugins.Add( wxEmptyString ); + m_lbPlugins->Append( name ); + m_lbPlugins->SetSelection( m_lbPlugins->GetCount() - 1 ); + pluginInit(); +} + +/* + * Browse plugin files, and set m_CommandStringCtrl field + */ +void DIALOG_BOM::OnChoosePlugin( 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 to run the external tool xslproc or python + // The default command line depending on plugin extension, currently + // "xsl" or "exe" or "py" + 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\" < \"%%I\" > \"%%O\""), GetChars(FullFileName) ); + else if( ext == wxT("py" ) || ext.IsEmpty() ) + cmdLine.Printf(wxT("python \"%s\" \"%%I\" \"%%O\""), GetChars(FullFileName) ); + else + cmdLine.Printf(wxT("\"%s\""), GetChars(FullFileName) ); + + m_textCtrlCommand->SetValue( cmdLine ); +} + +void DIALOG_BOM::OnEditPlugin( wxCommandEvent& event ) +{ + wxString pluginName, cmdline; + + // Try to find the plugin name. + // This is possible if the name ends by .py or .xsl + cmdline = m_textCtrlCommand->GetValue(); + int pos = -1; + + if( (pos = cmdline.Find( wxT(".py") )) != wxNOT_FOUND ) + pos += 2; + else if( (pos = cmdline.Find( wxT(".xsl") )) != wxNOT_FOUND ) + pos += 3; + + // the end of plugin name is at position pos. + if( pos > 0 ) + { + // Be sure this is the end of the name: the next char is " or space + int eos = cmdline[pos+1]; + + if( eos == ' '|| eos == '\"' ) + { + // search for the starting point of the name + int jj = pos-1; + while( jj >= 0 ) + if( cmdline[jj] != eos ) + jj--; + else + break; + + // extract the name + if( jj >= 0 ) + pluginName = cmdline.SubString( jj, pos ); + } + } + AddDelimiterString( pluginName ); + wxString editorname = wxGetApp().GetEditorName(); + + if( !editorname.IsEmpty() ) + ExecuteFile( this, editorname, pluginName ); + else + wxMessageBox( _("No text editor selected in KiCad. Please choose it") ); +} + +void DIALOG_BOM::OnHelp( wxCommandEvent& event ) +{ + DIALOG_DISPLAY_HTML_TEXT_BASE help_Dlg( this, wxID_ANY, + _("Bom generation Help"),wxDefaultPosition, wxSize( 750,550 ) ); + + wxString msg = FROM_UTF8(s_bomHelpInfo); + help_Dlg.m_htmlWindow->AppendToPage( msg ); + help_Dlg.ShowModal(); +} + +void DIALOG_BOM::OnCommandLineEdited( wxCommandEvent& event ) +{ + int ii = m_lbPlugins->GetSelection(); + + if( ii < 0 ) + return; + + m_plugins[(2 * ii)+1] = m_textCtrlCommand->GetValue(); +} + +void DIALOG_BOM::OnNameEdited( wxCommandEvent& event ) +{ + int ii = m_lbPlugins->GetSelection(); + + if( ii < 0 ) + return; + + m_plugins[2 * ii] = m_textCtrlName->GetValue(); + m_lbPlugins->SetString( ii, m_plugins[2 * ii] ); +} diff --git a/eeschema/dialogs/dialog_bom_base.cpp b/eeschema/dialogs/dialog_bom_base.cpp new file mode 100644 index 0000000000..03151f1232 --- /dev/null +++ b/eeschema/dialogs/dialog_bom_base.cpp @@ -0,0 +1,115 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 8 2012) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_bom_base.h" + +/////////////////////////////////////////////////////////////////////////// + +BEGIN_EVENT_TABLE( DIALOG_BOM_BASE, DIALOG_SHIM ) + EVT_LISTBOX( wxID_ANY, DIALOG_BOM_BASE::_wxFB_OnPluginSelected ) + EVT_TEXT( IN_NAMELINE, DIALOG_BOM_BASE::_wxFB_OnNameEdited ) + EVT_BUTTON( ID_CREATE_BOM, DIALOG_BOM_BASE::_wxFB_OnRunPlugin ) + EVT_BUTTON( wxID_CANCEL, DIALOG_BOM_BASE::_wxFB_OnCancelClick ) + EVT_BUTTON( ID_HELP, DIALOG_BOM_BASE::_wxFB_OnHelp ) + EVT_BUTTON( ID_ADD_PLUGIN, DIALOG_BOM_BASE::_wxFB_OnAddPlugin ) + EVT_BUTTON( wxID_BROWSE_PLUGINS, DIALOG_BOM_BASE::_wxFB_OnChoosePlugin ) + EVT_BUTTON( ID_REMOVEL_PLUGIN, DIALOG_BOM_BASE::_wxFB_OnRemovePlugin ) + EVT_BUTTON( wxID_ANY, DIALOG_BOM_BASE::_wxFB_OnEditPlugin ) + EVT_TEXT( ID_CMDLINE, DIALOG_BOM_BASE::_wxFB_OnCommandLineEdited ) +END_EVENT_TABLE() + +DIALOG_BOM_BASE::DIALOG_BOM_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bMainSizer; + bMainSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bUpperSizer; + bUpperSizer = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bLeftSizer; + bLeftSizer = new wxBoxSizer( wxVERTICAL ); + + m_staticTextPluginTitle = new wxStaticText( this, wxID_ANY, _("Plugins"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextPluginTitle->Wrap( -1 ); + bLeftSizer->Add( m_staticTextPluginTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_lbPlugins = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + bLeftSizer->Add( m_lbPlugins, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_staticTextName = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextName->Wrap( -1 ); + bLeftSizer->Add( m_staticTextName, 0, wxRIGHT|wxLEFT, 5 ); + + m_textCtrlName = new wxTextCtrl( this, IN_NAMELINE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlName->SetMaxLength( 0 ); + bLeftSizer->Add( m_textCtrlName, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bUpperSizer->Add( bLeftSizer, 1, wxEXPAND, 5 ); + + wxBoxSizer* bRightSizer; + bRightSizer = new wxBoxSizer( wxVERTICAL ); + + m_buttonNetlist = new wxButton( this, ID_CREATE_BOM, _("Generate"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNetlist->SetDefault(); + bRightSizer->Add( m_buttonNetlist, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); + bRightSizer->Add( m_buttonCancel, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_buttonHelp = new wxButton( this, ID_HELP, _("Help"), wxDefaultPosition, wxDefaultSize, 0 ); + bRightSizer->Add( m_buttonHelp, 0, wxALL|wxEXPAND, 5 ); + + m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bRightSizer->Add( m_staticline2, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + m_buttonAddPlugin = new wxButton( this, ID_ADD_PLUGIN, _("Add Plugin"), wxDefaultPosition, wxDefaultSize, 0 ); + bRightSizer->Add( m_buttonAddPlugin, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_buttonBrowsePlugin = new wxButton( this, wxID_BROWSE_PLUGINS, _("Set Plugin Cmd"), wxDefaultPosition, wxDefaultSize, 0 ); + bRightSizer->Add( m_buttonBrowsePlugin, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_buttonDelPlugin = new wxButton( this, ID_REMOVEL_PLUGIN, _("Remove Plugin"), wxDefaultPosition, wxDefaultSize, 0 ); + bRightSizer->Add( m_buttonDelPlugin, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_buttonEdit = new wxButton( this, wxID_ANY, _("Edit Plugin File"), wxDefaultPosition, wxDefaultSize, 0 ); + bRightSizer->Add( m_buttonEdit, 0, wxALL|wxEXPAND, 5 ); + + + bUpperSizer->Add( bRightSizer, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bMainSizer->Add( bUpperSizer, 1, wxEXPAND, 5 ); + + wxBoxSizer* bbottomSizer; + bbottomSizer = new wxBoxSizer( wxVERTICAL ); + + m_staticTextCmd = new wxStaticText( this, wxID_ANY, _("Command line:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextCmd->Wrap( -1 ); + bbottomSizer->Add( m_staticTextCmd, 0, wxRIGHT|wxLEFT, 5 ); + + m_textCtrlCommand = new wxTextCtrl( this, ID_CMDLINE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlCommand->SetMaxLength( 0 ); + m_textCtrlCommand->SetMinSize( wxSize( 380,-1 ) ); + + bbottomSizer->Add( m_textCtrlCommand, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bMainSizer->Add( bbottomSizer, 0, wxEXPAND, 5 ); + + + this->SetSizer( bMainSizer ); + this->Layout(); + + this->Centre( wxBOTH ); +} + +DIALOG_BOM_BASE::~DIALOG_BOM_BASE() +{ +} diff --git a/eeschema/dialogs/dialog_bom_base.fbp b/eeschema/dialogs/dialog_bom_base.fbp new file mode 100644 index 0000000000..2174dc853f --- /dev/null +++ b/eeschema/dialogs/dialog_bom_base.fbp @@ -0,0 +1,1357 @@ + + + + + + C++ + 0 + source_name + 0 + 0 + res + UTF-8 + table + dialog_bom_base + 1000 + none + 1 + dialog_bom_base + + . + + 1 + 1 + 1 + 1 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_BOM_BASE + + 404,315 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + DIALOG_SHIM; dialog_shim.h + Bill of Material + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bMainSizer + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bUpperSizer + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + bLeftSizer + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Plugins + + 0 + + + 0 + + 1 + m_staticTextPluginTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_lbPlugins + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + OnPluginSelected + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Name: + + 0 + + + 0 + + 1 + m_staticTextName + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + IN_NAMELINE + + 0 + + 0 + + 0 + + 1 + m_textCtrlName + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnNameEdited + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + bRightSizer + wxVERTICAL + none + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_CREATE_BOM + Generate + + 0 + + + 0 + + 1 + m_buttonNetlist + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRunPlugin + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_CANCEL + Close + + 0 + + + 0 + + 1 + m_buttonCancel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnCancelClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_HELP + Help + + 0 + + + 0 + + 1 + m_buttonHelp + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnHelp + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline2 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_ADD_PLUGIN + Add Plugin + + 0 + + + 0 + + 1 + m_buttonAddPlugin + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnAddPlugin + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_BROWSE_PLUGINS + Set Plugin Cmd + + 0 + + + 0 + + 1 + m_buttonBrowsePlugin + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnChoosePlugin + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_REMOVEL_PLUGIN + Remove Plugin + + 0 + + + 0 + + 1 + m_buttonDelPlugin + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRemovePlugin + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Edit Plugin File + + 0 + + + 0 + + 1 + m_buttonEdit + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnEditPlugin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bbottomSizer + wxVERTICAL + none + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Command line: + + 0 + + + 0 + + 1 + m_staticTextCmd + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_CMDLINE + + 0 + + 0 + + 0 + 380,-1 + 1 + m_textCtrlCommand + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnCommandLineEdited + + + + + + + + + + + + diff --git a/eeschema/dialogs/dialog_bom_base.h b/eeschema/dialogs/dialog_bom_base.h new file mode 100644 index 0000000000..7d4579e81b --- /dev/null +++ b/eeschema/dialogs/dialog_bom_base.h @@ -0,0 +1,100 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 8 2012) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __DIALOG_BOM_BASE_H__ +#define __DIALOG_BOM_BASE_H__ + +#include +#include +#include +class DIALOG_SHIM; + +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_BOM_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_BOM_BASE : public DIALOG_SHIM +{ + DECLARE_EVENT_TABLE() + private: + + // Private event handlers + void _wxFB_OnPluginSelected( wxCommandEvent& event ){ OnPluginSelected( event ); } + void _wxFB_OnNameEdited( wxCommandEvent& event ){ OnNameEdited( event ); } + void _wxFB_OnRunPlugin( wxCommandEvent& event ){ OnRunPlugin( event ); } + void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); } + void _wxFB_OnHelp( wxCommandEvent& event ){ OnHelp( event ); } + void _wxFB_OnAddPlugin( wxCommandEvent& event ){ OnAddPlugin( event ); } + void _wxFB_OnChoosePlugin( wxCommandEvent& event ){ OnChoosePlugin( event ); } + void _wxFB_OnRemovePlugin( wxCommandEvent& event ){ OnRemovePlugin( event ); } + void _wxFB_OnEditPlugin( wxCommandEvent& event ){ OnEditPlugin( event ); } + void _wxFB_OnCommandLineEdited( wxCommandEvent& event ){ OnCommandLineEdited( event ); } + + + protected: + enum + { + IN_NAMELINE = 1000, + ID_CREATE_BOM, + ID_HELP, + ID_ADD_PLUGIN, + wxID_BROWSE_PLUGINS, + ID_REMOVEL_PLUGIN, + ID_CMDLINE + }; + + wxStaticText* m_staticTextPluginTitle; + wxListBox* m_lbPlugins; + wxStaticText* m_staticTextName; + wxTextCtrl* m_textCtrlName; + wxButton* m_buttonNetlist; + wxButton* m_buttonCancel; + wxButton* m_buttonHelp; + wxStaticLine* m_staticline2; + wxButton* m_buttonAddPlugin; + wxButton* m_buttonBrowsePlugin; + wxButton* m_buttonDelPlugin; + wxButton* m_buttonEdit; + wxStaticText* m_staticTextCmd; + wxTextCtrl* m_textCtrlCommand; + + // Virtual event handlers, overide them in your derived class + virtual void OnPluginSelected( wxCommandEvent& event ) { event.Skip(); } + virtual void OnNameEdited( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRunPlugin( wxCommandEvent& event ) { event.Skip(); } + virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnHelp( wxCommandEvent& event ) { event.Skip(); } + virtual void OnAddPlugin( wxCommandEvent& event ) { event.Skip(); } + virtual void OnChoosePlugin( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRemovePlugin( wxCommandEvent& event ) { event.Skip(); } + virtual void OnEditPlugin( wxCommandEvent& event ) { event.Skip(); } + virtual void OnCommandLineEdited( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_BOM_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Bill of Material"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 404,315 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_BOM_BASE(); + +}; + +#endif //__DIALOG_BOM_BASE_H__ diff --git a/eeschema/dialogs/dialog_bom_cfg.keywords b/eeschema/dialogs/dialog_bom_cfg.keywords new file mode 100644 index 0000000000..8790280ce4 --- /dev/null +++ b/eeschema/dialogs/dialog_bom_cfg.keywords @@ -0,0 +1,4 @@ +plugins +plugin +cmd +opts diff --git a/eeschema/dialogs/dialog_bom_help.html b/eeschema/dialogs/dialog_bom_help.html new file mode 100644 index 0000000000..4ba5c5bac1 --- /dev/null +++ b/eeschema/dialogs/dialog_bom_help.html @@ -0,0 +1,210 @@ + + + + + kicad help + + + + + + +

+1 - Full +documentation:

+

+The +Eeschema +documentation, chapter 14 +describes this intermediate netlist and gives examples
See also +
https://answers.launchpad.net/kicad/+faq/2265

+

+2 - The +intermediate Netlist File

+

+BOM files (and +netlist files) can be created from an Intermediate netlist file +created by Eeschema.

+

+This file uses XML +syntax and is called the intermediate netlist. The intermediate +netlist includes a large amount of data about your board and because +of this, it can be used with post-processing to create a BOM or other +reports.

+

+Depending on the +output (BOM or netlist), different subsets of the complete +Intermediate Netlist file will be used in the post-processing.

+

+3 - Conversion to +a new format

+

+By applying a +post-processing filter to the Intermediate netlist file you can +generate foreign netlist files as well as BOM files. Because this +conversion is a text to text transformation.

+

+this post-processing +filter can be written using Python, XSLT, or any other tool capable +of taking XML as input.

+

+XSLT +itself is a XML language very suitable for XML transformations. There +is a free program called xsltproc +that +you can download and install. The +xsltproc +program can be used to read the Intermediate XML netlist input file, +apply a +style-sheet to transform the input, and save the results in an output +file. Use of xsltproc requires a style-sheet file using XSLT +conventions. The full conversion process is handled +by +Eeschema, after it is configured once to run xsltproc in a specific +way.

+

+4 - +Initialization of the dialog window

+

+You should add a new +pluging (a script) in plugin list by clicking on the Add Plugin +button.

+

+4.1 - Plugin +Configuration Parameters

+

+The Eeschema plug-in +configuration dialog requires the following information:

+
    +
  • + The title: for + instance, the name of the netlist format.

    +
  • + The command line to + launch the converter (usually a script).

    +
+

+Once you click on +the generate button the following will happen:

+
    +
  1. + Eeschema creates an + intermediate netlist file *.xml, for instance test.xml.

    +
  2. + Eeschema runs the + script from the command line to create the final output file.

    +
+

+4.2 - Generate +netlist files with the command line

+

+Assuming we are +using the program xsltproc.exe +to +apply the sheet style to the intermediate file, xsltproc.exe +is +executed with the following command.

+

+xsltproc.exe -o < +output filename > < style-sheet filename > < input XML +file to convert >

+

+On +Windows the command line is the +following.
f:/kicad/bin/xsltproc.exe +-o “%O” f:/kicad/bin/plugins/myconverter.xsl “%I”

+

+On +Linux the command becomes as +following.
xsltproc +-o “%O” /usr/local/kicad/bin/plugins/myconverter .xsl +“%I”

+

+Where +myconverter.xsl +is +the style-sheet that you are applying. Do not forget the double +quotes +around +the file names, this allows them to have spaces after the +substitution by Eeschema.

+

+The command line +format accepts parameters for filenames:

+

+The supported +formatting parameters are.

+
    +
  • + %B => base + filename and path of selected output file, minus path and extension.

    +
  • + %I => complete + filename and path of the temporary input file (the intermediate net + file).

    +
  • + %O => complete + filename and path of the user chosen output file.

    +
+

+%I will be replaced +by the actual intermediate file name
%O +will be replaced by the actual output file name.

+

+4.3 - Command +line format: example for xsltproc

+

+The +command line format for xsltproc is the following:
< path of +
xsltproc > xsltproc +< xsltproc parameters >

+

+On +Windows:
f:/kicad/bin/xsltproc.exe -o “%O” +f:/kicad/bin/plugins/netlist_form_pads-pcb.xsl “%I”

+

+On +Linux:
xsltproc +-o “%O” +/usr/local/kicad/bin/plugins/netlist_form_pads-pcb.xsl “%I”

+

+The +above examples assume +xsltproc +is installed on your PC under Windows and all files located in +kicad/bin.

+

+4.4 - Command +line format: example for +python scripts

+

+The command line +format for python is something like:
python +< +script file name > < input filename > < +output filename >

+

+On +Windows:
python.exe f:/kicad/python/my_python_script.py +“%I” “%O”

+

+On Linux:
python +/usr/local/kicad/python/my_python_script.py%I” +“%O”

+

+Assuming python is +installed on your PC.

+

+
+

+ + \ No newline at end of file diff --git a/eeschema/invoke_sch_dialog.h b/eeschema/invoke_sch_dialog.h index a8ccbff50a..a1f6ffcc95 100644 --- a/eeschema/invoke_sch_dialog.h +++ b/eeschema/invoke_sch_dialog.h @@ -37,8 +37,8 @@ // DIALOG_.cpp file. -#ifndef INVOKE_A_DIALOG_H_ -#define INVOKE_A_DIALOG_H_ +#ifndef INVOKE_SCH_DIALOG_H_ +#define INVOKE_SCH_DIALOG_H_ class wxFrame; @@ -61,6 +61,9 @@ wxDialog* InvokeDialogERC( SCH_EDIT_FRAME* aCaller ); /// DIALOG_PRINT_USING_PRINTER::ShowModal() returns. int InvokeDialogPrintUsingPrinter( SCH_EDIT_FRAME* aCaller ); +/// Create and show DIALOG_BOM and return whatever +/// DIALOG_BOM::ShowModal() returns. +int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller ); -#endif // INVOKE_A_DIALOG_H_ +#endif // INVOKE_SCH_DIALOG_H_ diff --git a/eeschema/netlist.h b/eeschema/netlist.h index 55189e5df4..2a3c439366 100644 --- a/eeschema/netlist.h +++ b/eeschema/netlist.h @@ -374,26 +374,6 @@ public: sort( componentFlatList.begin(), componentFlatList.end(), sortByRefAndValue ); } - /** - * Function SortByValueAndRef - * sorts the list of references by value. - *

- * Components are sorted in the following order: - *

    - *
  • Value of component.
  • - *
  • Numeric value of reference designator.
  • - *
  • Unit number when component has multiple parts.
  • - *
  • Sheet number.
  • - *
  • X coordinate position.
  • - *
  • Y coordinate position.
  • - *
- *

- */ - void SortByValueAndRef() - { - sort( componentFlatList.begin(), componentFlatList.end(), sortByValueAndRef ); - } - /** * Function SortByReferenceOnly * sorts the list of references by reference. @@ -410,25 +390,6 @@ public: sort( componentFlatList.begin(), componentFlatList.end(), sortByReferenceOnly ); } - /** - * Function SortByValueOnly - * sort the list of references by value. - *

- * Components are grouped by type and are sorted in the following order: - *

    - *
  • Value of component.
  • - *
  • Numeric value of reference designator.
  • - *
  • Unit number when component has multiple parts.
  • - *
- *

- * groups are made by the first letter of reference - * or the 2 first letters when existing - */ - void SortByValueOnly() - { - sort( componentFlatList.begin(), componentFlatList.end(), sortByValueOnly ); - } - /** * Function GetUnit * searches the sorted list of components for a another component with the same @@ -474,16 +435,12 @@ private: static bool sortByRefAndValue( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); - static bool sortByValueAndRef( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); - static bool sortByXPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); static bool sortByYPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); static bool sortByTimeStamp( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); - static bool sortByValueOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); - static bool sortByReferenceOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); /** diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 289f83e2ea..49fa8390e5 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -632,10 +632,7 @@ void SCH_EDIT_FRAME::OnCreateNetlist( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnCreateBillOfMaterials( wxCommandEvent& ) { - wxMessageDialog dlg( this, - wxT( "https://answers.launchpad.net/kicad/+faq/2265" ), - _( "BOM Howto" ) ); - dlg.ShowModal(); + InvokeDialogCreateBOM( this ); } diff --git a/scripts/bom-in-python/README-bom.txt b/scripts/bom-in-python/README-bom.txt new file mode 100644 index 0000000000..e5be840892 --- /dev/null +++ b/scripts/bom-in-python/README-bom.txt @@ -0,0 +1,14 @@ +bom_?.py are some python scripts which read a generic xml netlist from eeschema, +and create a bom. + +All examples use ky_generic_netlist_reader.py, which is a python utility to read +and parse this generic xml netlist and create the corresponding data +used to build the bom. + +You can modify them to build the bom you want. + +to use them, you should install python, and run: +python bom_example?.py + +See Eeschema doc, chapter 14 for info about the generic xml netlist format, +and how to run a script from Eeschema to create a customized netlist or BOM. diff --git a/scripts/bom-in-python/ky/bom_example5.py b/scripts/bom-in-python/bom-generation.py similarity index 89% rename from scripts/bom-in-python/ky/bom_example5.py rename to scripts/bom-in-python/bom-generation.py index 7f6cd3be69..8746575348 100644 --- a/scripts/bom-in-python/ky/bom_example5.py +++ b/scripts/bom-in-python/bom-generation.py @@ -5,7 +5,7 @@ # # Import the KiCad python helper module and the csv formatter -import ky +import ky_generic_netlist_reader import sys # Start with a basic html template @@ -30,13 +30,13 @@ html = """ """ def myEqu(self, other): - """myEqu is a more advanced equivalence function for components which is + """myEqu is a more advanced equivalence function for components which is used by component grouping. Normal operation is to group components based on their Value, Library source, and Library part. - - In this example of a more advanced equivalency operator we also compare the + + In this example of a more advanced equivalency operator we also compare the custom fields Voltage, Tolerance and Manufacturer as well as the assigned - footprint. If these fields are not used in some parts they will simply be + footprint. If these fields are not used in some parts they will simply be ignored (they will match as both will be empty strings). """ @@ -54,18 +54,18 @@ def myEqu(self, other): elif self.getField("Manufacturer") != other.getField("Manufacturer"): result = False elif self.getField("Voltage") != other.getField("Voltage"): - result = False - + result = False + return result # Override the component equivalence operator - it is important to do this # before loading the netlist, otherwise all components will have the original # equivalency operator. -ky.component.__equ__ = myEqu - +ky_generic_netlist_reader.component.__equ__ = myEqu + # Generate an instance of a generic netlist, and load the netlist tree from # video.tmp. If the file doesn't exist, execution will stop -net = ky.netlist(sys.argv[1]) +net = ky_generic_netlist_reader.netlist(sys.argv[1]) # Open a file to write too, if the file cannot be opened output to stdout # instead @@ -82,31 +82,33 @@ html = html.replace('', net.getTool()) html = html.replace('', "Component Count:" + \ str(len(net.components))) -row = "Ref" + "Qnty" +row = "Ref" + "Qnty" row += "Value" + "Part" + "Datasheet" row += "Description" + "Vendor" - + html = html.replace('', row + "") -# Get all of the components in groups of matching parts + values (see ky.py) +# Get all of the components in groups of matching parts + values +# (see ky_generic_netlist_reader.py) grouped = net.groupComponents() # Output all of the component information for group in grouped: refs = "" - # Add the reference of every component in the group and keep a reference + # Add the reference of every component in the group and keep a reference # to the component so that the other data can be filled in once per group for component in group: refs += component.getRef() + ", " c = component - row = "" + refs +"" + str(len(group)) - row += "" + c.getValue() + "" + c.getLib() + "/" - row += c.getPart() + "" + c.getDatasheet() + "" - row += c.getDescription() + "" + c.getField("Vendor") + row = "\n " + row += "" + refs +"" + str(len(group)) + row += "" + c.getValue() + "" + c.getLib() + "/" + row += c.getPart() + "" + c.getDatasheet() + "" + row += c.getDescription() + "" + c.getField("Vendor") row += "" - + html = html.replace('', row + "") # Print the formatted html to output file diff --git a/scripts/bom-in-python/ky/bom_example1.py b/scripts/bom-in-python/bom_csv_by_ref.py similarity index 82% rename from scripts/bom-in-python/ky/bom_example1.py rename to scripts/bom-in-python/bom_csv_by_ref.py index 354c6b5686..ccc874fd16 100644 --- a/scripts/bom-in-python/ky/bom_example1.py +++ b/scripts/bom-in-python/bom_csv_by_ref.py @@ -5,13 +5,13 @@ # # Import the KiCad python helper module and the csv formatter -import ky +import ky_generic_netlist_reader import csv import sys # Generate an instance of a generic netlist, and load the netlist tree from # the command line option. If the file doesn't exist, execution will stop -net = ky.netlist(sys.argv[1]) +net = ky_generic_netlist_reader.netlist(sys.argv[1]) # Open a file to write to, if the file cannot be opened output to stdout # instead @@ -23,16 +23,16 @@ except IOError: # Create a new csv writer object to use as the output formatter, although we # are created a tab delimited list instead! -out = csv.writer(f, delimiter='\t', quoting=csv.QUOTE_NONE) +out = csv.writer(f, lineterminator='\n', delimiter='\t', quoting=csv.QUOTE_NONE) # Output a field delimited header line out.writerow(['Source:', net.getSource()]) out.writerow(['Date:', net.getDate()]) out.writerow(['Tool:', net.getTool()]) -out.writerow(['Component Count:', len(net.components)]) +out.writerow(['Component Count:', len(net.components)]) out.writerow(['Ref', 'Value', 'Part', 'Documentation', 'Description', 'Vendor']) # Output all of the component information for c in net.components: - out.writerow([c.getRef(), c.getValue(), c.getLib() + "/" + c.getPart(), + out.writerow([c.getRef(), c.getValue(), c.getLib() + "/" + c.getPart(), c.getDatasheet(), c.getDescription(), c.getField("Vendor")]) diff --git a/scripts/bom-in-python/ky/bom_example2.py b/scripts/bom-in-python/bom_csv_by_ref_v2.py similarity index 81% rename from scripts/bom-in-python/ky/bom_example2.py rename to scripts/bom-in-python/bom_csv_by_ref_v2.py index 58b1c05453..38e6f0c75f 100644 --- a/scripts/bom-in-python/ky/bom_example2.py +++ b/scripts/bom-in-python/bom_csv_by_ref_v2.py @@ -5,16 +5,16 @@ # # Import the KiCad python helper module -import ky +import ky_generic_netlist_reader import csv import sys - + # Generate an instance of a generic netlist, and load the netlist tree from # the command line option. If the file doesn't exist, execution will stop -net = ky.netlist(sys.argv[1]) +net = ky_generic_netlist_reader.netlist(sys.argv[1]) # Open a file to write to, if the file cannot be opened output to stdout -# instead +# instead try: f = open(sys.argv[2], 'w') except IOError: @@ -22,13 +22,13 @@ except IOError: f = stdout # Create a new csv writer object to use as the output formatter -out = csv.writer(f, delimiter=',', quotechar="\"", quoting=csv.QUOTE_ALL) +out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar="\"", quoting=csv.QUOTE_ALL) # Output a field delimited header line out.writerow(['Source:', net.getSource()]) out.writerow(['Date:', net.getDate()]) out.writerow(['Tool:', net.getTool()]) -out.writerow(['Component Count:', len(net.components)]) +out.writerow(['Component Count:', len(net.components)]) out.writerow(['Ref', 'Value', 'Footprint', 'Datasheet', 'Manufacturer', 'Vendor']) # Output all of the component information (One component per row) diff --git a/scripts/bom-in-python/ky/bom_example3.py b/scripts/bom-in-python/bom_csv_grouped_by_value.py similarity index 83% rename from scripts/bom-in-python/ky/bom_example3.py rename to scripts/bom-in-python/bom_csv_grouped_by_value.py index dcbbf15b32..81d3acecf6 100644 --- a/scripts/bom-in-python/ky/bom_example3.py +++ b/scripts/bom-in-python/bom_csv_grouped_by_value.py @@ -5,13 +5,13 @@ # # Import the KiCad python helper module and the csv formatter -import ky +import ky_generic_netlist_reader import csv import sys # Generate an instance of a generic netlist, and load the netlist tree from # the command line option. If the file doesn't exist, execution will stop -net = ky.netlist(sys.argv[1]) +net = ky_generic_netlist_reader.netlist(sys.argv[1]) # Open a file to write to, if the file cannot be opened output to stdout # instead @@ -22,23 +22,24 @@ except IOError: f = stdout # Create a new csv writer object to use as the output formatter -out = csv.writer(f, delimiter=',', quotechar='\"', quoting=csv.QUOTE_ALL) +out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=csv.QUOTE_ALL) # Output a set of rows for a header providing general information out.writerow(['Source:', net.getSource()]) out.writerow(['Date:', net.getDate()]) out.writerow(['Tool:', net.getTool()]) -out.writerow(['Component Count:', len(net.components)]) +out.writerow(['Component Count:', len(net.components)]) out.writerow(['Ref', 'Qnty', 'Value', 'Part', 'Datasheet', 'Description', 'Vendor']) -# Get all of the components in groups of matching parts + values (see ky.py) +# Get all of the components in groups of matching parts + values +# (see ky_generic_netlist_reader.py) grouped = net.groupComponents() # Output all of the component information for group in grouped: refs = "" - # Add the reference of every component in the group and keep a reference + # Add the reference of every component in the group and keep a reference # to the component so that the other data can be filled in once per group for component in group: refs += component.getRef() + ", " diff --git a/scripts/bom-in-python/bom_html_by_value.py b/scripts/bom-in-python/bom_html_by_value.py new file mode 100644 index 0000000000..4c7fa5f2a5 --- /dev/null +++ b/scripts/bom-in-python/bom_html_by_value.py @@ -0,0 +1,119 @@ +# +# Example python script to generate a BOM from a KiCad generic netlist +# +# Example: Sorted and Grouped HTML BOM with more advanced grouping +# + +# Import the KiCad python helper module and the csv formatter +import ky_generic_netlist_reader +import sys + +# Start with a basic html template +html = """ + + + + + KiCad BOM Example 5 + + +

+

+

+

+ + +
+ + + """ + +def myEqu(self, other): + """myEqu is a more advanced equivalence function for components which is + used by component grouping. Normal operation is to group components based + on their Value, Library source, and Library part. + + In this example of a more advanced equivalency operator we also compare the + custom fields Voltage, Tolerance and Manufacturer as well as the assigned + footprint. If these fields are not used in some parts they will simply be + ignored (they will match as both will be empty strings). + + """ + result = True + if self.getValue() != other.getValue(): + result = False + elif self.getLib() != other.getLib(): + result = False + elif self.getPart() != other.getPart(): + result = False + elif self.getFootprint() != other.getFootprint(): + result = False + elif self.getField("Tolerance") != other.getField("Tolerance"): + result = False + elif self.getField("Manufacturer") != other.getField("Manufacturer"): + result = False + elif self.getField("Voltage") != other.getField("Voltage"): + result = False + + return result + +# Override the component equivalence operator - it is important to do this +# before loading the netlist, otherwise all components will have the original +# equivalency operator. +ky_generic_netlist_reader.component.__equ__ = myEqu + +# Generate an instance of a generic netlist, and load the netlist tree from +# video.xml. If the file doesn't exist, execution will stop +net = ky_generic_netlist_reader.netlist(sys.argv[1]) + +# Open a file to write too, if the file cannot be opened output to stdout +# instead +try: + f = open(sys.argv[2], 'w') +except IOError: + print >> sys.stderr, __file__, ":", e + f = stdout + +# Output a set of rows for a header providing general information +html = html.replace('', net.getSource()) +html = html.replace('', net.getDate()) +html = html.replace('', net.getTool()) +html = html.replace('', "Component Count:" + \ + str(len(net.components))) + +row = "Ref" + "Qnty" +row += "Value" + "Part" +row += "Description" +#row += "Datasheet" +row += "PartNumber" + "Vendor" + +html = html.replace('', row + "") + +# Get all of the components in groups of matching parts + values +# (see ky_generic_netlist_reader.py) +grouped = net.groupComponents() + +# Output all of the component information +for group in grouped: + refs = "" + + # Add the reference of every component in the group and keep a reference + # to the component so that the other data can be filled in once per group + for component in group: + refs += component.getRef() + ", " + c = component + + row = "" + refs +"" + str(len(group)) + row += "" + c.getValue() + "" + row += c.getLib() + "/" + c.getPart() + "" + #row += c.getDatasheet() + "" + row += c.getDescription() + "" + row += c.getField("PartNumber") + "" + row += c.getField("Vendor") + row += "" + + html = html.replace('', row + "") + +# Print the formatted html to output file +print >> f, html diff --git a/scripts/bom-in-python/ky/bom_example4.py b/scripts/bom-in-python/bom_html_grouped_by_value.py similarity index 89% rename from scripts/bom-in-python/ky/bom_example4.py rename to scripts/bom-in-python/bom_html_grouped_by_value.py index 201c041e39..d1cb8912f7 100644 --- a/scripts/bom-in-python/ky/bom_example4.py +++ b/scripts/bom-in-python/bom_html_grouped_by_value.py @@ -5,7 +5,7 @@ # # Import the KiCad python helper module and the csv formatter -import ky +import ky_generic_netlist_reader import sys # Start with a basic html template @@ -27,10 +27,10 @@ html = """ """ - + # Generate an instance of a generic netlist, and load the netlist tree from # the command line option. If the file doesn't exist, execution will stop -net = ky.netlist(sys.argv[1]) +net = ky_generic_netlist_reader.netlist(sys.argv[1]) # Open a file to write to, if the file cannot be opened output to stdout # instead @@ -47,31 +47,32 @@ html = html.replace('', net.getTool()) html = html.replace('', "Component Count:" + \ str(len(net.components))) -row = "Ref" + "Qnty" +row = "Ref" + "Qnty" row += "Value" + "Part" + "Datasheet" row += "Description" + "Vendor" - + html = html.replace('', row + "") -# Get all of the components in groups of matching parts + values (see ky.py) +# Get all of the components in groups of matching parts + values +# (see ky_generic_netlist_reader.py) grouped = net.groupComponents() # Output all of the component information for group in grouped: refs = "" - # Add the reference of every component in the group and keep a reference + # Add the reference of every component in the group and keep a reference # to the component so that the other data can be filled in once per group for component in group: refs += component.getRef() + ", " c = component - row = "" + refs +"" + str(len(group)) - row += "" + c.getValue() + "" + c.getLib() + "/" - row += c.getPart() + "" + c.getDatasheet() + "" - row += c.getDescription() + "" + c.getField("Vendor") + row = "" + refs +"" + str(len(group)) + row += "" + c.getValue() + "" + c.getLib() + "/" + row += c.getPart() + "" + c.getDatasheet() + "" + row += c.getDescription() + "" + c.getField("Vendor") row += "" - + html = html.replace('', row + "") # Print the formatted html to the file diff --git a/scripts/bom-in-python/ky/ky.py b/scripts/bom-in-python/ky_generic_netlist_reader.py similarity index 100% rename from scripts/bom-in-python/ky/ky.py rename to scripts/bom-in-python/ky_generic_netlist_reader.py diff --git a/scripts/bom-in-python/ky/round_robin.py b/scripts/bom-in-python/round_robin.py similarity index 87% rename from scripts/bom-in-python/ky/round_robin.py rename to scripts/bom-in-python/round_robin.py index 870797a1a5..6aff7ef1a9 100644 --- a/scripts/bom-in-python/ky/round_robin.py +++ b/scripts/bom-in-python/round_robin.py @@ -5,12 +5,12 @@ # # Import the KiCad python helper module and the csv formatter -import ky +import ky_generic_netlist_reader import sys # Generate an instance of a generic netlist, and load the netlist tree from # the command line option. If the file doesn't exist, execution will stop -net = ky.netlist(sys.argv[1]) +net = ky_generic_netlist_reader.netlist(sys.argv[1]) # Open a file to write to, if the file cannot be opened output to stdout # instead diff --git a/scripts/bom-in-python/ky/round_value_robin.py b/scripts/bom-in-python/round_value_robin.py similarity index 88% rename from scripts/bom-in-python/ky/round_value_robin.py rename to scripts/bom-in-python/round_value_robin.py index 725f1d64b6..c7834420a7 100644 --- a/scripts/bom-in-python/ky/round_value_robin.py +++ b/scripts/bom-in-python/round_value_robin.py @@ -5,7 +5,7 @@ # # Import the KiCad python helper module and the csv formatter -import ky +import ky_generic_netlist_reader import sys def checkvalue(self): @@ -21,7 +21,7 @@ def checkvalue(self): newval = dec[0] + "." + dec[1] self.setValue(newval) v = self.getValue() - + if len(r) == 2 and r[1].isdigit(): # This is a resistor - make values consistent # If the value is a pure value, add R to the end of the value @@ -34,8 +34,8 @@ def checkvalue(self): i = i / 1000 v = str(i) + "K" else: - v = str(i) + "R" - + v = str(i) + "R" + self.setValue(v) else: # Get the multiplier character @@ -45,17 +45,17 @@ def checkvalue(self): if (len(v) == 2): newval = v[0] + multiplier + v[1] self.setValue(newval) - v = self.getValue() - - + v = self.getValue() + + # Give components a new method for checking the values (this could easily be a # Company Part Number generator method instead) -ky.component.checkvalue = checkvalue - +ky_generic_netlist_reader.component.checkvalue = checkvalue + # Generate an instance of a generic netlist, and load the netlist tree from # the command line option. If the file doesn't exist, execution will stop -net = ky.netlist(sys.argv[1]) +net = ky_generic_netlist_reader.netlist(sys.argv[1]) # Open a file to write to, if the file cannot be opened output to stdout # instead @@ -67,5 +67,5 @@ except IOError: for c in net.components: c.checkvalue() - + print >> f, net.formatXML()