*) Start removing some of the problematic "<%s>.." format strings, which won't

pass into an HTML rendering panel and otherwise look goofey.
*) Implement BOARD::Move() can call it from EAGLE_PLUGIN::Load().
*) When USE_FP_LIB_TABLE, tolerate blank nicknames in FPIDs coming from eeschema.
   See the switch for this in pcbnew/netlist.cpp as ALLOW_PARTIAL_FPID.
*) Add an assert and a try catch block to figure out that View does not
   like some eagle pcb board.  bitset::set() is getting a -1 value and firing
   an exception.
This commit is contained in:
Dick Hollenbeck 2013-11-01 19:24:38 -05:00
parent 9e61c6ce1b
commit 42ef7f6215
9 changed files with 174 additions and 66 deletions

View File

@ -840,22 +840,3 @@ void FP_LIB_TABLE::Load( const wxFileName& aFileName, FP_LIB_TABLE* aFallBackTab
}
}
#if 0 // don't know that this is needed yet
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
throw( IO_ERROR )
{
const ROW* row = FindRow( aFootprintId.GetLibraryNickName() );
// row will never be NULL here.
PLUGIN::RELEASER pi( PluginFind( row->type ) );
return pi->FootprintLoad( aLibraryPath->GetFullURI() ),
aFootprintId.GetFootprintName(),
// fetch a PROPERTIES instance on stack here
row->GetPropertiesFromOptions()
);
}
#endif

View File

@ -367,8 +367,13 @@ protected:
m_layers.reset();
for( int i = 0; i < aCount; ++i )
{
// this fires on some eagle board after EAGLE_PLUGIN::Load()
wxASSERT( unsigned( aLayers[i] ) <= unsigned( VIEW::VIEW_MAX_LAYERS ) );
m_layers.set( aLayers[i] );
}
}
};
} // namespace KIGFX

View File

