visitor design pattern, MODULE::FindPadOrModule()

This commit is contained in:
dickelbeck 2007-08-09 21:15:08 +00:00
parent 59b4c5ba3b
commit 27bd9c751a
12 changed files with 509 additions and 364 deletions

View File

@ -4,6 +4,14 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2007-Aug-08 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+ pcbnew & common
Released the new Visitor paradigm. Wrote MODULE::FindPadOrModule() using
it.
2007-aug-09 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2007-aug-09 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================ ================================================================================
+ eeschema + eeschema

View File

@ -189,17 +189,54 @@ wxString EDA_BaseStruct::ReturnClassName() const
} }
// see base_struct.h
SEARCH_RESULT EDA_BaseStruct::IterateForward( EDA_BaseStruct* listStart,
INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] )
{
EDA_BaseStruct* p = listStart;
for( ; p; p = p->Pnext )
{
if( SEARCH_QUIT == p->Visit( inspector, testData, scanTypes ) )
return SEARCH_QUIT;
}
return SEARCH_CONTINUE;
}
// see base_struct.h
// many classes inherit this method, be careful:
SEARCH_RESULT EDA_BaseStruct::Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] )
{
KICAD_T stype;
for( const KICAD_T* p = scanTypes; (stype=*p) != EOT; ++p )
{
// If caller wants to inspect my type
if( stype == m_StructType )
{
if( SEARCH_QUIT == inspector->Inspect( this, testData ) )
return SEARCH_QUIT;
break;
}
}
return SEARCH_CONTINUE;
}
#if defined(DEBUG) #if defined(DEBUG)
// A function that should have been in wxWidgets // A function that should have been in wxWidgets
std::ostream& operator<<( std::ostream& out, wxSize& size ) std::ostream& operator<<( std::ostream& out, const wxSize& size )
{ {
out << " width=\"" << size.GetWidth() << "\" height=\"" << size.GetHeight() << "\""; out << " width=\"" << size.GetWidth() << "\" height=\"" << size.GetHeight() << "\"";
return out; return out;
} }
// A function that should have been in wxWidgets // A function that should have been in wxWidgets
std::ostream& operator<<( std::ostream& out, wxPoint& pt ) std::ostream& operator<<( std::ostream& out, const wxPoint& pt )
{ {
out << " x=\"" << pt.x << "\" y=\"" << pt.y << "\""; out << " x=\"" << pt.x << "\" y=\"" << pt.y << "\"";
return out; return out;
@ -242,43 +279,6 @@ std::ostream& EDA_BaseStruct::NestedSpace( int nestLevel, std::ostream& os )
return os; return os;
} }
// see base_struct.h
SEARCH_RESULT EDA_BaseStruct::IterateForward( EDA_BaseStruct* listStart,
INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] )
{
EDA_BaseStruct* p = listStart;
for( ; p; p = p->Pnext )
{
if( SEARCH_QUIT == p->Visit( inspector, testData, scanTypes ) )
return SEARCH_QUIT;
}
return SEARCH_CONTINUE;
}
// see base_struct.h
// many classes inherit this method, be careful:
SEARCH_RESULT EDA_BaseStruct::Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] )
{
KICAD_T stype;
for( const KICAD_T* p = scanTypes; (stype=*p) != EOT; ++p )
{
// If caller wants to inspect my type
if( stype == m_StructType )
{
if( SEARCH_QUIT == inspector->Inspect( this, testData ) )
return SEARCH_QUIT;
break;
}
}
return SEARCH_CONTINUE;
}
#endif #endif

View File

