From bf2f650eb90ed20b0b55a6053099b180d9cefa74 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 13 Jan 2015 09:05:43 +0100 Subject: [PATCH] Cvpcb: fix a typo which prevents cvpcb to be compiled with webkit suppport. Equ files support enhancements. --- cvpcb/CMakeLists.txt | 2 +- cvpcb/autosel.cpp | 182 ++++++++++++------ cvpcb/autosel.h | 45 +++++ cvpcb/cvframe.cpp | 2 +- cvpcb/cvpcb_mainframe.h | 15 +- .../dialogs/pcb_calculator_frame_base.cpp | 6 +- .../dialogs/pcb_calculator_frame_base.fbp | 6 +- 7 files changed, 190 insertions(+), 68 deletions(-) create mode 100644 cvpcb/autosel.h diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 88650baf24..7c701b382b 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -8,7 +8,7 @@ endif() add_definitions( -DCVPCB ) -if( KICAD_USE_WEBKITT AND BUILD_GITHUB_PLUGIN ) +if( KICAD_USE_WEBKIT AND BUILD_GITHUB_PLUGIN ) set( WEBVIEWER_WXLIB "webviewer" ) add_definitions( -DKICAD_USE_WEBKIT ) endif() diff --git a/cvpcb/autosel.cpp b/cvpcb/autosel.cpp index 2281cbfc21..11408b98fa 100644 --- a/cvpcb/autosel.cpp +++ b/cvpcb/autosel.cpp @@ -25,7 +25,11 @@ * @file autosel.cpp */ -// Routines for automatic selection of modules. +// This file handle automatic selection of footprints, from .equ files which give +// a footprint FPID associated to a component value. +// Thse assiciations have this form: +// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm' + #include #include @@ -39,24 +43,10 @@ #include #include #include +#include #define QUOTE '\'' -#define FMT_TITLE_LIB_LOAD_ERROR _( "Library Load Error" ) - - -class FOOTPRINT_ALIAS -{ -public: - int m_Type; - wxString m_Name; - wxString m_FootprintName; - - FOOTPRINT_ALIAS() { m_Type = 0; } -}; - -typedef boost::ptr_vector< FOOTPRINT_ALIAS > FOOTPRINT_ALIAS_LIST; - /* * read the string between quotes and put it in aTarget @@ -81,38 +71,48 @@ wxString GetQuotedText( wxString & text ) } -void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) +// A sort compare function, used to sort a FOOTPRINT_EQUIVALENCE_LIST by cmp values +// (m_ComponentValue member) +bool sortListbyCmpValue( const FOOTPRINT_EQUIVALENCE& ref, const FOOTPRINT_EQUIVALENCE& test ) { - FOOTPRINT_ALIAS_LIST aliases; - FOOTPRINT_ALIAS* alias; - COMPONENT* component; - wxFileName fn; - wxString msg, tmp; - char Line[1024]; - FILE* file; - size_t ii; + return ref.m_ComponentValue.Cmp( test.m_ComponentValue ) >= 0; +} - SEARCH_STACK& search = Kiface().KifaceSearch(); +// read the .equ files and populate the list of equvalents +int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wxString * aErrorMessages ) +{ + char Line[1024]; + int error_count = 0; + FILE* file; + wxFileName fn; + wxString tmp, error_msg; - if( m_netlist.IsEmpty() ) - return; + SEARCH_STACK& search = Kiface().KifaceSearch(); - // Find equivalents in all available files. - for( ii = 0; ii < m_EquFilesNames.GetCount(); ii++ ) + // Find equivalences in all available files, and populates the + // equiv_List with all equivalences found in .equ files + for( unsigned ii = 0; ii < m_EquFilesNames.GetCount(); ii++ ) { - if( m_EquFilesNames[ii].StartsWith( wxT("${") ) ) - fn = wxExpandEnvVars( m_EquFilesNames[ii] ); - else - fn = m_EquFilesNames[ii]; + fn = wxExpandEnvVars( m_EquFilesNames[ii] ); tmp = search.FindValidPath( fn.GetFullPath() ); if( !tmp ) { - msg.Printf( _( "Footprint equ file '%s' could not be found in the " - "default search paths." ), - GetChars( fn.GetFullName() ) ); - wxMessageBox( msg, FMT_TITLE_LIB_LOAD_ERROR, wxOK | wxICON_ERROR ); + error_count++; + + if( aErrorMessages ) + { + error_msg.Printf( _( "Equ file '%s' could not be found in the " + "default search paths." ), + GetChars( fn.GetFullName() ) ); + + if( ! aErrorMessages->IsEmpty() ) + *aErrorMessages << wxT("\n\n"); + + *aErrorMessages += error_msg; + } + continue; } @@ -120,8 +120,18 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) if( file == NULL ) { - msg.Printf( _( "Error opening equ file '%s'." ), GetChars( tmp ) ); - wxMessageBox( msg, FMT_TITLE_LIB_LOAD_ERROR, wxOK | wxICON_ERROR ); + error_count++; + + if( aErrorMessages ) + { + error_msg.Printf( _( "Error opening equ file '%s'." ), GetChars( tmp ) ); + + if( ! aErrorMessages->IsEmpty() ) + *aErrorMessages << wxT("\n\n"); + + *aErrorMessages += error_msg; + } + continue; } @@ -142,21 +152,46 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) value.Replace( wxT( " " ), wxT( "_" ) ); - alias = new FOOTPRINT_ALIAS(); - alias->m_Name = value; - alias->m_FootprintName = footprint; - aliases.push_back( alias ); + FOOTPRINT_EQUIVALENCE* equivItem = new FOOTPRINT_EQUIVALENCE(); + equivItem->m_ComponentValue = value; + equivItem->m_FootprintFPID = footprint; + aList.push_back( equivItem ); } fclose( file ); } - // Display the number of footprint aliases. - msg.Printf( _( "%d footprint/cmp equivalences found." ), aliases.size() ); + return error_count; +} + + +void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event ) +{ + FOOTPRINT_EQUIVALENCE_LIST equiv_List; + COMPONENT* component; + wxString msg, error_msg; + size_t ii; + + if( m_netlist.IsEmpty() ) + return; + + if( buildEquivalenceList( equiv_List, &error_msg ) ) + wxMessageBox( error_msg, _( "Equ files Load Error" ), wxOK | wxICON_WARNING, this ); + + // Sort the association list by component value. + // When sorted, find duplicate definitions (i.e. 2 or more items + // having the same component value) is more easy. + std::sort( equiv_List.begin(), equiv_List.end(), sortListbyCmpValue ); + + // Display the number of footprint/component equivalences. + msg.Printf( _( "%d footprint/cmp equivalences found." ), equiv_List.size() ); SetStatusText( msg, 0 ); + // Now, associe each free component with a footprint, when the association + // is found in list m_skipComponentSelect = true; ii = 0; + error_msg.Empty(); for( unsigned kk = 0; kk < m_netlist.GetCount(); kk++ ) { @@ -165,19 +200,41 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) bool found = false; m_compListBox->SetSelection( ii++, true ); - if( !component->GetFPID().empty() ) + if( !component->GetFPID().empty() ) // the component has already a footprint continue; - BOOST_FOREACH( FOOTPRINT_ALIAS& alias, aliases ) + // Here a first attempt is made. We can have multiple equivItem of the same value. + // When happens, using the footprint filter of components can remove the ambiguity by + // filtering equivItem so one can use multiple equiv_List (for polar and + // nonpolar caps for example) + for( unsigned idx = 0; idx < equiv_List.size(); idx++ ) { + FOOTPRINT_EQUIVALENCE& equivItem = equiv_List[idx]; - if( alias.m_Name.CmpNoCase( component->GetValue() ) != 0 ) + if( equivItem.m_ComponentValue.CmpNoCase( component->GetValue() ) != 0 ) continue; - // filter alias so one can use multiple aliases (for polar and - // nonpolar caps for example) - const FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( alias.m_FootprintName ); + const FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( equivItem.m_FootprintFPID ); + bool equ_is_unique = true; + unsigned next = idx+1; + unsigned previous = idx-1; + + if( next < equiv_List.size() && previous >= 0 && + ( equivItem.m_ComponentValue == equiv_List[next].m_ComponentValue || + equivItem.m_ComponentValue == equiv_List[previous].m_ComponentValue ) ) + equ_is_unique = false; + + // If the equivalence is unique, no ambiguity: use the association + if( module && equ_is_unique ) + { + SetNewPkg( equivItem.m_FootprintFPID ); + found = true; + break; + } + + // The equivalence is not unique: use the footprint filter to try to remove + // ambiguity if( module ) { size_t filtercount = component->GetFootprintFilters().GetCount(); @@ -193,31 +250,38 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) msg.Printf( _( "Component %s: footprint %s not found in any of the project " "footprint libraries." ), GetChars( component->GetReference() ), - GetChars( alias.m_FootprintName ) ); - wxMessageBox( msg, _( "CvPcb Error" ), wxOK | wxICON_ERROR, this ); + GetChars( equivItem.m_FootprintFPID ) ); + + if( ! error_msg.IsEmpty() ) + error_msg << wxT("\n\n"); + + error_msg += msg; } if( found ) { - SetNewPkg( alias.m_FootprintName ); + SetNewPkg( equivItem.m_FootprintFPID ); break; } - } + if( found ) + continue; + // obviously the last chance: there's only one filter matching one footprint - if( !found && 1 == component->GetFootprintFilters().GetCount() ) + if( 1 == component->GetFootprintFilters().GetCount() ) { // we do not need to analyse wildcards: single footprint do not // contain them and if there are wildcards it just will not match any const FOOTPRINT_INFO* module = m_footprints.GetModuleInfo( component->GetFootprintFilters()[0] ); if( module ) - { SetNewPkg( component->GetFootprintFilters()[0] ); - } } } + if( !error_msg.IsEmpty() ) + wxMessageBox( error_msg, _( "CvPcb Warning" ), wxOK | wxICON_WARNING, this ); + m_skipComponentSelect = false; } diff --git a/cvpcb/autosel.h b/cvpcb/autosel.h new file mode 100644 index 0000000000..30abce0c7c --- /dev/null +++ b/cvpcb/autosel.h @@ -0,0 +1,45 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2015 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 + */ + +#ifndef AUTOSEL_H +#define AUTOSEL_H + +// A helper class to handle info read in .equ files, which gives a footprint FPID +// corresponding to a component value. +// Each line is something like: +// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm' +// + + +class FOOTPRINT_EQUIVALENCE +{ +public: + wxString m_ComponentValue; // The value of a component + wxString m_FootprintFPID; // the footprint FPID corresponding to this value + + FOOTPRINT_EQUIVALENCE() {} +}; + +typedef boost::ptr_vector< FOOTPRINT_EQUIVALENCE > FOOTPRINT_EQUIVALENCE_LIST; + +#endif // ifndef AUTOSEL_H diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index 9ebae1a553..12b1067f7c 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -80,7 +80,7 @@ BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, EDA_BASE_FRAME ) EVT_TOOL( ID_CVPCB_GOTO_FIRSTNA, CVPCB_MAINFRAME::ToFirstNA ) EVT_TOOL( ID_CVPCB_GOTO_PREVIOUSNA, CVPCB_MAINFRAME::ToPreviousNA ) EVT_TOOL( ID_CVPCB_DEL_ASSOCIATIONS, CVPCB_MAINFRAME::DelAssociations ) - EVT_TOOL( ID_CVPCB_AUTO_ASSOCIE, CVPCB_MAINFRAME::AssocieModule ) + EVT_TOOL( ID_CVPCB_AUTO_ASSOCIE, CVPCB_MAINFRAME::AutomaticFootprintMatching ) EVT_TOOL( ID_PCB_DISPLAY_FOOTPRINT_DOC, CVPCB_MAINFRAME::DisplayDocFile ) EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST, CVPCB_MAINFRAME::OnSelectFilteringFootprint ) diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h index 8e76307ed6..8f83042341 100644 --- a/cvpcb/cvpcb_mainframe.h +++ b/cvpcb/cvpcb_mainframe.h @@ -36,6 +36,7 @@ #include #include +#include /* Forward declarations of all top-level window classes. */ @@ -158,7 +159,7 @@ public: * format of a line: * 'cmp_ref' 'footprint_name' */ - void AssocieModule( wxCommandEvent& event ); + void AutomaticFootprintMatching( wxCommandEvent& event ); void DisplayDocFile( wxCommandEvent& event ); @@ -177,6 +178,7 @@ public: * @param aFootprintName = the selected footprint */ void SetNewPkg( const wxString& aFootprintName ); + void BuildCmpListBox(); void BuildFOOTPRINTS_LISTBOX(); void BuildLIBRARY_LISTBOX(); @@ -292,6 +294,17 @@ public: COMPONENT* GetSelectedComponent(); +private: + + /** + * read the .equ files and populate the list of equvalents + * @param aList the list to populate + * @param aErrorMessages is a pointer to a wxString to store error messages + * (can be NULL) + * @return the error count ( 0 = no error) + */ + int buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wxString * aErrorMessages = NULL ); + DECLARE_EVENT_TABLE() }; diff --git a/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp b/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp index 412753b4a2..0c0496cfa6 100644 --- a/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp +++ b/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp @@ -247,7 +247,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow m_panelRegulators->SetSizer( bSizerMainReg ); m_panelRegulators->Layout(); bSizerMainReg->Fit( m_panelRegulators ); - m_Notebook->AddPage( m_panelRegulators, _("Regulators"), true ); + m_Notebook->AddPage( m_panelRegulators, _("Regulators"), false ); m_panelTrackWidth = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizerTrackWidth; bSizerTrackWidth = new wxBoxSizer( wxHORIZONTAL ); @@ -593,7 +593,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow wxBoxSizer* bLeftSizer; bLeftSizer = new wxBoxSizer( wxVERTICAL ); - wxString m_TranslineSelectionChoices[] = { _("Microstrip Line"), _("Coplanar wave guide"), _("Grounded Coplanar wave guide"), _("Rectangular Waveguide"), _("Coaxial Line"), _("Coupled Microstrip Line"), _("Stripline"), _("Twisted Pair") }; + wxString m_TranslineSelectionChoices[] = { _("Microstrip Line"), _("Coplanar wave guide"), _("Coplanar wave guide with ground plane"), _("Rectangular Waveguide"), _("Coaxial Line"), _("Coupled Microstrip Line"), _("Stripline"), _("Twisted Pair") }; int m_TranslineSelectionNChoices = sizeof( m_TranslineSelectionChoices ) / sizeof( wxString ); m_TranslineSelection = new wxRadioBox( m_panelTransline, wxID_ANY, _("Transmission Line Type:"), wxDefaultPosition, wxDefaultSize, m_TranslineSelectionNChoices, m_TranslineSelectionChoices, 1, wxRA_SPECIFY_COLS ); m_TranslineSelection->SetSelection( 0 ); @@ -998,7 +998,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow m_panelTransline->SetSizer( bSizeTransline ); m_panelTransline->Layout(); bSizeTransline->Fit( m_panelTransline ); - m_Notebook->AddPage( m_panelTransline, _("TransLine"), false ); + m_Notebook->AddPage( m_panelTransline, _("TransLine"), true ); m_panelAttenuators = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxStaticBoxSizer* sbSizerAtt; sbSizerAtt = new wxStaticBoxSizer( new wxStaticBox( m_panelAttenuators, wxID_ANY, _("label") ), wxHORIZONTAL ); diff --git a/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp b/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp index 3b8123ad68..2ccc08de96 100644 --- a/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp +++ b/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp @@ -270,7 +270,7 @@ Regulators - 1 + 0 1 1 @@ -8181,7 +8181,7 @@ TransLine - 0 + 1 1 1 @@ -8288,7 +8288,7 @@ 1 0 - "Microstrip Line" "Coplanar wave guide" "Grounded Coplanar wave guide" "Rectangular Waveguide" "Coaxial Line" "Coupled Microstrip Line" "Stripline" "Twisted Pair" + "Microstrip Line" "Coplanar wave guide" "Coplanar wave guide with ground plane" "Rectangular Waveguide" "Coaxial Line" "Coupled Microstrip Line" "Stripline" "Twisted Pair" 1 1