@ -176,7 +176,14 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
{
KIGFX::VIEW* view = m_galCanvas->GetView();
try
{
ViewReloadBoard( m_Pcb );
}
catch( const std::exception& ex )
{
DBG(printf( "ViewReloadBoard: exception: %s\n", ex.what() );)
}
// update the tool manager with the new board and its view.
if( m_toolManager )

View File

@ -45,6 +45,7 @@
#include <pcbnew.h>
#include <colors_selection.h>
#include <collectors.h>
#include <class_board.h>
#include <class_module.h>
@ -139,7 +140,39 @@ void BOARD::SetPosition( const wxPoint& aPos )
void BOARD::Move( const wxPoint& aMoveVector ) // overload
{
wxLogWarning( wxT( "This should not be called on the BOARD object") );
// Implement 'interface INSPECTOR' which is only INSPECTOR::Inspect(),
// here it does the moving.
struct MOVER : public INSPECTOR
{
SEARCH_RESULT Inspect( EDA_ITEM* item, const void* data )
{
BOARD_ITEM* brd_item = (BOARD_ITEM*) item;
const wxPoint* vector = (const wxPoint*) data;
brd_item->Move( *vector );
return SEARCH_CONTINUE;
}
} inspector;
// @todo : anything like this elsewhere? maybe put into GENERAL_COLLECTOR class.
static const KICAD_T top_level_board_stuff[] = {
PCB_MARKER_T,
PCB_TEXT_T,
PCB_LINE_T,
PCB_DIMENSION_T,
PCB_TARGET_T,
PCB_VIA_T,
PCB_TRACE_T,
// PCB_PAD_T,
// PCB_MODULE_TEXT_T,
PCB_MODULE_T,
PCB_ZONE_AREA_T, // if it is visible on screen, it should be selectable
EOT
};
// visit this BOARD with the above inspector, which moves all items.
Visit( &inspector, &aMoveVector, top_level_board_stuff );
}
@ -1395,10 +1428,11 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const
{
struct FindModule : public INSPECTOR
struct FINDER : public INSPECTOR
{
MODULE* found;
FindModule() : found( 0 ) {}
FINDER() : found( 0 ) {}
// implement interface INSPECTOR
SEARCH_RESULT Inspect( EDA_ITEM* item, const void* data )
@ -1427,20 +1461,29 @@ MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const
}
MODULE* BOARD::FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp )
{
for( MODULE* module = m_Modules; module != NULL; module = module->Next() )
MODULE* BOARD::FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp ) const
{
if( aSearchByTimeStamp )
{
for( MODULE* module = m_Modules; module; module = module->Next() )
{
if( aRefOrTimeStamp.CmpNoCase( module->GetPath() ) == 0 )
return module;
}
}
else
{
#if 0 // case independent compare, why?
for( MODULE* module = m_Modules; module; module = module->Next() )
{
if( aRefOrTimeStamp.CmpNoCase( module->GetReference() ) == 0 )
return module;
}
#else
return FindModuleByReference( aRefOrTimeStamp );
#endif
}
return NULL;
@ -2388,6 +2431,14 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
if( aReporter && aReporter->ReportAll() )
{
#if defined(DEBUG)
if( component->GetReference() == wxT( "D2" ) )
{
int breakhere = 1;
(void) breakhere;
}
#endif
msg.Printf( _( "Checking netlist component footprint \"%s:%s:%s\".\n" ),
GetChars( component->GetReference() ),
GetChars( component->GetTimeStamp() ),
@ -2626,12 +2677,15 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
if( aDeleteSinglePadNets && !aNetlist.IsDryRun() )
{
BuildListOfNets();
std::vector<D_PAD*> padlist = GetPads();
// padlist is the list of pads, sorted by netname.
int count = 0;
wxString netname;
D_PAD* pad = NULL;
D_PAD* previouspad = NULL;
for( unsigned ii = 0; ii < padlist.size(); ii++ )
{
pad = padlist[ii];
@ -2645,7 +2699,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
{
if( aReporter && aReporter->ReportAll() )
{
msg.Printf( _( "Remove single pad net \"%s\" on \"%s\" pad <%s>\n" ),
msg.Printf( _( "Remove single pad net \"%s\" on \"%s\" pad '%s'\n" ),
GetChars( previouspad->GetNetname() ),
GetChars( previouspad->GetParent()->GetReference() ),
GetChars( previouspad->GetPadName() ) );
@ -2693,7 +2747,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
continue; // OK, pad found
// not found: bad footprint, report error
msg.Printf( _( "** Error: Component \"%s\" pad <%s> not found in footprint \"%s\" **\n" ),
msg.Printf( _( "** Error: Component \"%s\" pad '%s' not found in footprint \"%s\" **\n" ),
GetChars( component->GetReference() ),
GetChars( padname ),
footprint->GetFPID().Format().c_str() );
@ -2718,7 +2772,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
// Net name not valid, report error
wxString coord;
coord << zone->GetPosition();
msg.Printf( _( "** Error: Zone %s layer <%s>"
msg.Printf( _( "** Error: Zone '%s' layer '%s'"
" has non-existent net name \"%s\" **\n" ),
GetChars( coord ),
GetChars( zone->GetLayerName() ),

View File

@ -919,9 +919,9 @@ public:
* @param aRefOrTimeStamp is the search string.
* @param aSearchByTimeStamp searches by the module time stamp value if true. Otherwise
* search by reference designator.
* @return the module found or NULL if not module is found that meets the search criteria.
* @return MODULE* - If found, the module meeting the search criteria, else NULL.
*/
MODULE* FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp = false );
MODULE* FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp = false ) const;
/**
* Function ReplaceNetlist

View File

@ -2692,22 +2692,28 @@ LAYER_NUM EAGLE_PLUGIN::kicad_layer( int aEagleLayer ) const
void EAGLE_PLUGIN::centerBoard()
{
/*
if( m_props )
{
const wxString& pageWidth = (*m_props)["page_width"];
const wxString& pageHeight = (*m_props)["page_height"];
std::string page_width;
std::string page_height;
if( pageWidth.size() && pageHeight.size() )
if( m_props->Value( "page_width", &page_width ) &&
m_props->Value( "page_height", &page_height ) )
{
EDA_RECT bbbox = m_board->GetBoundingBox();
int w = wxAtoi( pageWidth );
int h = wxAtoi( pageHeight );
EDA_RECT bbbox = m_board->ComputeBoundingBox( true );
m_board->Move( );
int w = atoi( page_width.c_str() );
int h = atoi( page_height.c_str() );
int desired_x = ( w - bbbox.GetWidth() ) / 2;
int desired_y = ( h - bbbox.GetHeight() ) / 2;
DBG(printf( "bbox.width:%d bbox.height:%d w:%d h:%d desired_x:%d desired_y:%d\n",
bbbox.GetWidth(), bbbox.GetHeight(), w, h, desired_x, desired_y );)
m_board->Move( wxPoint( desired_x - bbbox.GetX(), desired_y - bbbox.GetY() ) );
}
}
*/
}

View File

@ -41,6 +41,24 @@ class MODULE;
class PROPERTIES : public std::map< std::string, std::string >
{
// alphabetical tuple of name and value hereby defined.
public:
/**
* Function Value
* fetches a property by aName and returns true if that property was found, else false.
* If not found, aFetchedValue is not touched.
*/
bool Value( const char* aName, std::string* aFetchedValue ) const
{
PROPERTIES::const_iterator it = find( aName );
if( it != end() )
{
*aFetchedValue = it->second;
return true;
}
return false;
}
};

View File

@ -225,7 +225,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
FPID fpid;
wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
wxString::Format( wxT( "Could not parse FPID string <%s>." ),
wxString::Format( wxT( "Could not parse FPID string '%s'." ),
GetChars( moduleName ) ) );
try
@ -234,7 +234,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
}
catch( IO_ERROR ioe )
{
wxLogDebug( wxT( "An error occurred attemping to load footprint <%s>.\n\nError: %s" ),
wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ),
fpid.Format().c_str(), GetChars( ioe.errorText ) );
}
#endif
@ -261,7 +261,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
FPID fpid;
wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL,
wxString::Format( wxT( "Could not parse FPID string <%s>." ),
wxString::Format( wxT( "Could not parse FPID string '%s'." ),
GetChars( moduleName ) ) );
try
@ -270,7 +270,7 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary,
}
catch( IO_ERROR ioe )
{
wxLogDebug( wxT( "An error occurred attemping to load footprint <%s>.\n\nError: %s" ),
wxLogDebug( wxT( "An error occurred attemping to load footprint '%s'.\n\nError: %s" ),
fpid.Format().c_str(), GetChars( ioe.errorText ) );
}
#endif
@ -341,7 +341,7 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibrary( const wxString& aLibraryPath,
if( aDisplayError )
{
wxString msg = wxString::Format(
_( "Footprint %s not found in library <%s>." ),
_( "Footprint '%s' not found in library '%s'." ),
aFootprintName.GetData(),
libPath.GetData() );
@ -384,7 +384,7 @@ MODULE* PCB_BASE_FRAME::loadFootprintFromLibraries(
if( aDisplayError && !showed_error )
{
wxString msg = wxString::Format(
_( "PCB footprint library file <%s> not found in search paths." ),
_( "PCB footprint library file '%s' not found in search paths." ),
fn.GetFullName().GetData() );
DisplayError( this, msg );
@ -435,9 +435,30 @@ MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId )
wxString nickname = FROM_UTF8( aFootprintId.GetLibNickname().c_str() );
wxString fpname = FROM_UTF8( aFootprintId.GetFootprintName().c_str() );
if( nickname.size() )
{
return m_footprintLibTable->FootprintLoad( nickname, fpname );
}
// user did not enter a nickname, just a footprint name, help him out a little:
else
{
std::vector<wxString> nicks = m_footprintLibTable->GetLogicalLibs();
// Search each library going through libraries alphabetically.
for( unsigned i = 0; i<nicks.size(); ++i )
{
// FootprintLoad() returns NULL on not found, does not throw exception
// unless there's an IO_ERROR.
MODULE* ret = m_footprintLibTable->FootprintLoad( nicks[i], fpname );
if( ret )
return ret;
}
return NULL;
}
}
wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow,
const wxString& aLibraryName,
@ -477,7 +498,7 @@ wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow,
if( !MList.ReadFootprintFiles( aTable, !aLibraryName ? NULL : &aLibraryName ) )
{
msg.Format( _( "Error occurred attempting to load footprint library <%s>:\n\n" ),
msg.Format( _( "Error occurred attempting to load footprint library '%s':\n\n" ),
GetChars( aLibraryName ) );
if( !MList.m_filesNotFound.IsEmpty() )
@ -580,7 +601,7 @@ wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow,
if( CmpName != wxEmptyString )
OldName = CmpName;
wxLogDebug( wxT( "Footprint <%s> was selected." ), GetChars( CmpName ) );
wxLogDebug( wxT( "Footprint '%s' was selected." ), GetChars( CmpName ) );
return CmpName;
}
@ -682,7 +703,7 @@ void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent )
}
wxString msg = wxString::Format(
_( "Footprint library <%s> saved as <%s>." ),
_( "Footprint library '%s' saved as '%s'." ),
GetChars( curLibPath ), GetChars( dstLibPath ) );
DisplayInfoMessage( this, msg );

View File

@ -196,7 +196,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
{
if( aReporter )
{
msg.Printf( _( "No footprint defined for component `%s`.\n" ),
msg.Printf( _( "No footprint defined for component '%s'.\n" ),
GetChars( component->GetReference() ) );
aReporter->Report( msg );
}
@ -218,7 +218,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
{
if( aReporter )
{
msg.Printf( _( "* Warning: component `%s` has footprint <%s> and should be <%s>\n" ),
msg.Printf( _( "* Warning: component '%s' has footprint '%s' and should be '%s'\n" ),
GetChars( component->GetReference() ),
fpOnBoard->GetFPID().Format().c_str(),
component->GetFPID().GetFootprintName().c_str() );
@ -289,7 +289,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
{
if( aReporter )
{
msg.Printf( _( "*** Warning: component `%s` footprint <%s> was not found in "
msg.Printf( _( "*** Warning: component '%s' footprint '%s' was not found in "
"any libraries. ***\n" ),
GetChars( component->GetReference() ),
component->GetFPID().GetFootprintName().c_str() );
@ -317,6 +317,10 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
#else
#define ALLOW_PARTIAL_FPID 1
void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
throw( IO_ERROR, PARSE_ERROR )
{
@ -335,11 +339,17 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
{
component = aNetlist.GetComponent( ii );
#if ALLOW_PARTIAL_FPID
// The FPID is ok as long as there is a footprint portion coming
// from eeschema.
if( !component->GetFPID().GetFootprintName().size() )
#else
if( component->GetFPID().empty() )
#endif
{
if( aReporter )
{
msg.Printf( _( "No footprint defined for component `%s`.\n" ),
msg.Printf( _( "No footprint defined for component '%s'.\n" ),
GetChars( component->GetReference() ) );
aReporter->Report( msg );
}
@ -348,7 +358,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
}
// Check if component footprint is already on BOARD and only load the footprint from
// the library if it's needed.
// the library if it's needed. Nickname can be blank.
if( aNetlist.IsFindByTimeStamp() )
fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetTimeStamp(), true );
else
@ -361,7 +371,7 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
{
if( aReporter )
{
msg.Printf( _( "* Warning: component `%s` has footprint <%s> and should be <%s>\n" ),
msg.Printf( _( "* Warning: component '%s' has footprint '%s' and should be '%s'\n" ),
GetChars( component->GetReference() ),
fpOnBoard->GetFPID().GetFootprintName().c_str(),
component->GetFPID().GetFootprintName().c_str() );
@ -380,11 +390,17 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
{
module = NULL;
#if ALLOW_PARTIAL_FPID
// The FPID is ok as long as there is a footprint portion coming
// the library if it's needed. Nickname can be blank.
if( !component->GetFPID().GetFootprintName().size() )
#else
if( !component->GetFPID().IsValid() )
#endif
{
if( aReporter )
{
msg.Printf( _( "*** Warning: Component \"%s\" footprint ID <%s> is not "
msg.Printf( _( "*** Warning: Component '%s' footprint ID '%s' is not "
"valid. ***\n" ),
GetChars( component->GetReference() ),
component->GetFPID().GetFootprintName().c_str() );
@ -394,19 +410,19 @@ void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
continue;
}
// loadFootprint() can find a footprint with an empty nickname in fpid.
module = PCB_BASE_FRAME::loadFootprint( component->GetFPID() );
if( module )
{
lastFPID = component->GetFPID();
}
if( module == NULL )
else
{
if( aReporter )
{
wxString msg;
msg.Printf( _( "*** Warning: component `%s` footprint <%s> was not found in "
msg.Printf( _( "*** Warning: component '%s' footprint '%s' was not found in "
"any libraries in the footprint library table. ***\n" ),
GetChars( component->GetReference() ),
component->GetFPID().GetFootprintName().c_str() );