@ -8,8 +8,8 @@
#if defined(DEBUG) #if defined(DEBUG)
#include <iostream> // needed for Show() #include <iostream> // needed for Show()
extern std::ostream& operator<<( std::ostream& out, wxSize& size ); extern std::ostream& operator<<( std::ostream& out, const wxSize& size );
extern std::ostream& operator<<( std::ostream& out, wxPoint& pt ); extern std::ostream& operator<<( std::ostream& out, const wxPoint& pt );
#endif #endif
@ -75,7 +75,6 @@ enum DrawStructureType {
}; };
#if defined(DEBUG) // new searching technique incubator
enum SEARCH_RESULT { enum SEARCH_RESULT {
SEARCH_QUIT, SEARCH_QUIT,
SEARCH_CONTINUE SEARCH_CONTINUE
@ -118,8 +117,6 @@ public:
// retrieval here. // retrieval here.
}; };
#endif
/********************************************************************/ /********************************************************************/
/* Classes de base: servent a deriver les classes reellement utiles */ /* Classes de base: servent a deriver les classes reellement utiles */
@ -191,6 +188,44 @@ public:
return false; // derived classes should override this function return false; // derived classes should override this function
} }
/**
* Function IterateForward
* walks through the object tree calling the testFunc on each object
* type requested in scanTypes.
*
* @param listStart The first in a list of EDA_BaseStructs to iterate over.
* @param inspector Is an INSPECTOR to call on each object that is one of
* the requested scanTypes.
* @param testData Is an aid to testFunc, and should be sufficient to
* allow it to fully determine if an item meets the match criteria, but it
* may also be used to collect output.
* @param scanTypes A KICAD_T array that is EOT
* terminated, and provides both the order and interest level of of
* the types of objects to be iterated over.
* @return SEARCH_RESULT - SEARCH_QUIT if the called INSPECTOR returned
* SEARCH_QUIT, else SCAN_CONTINUE;
*/
static SEARCH_RESULT IterateForward( EDA_BaseStruct* listStart,
INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] );
/**
* Function Visit
* may be re-implemented for each derived class in order to handle
* all the types given by its member data. Implementations should call
* inspector->Inspect() on types in scanTypes[], and may use IterateForward()
* to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE, and determined by the inspector.
*/
virtual SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
#if defined(DEBUG) #if defined(DEBUG)
@ -230,44 +265,6 @@ public:
static std::ostream& NestedSpace( int nestLevel, std::ostream& os ); static std::ostream& NestedSpace( int nestLevel, std::ostream& os );
/**
* Function IterateForward
* walks through the object tree calling the testFunc on each object
* type requested in scanTypes.
*
* @param listStart The first in a list of EDA_BaseStructs to iterate over.
* @param inspector Is an INSPECTOR to call on each object that is one of
* the requested scanTypes.
* @param testData Is an aid to testFunc, and should be sufficient to
* allow it to fully determine if an item meets the match criteria, but it
* may also be used to collect output.
* @param scanTypes A KICAD_T array that is EOT
* terminated, and provides both the order and interest level of of
* the types of objects to be iterated over.
* @return SEARCH_RESULT - SEARCH_QUIT if the called INSPECTOR returned
* SEARCH_QUIT, else SCAN_CONTINUE;
*/
static SEARCH_RESULT IterateForward( EDA_BaseStruct* listStart,
INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] );
/**
* Function Visit
* should be re-implemented for each derived class in order to handle
* all the types given by its member data. Implementations should call
* inspector->Inspect() on types in scanTypes[], and may use IterateForward()
* to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE, and determined by the inspector.
*/
virtual SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
/** /**
* Function ListHas * Function ListHas
* scans the given array and detects if the given type t is present. * scans the given array and detects if the given type t is present.

View File

@ -232,6 +232,35 @@ public:
// Calcul du rectangle d'encadrement: // Calcul du rectangle d'encadrement:
bool ComputeBoundaryBox( void ); bool ComputeBoundaryBox( void );
/**
* Function Visit
* may be re-implemented for each derived class in order to handle
* all the types given by its member data. Implementations should call
* inspector->Inspect() on types in scanTypes[], and may use IterateForward()
* to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE, and determined by the inspector.
*/
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
/**
* Function FindPadOrModule
* searches for either a pad or module, giving precedence to pads.
* Any Pad or Module on the desired layer that HitTest()s true will be
* returned, otherwise any visible Pad or Module on any other layer.
* The provided layer must be visible.
* @param refPos The wxPoint to hit-test.
* @return EDA_BaseStruct* - if a direct hit, else NULL.
*/
EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer );
#if defined(DEBUG) #if defined(DEBUG)
@ -240,12 +269,11 @@ public:
* returns the class name. * returns the class name.
* @return wxString * @return wxString
*/ */
virtual wxString GetClass() const wxString GetClass() const
{ {
return wxT( "BOARD" ); return wxT( "BOARD" );
} }
/** /**
* Function Show * Function Show
* is used to output the object tree, currently for debugging only. * is used to output the object tree, currently for debugging only.
@ -253,18 +281,8 @@ public:
* of nesting of this object within the overall tree. * of nesting of this object within the overall tree.
* @param os The ostream& to output to. * @param os The ostream& to output to.
*/ */
virtual void Show( int nestLevel, std::ostream& os ); void Show( int nestLevel, std::ostream& os );
/**
* Function FindPadOrModule
* searches for either a pad or module, giving precedence to pads.
* @param refPos The wxPoint to hit-test.
* @param typeloc
* @return EDA_BaseStruct* - if a direct hit, else NULL.
*/
EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer );
#endif #endif
}; };

View File

