diff --git a/common/ptree.cpp b/common/ptree.cpp index 19cb21f94f..010d4b3f26 100644 --- a/common/ptree.cpp +++ b/common/ptree.cpp @@ -83,7 +83,11 @@ inline void scanAtom( PTREE* aTree, DSNLEXER* aLexer ) //D(printf( "%s: '%s'\n", __func__, key );) +#if 0 aTree->push_back( PTREE::value_type( key, PTREE() ) ); +#else + aTree->put_value( key ); +#endif } @@ -190,7 +194,7 @@ static void formatNode( OUTPUTFORMATTER* out, int aNestLevel, int aCtl, out->Print( aNestLevel, "(%s%s", out->Quotes( aKey ).c_str(), ctl & CTL_OMIT_NL ? "" : "\n" ); - if( aTree.data().size() ) // only xml typically uses "data()", not sexpr. + if( aTree.data().size() ) { out->Print( 0, " %s%s", out->Quotes( aTree.data() ).c_str(), diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index efcb59d0f7..c48d6dfe89 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -28,6 +28,7 @@ */ #include +#include #include #include #include @@ -343,6 +344,11 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) if( !fn.HasExt() ) fn.SetExt( ComponentFileExtension ); +#if 0 // RHH 6-Jul-14: We did not auto generate the + // footprint table. And the dialog which does suppport editing does the saving. + // Besides, this is not the place to do this, it belies the name of this + // function. + // Save the project specific footprint library table. if( !Prj().PcbFootprintLibs()->IsEmpty( false ) ) { @@ -368,6 +374,8 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) } } } +#endif + } if( !IsWritable( fn.GetFullPath() ) ) @@ -380,6 +388,16 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) } wxString msg = wxString::Format( _("File %s saved"), GetChars( fn.GetFullPath() ) ); + + // Perhaps this replaces all of the above someday. + { + STRING_FORMATTER sf; + + m_netlist.FormatBackAnnotation( &sf ); + + Kiway().ExpressMail( FRAME_SCH, MAIL_BACKANNOTATE_FOOTPRINTS, sf.GetString() ); + } + SetStatusText( msg ); return 1; } diff --git a/eeschema/backanno.cpp b/eeschema/backanno.cpp index b72509d98b..4b704e44dc 100644 --- a/eeschema/backanno.cpp +++ b/eeschema/backanno.cpp @@ -42,15 +42,84 @@ #include #include +#include +#include +#include -bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( wxString& aFullFilename, +void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfReferences ) throw( IO_ERROR ) +{ + // Build a flat list of components in schematic: + SCH_REFERENCE_LIST refs; + SCH_SHEET_LIST sheets; + bool isChanged = false; + + sheets.GetComponents( refs, false ); + + static const KEYWORD empty_keywords[1] = {}; + + DSNLEXER lexer( empty_keywords, 0, aChangedSetOfReferences, FROM_UTF8( __func__ ) ); + PTREE doc; + + Scan( &doc, &lexer ); + +#if defined(DEBUG) && 0 + STRING_FORMATTER sf; + Format( &sf, 0, 0, doc ); + printf( "%s: '%s'\n", __func__, sf.GetString().c_str() ); +#endif + + CPTREE& back_anno = doc.get_child( "back_annotation" ); + + for( PTREE::const_iterator ref = back_anno.begin(); ref != back_anno.end(); ++ref ) + { + wxASSERT( ref->first == "ref" ); + + wxString reference = (UTF8&) ref->second.data(); + wxString footprint = (UTF8) ref->second.get( "fpid" ); + + // DBG( printf( "%s: ref:%s fpid:%s\n", __func__, TO_UTF8( reference ), TO_UTF8( footprint ) ); ) + + // Search the component in the flat list + for( unsigned ii = 0; ii < refs.GetCount(); ++ii ) + { + if( Cmp_KEEPCASE( reference, refs[ii].GetRef() ) == 0 ) + { + // We have found a candidate. + // Note: it can be not unique (multiple parts per package) + // So we *do not* stop the search here + SCH_COMPONENT* component = refs[ii].GetComponent(); + SCH_FIELD* fpfield = component->GetField( FOOTPRINT ); + const wxString& oldfp = fpfield->GetText(); + + if( !oldfp && fpfield->IsVisible() ) + { + fpfield->SetVisible( false ); + } + + // DBG( printf("%s: ref:%s fpid:%s\n", __func__, TO_UTF8( refs[ii].GetRef() ), TO_UTF8( footprint ) );) + + fpfield->SetText( footprint ); + + if( oldfp != footprint ) + isChanged = true; + } + } + } + + if( isChanged ) + OnModify(); +} + + +bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( const wxString& aFullFilename, bool aForceFieldsVisibleAttribute, bool aFieldsVisibleAttributeState ) { // Build a flat list of components in schematic: - SCH_REFERENCE_LIST referencesList; - SCH_SHEET_LIST SheetList; + SCH_REFERENCE_LIST referencesList; + SCH_SHEET_LIST SheetList; + SheetList.GetComponents( referencesList, false ); FILE* cmpFile = wxFopen( aFullFilename, wxT( "rt" ) ); @@ -71,7 +140,7 @@ bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( wxString& aFullFilename, { buffer = FROM_UTF8( cmpFileReader.Line() ); - if( ! buffer.StartsWith( wxT("BeginCmp") ) ) + if( !buffer.StartsWith( wxT("BeginCmp") ) ) continue; // Begin component description. @@ -87,20 +156,17 @@ bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( wxString& aFullFilename, // store string value, stored between '=' and ';' delimiters. value = buffer.AfterFirst( '=' ); - value = value.BeforeLast( ';'); + value = value.BeforeLast( ';' ); value.Trim(true); value.Trim(false); if( buffer.StartsWith( wxT("Reference") ) ) { reference = value; - continue; } - - if( buffer.StartsWith( wxT("IdModule =" ) ) ) + else if( buffer.StartsWith( wxT("IdModule =" ) ) ) { footprint = value; - continue; } } @@ -108,26 +174,29 @@ bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( wxString& aFullFilename, // if the footprint name is not empty if( reference.IsEmpty() ) continue; + // Search the component in the flat list - for( unsigned ii = 0; ii < referencesList.GetCount(); ii++ ) + for( unsigned ii = 0; ii < referencesList.GetCount(); ii++ ) { - if( reference.CmpNoCase( referencesList[ii].GetRef() ) == 0 ) + if( Cmp_KEEPCASE( reference, referencesList[ii].GetRef() ) == 0 ) { // We have found a candidate. // Note: it can be not unique (multiple parts per package) // So we *do not* stop the search here - SCH_COMPONENT* component = referencesList[ii].GetComponent(); - SCH_FIELD * fpfield = component->GetField( FOOTPRINT ); + SCH_COMPONENT* component = referencesList[ii].GetComponent(); + SCH_FIELD* fpfield = component->GetField( FOOTPRINT ); + fpfield->SetText( footprint ); if( aForceFieldsVisibleAttribute ) { - component->GetField( FOOTPRINT ) + component->GetField( FOOTPRINT ) ->SetVisible( aFieldsVisibleAttributeState ); } } } } + return true; } @@ -170,10 +239,12 @@ bool SCH_EDIT_FRAME::LoadCmpToFootprintLinkFile() visible = response == wxYES; } - if( ! ProcessCmpToFootprintLinkFile( filename, changevisibility, visible ) ) + if( !ProcessCmpToFootprintLinkFile( filename, changevisibility, visible ) ) { - wxString msg; - msg.Printf( _( "Failed to open component-footprint link file <%s>" ), filename.GetData() ); + wxString msg = wxString::Format( _( + "Failed to open component-footprint link file '%s'" ), + filename.GetData() + ); DisplayError( this, msg ); return false; } diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index b8bd39884a..59697b5760 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -196,8 +196,20 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) ExecuteRemoteCommand( payload.c_str() ); break; + case MAIL_BACKANNOTATE_FOOTPRINTS: + try + { + backAnnotateFootprints( payload ); + } + catch( const IO_ERROR& ioe ) + { + DBG( printf( "%s: ioe:%s\n", __func__, TO_UTF8( ioe.errorText ) );) + } + break; + // many many others. } } + diff --git a/include/fp_lib_table.h b/include/fp_lib_table.h index 4a2b822137..90ff3a9106 100644 --- a/include/fp_lib_table.h +++ b/include/fp_lib_table.h @@ -39,9 +39,6 @@ class OUTPUTFORMATTER; class MODULE; class FP_LIB_TABLE_LEXER; class FPID; -class NETLIST; -class REPORTER; -class SEARCH_STACK; /** * Class FP_LIB_TABLE diff --git a/include/mail_type.h b/include/mail_type.h index 9f30d3e284..4b4ced967f 100644 --- a/include/mail_type.h +++ b/include/mail_type.h @@ -10,7 +10,9 @@ */ enum MAIL_T { - MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing. + MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing. + MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing at cvpcb termination + }; #endif // MAIL_TYPE_H_ diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index ef71d06b96..247b79a35a 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -202,6 +202,8 @@ protected: void updateFindReplaceView( wxFindDialogEvent& aEvent ); + void backAnnotateFootprints( const std::string& aChangedSetOfReferences ) throw( IO_ERROR ); + public: SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ); ~SCH_EDIT_FRAME(); @@ -709,7 +711,7 @@ public: * @param aFieldsVisibleAttributeState = footprint field flag visible new state * @return bool = true if success. */ - bool ProcessCmpToFootprintLinkFile( wxString& aFullFilename, + bool ProcessCmpToFootprintLinkFile( const wxString& aFullFilename, bool aForceFieldsVisibleAttribute, bool aFieldsVisibleAttributeState ); diff --git a/kicad/files-io.cpp b/kicad/files-io.cpp index f0eed253e2..018726654b 100644 --- a/kicad/files-io.cpp +++ b/kicad/files-io.cpp @@ -130,19 +130,17 @@ void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event ) void KICAD_MANAGER_FRAME::OnArchiveFiles( wxCommandEvent& event ) { - /* List of file extensions to save. */ + // List of file extensions to save. static const wxChar* extentionList[] = { wxT( "*.sch" ), wxT( "*.lib" ), wxT( "*.mod" ), wxT( "*.cmp" ), wxT( "*.brd" ), wxT( "*.kicad_pcb" ), wxT( "*.gbr" ), wxT( "*.net" ), wxT( "*.pro" ), wxT( "*.pho" ), wxT( "*.py" ), wxT( "*.pdf" ), wxT( "*.txt" ), wxT( "*.dcm" ), wxT( "*.kicad_wks" ), - NULL }; - wxString msg; - size_t i; - wxFileName fileName = m_ProjectFileName; - wxString oldPath = wxGetCwd(); + wxString msg; + wxFileName fileName = m_ProjectFileName; + wxString oldPath = wxGetCwd(); fileName.SetExt( wxT( "zip" ) ); @@ -153,7 +151,6 @@ void KICAD_MANAGER_FRAME::OnArchiveFiles( wxCommandEvent& event ) if( dlg.ShowModal() == wxID_CANCEL ) return; - wxFileName zip = dlg.GetPath(); wxString currdirname = wxT( "." ); @@ -172,17 +169,21 @@ void KICAD_MANAGER_FRAME::OnArchiveFiles( wxCommandEvent& event ) // Build list of filenames to put in zip archive wxString currFilename; int zipBytesCnt = 0; // Size of the zip file - for( i = 0; extentionList[i] != 0; i++ ) + + for( unsigned i = 0; i" ), GetChars( currFilename ) ); PrintMsg( msg ); + // Read input file and put it in zip file: - wxFSFile * infile = fsfile.OpenFile(currFilename); + wxFSFile* infile = fsfile.OpenFile(currFilename); + if( infile ) { zipstream.PutNextEntry( currFilename, infile->GetModificationTime() ); diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 05f12dc766..8000d05adf 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -227,7 +227,8 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) break; // many many others. - + default: + ; } } diff --git a/pcbnew/dialogs/dialog_netlist.cpp b/pcbnew/dialogs/dialog_netlist.cpp index 2fc522383b..728af0acec 100644 --- a/pcbnew/dialogs/dialog_netlist.cpp +++ b/pcbnew/dialogs/dialog_netlist.cpp @@ -27,7 +27,6 @@ */ #include -//#include #include #include #include @@ -435,9 +434,16 @@ bool DIALOG_NETLIST::verifyFootprints( const wxString& aNetlistFilename, #if defined( DEBUG ) - m_MessageWindow->Clear(); - WX_TEXT_CTRL_REPORTER rpt( m_MessageWindow ); - netlist.Show( 0, rpt ); + { + m_MessageWindow->Clear(); + WX_TEXT_CTRL_REPORTER rpt( m_MessageWindow ); + + STRING_FORMATTER sf; + + netlist.Format( &sf, 0 ); + + rpt.Report( FROM_UTF8( sf.GetString().c_str() ) ); + } #endif BOARD* pcb = m_parent->GetBoard(); diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index b5693e0e6b..0a31eb956c 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -608,6 +608,9 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF GetChars( pcbFileName.GetFullPath() ) )) ) return false; +#if 0 // RHH 6-Jul-14: I see no plausible reason to do this. We did not auto generate the + // footprint table. And the dialog which does suppport editing does the saving. + // Save the project specific footprint library table. if( !Prj().PcbFootprintLibs()->IsEmpty( false ) ) { @@ -633,6 +636,8 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF } } } +#endif + } else { @@ -640,7 +645,6 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF if( pcbFileName.GetExt() == LegacyPcbFileExtension ) pluginType = IO_MGR::LEGACY; - else { pluginType = IO_MGR::KICAD; pcbFileName.SetExt( KiCadPcbFileExtension ); diff --git a/pcbnew/pcb_netlist.cpp b/pcbnew/pcb_netlist.cpp index 7e1ee53aa1..70c2d0e7f3 100644 --- a/pcbnew/pcb_netlist.cpp +++ b/pcbnew/pcb_netlist.cpp @@ -35,32 +35,14 @@ #include -#if defined(DEBUG) -/** - * Function NestedSpace - * outputs nested space for pretty indenting. - * @param aNestLevel The nest count - * @param aReporter A reference to a #REPORTER object where to output. - * @return REPORTER& for continuation. - **/ -static REPORTER& NestedSpace( int aNestLevel, REPORTER& aReporter ) +int COMPONENT_NET::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl ) { - for( int i = 0; i < aNestLevel; ++i ) - aReporter.Report( wxT( " " ) ); - - return aReporter; + return aOut->Print( aNestLevel, "(pin_net %s %s)", + aOut->Quotew( m_pinName ).c_str(), + aOut->Quotew( m_netName ).c_str() ); } -void COMPONENT_NET::Show( int aNestLevel, REPORTER& aReporter ) -{ - NestedSpace( aNestLevel, aReporter ); - aReporter.Report( wxString::Format( wxT( "\n" ), - GetChars( m_pinName ), GetChars( m_netName ) ) ); -} -#endif - - void COMPONENT::SetModule( MODULE* aModule ) { m_footprint.reset( aModule ); @@ -108,51 +90,66 @@ bool COMPONENT::MatchesFootprintFilters( const wxString& aFootprintName ) const } -#if defined(DEBUG) -void COMPONENT::Show( int aNestLevel, REPORTER& aReporter ) +void COMPONENT::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl ) { - NestedSpace( aNestLevel, aReporter ); - aReporter.Report( wxT( "\n" ) ); - NestedSpace( aNestLevel+1, aReporter ); - aReporter.Report( wxString::Format( wxT( "\n" ), - GetChars( m_reference ), GetChars( m_value ), - GetChars( m_name ), GetChars( m_library ), - m_fpid.Format().c_str(), - GetChars( m_timeStamp ) ) ); + int nl = aNestLevel; - if( !m_footprintFilters.IsEmpty() ) + aOut->Print( nl, "(ref %s ", aOut->Quotew( m_reference ).c_str() ); + aOut->Print( 0, "(fpid %s)\n", m_fpid.Format().c_str() ); + + if( ! ( aCtl & CTL_OMIT_EXTRA ) ) { - NestedSpace( aNestLevel+1, aReporter ); - aReporter.Report( wxT( "\n" ) ); + aOut->Print( nl+1, "(value %s)\n", aOut->Quotew( m_value ).c_str() ); + aOut->Print( nl+1, "(name %s)\n", aOut->Quotew( m_name ).c_str() ); + aOut->Print( nl+1, "(library %s)\n", aOut->Quotew( m_library ).c_str() ); + aOut->Print( nl+1, "(timestamp %s)\n", aOut->Quotew( m_timeStamp ).c_str() ); + } - for( unsigned i = 0; i < m_footprintFilters.GetCount(); i++ ) + if( !( aCtl & CTL_OMIT_FILTERS ) && m_footprintFilters.GetCount() ) + { + aOut->Print( nl+1, "(fp_filters" ); + + for( unsigned i = 0; i < m_footprintFilters.GetCount(); ++i ) + aOut->Print( 0, " %s", aOut->Quotew( m_footprintFilters[i] ).c_str() ); + + aOut->Print( 0, ")\n" ); + } + + if( !( aCtl & CTL_OMIT_NETS ) && m_nets.size() ) + { + int llen = aOut->Print( nl+1, "(nets " ); + + for( unsigned i = 0; i < m_nets.size(); ++i ) { - NestedSpace( aNestLevel+2, aReporter ); - aReporter.Report( wxString::Format( wxT( "<%s>\n" ), - GetChars( m_footprintFilters[i] ) ) ); + if( llen > 80 ) + { + aOut->Print( 0, "\n" ); + llen = aOut->Print( nl+1, " " ); + } + + llen += m_nets[i].Format( aOut, 0, aCtl ); } - NestedSpace( aNestLevel+1, aReporter ); - aReporter.Report( wxT( "\n" ) ); + aOut->Print( 0, ")\n" ); } - if( !m_nets.empty() ) - { - NestedSpace( aNestLevel+1, aReporter ); - aReporter.Report( wxT( "\n" ) ); - - for( unsigned i = 0; i < m_nets.size(); i++ ) - m_nets[i].Show( aNestLevel+3, aReporter ); - - NestedSpace( aNestLevel+1, aReporter ); - aReporter.Report( "\n" ); - } - - NestedSpace( aNestLevel, aReporter ); - aReporter.Report( "\n" ); + aOut->Print( nl, ")\n" ); // +} + + +void NETLIST::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl ) +{ + int nl = aNestLevel; + + aOut->Print( nl, "(back_annotation\n" ); + + for( unsigned i = 0; i < m_components.size(); i++ ) + { + m_components[i].Format( aOut, nl+1, aCtl ); + } + + aOut->Print( nl, ")\n" ); } -#endif void NETLIST::AddComponent( COMPONENT* aComponent ) @@ -250,29 +247,3 @@ bool NETLIST::AllFootprintsLinked() const return true; } - -#if defined( DEBUG ) -void NETLIST::Show( int aNestLevel, REPORTER& aReporter ) -{ - NestedSpace( aNestLevel, aReporter ); - aReporter.Report( "\n" ); - - if( !m_components.empty() ) - { - NestedSpace( aNestLevel+1, aReporter ); - aReporter.Report( "\n" ); - - for( unsigned i = 0; i < m_components.size(); i++ ) - { - m_components[i].Show( aNestLevel+2, aReporter ); - } - - NestedSpace( aNestLevel+1, aReporter ); - - aReporter.Report( "\n" ); - } - - NestedSpace( aNestLevel, aReporter ); - aReporter.Report( "\n" ); -} -#endif diff --git a/pcbnew/pcb_netlist.h b/pcbnew/pcb_netlist.h index 58ab9bf17d..e48385c9fe 100644 --- a/pcbnew/pcb_netlist.h +++ b/pcbnew/pcb_netlist.h @@ -68,16 +68,7 @@ public: return m_pinName < aNet.m_pinName; } -#if defined(DEBUG) - /** - * Function Show - * is used to output the object tree, currently for debugging only. - * @param aNestLevel An aid to prettier tree indenting, and is the level - * of nesting of this object within the overall tree. - * @param aReporter A reference to a #REPORTER object to output to. - */ - virtual void Show( int aNestLevel, REPORTER& aReporter ); -#endif + int Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl ); }; @@ -192,16 +183,7 @@ public: bool FootprintChanged() const { return m_footprintChanged; } -#if defined(DEBUG) - /** - * Function Show - * is used to output the object tree, currently for debugging only. - * @param aNestLevel An aid to prettier tree indenting, and is the level - * of nesting of this object within the overall tree. - * @param aReporter A reference to a #REPORTER object to output to. - */ - virtual void Show( int aNestLevel, REPORTER& aReporter ); -#endif + void Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl ); }; @@ -348,16 +330,18 @@ public: */ bool AnyFootprintsChanged() const; -#if defined(DEBUG) - /** - * Function Show - * is used to output the object tree, currently for debugging only. - * @param aNestLevel An aid to prettier tree indenting, and is the level - * of nesting of this object within the overall tree. - * @param aReporter A reference to a #REPORTER object to output to. - */ - virtual void Show( int aNestLevel, REPORTER& aReporter ); -#endif + void Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl = 0 ); + +#define CTL_OMIT_EXTRA (1<<0) +#define CTL_OMIT_NETS (1<<1) +#define CTL_OMIT_FILTERS (1<<2) + +#define CTL_FOR_BACKANNO (CTL_OMIT_NETS | CTL_OMIT_FILTERS | CTL_OMIT_EXTRA) + + void FormatBackAnnotation( OUTPUTFORMATTER* aOut ) + { + Format( aOut, 0, CTL_FOR_BACKANNO ); + } };