@ -256,66 +256,71 @@ bool BOARD::ComputeBoundaryBox( void )
} }
#if defined(DEBUG) // virtual, see pcbstruct.h
SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData,
/** const KICAD_T scanTypes[] )
* Function Show
* is used to output the object tree, currently for debugging only.
* @param nestLevel An aid to prettier tree indenting, and is the level
* of nesting of this object within the overall tree.
* @param os The ostream& to output to.
*/
void BOARD::Show( int nestLevel, std::ostream& os )
{ {
EDA_BaseStruct* p; KICAD_T stype;
SEARCH_RESULT result = SEARCH_CONTINUE;
const KICAD_T* p = scanTypes;
// for now, make it look like XML: while( (stype = *p++) != EOT )
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
// specialization of the output:
NestedSpace( nestLevel+1, os ) << "<modules>\n";
p = m_Modules;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</modules>\n";
NestedSpace( nestLevel+1, os ) << "<pdrawings>\n";
p = m_Drawings;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</pdrawings>\n";
NestedSpace( nestLevel+1, os ) << "<nets>\n";
p = m_Equipots;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</nets>\n";
NestedSpace( nestLevel+1, os ) << "<tracks>\n";
p = m_Track;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</tracks>\n";
NestedSpace( nestLevel+1, os ) << "<zones>\n";
p = m_Zone;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</zones>\n";
NestedSpace( nestLevel+1, os ) << "<edgezones>\n";
p = m_CurrentLimitZone;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</edgezones>\n";
p = m_Son;
for( ; p; p = p->Pnext )
{ {
p->Show( nestLevel+1, os ); switch( stype )
{
case TYPEPCB:
result = inspector->Inspect( this, testData ); // inspect me
break;
/* Instances of the requested KICAD_T live in a list, either one
that I manage, or that my modules manage. If it's a type managed
by class MODULE, then simply pass it on to each module's
MODULE::Visit() function by way of the
IterateForward( m_Modules, ... ) call.
*/
case TYPEMODULE:
case TYPEPAD:
case TYPETEXTEMODULE:
case TYPEEDGEMODULE:
// this calls MODULE::Visit() on each module.
result = IterateForward( m_Modules, inspector, testData, scanTypes );
break;
case TYPEDRAWSEGMENT:
case TYPETEXTE:
case TYPEMARQUEUR:
case TYPECOTATION:
case TYPEMIRE:
result = IterateForward( m_Drawings, inspector, testData, scanTypes );
break;
case TYPEVIA:
case TYPETRACK:
result = IterateForward( m_Track, inspector, testData, scanTypes );
break;
case PCB_EQUIPOT_STRUCT_TYPE:
result = IterateForward( m_Equipots, inspector, testData, scanTypes );
break;
case TYPEZONE:
result = IterateForward( m_Zone, inspector, testData, scanTypes );
break;
case TYPEEDGEZONE:
result = IterateForward( m_CurrentLimitZone, inspector, testData, scanTypes );
break;
default:
break;
}
if( result == SEARCH_QUIT )
break;
} }
NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n"; return result;
} }
@ -381,4 +386,67 @@ EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer )
return inspector.found; return inspector.found;
} }
#if defined(DEBUG)
/**
* Function Show
* is used to output the object tree, currently for debugging only.
* @param nestLevel An aid to prettier tree indenting, and is the level
* of nesting of this object within the overall tree.
* @param os The ostream& to output to.
*/
void BOARD::Show( int nestLevel, std::ostream& os )
{
EDA_BaseStruct* p;
// for now, make it look like XML:
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
// specialization of the output:
NestedSpace( nestLevel+1, os ) << "<modules>\n";
p = m_Modules;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</modules>\n";
NestedSpace( nestLevel+1, os ) << "<pdrawings>\n";
p = m_Drawings;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</pdrawings>\n";
NestedSpace( nestLevel+1, os ) << "<nets>\n";
p = m_Equipots;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</nets>\n";
NestedSpace( nestLevel+1, os ) << "<tracks>\n";
p = m_Track;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</tracks>\n";
NestedSpace( nestLevel+1, os ) << "<zones>\n";
p = m_Zone;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</zones>\n";
NestedSpace( nestLevel+1, os ) << "<edgezones>\n";
p = m_CurrentLimitZone;
for( ; p; p = p->Pnext )
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</edgezones>\n";
p = m_Son;
for( ; p; p = p->Pnext )
{
p->Show( nestLevel+1, os );
}
NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
}
#endif #endif

View File

@ -829,7 +829,8 @@ void MODULE::SetPosition( const wxPoint& newpos )
D_PAD* pad = m_Pads; D_PAD* pad = m_Pads;
for( ; pad != NULL; pad = (D_PAD*) pad->Pnext ) for( ; pad != NULL; pad = (D_PAD*) pad->Pnext )
{ {
pad->m_Pos.x += deltaX; pad->m_Pos.y += deltaY; pad->m_Pos.x += deltaX;
pad->m_Pos.y += deltaY;
} }
/* deplacement des dessins de l'empreinte : */ /* deplacement des dessins de l'empreinte : */
@ -848,7 +849,8 @@ void MODULE::SetPosition( const wxPoint& newpos )
case TYPETEXTEMODULE: case TYPETEXTEMODULE:
{ {
TEXTE_MODULE* pt_texte = (TEXTE_MODULE*) PtStruct; TEXTE_MODULE* pt_texte = (TEXTE_MODULE*) PtStruct;
pt_texte->m_Pos.x += deltaX; pt_texte->m_Pos.y += deltaY; pt_texte->m_Pos.x += deltaX;
pt_texte->m_Pos.y += deltaY;
break; break;
} }
@ -1168,6 +1170,54 @@ bool MODULE::HitTest( const wxPoint& refPos )
} }
// see class_module.h
SEARCH_RESULT MODULE::Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] )
{
KICAD_T stype;
SEARCH_RESULT result = SEARCH_CONTINUE;
const KICAD_T* p = scanTypes;
while( (stype = *p++) != EOT )
{
switch( stype )
{
case TYPEMODULE:
result = inspector->Inspect( this, testData ); // inspect me
break;
case TYPEPAD:
result = IterateForward( m_Pads, inspector, testData, scanTypes );
break;
case TYPETEXTEMODULE:
result = inspector->Inspect( m_Reference, testData );
if( result == SEARCH_QUIT )
break;
result = inspector->Inspect( m_Value, testData );
if( result == SEARCH_QUIT )
break;
// m_Drawings can hold TYPETEXTMODULE also?
result = IterateForward( m_Drawings, inspector, testData, scanTypes );
break;
case TYPEEDGEMODULE:
result = IterateForward( m_Drawings, inspector, testData, scanTypes );
break;
default:
break;
}
if( result == SEARCH_QUIT )
break;
}
return result;
}
#if defined(DEBUG) #if defined(DEBUG)
/** /**
@ -1213,50 +1263,4 @@ void MODULE::Show( int nestLevel, std::ostream& os )
NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n"; NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
} }
// see class_module.h
SEARCH_RESULT MODULE::Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] )
{
KICAD_T stype;
for( const KICAD_T* p = scanTypes; (stype=*p) != EOT; ++p )
{
// If caller wants to inspect my type
if( stype == m_StructType )
{
if( SEARCH_QUIT == inspector->Inspect( this, testData ) )
return SEARCH_QUIT;
}
else if( stype == TYPEPAD )
{
if( SEARCH_QUIT == IterateForward( m_Pads, inspector,
testData, scanTypes ) )
return SEARCH_QUIT;
}
else if( stype == TYPETEXTEMODULE )
{
if( SEARCH_QUIT == inspector->Inspect( m_Reference, testData ) )
return SEARCH_QUIT;
if( SEARCH_QUIT == inspector->Inspect( m_Value, testData ) )
return SEARCH_QUIT;
// m_Drawings can hold TYPETEXTMODULE also?
if( SEARCH_QUIT == IterateForward( m_Drawings, inspector,
testData, scanTypes ) )
return SEARCH_QUIT;
}
else if( stype == TYPEEDGEMODULE )
{
// iterate over m_Drawings
if( SEARCH_QUIT == IterateForward( m_Drawings, inspector,
testData, scanTypes ) )
return SEARCH_QUIT;
}
}
return SEARCH_CONTINUE;
}
#endif #endif

View File

@ -143,6 +143,23 @@ public:
bool HitTest( const wxPoint& refPos ); bool HitTest( const wxPoint& refPos );
/**
* Function Visit
* should be re-implemented for each derived class in order to handle
* all the types given by its member data. Implementations should call
* inspector->Inspect() on types in scanTypes[], and may use IterateForward()
* to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE;
*/
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function GetClass * Function GetClass
@ -164,23 +181,6 @@ public:
*/ */
virtual void Show( int nestLevel, std::ostream& os ); virtual void Show( int nestLevel, std::ostream& os );
/**
* Function Visit
* should be re-implemented for each derived class in order to handle
* all the types given by its member data. Implementations should call
* inspector->Inspect() on types in scanTypes[], and may use IterateForward()
* to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE;
*/
virtual SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
#endif #endif
}; };

View File

@ -125,13 +125,8 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
break; break;
case ID_PCB_SHOW_1_RATSNEST_BUTT: case ID_PCB_SHOW_1_RATSNEST_BUTT:
#if defined(DEBUG) DrawStruct = m_Pcb->FindPadOrModule( GetScreen()->RefPos(true),
DrawStruct = m_Pcb->FindPadOrModule(
GetScreen()->RefPos(true),
GetScreen()->m_Active_Layer ); GetScreen()->m_Active_Layer );
#else
DrawStruct = PcbGeneralLocateAndDisplay();
#endif
Show_1_Ratsnest( DrawStruct, DC ); Show_1_Ratsnest( DrawStruct, DC );
break; break;

View File

@ -301,7 +301,8 @@ bool WinEDA_PcbFrame::SavePcbFile( const wxString& FileName )
} }
else else
{ {
old_name = wxEmptyString; saveok = FALSE; old_name = wxEmptyString;
saveok = FALSE;
} }
/* Sauvegarde de l'ancien fichier */ /* Sauvegarde de l'ancien fichier */
@ -317,7 +318,10 @@ bool WinEDA_PcbFrame::SavePcbFile( const wxString& FileName )
{ {
GetScreen()->m_FileName = FullFileName; GetScreen()->m_FileName = FullFileName;
SetTitle( GetScreen()->m_FileName ); SetTitle( GetScreen()->m_FileName );
SavePcbFormatAscii( dest ); SavePcbFormatAscii( dest );
fclose( dest ); fclose( dest );
} }

View File

@ -1,13 +1,13 @@
/***************************************************/ /***************************************************/
/* PCBNEW - Gestion des Recherches (fonction Find) */ /* PCBNEW - Gestion des Recherches (fonction Find) */
/***************************************************/ /***************************************************/
/* Fichier find.cpp */ /* Fichier find.cpp */
/* /*
Affichage et modifications des parametres de travail de PcbNew * Affichage et modifications des parametres de travail de PcbNew
Parametres = dimensions des via, pistes, isolements, options... * Parametres = dimensions des via, pistes, isolements, options...
*/ */
#include "fctsys.h" #include "fctsys.h"
@ -26,126 +26,135 @@
/* variables locales */ /* variables locales */
static wxString s_OldStringFound; static wxString s_OldStringFound;
static int s_ItemCount, s_MarkerCount; static int s_ItemCount, s_MarkerCount;
/*********************************************************************/ /*********************************************************************/
void WinEDA_PcbFrame::InstallFindFrame(const wxPoint & pos, wxDC * DC) void WinEDA_PcbFrame::InstallFindFrame( const wxPoint& pos, wxDC* DC )
/*********************************************************************/ /*********************************************************************/
{ {
WinEDA_PcbFindFrame * frame = new WinEDA_PcbFindFrame(this, DC, pos); WinEDA_PcbFindFrame* frame = new WinEDA_PcbFindFrame( this, DC, pos );
frame->ShowModal(); frame->Destroy(); frame->ShowModal(); frame->Destroy();
} }
/*******************************************************/ /*******************************************************/
void WinEDA_PcbFindFrame::FindItem(wxCommandEvent& event) void WinEDA_PcbFindFrame::FindItem( wxCommandEvent& event )
/********************************************************/ /********************************************************/
{ {
PCB_SCREEN * screen = m_Parent->GetScreen(); PCB_SCREEN* screen = m_Parent->GetScreen();
wxPoint locate_pos; wxPoint locate_pos;
wxString msg; wxString msg;
bool succes = FALSE; bool succes = FALSE;
bool FindMarker = FALSE; bool FindMarker = FALSE;
MODULE * Module; MODULE* Module;
int StartCount; int StartCount;
switch ( event.GetId() ) switch( event.GetId() )
{ {
case ID_FIND_ITEM: case ID_FIND_ITEM:
s_ItemCount = 0; s_ItemCount = 0;
break; break;
case ID_FIND_MARKER: s_MarkerCount = 0; case ID_FIND_MARKER:
case ID_FIND_NEXT_MARKER: s_MarkerCount = 0;
FindMarker = TRUE;
break; case ID_FIND_NEXT_MARKER:
FindMarker = TRUE;
break;
} }
s_OldStringFound = m_NewText->GetValue(); s_OldStringFound = m_NewText->GetValue();
m_Parent->DrawPanel->GetViewStart(&screen->m_StartVisu.x, &screen->m_StartVisu.y); m_Parent->DrawPanel->GetViewStart( &screen->m_StartVisu.x, &screen->m_StartVisu.y );
StartCount = 0; StartCount = 0;
if( FindMarker ) if( FindMarker )
{ {
MARQUEUR * Marker = (MARQUEUR *) m_Parent->m_Pcb->m_Drawings; MARQUEUR* Marker = (MARQUEUR*) m_Parent->m_Pcb->m_Drawings;
for( ; Marker != NULL; Marker = (MARQUEUR *)Marker->Pnext) for( ; Marker != NULL; Marker = (MARQUEUR*) Marker->Pnext )
{ {
if( Marker->m_StructType != TYPEMARQUEUR ) continue; if( Marker->m_StructType != TYPEMARQUEUR )
continue;
StartCount++; StartCount++;
if ( StartCount > s_MarkerCount ) if( StartCount > s_MarkerCount )
{ {
succes = TRUE; succes = TRUE;
locate_pos = Marker->m_Pos; locate_pos = Marker->m_Pos;
s_MarkerCount++; s_MarkerCount++;
break; break;
} }
} }
} }
else for ( Module = m_Parent->m_Pcb->m_Modules; Module != NULL; Module = (MODULE*)Module->Pnext)
{
if( WildCompareString( s_OldStringFound, Module->m_Reference->m_Text.GetData(), FALSE ) )
{
StartCount++;
if ( StartCount > s_ItemCount )
{
succes = TRUE;
locate_pos = Module->m_Pos;
s_ItemCount++;
break;
}
}
if( WildCompareString( s_OldStringFound, Module->m_Value->m_Text.GetData(), FALSE ) )
{
StartCount++;
if ( StartCount > s_ItemCount )
{
succes = TRUE;
locate_pos = Module->m_Pos;
s_ItemCount++;
break;
}
}
}
if ( succes )
{ /* Il y a peut-etre necessite de recadrer le dessin: */
if( ! m_Parent->DrawPanel->IsPointOnDisplay(locate_pos) )
{
screen->m_Curseur = locate_pos;
m_Parent->Recadre_Trace(TRUE);
}
else
{ // Positionnement du curseur sur l'item
m_Parent->DrawPanel->CursorOff(m_DC);
screen->m_Curseur = locate_pos;
GRMouseWarp(m_Parent->DrawPanel, screen->m_Curseur );
m_Parent->DrawPanel->MouseToCursorSchema();
m_Parent->DrawPanel->CursorOn(m_DC);
}
if( FindMarker ) msg = _("Marker found");
else msg.Printf( _("<%s> Found"), s_OldStringFound.GetData() );
m_Parent->Affiche_Message(msg);
EndModal(1);
}
else else
{ {
m_Parent->Affiche_Message(wxEmptyString); for( Module = m_Parent->m_Pcb->m_Modules; Module != NULL; Module = (MODULE*) Module->Pnext )
if( FindMarker ) msg = _("Marker not found"); {
else msg.Printf( _("<%s> Not Found"), s_OldStringFound.GetData()); if( WildCompareString( s_OldStringFound, Module->m_Reference->m_Text.GetData(),
DisplayError(this,msg, 10); FALSE ) )
EndModal(0); {
StartCount++;
if( StartCount > s_ItemCount )
{
succes = TRUE;
locate_pos = Module->m_Pos;
s_ItemCount++;
break;
}
}
if( WildCompareString( s_OldStringFound, Module->m_Value->m_Text.GetData(), FALSE ) )
{
StartCount++;
if( StartCount > s_ItemCount )
{
succes = TRUE;
locate_pos = Module->m_Pos;
s_ItemCount++;
break;
}
}
}
}
if( succes )
{
/* Il y a peut-etre necessite de recadrer le dessin: */
if( !m_Parent->DrawPanel->IsPointOnDisplay( locate_pos ) )
{
screen->m_Curseur = locate_pos;
m_Parent->Recadre_Trace( TRUE );
}
else
{
// Positionnement du curseur sur l'item
m_Parent->DrawPanel->CursorOff( m_DC );
screen->m_Curseur = locate_pos;
GRMouseWarp( m_Parent->DrawPanel, screen->m_Curseur );
m_Parent->DrawPanel->MouseToCursorSchema();
m_Parent->DrawPanel->CursorOn( m_DC );
}
if( FindMarker )
msg = _( "Marker found" );
else
msg.Printf( _( "<%s> Found" ), s_OldStringFound.GetData() );
m_Parent->Affiche_Message( msg );
EndModal( 1 );
}
else
{
m_Parent->Affiche_Message( wxEmptyString );
if( FindMarker )
msg = _( "Marker not found" );
else
msg.Printf( _( "<%s> Not Found" ), s_OldStringFound.GetData() );
DisplayError( this, msg, 10 );
EndModal( 0 );
} }
} }
/*! /*!
* WinEDA_PcbFindFrame type definition * WinEDA_PcbFindFrame type definition
*/ */
@ -159,13 +168,13 @@ IMPLEMENT_DYNAMIC_CLASS( WinEDA_PcbFindFrame, wxDialog )
BEGIN_EVENT_TABLE( WinEDA_PcbFindFrame, wxDialog ) BEGIN_EVENT_TABLE( WinEDA_PcbFindFrame, wxDialog )
////@begin WinEDA_PcbFindFrame event table entries ////@begin WinEDA_PcbFindFrame event table entries
EVT_BUTTON( ID_FIND_ITEM, WinEDA_PcbFindFrame::OnFindItemClick ) EVT_BUTTON( ID_FIND_ITEM, WinEDA_PcbFindFrame::OnFindItemClick )
EVT_BUTTON( ID_FIND_NEXT_ITEM, WinEDA_PcbFindFrame::OnFindNextItemClick ) EVT_BUTTON( ID_FIND_NEXT_ITEM, WinEDA_PcbFindFrame::OnFindNextItemClick )
EVT_BUTTON( ID_FIND_MARKER, WinEDA_PcbFindFrame::OnFindMarkerClick ) EVT_BUTTON( ID_FIND_MARKER, WinEDA_PcbFindFrame::OnFindMarkerClick )
EVT_BUTTON( ID_FIND_NEXT_MARKER, WinEDA_PcbFindFrame::OnFindNextMarkerClick ) EVT_BUTTON( ID_FIND_NEXT_MARKER, WinEDA_PcbFindFrame::OnFindNextMarkerClick )
////@end WinEDA_PcbFindFrame event table entries ////@end WinEDA_PcbFindFrame event table entries
@ -175,95 +184,127 @@ END_EVENT_TABLE()
* WinEDA_PcbFindFrame constructors * WinEDA_PcbFindFrame constructors
*/ */
WinEDA_PcbFindFrame::WinEDA_PcbFindFrame( ) WinEDA_PcbFindFrame::WinEDA_PcbFindFrame()
{ {
} }
WinEDA_PcbFindFrame::WinEDA_PcbFindFrame( WinEDA_BasePcbFrame *parent, wxDC * DC,
const wxPoint& pos, WinEDA_PcbFindFrame::WinEDA_PcbFindFrame( WinEDA_BasePcbFrame* parent,
wxWindowID id, const wxString& caption, const wxSize& size, long style ) wxDC* DC,
const wxPoint& pos,
wxWindowID id,
const wxString& caption,
const wxSize& size,
long style )
{ {
m_Parent = parent; m_Parent = parent;
m_DC = DC; m_DC = DC;
Create(parent, id, caption, pos, size, style); Create( parent, id, caption, pos, size, style );
m_NewText->SetFocus(); m_NewText->SetFocus();
} }
/*! /*!
* WinEDA_PcbFindFrame creator * WinEDA_PcbFindFrame creator
*/ */
bool WinEDA_PcbFindFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) bool WinEDA_PcbFindFrame::Create( wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
{ {
////@begin WinEDA_PcbFindFrame member initialisation ////@begin WinEDA_PcbFindFrame member initialisation
m_NewText = NULL; m_NewText = NULL;
////@end WinEDA_PcbFindFrame member initialisation ////@end WinEDA_PcbFindFrame member initialisation
////@begin WinEDA_PcbFindFrame creation ////@begin WinEDA_PcbFindFrame creation
SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS); SetExtraStyle( GetExtraStyle() | wxWS_EX_BLOCK_EVENTS );
wxDialog::Create( parent, id, caption, pos, size, style ); wxDialog::Create( parent, id, caption, pos, size, style );
CreateControls(); CreateControls();
GetSizer()->Fit(this); GetSizer()->Fit( this );
GetSizer()->SetSizeHints(this); GetSizer()->SetSizeHints( this );
Centre(); Centre();
////@end WinEDA_PcbFindFrame creation ////@end WinEDA_PcbFindFrame creation
return true; return true;
} }
/*! /*!
* Control creation for WinEDA_PcbFindFrame * Control creation for WinEDA_PcbFindFrame
*/ */
void WinEDA_PcbFindFrame::CreateControls() void WinEDA_PcbFindFrame::CreateControls()
{ {
SetFont(*g_DialogFont); SetFont( *g_DialogFont );
////@begin WinEDA_PcbFindFrame content construction ////@begin WinEDA_PcbFindFrame content construction
// Generated by DialogBlocks, 04/03/2006 14:04:20 (unregistered) // Generated by DialogBlocks, 04/03/2006 14:04:20 (unregistered)
WinEDA_PcbFindFrame* itemDialog1 = this; WinEDA_PcbFindFrame* itemDialog1 = this;
wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* itemBoxSizer2 = new wxBoxSizer( wxVERTICAL );
itemDialog1->SetSizer(itemBoxSizer2); itemDialog1->SetSizer( itemBoxSizer2 );
wxStaticText* itemStaticText3 = new wxStaticText( itemDialog1, wxID_STATIC, _("Item to find:"), wxDefaultPosition, wxDefaultSize, 0 ); wxStaticText* itemStaticText3 = new wxStaticText( itemDialog1, wxID_STATIC,
itemBoxSizer2->Add(itemStaticText3, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); _(
"Item to find:" ),
wxDefaultPosition, wxDefaultSize, 0 );
itemBoxSizer2->Add( itemStaticText3,
0,
wxGROW | wxLEFT | wxRIGHT | wxTOP | wxADJUST_MINSIZE,
5 );
m_NewText = new wxTextCtrl( itemDialog1, ID_TEXTCTRL, _T(""), wxDefaultPosition, wxDefaultSize, 0 ); m_NewText = new wxTextCtrl( itemDialog1, ID_TEXTCTRL, _T(
itemBoxSizer2->Add(m_NewText, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); "" ), wxDefaultPosition, wxDefaultSize, 0 );
itemBoxSizer2->Add( m_NewText, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* itemBoxSizer5 = new wxBoxSizer( wxHORIZONTAL );
itemBoxSizer2->Add(itemBoxSizer5, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT|wxBOTTOM, 5); itemBoxSizer2->Add( itemBoxSizer5,
0,
wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxBOTTOM,
5 );
wxBoxSizer* itemBoxSizer6 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* itemBoxSizer6 = new wxBoxSizer( wxVERTICAL );
itemBoxSizer5->Add(itemBoxSizer6, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5); itemBoxSizer5->Add( itemBoxSizer6, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
wxButton* itemButton7 = new wxButton( itemDialog1, ID_FIND_ITEM, _("Find Item"), wxDefaultPosition, wxDefaultSize, 0 ); wxButton* itemButton7 = new wxButton( itemDialog1, ID_FIND_ITEM, _(
"Find Item" ), wxDefaultPosition, wxDefaultSize, 0 );
itemButton7->SetDefault(); itemButton7->SetDefault();
itemButton7->SetForegroundColour(wxColour(102, 0, 0)); itemButton7->SetForegroundColour( wxColour( 102, 0, 0 ) );
itemBoxSizer6->Add(itemButton7, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5); itemBoxSizer6->Add( itemButton7, 0, wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
wxButton* itemButton8 = new wxButton( itemDialog1, ID_FIND_NEXT_ITEM, _("Find Next Item"), wxDefaultPosition, wxDefaultSize, 0 ); wxButton* itemButton8 = new wxButton( itemDialog1, ID_FIND_NEXT_ITEM, _(
itemButton8->SetForegroundColour(wxColour(111, 0, 0)); "Find Next Item" ), wxDefaultPosition, wxDefaultSize,
itemBoxSizer6->Add(itemButton8, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); 0 );
itemButton8->SetForegroundColour( wxColour( 111, 0, 0 ) );
itemBoxSizer6->Add( itemButton8, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* itemBoxSizer9 = new wxBoxSizer( wxVERTICAL );
itemBoxSizer5->Add(itemBoxSizer9, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5); itemBoxSizer5->Add( itemBoxSizer9, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 );
wxButton* itemButton10 = new wxButton( itemDialog1, ID_FIND_MARKER, _("Find Marker"), wxDefaultPosition, wxDefaultSize, 0 ); wxButton* itemButton10 = new wxButton( itemDialog1, ID_FIND_MARKER, _(
itemButton10->SetForegroundColour(wxColour(0, 0, 255)); "Find Marker" ), wxDefaultPosition, wxDefaultSize,
itemBoxSizer9->Add(itemButton10, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5); 0 );
itemButton10->SetForegroundColour( wxColour( 0, 0, 255 ) );
itemBoxSizer9->Add( itemButton10, 0, wxGROW | wxLEFT | wxRIGHT | wxTOP, 5 );
wxButton* itemButton11 = new wxButton( itemDialog1, ID_FIND_NEXT_MARKER, _("Find Next Marker"), wxDefaultPosition, wxDefaultSize, 0 ); wxButton* itemButton11 = new wxButton( itemDialog1, ID_FIND_NEXT_MARKER, _(
itemButton11->SetForegroundColour(wxColour(0, 0, 255)); "Find Next Marker" ), wxDefaultPosition,
itemBoxSizer9->Add(itemButton11, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); wxDefaultSize, 0 );
itemButton11->SetForegroundColour( wxColour( 0, 0, 255 ) );
itemBoxSizer9->Add( itemButton11, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
////@end WinEDA_PcbFindFrame content construction ////@end WinEDA_PcbFindFrame content construction
} }
/*! /*!
* Should we show tooltips? * Should we show tooltips?
*/ */
@ -273,6 +314,7 @@ bool WinEDA_PcbFindFrame::ShowToolTips()
return true; return true;
} }
/*! /*!
* Get bitmap resources * Get bitmap resources
*/ */
@ -281,11 +323,13 @@ wxBitmap WinEDA_PcbFindFrame::GetBitmapResource( const wxString& name )
{ {
// Bitmap retrieval // Bitmap retrieval
////@begin WinEDA_PcbFindFrame bitmap retrieval ////@begin WinEDA_PcbFindFrame bitmap retrieval
wxUnusedVar(name); wxUnusedVar( name );
return wxNullBitmap; return wxNullBitmap;
////@end WinEDA_PcbFindFrame bitmap retrieval ////@end WinEDA_PcbFindFrame bitmap retrieval
} }
/*! /*!
* Get icon resources * Get icon resources
*/ */
@ -294,44 +338,48 @@ wxIcon WinEDA_PcbFindFrame::GetIconResource( const wxString& name )
{ {
// Icon retrieval // Icon retrieval
////@begin WinEDA_PcbFindFrame icon retrieval ////@begin WinEDA_PcbFindFrame icon retrieval
wxUnusedVar(name); wxUnusedVar( name );
return wxNullIcon; return wxNullIcon;
////@end WinEDA_PcbFindFrame icon retrieval ////@end WinEDA_PcbFindFrame icon retrieval
} }
/*! /*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_ITEM * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_ITEM
*/ */
void WinEDA_PcbFindFrame::OnFindItemClick( wxCommandEvent& event ) void WinEDA_PcbFindFrame::OnFindItemClick( wxCommandEvent& event )
{ {
FindItem(event); FindItem( event );
} }
/*! /*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_NEXT_ITEM * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_NEXT_ITEM
*/ */
void WinEDA_PcbFindFrame::OnFindNextItemClick( wxCommandEvent& event ) void WinEDA_PcbFindFrame::OnFindNextItemClick( wxCommandEvent& event )
{ {
FindItem(event); FindItem( event );
} }
/*! /*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_MARKER * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_MARKER
*/ */
void WinEDA_PcbFindFrame::OnFindMarkerClick( wxCommandEvent& event ) void WinEDA_PcbFindFrame::OnFindMarkerClick( wxCommandEvent& event )
{ {
FindItem(event); FindItem( event );
} }
/*! /*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_NEXT_MARKER * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_FIND_NEXT_MARKER
*/ */
void WinEDA_PcbFindFrame::OnFindNextMarkerClick( wxCommandEvent& event ) void WinEDA_PcbFindFrame::OnFindNextMarkerClick( wxCommandEvent& event )
{ {
FindItem(event); FindItem( event );
} }

View File

@ -1082,8 +1082,11 @@ int WinEDA_PcbFrame::SavePcbFormatAscii( FILE* File )
/* Ecriture des donnes utiles du pcb */ /* Ecriture des donnes utiles du pcb */
Equipot = m_Pcb->m_Equipots; Equipot = m_Pcb->m_Equipots;
Pas = 100.0; if( m_Pcb->m_NbNets )
Pas = 100.0;
if( m_Pcb->m_NbNets )
Pas /= m_Pcb->m_NbNets; Pas /= m_Pcb->m_NbNets;
for( ii = 0; Equipot != NULL; ii++, Equipot = (EQUIPOT*) Equipot->Pnext ) for( ii = 0; Equipot != NULL; ii++, Equipot = (EQUIPOT*) Equipot->Pnext )
{ {
Equipot->WriteEquipotDescr( File ); Equipot->WriteEquipotDescr( File );

View File

@ -896,7 +896,7 @@ TEXTE_PCB* Locate_Texte_Pcb( EDA_BaseStruct* PtStruct, int LayerSearch, int type
if( pt_txt_pcb->m_Layer == LayerSearch ) if( pt_txt_pcb->m_Layer == LayerSearch )
{ {
// because HitTest() is present in both base classes of TEXTE_PCB // because HitTest() is present in both base classes of TEXTE_PCB
// use a dis-ambiguating cast to tell compiler which HitTest() // use a clarifying cast to tell compiler which HitTest()
// to call. // to call.
if( static_cast<EDA_TextStruct*>(pt_txt_pcb)->HitTest( ref ) ) if( static_cast<EDA_TextStruct*>(pt_txt_pcb)->HitTest( ref ) )
{ {