Commit 128521f0 authored by dickelbeck's avatar dickelbeck

2nd of 3 commits for DrcDialog rework

parent cea3f06a
......@@ -4,6 +4,21 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2007-Nov-30 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew
* added virtual GetPosition() to BOARD_ITEM and derivatives.
* added classes DRC, REPORT_ISSUE, DRC_ITEM and rearranged drc.cpp entirely
to comprize the DRC class. The result has finer granularity of functions
and each is fairly well documented in English, see drc_stuff.h.
Keeping old stuff commented out at bottom of drc.cpp until some more usage
and testing is done.
* Made the DRC dialog modeless, so it can sit off to the side while the MARKER
are inspected one by one.
Need another 4-8 hours or so to finish the actual dialog display, remove
debug statements and finish testing.
2007-Nov-29 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
......
......@@ -456,6 +456,13 @@ public:
BOARD_ITEM* Back() const { return (BOARD_ITEM*) Pback; }
BOARD_ITEM* GetParent() const { return (BOARD_ITEM*) m_Parent; }
/**
* Function GetPosition
* returns the position of this object.
* @return wxPoint& - The position of this object, non-const so it
* can be changed
*/
virtual wxPoint& GetPosition() = 0;
/**
* Function GetLayer
......
......@@ -199,8 +199,11 @@ enum DisplayViaMode {
class BOARD : public BOARD_ITEM
{
friend class WinEDA_PcbFrame;
private:
std::vector<MARKER*> m_markers; ///< MARKERs which we own by pointer
std::vector<MARKER*> m_markers; ///< MARKERs for clearance problems, owned by pointer
// std::vector<MARKER*> m_markersUnconnected; ///< MARKERs for unconnected problems, owned by pointer
public:
WinEDA_BasePcbFrame* m_PcbFrame; // Window de visualisation
......@@ -233,6 +236,14 @@ public:
BOARD( EDA_BaseStruct* StructFather, WinEDA_BasePcbFrame* frame );
~BOARD();
/**
* Function GetPosition
* is here to satisfy BOARD_ITEM's requirements, but this implementation
* is a dummy.
* @return const wxPoint& of (0,0)
*/
wxPoint& GetPosition();
/* supprime du chainage la structure Struct */
void UnLink();
......@@ -275,7 +286,16 @@ public:
int GetNumSegmTrack();
int GetNumSegmZone();
int GetNumNoconnect(); // retourne le nombre de connexions manquantes
int GetNumRatsnests(); // retourne le nombre de chevelus
/**
* Function GetNumRatsnests
* @return int - The number of rats
*/
int GetNumRatsnests()
{
return m_NbLinks;
}
int GetNumNodes(); // retourne le nombre de pads a netcode > 0
// Calcul du rectangle d'encadrement:
......@@ -407,7 +427,18 @@ public:
DRAWSEGMENT( BOARD_ITEM* StructFather, KICAD_T idtype = TYPEDRAWSEGMENT );
~DRAWSEGMENT();
// Read/write data
/**
* Function GetPosition
* returns the position of this object.
* Required by pure virtual BOARD_ITEM::GetPosition()
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Start;
}
/**
* Function Save
......
......@@ -101,6 +101,7 @@ class Ki_PageDescr;
class Ki_HotkeyInfo;
class GENERAL_COLLECTOR;
class GENERAL_COLLECTORS_GUIDE;
class DRC;
enum id_librarytype {
......@@ -574,6 +575,9 @@ private:
bool m_SelViaSizeBox_Changed;
wxMenu* m_FilesMenu;
DRC* m_drc; ///< the DRC controller, see drc.cpp
// we'll use lower case function names for private member functions.
void createPopUpMenuForFootprints( MODULE* aModule, wxMenu* aPopMenu );
void createPopUpMenuForFpTexts( TEXTE_MODULE* aText, wxMenu* aPopMenu );
......@@ -655,7 +659,6 @@ public:
MODULE* ListAndSelectModuleName();
void Liste_Equipot( wxCommandEvent& event );
void Swap_Layers( wxCommandEvent& event );
int Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone );
void Install_Test_DRC_Frame( wxDC* DC );
void Trace_Pcb( wxDC* DC, int mode );
......@@ -719,6 +722,8 @@ public:
bool PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC );
void Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC );
void SwitchLayer( wxDC* DC, int layer );
int Add_45_degrees_Segment( wxDC* DC, TRACK* pt_segm );
bool Genere_Pad_Connexion( wxDC* DC, int layer );
// zone handling
EDGE_ZONE* Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone );
......
......@@ -865,22 +865,25 @@ float WinEDA_PcbFrame::Compute_Ratsnest_PlaceModule( wxDC* DC )
CHEVELU* pt_local_chevelu;
int ii;
float cout, icout;
int ox, oy, fx, fy, dx, dy;
int ox, oy;
int fx, fy;
int dx, dy;
if( (m_Pcb->m_Status_Pcb & CHEVELU_LOCAL_OK) == 0 )
return -1;
pt_local_chevelu = local_liste_chevelu;
ii = nb_local_chevelu; cout = 0;
ii = nb_local_chevelu;
cout = 0;
while( ii-- > 0 )
{
if( !(pt_local_chevelu->status & LOCAL_CHEVELU) )
{
ox = pt_local_chevelu->pad_start->m_Pos.x - g_Offset_Module.x;
oy = pt_local_chevelu->pad_start->m_Pos.y - g_Offset_Module.y;
fx = pt_local_chevelu->pad_end->m_Pos.x;
fy = pt_local_chevelu->pad_end->m_Pos.y;
ox = pt_local_chevelu->pad_start->GetPosition().x - g_Offset_Module.x;
oy = pt_local_chevelu->pad_start->GetPosition().y - g_Offset_Module.y;
fx = pt_local_chevelu->pad_end->GetPosition().x;
fy = pt_local_chevelu->pad_end->GetPosition().y;
if( AutoPlaceShowAll )
{
......@@ -889,12 +892,18 @@ float WinEDA_PcbFrame::Compute_Ratsnest_PlaceModule( wxDC* DC )
}
/* Evaluation du cout du chevelu: */
dx = fx - ox; dy = fy - oy;
dx = abs( dx ); dy = abs( dy );
dx = fx - ox;
dy = fy - oy;
dx = abs( dx );
dy = abs( dy );
if( dx < dy )
EXCHG( dx, dy );/* dx >= dy */
/* cout de la distance: */
icout = (float) dx * dx;
/* cout de l'inclinaison */
icout += 3 * (float) dy * dy;
icout = sqrt( icout );
......
......@@ -55,9 +55,10 @@ public:
void SetNet( int aNetCode )
{
m_NetCode = aNetCode;
};
}
};
/****************************************************************/
/* description d'un point de piste pour le suivi des connexions */
/****************************************************************/
......@@ -81,9 +82,6 @@ enum StatusPcbFlags {
DO_NOT_SHOW_GENERAL_RASTNEST = 0x20 /* Do not display the general rastnest (used in module moves) */
};
#define OK_DRC 0
#define BAD_DRC 1
/* Commandes d'autoplacement / autorouage possibles */
enum CommandOpt {
......@@ -170,4 +168,5 @@ eda_global BOARDHEAD Board; /* 2-sided board */
#include "ar_protos.h"
#endif /* AUTOROUT_H */
#endif // AUTOROUT_H
......@@ -471,8 +471,8 @@ void MoveMarkedItems( MODULE* module, wxPoint offset )
{
if( pad->m_Selected == 0 )
continue;
pad->m_Pos.x += offset.x;
pad->m_Pos.y += offset.y;
pad->GetPosition().x += offset.x;
pad->GetPosition().y += offset.y;
pad->m_Pos0.x += offset.x;
pad->m_Pos0.y += offset.y;
}
......@@ -486,8 +486,8 @@ void MoveMarkedItems( MODULE* module, wxPoint offset )
switch( item->Type() )
{
case TYPETEXTEMODULE:
( (TEXTE_MODULE*) item )->m_Pos.x += offset.x;
( (TEXTE_MODULE*) item )->m_Pos.y += offset.y;
( (TEXTE_MODULE*) item )->GetPosition().x += offset.x;
( (TEXTE_MODULE*) item )->GetPosition().y += offset.y;
( (TEXTE_MODULE*) item )->m_Pos0.x += offset.x;
( (TEXTE_MODULE*) item )->m_Pos0.y += offset.y;
break;
......@@ -495,10 +495,13 @@ void MoveMarkedItems( MODULE* module, wxPoint offset )
case TYPEEDGEMODULE:
( (EDGE_MODULE*) item )->m_Start.x += offset.x;
( (EDGE_MODULE*) item )->m_Start.y += offset.y;
( (EDGE_MODULE*) item )->m_End.x += offset.x;
( (EDGE_MODULE*) item )->m_End.y += offset.y;
( (EDGE_MODULE*) item )->m_Start0.x += offset.x;
( (EDGE_MODULE*) item )->m_Start0.y += offset.y;
( (EDGE_MODULE*) item )->m_End0.x += offset.x;
( (EDGE_MODULE*) item )->m_End0.y += offset.y;
break;
......@@ -565,8 +568,8 @@ void MirrorMarkedItems( MODULE* module, wxPoint offset )
{
if( pad->m_Selected == 0 )
continue;
SETMIRROR( pad->m_Pos.x );
pad->m_Pos0.x = pad->m_Pos.x;
SETMIRROR( pad->GetPosition().x );
pad->m_Pos0.x = pad->GetPosition().x;
pad->m_Offset.x = -pad->m_Offset.x;
pad->m_DeltaSize.x = -pad->m_DeltaSize.x;
pad->m_Orient = 1800 - pad->m_Orient;
......@@ -590,8 +593,8 @@ void MirrorMarkedItems( MODULE* module, wxPoint offset )
break;
case TYPETEXTEMODULE:
SETMIRROR( ( (TEXTE_MODULE*) item )->m_Pos.x );
( (TEXTE_MODULE*) item )->m_Pos0.x = ( (TEXTE_MODULE*) item )->m_Pos.x;
SETMIRROR( ( (TEXTE_MODULE*) item )->GetPosition().x );
( (TEXTE_MODULE*) item )->m_Pos0.x = ( (TEXTE_MODULE*) item )->GetPosition().x;
break;
default:
......@@ -621,8 +624,8 @@ void RotateMarkedItems( MODULE* module, wxPoint offset )
{
if( pad->m_Selected == 0 )
continue;
ROTATE( pad->m_Pos );
pad->m_Pos0 = pad->m_Pos;
ROTATE( pad->GetPosition() );
pad->m_Pos0 = pad->GetPosition();
pad->m_Orient += 900;
NORMALIZE_ANGLE( pad->m_Orient );
}
......@@ -643,8 +646,8 @@ void RotateMarkedItems( MODULE* module, wxPoint offset )
break;
case TYPETEXTEMODULE:
ROTATE( ( (TEXTE_MODULE*) item )->m_Pos );
( (TEXTE_MODULE*) item )->m_Pos0 = ( (TEXTE_MODULE*) item )->m_Pos;
ROTATE( ( (TEXTE_MODULE*) item )->GetPosition() );
( (TEXTE_MODULE*) item )->m_Pos0 = ( (TEXTE_MODULE*) item )->GetPosition();
( (TEXTE_MODULE*) item )->m_Orient += 900;
break;
......@@ -696,7 +699,7 @@ int MarkItemsInBloc( MODULE* module, EDA_Rect& Rect )
for( ; pad != NULL; pad = pad->Next() )
{
pad->m_Selected = 0;
pos = pad->m_Pos;
pos = pad->GetPosition();
if( Rect.Inside( pos ) )
{
pad->m_Selected = IS_SELECTED;
......@@ -727,7 +730,7 @@ int MarkItemsInBloc( MODULE* module, EDA_Rect& Rect )
break;
case TYPETEXTEMODULE:
pos = ( (TEXTE_MODULE*) item )->m_Pos;
pos = ( (TEXTE_MODULE*) item )->GetPosition();
if( Rect.Inside( pos ) )
{
item->m_Selected = IS_SELECTED;
......
......@@ -360,38 +360,38 @@ int Build_Work( BOARD* Pcb, CHEVELU* pt_base_chevelu )
current_net_code = pt_pad->GetNet();
pt_ch = pt_rats;
r1 = (pt_pad->m_Pos.y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize;
r1 = (pt_pad->GetPosition().y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize;
if( r1 < 0 || r1 >= Nrows )
{
msg.Printf( wxT( "erreur : row = %d ( padY %d pcbY %d) " ), r1,
pt_pad->m_Pos.y, Pcb->m_BoundaryBox.m_Pos.y );
pt_pad->GetPosition().y, Pcb->m_BoundaryBox.m_Pos.y );
DisplayError( NULL, msg );
return 0;
}
c1 = (pt_pad->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize;
c1 = (pt_pad->GetPosition().x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize;
if( c1 < 0 || c1 >= Ncols )
{
msg.Printf( wxT( "erreur : col = %d ( padX %d pcbX %d) " ), c1,
pt_pad->m_Pos.x, Pcb->m_BoundaryBox.m_Pos.x );
pt_pad->GetPosition().x, Pcb->m_BoundaryBox.m_Pos.x );
DisplayError( NULL, msg );
return 0;
}
pt_pad = pt_rats->pad_end;
r2 = (pt_pad->m_Pos.y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize;
r2 = (pt_pad->GetPosition().y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize;
if( r2 < 0 || r2 >= Nrows )
{
msg.Printf( wxT( "erreur : row = %d ( padY %d pcbY %d) " ), r2,
pt_pad->m_Pos.y, Pcb->m_BoundaryBox.m_Pos.y );
pt_pad->GetPosition().y, Pcb->m_BoundaryBox.m_Pos.y );
DisplayError( NULL, msg );
return 0;
}
c2 = (pt_pad->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize;
c2 = (pt_pad->GetPosition().x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize;
if( c2 < 0 || c2 >= Ncols )
{
msg.Printf( wxT( "erreur : col = %d ( padX %d pcbX %d) " ), c2,
pt_pad->m_Pos.x, Pcb->m_BoundaryBox.m_Pos.x );
pt_pad->GetPosition().x, Pcb->m_BoundaryBox.m_Pos.x );
DisplayError( NULL, msg );
return 0;
}
......
......@@ -79,6 +79,13 @@ BOARD::~BOARD()
}
wxPoint& BOARD::GetPosition()
{
static wxPoint dummy(0,0);
return dummy; // a reference
}
void BOARD::UnLink()
{
/* Modification du chainage arriere */
......@@ -108,6 +115,7 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
{
// this one uses a vector
case TYPEMARKER:
aBoardItem->m_Parent = this;
m_markers.push_back( (MARKER*) aBoardItem );
break;
......@@ -188,13 +196,6 @@ int BOARD::GetNumNoconnect()
}
// retourne le nombre de chevelus
int BOARD::GetNumRatsnests()
{
return m_NbLinks;
}
// retourne le nombre de pads a netcode > 0
int BOARD::GetNumNodes()
{
......@@ -273,11 +274,13 @@ bool BOARD::ComputeBoundaryBox()
D_PAD* pt_pad = module->m_Pads;
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
{
const wxPoint& pos = pt_pad->GetPosition();
d = pt_pad->m_Rayon;
xmin = MIN( xmin, pt_pad->m_Pos.x - d );
ymin = MIN( ymin, pt_pad->m_Pos.y - d );
xmax = MAX( xmax, pt_pad->m_Pos.x + d );
ymax = MAX( ymax, pt_pad->m_Pos.y + d );
xmin = MIN( xmin, pos.x - d );
ymin = MIN( ymin, pos.y - d );
xmax = MAX( xmax, pos.x + d );
ymax = MAX( ymax, pos.y + d );
}
}
......
......@@ -195,7 +195,8 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
break;
case TYPEMARKER:
text << _( "Marker" ) << wxT( " @(" ) << ((MARKER*)item)->m_Pos.x << wxT(",") << ((MARKER*)item)->m_Pos.y << wxT(")");
text << _( "Marker" ) << wxT( " @(" ) << ((MARKER*)item)->GetPos().x
<< wxT(",") << ((MARKER*)item)->GetPos().y << wxT(")");
break;
case TYPECOTATION:
......
......@@ -28,6 +28,12 @@ public:
COTATION( BOARD_ITEM* StructFather );
~COTATION();
wxPoint& GetPosition()
{
return m_Pos;
}
bool ReadCotationDescr( FILE* File, int* LineNum );
/**
......
......@@ -29,6 +29,18 @@ public:
EDGE_MODULE( EDGE_MODULE* edge );
~EDGE_MODULE();
/**
* Function GetPosition
* returns the position of this object.
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Start;
}
/* supprime du chainage la structure Struct */
void UnLink();
......
......@@ -44,6 +44,13 @@ EQUIPOT::~EQUIPOT()
}
wxPoint& EQUIPOT::GetPosition()
{
static wxPoint dummy;
return dummy;
}
void EQUIPOT::UnLink()
{
/* Modification du chainage arriere */
......
......@@ -30,6 +30,16 @@ public:
EQUIPOT* Next() { return (EQUIPOT*) Pnext; }
/**
* Function GetPosition
* returns the position of this object.
* @return wxPoint& - The position of this object, non-const so it
* can be changed
* A dummy to satisfy pure virtual BOARD::GetPosition()
*/
wxPoint& GetPosition();
/* Effacement memoire de la structure */
void UnLink();
......
......@@ -38,8 +38,7 @@ static char Default_MarkerBitmap[] =
/* Classe MARKER */
/*******************/
MARKER::MARKER( BOARD_ITEM* StructFather ) :
BOARD_ITEM( StructFather, TYPEMARKER )
void MARKER::init()
{
m_Bitmap = NULL;
m_Type = 0;
......@@ -49,6 +48,26 @@ MARKER::MARKER( BOARD_ITEM* StructFather ) :
m_Size.y = Default_MarkerBitmap[1];
}
MARKER::MARKER( BOARD_ITEM* StructFather ) :
BOARD_ITEM( StructFather, TYPEMARKER ),
m_drc()
{
init();
}
MARKER::MARKER( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos ) :
BOARD_ITEM( NULL, TYPEMARKER ) // parent set during BOARD::Add()
{
init();
SetData( aErrorCode, aMarkerPos,
aText, aPos,
bText, bPos );
}
/* Effacement memoire de la structure */
MARKER::~MARKER()
......@@ -59,6 +78,19 @@ MARKER::~MARKER()
}
void MARKER::SetData( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos )
{
m_drc.SetData( aErrorCode, aMarkerPos,
aText, bText,
aPos, bPos );
// @todo: switch on error code to set error code specific color, and possibly bitmap.
m_Color = WHITE;
}
/* supprime du chainage la structure Struct
* les structures arrieres et avant sont chainees directement
*/
......@@ -78,7 +110,7 @@ void MARKER::Display_Infos( WinEDA_DrawFrame* frame )
Affiche_1_Parametre( frame, text_pos, _( "Type" ), _("Marker"), DARKCYAN );
text_pos = 12;
Affiche_1_Parametre( frame, text_pos, _( "Marker Error Text" ), m_Diag, RED );
Affiche_1_Parametre( frame, text_pos, _( "Marker Error Text" ), GetOneLineMessage(), RED );
}
......@@ -96,8 +128,10 @@ bool MARKER::HitTest( const wxPoint& refPos )
TrueSize.y *= ActiveScreen->GetZoom();
}
int dx = refPos.x - m_Pos.x;
int dy = refPos.y - m_Pos.y;
wxPoint pos = GetPosition();
int dx = refPos.x - pos.x;
int dy = refPos.y - pos.y;
/* is refPos in the box: Marker size to right an bottom,
or size/2 to left or top */
......@@ -130,8 +164,8 @@ void MARKER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int DrawMode )
GRSetDrawMode( DC, DrawMode );
px = GRMapX( m_Pos.x );
py = GRMapY( m_Pos.y );
px = GRMapX( GetPosition().x );
py = GRMapY( GetPosition().y );
/* Get the bitmap size */
m_Size.x = *(pt_bitmap++);
......
......@@ -7,39 +7,106 @@
#include "base_struct.h"
#include "drc_stuff.h"
class MARKER : public BOARD_ITEM
{
private:
wxString m_Diag; /* Associated text (comment) */
public:
wxPoint m_Pos;
char* m_Bitmap; /* Shape (bitmap) */
protected:
char* m_Bitmap; ///< Shape (bitmap)
int m_Type;
int m_Color; /* color */
wxSize m_Size; /* Size of the graphic symbol */
int m_Color; ///< color
wxSize m_Size; ///< Size of the graphic symbol
DRC_ITEM m_drc;
void init();
public:
MARKER( BOARD_ITEM* StructFather );
/**
* Constructor
* @param aErrorCode The categorizing identifier for an error
* @param aMarkerPos The position of the MARKER on the BOARD
* @param aText Text describing the first of two objects
* @param aPos The position of the first of two objects
* @param bText Text describing the second of the two conflicting objects
* @param bPos The position of the second of two objects
*/
MARKER( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos );
~MARKER();
void UnLink();
void Draw( WinEDA_DrawPanel* panel, wxDC* DC, int DrawMode );
/**
* Function GetPosition
* returns the position of this MARKER.
*/
wxPoint& GetPosition()
{
return (wxPoint&) m_drc.GetPosition();
}
/**
* Function GetPos
* returns the position of this MARKER, const.
*/
const wxPoint& GetPos() const
{
return m_drc.GetPosition();
}
/**
* Function SetData
* fills in all the reportable data associated with a MARKER.
* @param aErrorCode The categorizing identifier for an error
* @param aMarkerPos The position of the MARKER on the BOARD
* @param aText Text describing the first of two objects
* @param aPos The position of the first of two objects
* @param bText Text describing the second of the two conflicting objects
* @param bPos The position of the second of two objects
*/
void SetData( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos );
/**
* Function GetMessage
* @return const wxString& - the diagnostic message
*/
const wxString& GetMessage()
const wxString GetOneLineMessage()
{
return m_Diag;
return m_drc.ShowText();
}
/**
* Function GetReporter
* returns the REPORT_ISSUE held within this MARKER so that its
* interface may be used.
* @return const& REPORT_ISSUE
*/
const REPORT_ISSUE& GetReporter() const
{
return m_drc;
}
/*
void SetMessage( const wxString& aMsg )
{
m_Diag = aMsg;
}
*/
/**
......@@ -75,4 +142,4 @@ public:
};
#endif // end #ifndef CLASS_MARKER_H
#endif // CLASS_MARKER_H
......@@ -19,6 +19,12 @@ public:
MIREPCB( BOARD_ITEM* StructFather );
~MIREPCB();
wxPoint& GetPosition()
{
return m_Pos;
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
......
......@@ -37,6 +37,7 @@ enum Mod_Attribut /* Attributs d'un module */
class MODULE : public BOARD_ITEM
{
public:
wxPoint m_Pos; // Real coord on board
D_PAD* m_Pads; /* Pad list (linked list) */
......@@ -82,6 +83,18 @@ public:
void SetRectangleExinscrit();/* mise a jour du rect d'encadrement
* et de la surface en coord reelles */
/**
* Function GetPosition
* returns the position of this object.
* Required by pure virtual BOARD_ITEM::GetPosition()
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Pos;
}
// deplacements
void SetPosition( const wxPoint& newpos );
void SetOrientation( int newangle );
......
......@@ -38,7 +38,7 @@ D_PAD::D_PAD( MODULE* parent ) :
if( m_Parent && (m_Parent->Type() == TYPEMODULE) )
{
m_Pos = ( (MODULE*) m_Parent )->m_Pos;
m_Pos = ( (MODULE*) m_Parent )->GetPosition();
}
m_PadShape = CIRCLE; // forme CERCLE, RECT OVALE TRAPEZE ou libre
......@@ -75,8 +75,8 @@ void D_PAD::ComputeRayon()
case RECT:
case TRAPEZE:
m_Rayon = (int) (sqrt( (float) m_Size.y * m_Size.y
+ (float) m_Size.x * m_Size.x ) / 2);
m_Rayon = (int) (sqrt( (double) m_Size.y * m_Size.y
+ (double) m_Size.x * m_Size.x ) / 2);
break;
}
}
......@@ -88,7 +88,7 @@ const wxPoint D_PAD::ReturnShapePos()
// retourne la position de la forme (pastilles excentrees)
{
if( (m_Offset.x == 0) && (m_Offset.y == 0) )
if( m_Offset.x == 0 && m_Offset.y == 0 )
return m_Pos;
wxPoint shape_pos;
......
......@@ -24,7 +24,10 @@ class D_PAD : public BOARD_ITEM
private:
int m_NetCode; // Net number for fast comparisons
public:
wxPoint m_Pos; // pad Position on board
union
{
unsigned long m_NumPadName;
......@@ -42,7 +45,6 @@ public:
int m_PadShape; // Shape: CIRCLE, RECT, OVAL, TRAPEZOID
int m_DrillShape; // Shape CIRCLE, OVAL
wxPoint m_Pos; // pad Position on board
wxSize m_Drill; // Drill diam (drill shape = CIRCLE) or drill size(shape = OVAL)
// for drill shape = CIRCLE, drill diam = m_Drill.x
......@@ -72,6 +74,21 @@ public:
D_PAD* Next() { return (D_PAD*) Pnext; }
/**
* Function GetPosition
* returns the position of this object.
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Pos;
}
void SetPosition( const wxPoint& aPos )
{
m_Pos = aPos;
}
/* remove from linked list */
void UnLink();
......@@ -87,6 +104,7 @@ public:
bool Save( FILE* aFile ) const;
/* drawing functions */
void Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int draw_mode );
void Draw3D( Pcb3D_GLCanvas* glcanvas );
......
......@@ -13,6 +13,19 @@ public:
TEXTE_PCB( TEXTE_PCB* textepcb );
~TEXTE_PCB();
/**
* Function GetPosition
* returns the position of this object.
* @return wxPoint& - The position of this object, non-const so it
* can be changed
*/
wxPoint& GetPosition()
{
return m_Pos; // within EDA_TextStruct
}
/* supprime du chainage la structure Struct */
void UnLink();
......
......@@ -16,8 +16,8 @@
class TEXTE_MODULE : public BOARD_ITEM
{
public:
int m_Width;
wxPoint m_Pos; // Real coord
int m_Width;
wxPoint m_Pos0; // coord du debut du texte /ancre, orient 0
char m_Unused; // unused (reserved for future extensions)
char m_Miroir; // vue normale / miroir
......@@ -31,6 +31,18 @@ public:
TEXTE_MODULE( MODULE* parent, int text_type = TEXT_is_DIVERS );
~TEXTE_MODULE();
/**
* Function GetPosition
* returns the position of this object.
* Required by pure virtual BOARD_ITEM::GetPosition()
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Pos;
}
/* supprime du chainage la structure Struct */
void UnLink();
......
......@@ -144,21 +144,6 @@ bool TRACK::IsNull()
}
/*************************************************************/
double TRACK::GetLength() const
/*************************************************************/
{
int dx = m_Start.x - m_End.x;
int dy = m_Start.y - m_End.y;
double dist = ( (double) dx * dx ) + ( (double) dy * dy );
dist = sqrt( dist );
return dist;
}
/*************************************************************/
int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist )
/*************************************************************/
......
......@@ -55,6 +55,16 @@ public:
TRACK* Back() const { return (TRACK*) Pback; }
/**
* Function GetPosition
* returns the position of this object.
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Start; // it had to be start or end.
}
/* supprime du chainage la structure Struct */
void UnLink();
......@@ -122,7 +132,12 @@ public:
* returns the length of the track using the hypotenuse calculation.
* @return double - the length of the track
*/
double GetLength() const;
double GetLength() const
{
int dx = m_Start.x - m_End.x;
int dy = m_Start.y - m_End.y;
return hypot( dx, dy );
}
/* Display on screen: */
......@@ -255,8 +270,16 @@ public:
void SetLayerPair( int top_layer, int bottom_layer );
void ReturnLayerPair( int* top_layer, int* bottom_layer ) const;
const wxPoint& GetPos() const { return m_Start; }
void SetPos( const wxPoint& aPoint ) { m_Start=aPoint; m_End=aPoint; }
/**
* Function GetPosition
* returns the position of this object.
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Start;
}
void SetPosition( const wxPoint& aPoint ) { m_Start=aPoint; m_End=aPoint; }
/**
* Function GetClass
......
......@@ -985,12 +985,12 @@ static void ConnectDanglingEndToVia( BOARD* pcb )
// if the other track's m_End does not match the via position, and the track's m_Start is
// within the bounds of the via, and the other track has no start
if( other->m_End!=via->GetPos() && via->HitTest( other->m_Start ) && !other->start )
if( other->m_End!=via->GetPosition() && via->HitTest( other->m_Start ) && !other->start )
{
TRACK* newTrack = other->Copy();
newTrack->Insert( pcb, other );
newTrack->m_End = via->GetPos();
newTrack->m_End = via->GetPosition();
newTrack->start = other;
newTrack->end = via;
......@@ -1007,12 +1007,12 @@ static void ConnectDanglingEndToVia( BOARD* pcb )
// if the other track's m_Start does not match the via position, and the track's m_End is
// within the bounds of the via, and the other track has no end
else if( other->m_Start!=via->GetPos() && via->HitTest( other->m_End ) && !other->end )
else if( other->m_Start!=via->GetPosition() && via->HitTest( other->m_End ) && !other->end )
{
TRACK* newTrack = other->Copy();
newTrack->Insert( pcb, other );
newTrack->m_Start = via->GetPos();
newTrack->m_Start = via->GetPosition();
newTrack->start = via;
newTrack->end = other;
......
......@@ -58,7 +58,7 @@ void RemoteCommand( const char* cmdline )
frame->DrawPanel->PrepareGraphicContext( &dc );
frame->DrawPanel->CursorOff( &dc );
frame->GetScreen()->m_Curseur = module->m_Pos;
frame->GetScreen()->m_Curseur = module->GetPosition();
frame->DrawPanel->CursorOn( &dc );
}
}
......@@ -96,7 +96,7 @@ void RemoteCommand( const char* cmdline )
frame->Hight_Light( &dc ); /* hightlighted the new one */
frame->DrawPanel->CursorOff( &dc );
frame->GetScreen()->m_Curseur = pad->m_Pos;
frame->GetScreen()->m_Curseur = pad->GetPosition();
frame->DrawPanel->CursorOn( &dc );
}
......
......@@ -123,63 +123,62 @@ public:
/*!
* WinEDA_DrcFrame type definition
* DrcDialog type definition
*/
IMPLEMENT_DYNAMIC_CLASS( WinEDA_DrcFrame, wxDialog )
IMPLEMENT_DYNAMIC_CLASS( DrcDialog, wxDialog )
/*!
* WinEDA_DrcFrame event table definition
* DrcDialog event table definition
*/
BEGIN_EVENT_TABLE( WinEDA_DrcFrame, wxDialog )
BEGIN_EVENT_TABLE( DrcDialog, wxDialog )
////@begin WinEDA_DrcFrame event table entries
EVT_INIT_DIALOG( WinEDA_DrcFrame::OnInitDialog )
////@begin DrcDialog event table entries
EVT_INIT_DIALOG( DrcDialog::OnInitDialog )
EVT_WINDOW_DESTROY( DrcDialog::OnDestroy )
EVT_CHECKBOX( ID_CHECKBOX, WinEDA_DrcFrame::OnReportCheckBoxClicked )
EVT_CHECKBOX( ID_CHECKBOX, DrcDialog::OnReportCheckBoxClicked )
EVT_BUTTON( ID_BUTTON_BROWSE_RPT_FILE, WinEDA_DrcFrame::OnButtonBrowseRptFileClick )
EVT_BUTTON( ID_BUTTON_BROWSE_RPT_FILE, DrcDialog::OnButtonBrowseRptFileClick )
EVT_BUTTON( ID_STARTDRC, WinEDA_DrcFrame::OnStartdrcClick )
EVT_BUTTON( ID_STARTDRC, DrcDialog::OnStartdrcClick )
EVT_BUTTON( ID_LIST_UNCONNECTED, WinEDA_DrcFrame::OnListUnconnectedClick )
EVT_BUTTON( ID_LIST_UNCONNECTED, DrcDialog::OnListUnconnectedClick )
EVT_BUTTON( ID_DELETE_ALL, WinEDA_DrcFrame::OnDeleteAllClick )
EVT_BUTTON( ID_DELETE_ALL, DrcDialog::OnDeleteAllClick )
EVT_BUTTON( wxID_CANCEL, WinEDA_DrcFrame::OnCancelClick )
EVT_BUTTON( wxID_CANCEL, DrcDialog::OnCancelClick )
EVT_BUTTON( wxID_OK, WinEDA_DrcFrame::OnOkClick )
EVT_BUTTON( wxID_OK, DrcDialog::OnOkClick )
////@end WinEDA_DrcFrame event table entries
////@end DrcDialog event table entries
// outside bracket: DialogBlocks does not know about the listbox events on a custom list box.
EVT_LISTBOX( ID_CLEARANCE_LIST, WinEDA_DrcFrame::OnMarkerSelectionEvent)
EVT_LISTBOX( ID_UNCONNECTED_LIST, WinEDA_DrcFrame::OnUnconnectedSelectionEvent)
EVT_LISTBOX( ID_CLEARANCE_LIST, DrcDialog::OnMarkerSelectionEvent)
EVT_LISTBOX( ID_UNCONNECTED_LIST, DrcDialog::OnUnconnectedSelectionEvent)
END_EVENT_TABLE()
/*!
* WinEDA_DrcFrame constructors
* DrcDialog constructors
*/
WinEDA_DrcFrame::WinEDA_DrcFrame( )
DrcDialog::DrcDialog( )
{
}
WinEDA_DrcFrame::WinEDA_DrcFrame( DRC_TESTER* aDrc_tester, WinEDA_PcbFrame* parent, wxDC * panelDC,
DrcDialog::DrcDialog( DRC* aTester, WinEDA_PcbFrame* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
{
m_Tester = aDrc_tester;
m_tester = aTester;
m_Parent = parent;
m_DC = panelDC;
AbortDrc = FALSE;
Create(parent, id, caption, pos, size, style);
......@@ -191,9 +190,9 @@ WinEDA_DrcFrame::WinEDA_DrcFrame( DRC_TESTER* aDrc_tester, WinEDA_PcbFrame* pare
* WinEDA_DrcFrame creator
*/
bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
bool DrcDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
////@begin WinEDA_DrcFrame member initialisation
////@begin DrcDialog member initialisation
m_MainSizer = NULL;
m_CommandSizer = NULL;
m_ClearenceTitle = NULL;
......@@ -202,16 +201,17 @@ bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& c
m_RptFilenameCtrl = NULL;
m_BrowseButton = NULL;
m_Pad2PadTestCtrl = NULL;
m_UnconnectedTestCtrl = NULL;
m_ZonesTestCtrl = NULL;
m_UnconnectedTestCtrl = NULL;
m_DeleteAllButton = NULL;
m_DeleteCurrentMarkerButton = NULL;
m_ClearanceListBox = NULL;
m_UnconnectedListBox = NULL;
StdDialogButtonSizer = NULL;
////@end WinEDA_DrcFrame member initialisation
////@end DrcDialog member initialisation
////@begin WinEDA_DrcFrame creation
////@begin DrcDialog creation
SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
wxDialog::Create( parent, id, caption, pos, size, style );
......@@ -221,7 +221,7 @@ bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& c
GetSizer()->SetSizeHints(this);
}
Centre();
////@end WinEDA_DrcFrame creation
////@end DrcDialog creation
// m_ClearanceListBox->SetList( &gList );
......@@ -234,14 +234,14 @@ bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& c
* Control creation for WinEDA_DrcFrame
*/
void WinEDA_DrcFrame::CreateControls()
void DrcDialog::CreateControls()
{
SetFont( *g_DialogFont );
////@begin WinEDA_DrcFrame content construction
// Generated by DialogBlocks, Tue 27 Nov 2007 00:10:16 CST (unregistered)
////@begin DrcDialog content construction
// Generated by DialogBlocks, Fri 30 Nov 2007 18:52:20 CST (unregistered)
WinEDA_DrcFrame* itemDialog1 = this;
DrcDialog* itemDialog1 = this;
m_MainSizer = new wxBoxSizer(wxVERTICAL);
itemDialog1->SetSizer(m_MainSizer);
......@@ -251,7 +251,7 @@ void WinEDA_DrcFrame::CreateControls()
wxStaticBox* itemStaticBoxSizer4Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Options"));
wxStaticBoxSizer* itemStaticBoxSizer4 = new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxHORIZONTAL);
m_CommandSizer->Add(itemStaticBoxSizer4, 20, wxGROW|wxTOP|wxBOTTOM, 8);
m_CommandSizer->Add(itemStaticBoxSizer4, 3, wxGROW|wxTOP|wxBOTTOM, 8);
wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL);
itemStaticBoxSizer4->Add(itemBoxSizer5, 2, wxGROW|wxALL, 5);
......@@ -262,139 +262,138 @@ void WinEDA_DrcFrame::CreateControls()
m_ClearenceTitle = new wxStaticText( itemDialog1, wxID_STATIC, _("Clearance"), wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE );
itemBoxSizer6->Add(m_ClearenceTitle, 0, wxALIGN_TOP|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5);
itemBoxSizer6->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10);
m_SetClearance = new wxTextCtrl( itemDialog1, ID_TEXTCTRL1, _T(""), wxDefaultPosition, wxSize(144, -1), 0 );
if (WinEDA_DrcFrame::ShowToolTips())
if (DrcDialog::ShowToolTips())
m_SetClearance->SetToolTip(_("In the clearance units, enter the clearance distance"));
itemBoxSizer6->Add(m_SetClearance, 1, wxALIGN_TOP|wxLEFT|wxRIGHT|wxBOTTOM|wxADJUST_MINSIZE, 5);
wxStaticBox* itemStaticBoxSizer10Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Create Report File"));
wxStaticBoxSizer* itemStaticBoxSizer10 = new wxStaticBoxSizer(itemStaticBoxSizer10Static, wxHORIZONTAL);
itemBoxSizer5->Add(itemStaticBoxSizer10, 1, wxGROW|wxALL, 5);
wxStaticBox* itemStaticBoxSizer9Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Create Report File"));
wxStaticBoxSizer* itemStaticBoxSizer9 = new wxStaticBoxSizer(itemStaticBoxSizer9Static, wxHORIZONTAL);
itemBoxSizer5->Add(itemStaticBoxSizer9, 1, wxGROW|wxALL, 5);
m_CreateRptCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
m_CreateRptCtrl->SetValue(false);
if (WinEDA_DrcFrame::ShowToolTips())
if (DrcDialog::ShowToolTips())
m_CreateRptCtrl->SetToolTip(_("Enable writing report to this file"));
itemStaticBoxSizer10->Add(m_CreateRptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5);
itemStaticBoxSizer9->Add(m_CreateRptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5);
m_RptFilenameCtrl = new wxTextCtrl( itemDialog1, ID_TEXTCTRL3, _T(""), wxDefaultPosition, wxSize(250, -1), 0 );
if (WinEDA_DrcFrame::ShowToolTips())
if (DrcDialog::ShowToolTips())
m_RptFilenameCtrl->SetToolTip(_("Enter the report filename"));
itemStaticBoxSizer10->Add(m_RptFilenameCtrl, 2, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 5);
itemStaticBoxSizer9->Add(m_RptFilenameCtrl, 2, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 5);
m_BrowseButton = new wxButton( itemDialog1, ID_BUTTON_BROWSE_RPT_FILE, _("..."), wxDefaultPosition, wxSize(35, -1), 0 );
if (WinEDA_DrcFrame::ShowToolTips())
if (DrcDialog::ShowToolTips())
m_BrowseButton->SetToolTip(_("Pick a filename interactively"));
itemStaticBoxSizer10->Add(m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM|wxADJUST_MINSIZE, 5);
itemStaticBoxSizer9->Add(m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM|wxADJUST_MINSIZE, 5);
wxStaticBox* itemStaticBoxSizer14Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Include Tests For:"));
wxStaticBoxSizer* itemStaticBoxSizer14 = new wxStaticBoxSizer(itemStaticBoxSizer14Static, wxVERTICAL);
itemStaticBoxSizer4->Add(itemStaticBoxSizer14, 0, wxGROW|wxALL, 5);
wxStaticBox* itemStaticBoxSizer13Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Include Tests For:"));
wxStaticBoxSizer* itemStaticBoxSizer13 = new wxStaticBoxSizer(itemStaticBoxSizer13Static, wxVERTICAL);
itemStaticBoxSizer4->Add(itemStaticBoxSizer13, 0, wxGROW|wxALL, 5);
m_Pad2PadTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX2, _("Clearances"), wxDefaultPosition, wxDefaultSize, 0 );
m_Pad2PadTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX2, _("Pad to pad"), wxDefaultPosition, wxDefaultSize, 0 );
m_Pad2PadTestCtrl->SetValue(false);
if (WinEDA_DrcFrame::ShowToolTips())
m_Pad2PadTestCtrl->SetToolTip(_("Test pad to pad, pad to track, and track to track clearances"));
itemStaticBoxSizer14->Add(m_Pad2PadTestCtrl, 0, wxGROW|wxALL, 5);
m_UnconnectedTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX3, _("Unconnected"), wxDefaultPosition, wxDefaultSize, 0 );
m_UnconnectedTestCtrl->SetValue(false);
if (WinEDA_DrcFrame::ShowToolTips())
m_UnconnectedTestCtrl->SetToolTip(_("Find unconnected pads and tracks"));
itemStaticBoxSizer14->Add(m_UnconnectedTestCtrl, 0, wxGROW|wxALL, 5);
if (DrcDialog::ShowToolTips())
m_Pad2PadTestCtrl->SetToolTip(_("Include tests for clearances between pad to pads"));
itemStaticBoxSizer13->Add(m_Pad2PadTestCtrl, 0, wxGROW|wxALL, 5);
m_ZonesTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX7, _("Zones"), wxDefaultPosition, wxDefaultSize, 0 );
m_ZonesTestCtrl->SetValue(false);
if (WinEDA_DrcFrame::ShowToolTips())
if (DrcDialog::ShowToolTips())
m_ZonesTestCtrl->SetToolTip(_("Include zones in clearance or unconnected tests"));
itemStaticBoxSizer14->Add(m_ZonesTestCtrl, 0, wxGROW|wxALL, 5);
wxBoxSizer* itemBoxSizer18 = new wxBoxSizer(wxVERTICAL);
m_CommandSizer->Add(itemBoxSizer18, 0, wxALIGN_TOP|wxALL, 5);
itemStaticBoxSizer13->Add(m_ZonesTestCtrl, 0, wxGROW|wxALL, 5);
wxButton* itemButton19 = new wxButton( itemDialog1, ID_STARTDRC, _("Start DRC"), wxDefaultPosition, wxDefaultSize, 0 );
if (WinEDA_DrcFrame::ShowToolTips())
itemButton19->SetToolTip(_("Start the Design Rule Checker"));
itemButton19->SetForegroundColour(wxColour(202, 0, 0));
itemBoxSizer18->Add(itemButton19, 0, wxGROW|wxALL, 5);
wxButton* itemButton20 = new wxButton( itemDialog1, ID_LIST_UNCONNECTED, _("List Unconnected"), wxDefaultPosition, wxDefaultSize, 0 );
if (WinEDA_DrcFrame::ShowToolTips())
itemButton20->SetToolTip(_("List unconnected pads or tracks"));
itemButton20->SetForegroundColour(wxColour(0, 0, 255));
itemBoxSizer18->Add(itemButton20, 0, wxGROW|wxALL, 5);
wxButton* itemButton21 = new wxButton( itemDialog1, ID_DELETE_ALL, _("Delete All Markers"), wxDefaultPosition, wxDefaultSize, 0 );
if (WinEDA_DrcFrame::ShowToolTips())
itemButton21->SetToolTip(_("Delete every marker"));
itemButton21->SetForegroundColour(wxColour(0, 128, 0));
itemBoxSizer18->Add(itemButton21, 0, wxGROW|wxALL, 5);
m_UnconnectedTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX3, _("Unconnected pads"), wxDefaultPosition, wxDefaultSize, 0 );
m_UnconnectedTestCtrl->SetValue(false);
if (DrcDialog::ShowToolTips())
m_UnconnectedTestCtrl->SetToolTip(_("Find unconnected pads"));
itemStaticBoxSizer13->Add(m_UnconnectedTestCtrl, 0, wxGROW|wxALL, 5);
wxBoxSizer* itemBoxSizer17 = new wxBoxSizer(wxVERTICAL);
m_CommandSizer->Add(itemBoxSizer17, 0, wxALIGN_TOP|wxALL, 5);
wxButton* itemButton18 = new wxButton( itemDialog1, ID_STARTDRC, _("Start DRC"), wxDefaultPosition, wxDefaultSize, 0 );
if (DrcDialog::ShowToolTips())
itemButton18->SetToolTip(_("Start the Design Rule Checker"));
itemButton18->SetForegroundColour(wxColour(202, 0, 0));
itemBoxSizer17->Add(itemButton18, 0, wxGROW|wxALL, 5);
wxButton* itemButton19 = new wxButton( itemDialog1, ID_LIST_UNCONNECTED, _("List Unconnected"), wxDefaultPosition, wxDefaultSize, 0 );
if (DrcDialog::ShowToolTips())
itemButton19->SetToolTip(_("List unconnected pads or tracks"));
itemButton19->SetForegroundColour(wxColour(0, 0, 255));
itemBoxSizer17->Add(itemButton19, 0, wxGROW|wxALL, 5);
m_DeleteAllButton = new wxButton( itemDialog1, ID_DELETE_ALL, _("Delete All Markers"), wxDefaultPosition, wxDefaultSize, 0 );
if (DrcDialog::ShowToolTips())
m_DeleteAllButton->SetToolTip(_("Delete every marker"));
m_DeleteAllButton->SetForegroundColour(wxColour(0, 128, 0));
itemBoxSizer17->Add(m_DeleteAllButton, 0, wxGROW|wxALL, 5);
m_DeleteCurrentMarkerButton = new wxButton( itemDialog1, ID_DELETE_ONE, _("Delete Current Marker"), wxDefaultPosition, wxDefaultSize, 0 );
if (WinEDA_DrcFrame::ShowToolTips())
if (DrcDialog::ShowToolTips())
m_DeleteCurrentMarkerButton->SetToolTip(_("Delete the marker selected in the listBox below"));
m_DeleteCurrentMarkerButton->Enable(false);
itemBoxSizer18->Add(m_DeleteCurrentMarkerButton, 0, wxGROW|wxALL, 5);
itemBoxSizer17->Add(m_DeleteCurrentMarkerButton, 0, wxGROW|wxALL, 5);
wxStaticText* itemStaticText23 = new wxStaticText( itemDialog1, wxID_STATIC, _("Error Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
m_MainSizer->Add(itemStaticText23, 0, wxGROW|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 10);
wxStaticText* itemStaticText22 = new wxStaticText( itemDialog1, wxID_STATIC, _("Error Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
m_MainSizer->Add(itemStaticText22, 0, wxGROW|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 10);
wxNotebook* itemNotebook24 = new wxNotebook( itemDialog1, ID_NOTEBOOK1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT|wxRAISED_BORDER );
wxNotebook* itemNotebook23 = new wxNotebook( itemDialog1, ID_NOTEBOOK1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT|wxRAISED_BORDER );
#if !wxCHECK_VERSION(2,5,2)
wxNotebookSizer* itemNotebook24Sizer = new wxNotebookSizer(itemNotebook24);
wxNotebookSizer* itemNotebook23Sizer = new wxNotebookSizer(itemNotebook23);
#endif
m_ClearanceListBox = new DRCLISTBOX( itemNotebook24, ID_CLEARANCE_LIST, wxDefaultPosition, wxSize(100, 300), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL );
if (WinEDA_DrcFrame::ShowToolTips())
m_ClearanceListBox = new DRCLISTBOX( itemNotebook23, ID_CLEARANCE_LIST, wxDefaultPosition, wxSize(100, 300), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL );
if (DrcDialog::ShowToolTips())
m_ClearanceListBox->SetToolTip(_("MARKERs on the PCB, double click on any MARKER to go there in PCB"));
itemNotebook24->AddPage(m_ClearanceListBox, _("Distance Problem Markers"));
itemNotebook23->AddPage(m_ClearanceListBox, _("Distance Problem Markers"));
m_UnconnectedListBox = new DRCLISTBOX( itemNotebook24, ID_UNCONNECTED_LIST, wxDefaultPosition, wxSize(100, 100), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL );
if (WinEDA_DrcFrame::ShowToolTips())
m_UnconnectedListBox = new DRCLISTBOX( itemNotebook23, ID_UNCONNECTED_LIST, wxDefaultPosition, wxSize(100, 100), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL );
if (DrcDialog::ShowToolTips())
m_UnconnectedListBox->SetToolTip(_("Pad to pad, pad to track, and track to track clearance problems"));
itemNotebook24->AddPage(m_UnconnectedListBox, _("Unconnected"));
itemNotebook23->AddPage(m_UnconnectedListBox, _("Unconnected"));
#if !wxCHECK_VERSION(2,5,2)
m_MainSizer->Add(itemNotebook24Sizer, 5, wxGROW|wxALL, 5);
m_MainSizer->Add(itemNotebook23Sizer, 5, wxGROW|wxALL, 5);
#else
m_MainSizer->Add(itemNotebook24, 5, wxGROW|wxALL, 5);
m_MainSizer->Add(itemNotebook23, 5, wxGROW|wxALL, 5);
#endif
StdDialogButtonSizer = new wxStdDialogButtonSizer;
m_MainSizer->Add(StdDialogButtonSizer, 0, wxGROW|wxALL, 10);
wxButton* itemButton28 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
itemButton28->SetForegroundColour(wxColour(0, 0, 255));
StdDialogButtonSizer->AddButton(itemButton28);
wxButton* itemButton27 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
itemButton27->SetForegroundColour(wxColour(0, 0, 255));
StdDialogButtonSizer->AddButton(itemButton27);
wxButton* itemButton29 = new wxButton( itemDialog1, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
itemButton29->SetDefault();
StdDialogButtonSizer->AddButton(itemButton29);
wxButton* itemButton28 = new wxButton( itemDialog1, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
itemButton28->SetDefault();
StdDialogButtonSizer->AddButton(itemButton28);
StdDialogButtonSizer->Realize();
// Set validators
m_CreateRptCtrl->SetValidator( wxGenericValidator(& s_CreateRptFileOpt) );
m_Pad2PadTestCtrl->SetValidator( wxGenericValidator(& s_Pad2PadTestOpt) );
m_UnconnectedTestCtrl->SetValidator( wxGenericValidator(& s_UnconnectedTestOpt) );
m_ZonesTestCtrl->SetValidator( wxGenericValidator(& s_ZonesTestOpt) );
// Connect events and objects
m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(WinEDA_DrcFrame::OnLeftDClickClearance), NULL, this);
m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(WinEDA_DrcFrame::OnRightUpClearance), NULL, this);
m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(WinEDA_DrcFrame::OnLeftDClickUnconnected), NULL, this);
m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(WinEDA_DrcFrame::OnRightUpUnconnected), NULL, this);
////@end WinEDA_DrcFrame content construction
itemDialog1->Connect(ID_DIALOG, wxEVT_DESTROY, wxWindowDestroyEventHandler(DrcDialog::OnDestroy), NULL, this);
m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(DrcDialog::OnLeftDClickClearance), NULL, this);
m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(DrcDialog::OnRightUpClearance), NULL, this);
m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(DrcDialog::OnLeftDClickUnconnected), NULL, this);
m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(DrcDialog::OnRightUpUnconnected), NULL, this);
////@end DrcDialog content construction
// @todo this is expanding the Clearance text, so we need to recalc sizers.
AddUnitSymbol(*m_ClearenceTitle);
Layout(); // adding the units above expanded Clearance text, now resize.
}
/*!
* Should we show tooltips?
*/
bool WinEDA_DrcFrame::ShowToolTips()
bool DrcDialog::ShowToolTips()
{
return true;
}
......@@ -403,34 +402,34 @@ bool WinEDA_DrcFrame::ShowToolTips()
* Get bitmap resources
*/
wxBitmap WinEDA_DrcFrame::GetBitmapResource( const wxString& name )
wxBitmap DrcDialog::GetBitmapResource( const wxString& name )
{
// Bitmap retrieval
////@begin WinEDA_DrcFrame bitmap retrieval
////@begin DrcDialog bitmap retrieval
wxUnusedVar(name);
return wxNullBitmap;
////@end WinEDA_DrcFrame bitmap retrieval
////@end DrcDialog bitmap retrieval
}
/*!
* Get icon resources
*/
wxIcon WinEDA_DrcFrame::GetIconResource( const wxString& name )
wxIcon DrcDialog::GetIconResource( const wxString& name )
{
// Icon retrieval
////@begin WinEDA_DrcFrame icon retrieval
////@begin DrcDialog icon retrieval
wxUnusedVar(name);
return wxNullIcon;
////@end WinEDA_DrcFrame icon retrieval
////@end DrcDialog icon retrieval
}
/*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DRC_RUN
*/
void WinEDA_DrcFrame::OnStartdrcClick( wxCommandEvent& event )
void DrcDialog::OnStartdrcClick( wxCommandEvent& event )
{
TestDrc(event);
CmdDrc();
}
/*!
......@@ -438,7 +437,7 @@ void WinEDA_DrcFrame::OnStartdrcClick( wxCommandEvent& event )
*/
/*
void WinEDA_DrcFrame::OnStopControlDrcClick( wxCommandEvent& event )
void DrcDialog::OnStopControlDrcClick( wxCommandEvent& event )
{
if( DrcInProgress )
AbortDrc = TRUE;
......@@ -451,7 +450,7 @@ void WinEDA_DrcFrame::OnStopControlDrcClick( wxCommandEvent& event )
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_ERASE_DRC_MARKERS
*/
void WinEDA_DrcFrame::OnDeleteAllClick( wxCommandEvent& event )
void DrcDialog::OnDeleteAllClick( wxCommandEvent& event )
{
DelDRCMarkers(event);
}
......@@ -460,7 +459,7 @@ void WinEDA_DrcFrame::OnDeleteAllClick( wxCommandEvent& event )
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIST_UNCONNECTED_PADS
*/
void WinEDA_DrcFrame::OnListUnconnectedClick( wxCommandEvent& event )
void DrcDialog::OnListUnconnectedClick( wxCommandEvent& event )
{
ListUnconnectedPads(event);
}
......@@ -469,7 +468,7 @@ void WinEDA_DrcFrame::OnListUnconnectedClick( wxCommandEvent& event )
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_BROWSE_RPT_FILE
*/
void WinEDA_DrcFrame::OnButtonBrowseRptFileClick( wxCommandEvent& event )
void DrcDialog::OnButtonBrowseRptFileClick( wxCommandEvent& event )
{
wxString FileName;
wxString Mask(wxT("*"));
......@@ -492,7 +491,6 @@ void WinEDA_DrcFrame::OnButtonBrowseRptFileClick( wxCommandEvent& event )
return;
m_RptFilenameCtrl->SetValue(FileName);
s_RptFilename = FileName;
}
......@@ -500,12 +498,8 @@ void WinEDA_DrcFrame::OnButtonBrowseRptFileClick( wxCommandEvent& event )
* wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
*/
void WinEDA_DrcFrame::OnOkClick( wxCommandEvent& event )
void DrcDialog::OnOkClick( wxCommandEvent& event )
{
s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked();
s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked();
s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked();
s_CreateRptFileOpt = m_CreateRptCtrl->IsChecked();
event.Skip();
}
......@@ -514,7 +508,7 @@ void WinEDA_DrcFrame::OnOkClick( wxCommandEvent& event )
* wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
*/
void WinEDA_DrcFrame::OnCancelClick( wxCommandEvent& event )
void DrcDialog::OnCancelClick( wxCommandEvent& event )
{
////@begin wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_DrcFrame.
// Before editing this code, remove the block markers.
......@@ -527,10 +521,8 @@ void WinEDA_DrcFrame::OnCancelClick( wxCommandEvent& event )
* wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_CHECKBOX1
*/
void WinEDA_DrcFrame::OnReportCheckBoxClicked( wxCommandEvent& event )
void DrcDialog::OnReportCheckBoxClicked( wxCommandEvent& event )
{
// @todo: see if the checkbox is selected, if so, enable the report name field
// and browse button, else disable them.
if( m_CreateRptCtrl->IsChecked() )
{
m_RptFilenameCtrl->Enable(true);
......@@ -549,21 +541,18 @@ void WinEDA_DrcFrame::OnReportCheckBoxClicked( wxCommandEvent& event )
* wxEVT_INIT_DIALOG event handler for ID_DIALOG
*/
void WinEDA_DrcFrame::OnInitDialog( wxInitDialogEvent& event )
void DrcDialog::OnInitDialog( wxInitDialogEvent& event )
{
wxCommandEvent junk;
// Set the initial status of the browse button and the text
// Set the initial "enabled" status of the browse button and the text
// field for report name
OnReportCheckBoxClicked( junk );
AddUnitSymbol(*m_ClearenceTitle);
m_RptFilenameCtrl->SetValue(s_RptFilename);
m_SetClearance->SetFocus();
// deselect the existing text, seems SetFocus() wants to emulate
// Microsoft, which is not desireable here.
// Microsoft and select all text, which is not desireable here.
m_SetClearance->SetSelection(0,0);
event.Skip();
......@@ -574,7 +563,7 @@ void WinEDA_DrcFrame::OnInitDialog( wxInitDialogEvent& event )
* wxEVT_LEFT_DCLICK event handler for ID_CLEARANCE_LIST
*/
void WinEDA_DrcFrame::OnLeftDClickClearance( wxMouseEvent& event )
void DrcDialog::OnLeftDClickClearance( wxMouseEvent& event )
{
int selection = m_ClearanceListBox->GetSelection();
......@@ -595,7 +584,7 @@ void WinEDA_DrcFrame::OnLeftDClickClearance( wxMouseEvent& event )
* wxEVT_RIGHT_UP event handler for ID_CLEARANCE_LIST
*/
void WinEDA_DrcFrame::OnRightUpUnconnected( wxMouseEvent& event )
void DrcDialog::OnRightUpUnconnected( wxMouseEvent& event )
{
event.Skip();
}
......@@ -605,7 +594,7 @@ void WinEDA_DrcFrame::OnRightUpUnconnected( wxMouseEvent& event )
* wxEVT_RIGHT_UP event handler for ID_CLEARANCE_LIST
*/
void WinEDA_DrcFrame::OnRightUpClearance( wxMouseEvent& event )
void DrcDialog::OnRightUpClearance( wxMouseEvent& event )
{
////@begin wxEVT_RIGHT_UP event handler for ID_CLEARANCE_LIST in WinEDA_DrcFrame.
// Before editing this code, remove the block markers.
......@@ -618,7 +607,7 @@ void WinEDA_DrcFrame::OnRightUpClearance( wxMouseEvent& event )
* wxEVT_LEFT_DCLICK event handler for ID_UNCONNECTED_LIST
*/
void WinEDA_DrcFrame::OnLeftDClickUnconnected( wxMouseEvent& event )
void DrcDialog::OnLeftDClickUnconnected( wxMouseEvent& event )
{
int selection = m_UnconnectedListBox->GetSelection();
......@@ -631,7 +620,7 @@ void WinEDA_DrcFrame::OnLeftDClickUnconnected( wxMouseEvent& event )
}
void WinEDA_DrcFrame::OnMarkerSelectionEvent( wxCommandEvent& event )
void DrcDialog::OnMarkerSelectionEvent( wxCommandEvent& event )
{
int selection = event.GetSelection();
......@@ -645,7 +634,7 @@ void WinEDA_DrcFrame::OnMarkerSelectionEvent( wxCommandEvent& event )
event.Skip();
}
void WinEDA_DrcFrame::OnUnconnectedSelectionEvent( wxCommandEvent& event )
void DrcDialog::OnUnconnectedSelectionEvent( wxCommandEvent& event )
{
int selection = event.GetSelection();
......@@ -657,3 +646,16 @@ void WinEDA_DrcFrame::OnUnconnectedSelectionEvent( wxCommandEvent& event )
event.Skip();
}
/*!
* wxEVT_DESTROY event handler for ID_DIALOG
*/
void DrcDialog::OnDestroy( wxWindowDestroyEvent& event )
{
////@begin wxEVT_DESTROY event handler for ID_DIALOG in WinEDA_DrcFrame.
// Before editing this code, remove the block markers.
event.Skip();
////@end wxEVT_DESTROY event handler for ID_DIALOG in WinEDA_DrcFrame.
}
......@@ -23,7 +23,6 @@
*/
////@begin includes
#include "wx/valgen.h"
#include "wx/notebook.h"
////@end includes
......@@ -50,8 +49,8 @@ class wxStdDialogButtonSizer;
#define ID_TEXTCTRL3 10014
#define ID_BUTTON_BROWSE_RPT_FILE 10018
#define ID_CHECKBOX2 10019
#define ID_CHECKBOX3 10020
#define ID_CHECKBOX7 10021
#define ID_CHECKBOX3 10011
#define ID_STARTDRC 10006
#define ID_LIST_UNCONNECTED 10003
#define ID_DELETE_ALL 10005
......@@ -59,14 +58,14 @@ class wxStdDialogButtonSizer;
#define ID_NOTEBOOK1 10008
#define ID_CLEARANCE_LIST 10001
#define ID_UNCONNECTED_LIST 10009
#define SYMBOL_WINEDA_DRCFRAME_STYLE wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER
#define SYMBOL_WINEDA_DRCFRAME_TITLE _("DRC Control")
#define SYMBOL_WINEDA_DRCFRAME_IDNAME ID_DIALOG
#define SYMBOL_WINEDA_DRCFRAME_SIZE wxSize(400, 300)
#define SYMBOL_WINEDA_DRCFRAME_POSITION wxDefaultPosition
#define SYMBOL_DRCDIALOG_STYLE wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX
#define SYMBOL_DRCDIALOG_TITLE _("DRC Control")
#define SYMBOL_DRCDIALOG_IDNAME ID_DIALOG
#define SYMBOL_DRCDIALOG_SIZE wxSize(400, 300)
#define SYMBOL_DRCDIALOG_POSITION wxDefaultPosition
////@end control identifiers
#define ID_DRCLISTCTRL 10001 // outside @end control identifiers since DialogBlocks knows not DRCLISTBOX
#define ID_DRCLISTCTRL 14000 // outside @end control identifiers since DialogBlocks knows not DRCLISTBOX
/*!
* Compatibility
......@@ -77,35 +76,38 @@ class wxStdDialogButtonSizer;
#endif
/*!
* WinEDA_DrcFrame class declaration
* DrcDialog class declaration
*/
class WinEDA_DrcFrame: public wxDialog
class DrcDialog: public wxDialog
{
DECLARE_DYNAMIC_CLASS( WinEDA_DrcFrame )
DECLARE_DYNAMIC_CLASS( DrcDialog )
DECLARE_EVENT_TABLE()
public:
/// Constructors
WinEDA_DrcFrame( );
WinEDA_DrcFrame( DRC_TESTER* aDrc_tester, WinEDA_PcbFrame* parent, wxDC * panelDC,
wxWindowID id = SYMBOL_WINEDA_DRCFRAME_IDNAME,
const wxString& caption = SYMBOL_WINEDA_DRCFRAME_TITLE,
const wxPoint& pos = SYMBOL_WINEDA_DRCFRAME_POSITION,
const wxSize& size = SYMBOL_WINEDA_DRCFRAME_SIZE,
long style = SYMBOL_WINEDA_DRCFRAME_STYLE );
DrcDialog( );
DrcDialog( DRC* aTester, WinEDA_PcbFrame* parent,
wxWindowID id = SYMBOL_DRCDIALOG_IDNAME,
const wxString& caption = SYMBOL_DRCDIALOG_TITLE,
const wxPoint& pos = SYMBOL_DRCDIALOG_POSITION,
const wxSize& size = SYMBOL_DRCDIALOG_SIZE,
long style = SYMBOL_DRCDIALOG_STYLE );
/// Creation
bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WINEDA_DRCFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_DRCFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_DRCFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_DRCFRAME_SIZE, long style = SYMBOL_WINEDA_DRCFRAME_STYLE );
bool Create( wxWindow* parent, wxWindowID id = SYMBOL_DRCDIALOG_IDNAME, const wxString& caption = SYMBOL_DRCDIALOG_TITLE, const wxPoint& pos = SYMBOL_DRCDIALOG_POSITION, const wxSize& size = SYMBOL_DRCDIALOG_SIZE, long style = SYMBOL_DRCDIALOG_STYLE );
/// Creates the controls and sizers
void CreateControls();
////@begin WinEDA_DrcFrame event handler declarations
////@begin DrcDialog event handler declarations
/// wxEVT_INIT_DIALOG event handler for ID_DIALOG
void OnInitDialog( wxInitDialogEvent& event );
/// wxEVT_DESTROY event handler for ID_DIALOG
void OnDestroy( wxWindowDestroyEvent& event );
/// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_CHECKBOX
void OnReportCheckBoxClicked( wxCommandEvent& event );
......@@ -139,16 +141,16 @@ public:
/// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK
void OnOkClick( wxCommandEvent& event );
////@end WinEDA_DrcFrame event handler declarations
////@end DrcDialog event handler declarations
////@begin WinEDA_DrcFrame member function declarations
////@begin DrcDialog member function declarations
/// Retrieves bitmap resources
wxBitmap GetBitmapResource( const wxString& name );
/// Retrieves icon resources
wxIcon GetIconResource( const wxString& name );
////@end WinEDA_DrcFrame member function declarations
////@end DrcDialog member function declarations
void OnMarkerSelectionEvent( wxCommandEvent& event );
void OnUnconnectedSelectionEvent( wxCommandEvent& event );
......@@ -156,11 +158,11 @@ public:
/// Should we show tooltips?
static bool ShowToolTips();
void TestDrc(wxCommandEvent & event);
void CmdDrc();
void DelDRCMarkers(wxCommandEvent & event);
void ListUnconnectedPads(wxCommandEvent & event);
////@begin WinEDA_DrcFrame member variables
////@begin DrcDialog member variables
wxBoxSizer* m_MainSizer;
wxBoxSizer* m_CommandSizer;
wxStaticText* m_ClearenceTitle;
......@@ -169,18 +171,18 @@ public:
wxTextCtrl* m_RptFilenameCtrl;
wxButton* m_BrowseButton;
wxCheckBox* m_Pad2PadTestCtrl;
wxCheckBox* m_UnconnectedTestCtrl;
wxCheckBox* m_ZonesTestCtrl;
wxCheckBox* m_UnconnectedTestCtrl;
wxButton* m_DeleteAllButton;
wxButton* m_DeleteCurrentMarkerButton;
DRCLISTBOX* m_ClearanceListBox;
DRCLISTBOX* m_UnconnectedListBox;
wxStdDialogButtonSizer* StdDialogButtonSizer;
////@end WinEDA_DrcFrame member variables
////@end DrcDialog member variables
DRC_TESTER* m_Tester;
DRC* m_tester;
WinEDA_PcbFrame* m_Parent;
wxDC* m_DC;
int m_UnconnectedCount;
};
......
......@@ -218,10 +218,11 @@
<string name="id-suffix">""</string>
<long name="use-xrc">0</long>
<long name="working-mode">0</long>
<string name="event-handler-0">"wxEVT_INIT_DIALOG|OnInitDialog|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_INIT_DIALOG|OnInitDialog|NONE||DrcDialog"</string>
<string name="event-handler-1">"wxEVT_DESTROY|OnDestroy|NONE||DrcDialog"</string>
<string name="proxy-Id name">"ID_DIALOG"</string>
<long name="proxy-Id value">10000</long>
<string name="proxy-Class">"WinEDA_DrcFrame"</string>
<string name="proxy-Class">"DrcDialog"</string>
<string name="proxy-Base class">"wxDialog"</string>
<string name="proxy-Window kind">"wxDialog"</string>
<string name="proxy-Implementation filename">"dialog_drc.cpp"</string>
......@@ -253,8 +254,8 @@
<bool name="proxy-wxSTAY_ON_TOP">0</bool>
<bool name="proxy-wxDIALOG_NO_PARENT">0</bool>
<bool name="proxy-wxCLOSE_BOX">0</bool>
<bool name="proxy-wxMAXIMIZE_BOX">0</bool>
<bool name="proxy-wxMINIMIZE_BOX">0</bool>
<bool name="proxy-wxMAXIMIZE_BOX">1</bool>
<bool name="proxy-wxMINIMIZE_BOX">1</bool>
<bool name="proxy-wxDIALOG_MODAL">0</bool>
<bool name="proxy-wxNO_BORDER">0</bool>
<bool name="proxy-wxSIMPLE_BORDER">0</bool>
......@@ -344,7 +345,7 @@
<string name="proxy-Orientation">"Horizontal"</string>
<string name="proxy-AlignH">"Expand"</string>
<string name="proxy-AlignV">"Expand"</string>
<long name="proxy-Stretch factor">20</long>
<long name="proxy-Stretch factor">3</long>
<long name="proxy-Border">8</long>
<bool name="proxy-wxLEFT">0</bool>
<bool name="proxy-wxRIGHT">0</bool>
......@@ -474,32 +475,6 @@
<string name="proxy-Custom arguments">""</string>
<string name="proxy-Custom ctor arguments">""</string>
</document>
<document>
<string name="title">"Spacer"</string>
<string name="type">"dialog-control-document"</string>
<string name="filename">""</string>
<string name="icon-name">"spacer"</string>
<long name="is-transient">0</long>
<long name="owns-file">1</long>
<long name="title-mode">0</long>
<long name="locked">0</long>
<string name="created">"26/11/2007"</string>
<string name="proxy-type">"wbSpacerProxy"</string>
<long name="proxy-Width">5</long>
<long name="proxy-Height">5</long>
<string name="proxy-AlignH">"Centre"</string>
<string name="proxy-AlignV">"Centre"</string>
<long name="proxy-Stretch factor">0</long>
<long name="proxy-Border">10</long>
<bool name="proxy-wxLEFT">1</bool>
<bool name="proxy-wxRIGHT">1</bool>
<bool name="proxy-wxTOP">0</bool>
<bool name="proxy-wxBOTTOM">0</bool>
<bool name="proxy-wxSHAPED">0</bool>
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
<bool name="proxy-wxFIXED_MINSIZE">0</bool>
<string name="proxy-Platform">"&lt;Any platform&gt;"</string>
</document>
<document>
<string name="title">"wxTextCtrl: ID_TEXTCTRL1"</string>
<string name="type">"dialog-control-document"</string>
......@@ -628,13 +603,13 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbCheckBoxProxy"</string>
<string name="event-handler-0">"wxEVT_COMMAND_CHECKBOX_CLICKED|OnReportCheckBoxClicked|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_COMMAND_CHECKBOX_CLICKED|OnReportCheckBoxClicked|NONE||DrcDialog"</string>
<string name="proxy-Id name">"ID_CHECKBOX"</string>
<long name="proxy-Id value">10004</long>
<string name="proxy-Name">""</string>
<string name="proxy-Class">"wxCheckBox"</string>
<string name="proxy-Base class">"wxCheckBox"</string>
<bool name="proxy-External implementation">1</bool>
<bool name="proxy-External implementation">0</bool>
<bool name="proxy-Separate files">0</bool>
<string name="proxy-Implementation filename">""</string>
<string name="proxy-Header filename">""</string>
......@@ -643,8 +618,8 @@
<bool name="proxy-Initial value">0</bool>
<string name="proxy-Help text">""</string>
<string name="proxy-Tooltip text">"Enable writing report to this file"</string>
<string name="proxy-Data variable">"s_CreateRptFileOpt"</string>
<string name="proxy-Data validator">"wxGenericValidator(&amp; %VARIABLE%)"</string>
<string name="proxy-Data variable">""</string>
<string name="proxy-Data validator">""</string>
<string name="proxy-Data source">""</string>
<string name="proxy-Data class name">""</string>
<string name="proxy-Data class implementation filename">""</string>
......@@ -775,7 +750,7 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbButtonProxy"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnButtonBrowseRptFileClick|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnButtonBrowseRptFileClick|NONE||DrcDialog"</string>
<string name="proxy-Id name">"ID_BUTTON_BROWSE_RPT_FILE"</string>
<long name="proxy-Id value">10018</long>
<string name="proxy-Name">""</string>
......@@ -888,12 +863,12 @@
<string name="proxy-Implementation filename">""</string>
<string name="proxy-Header filename">""</string>
<string name="proxy-Member variable name">"m_Pad2PadTestCtrl"</string>
<string name="proxy-Label">"Clearances"</string>
<string name="proxy-Label">"Pad to pad"</string>
<bool name="proxy-Initial value">0</bool>
<string name="proxy-Help text">""</string>
<string name="proxy-Tooltip text">"Test pad to pad, pad to track, and track to track clearances"</string>
<string name="proxy-Data variable">"s_Pad2PadTestOpt"</string>
<string name="proxy-Data validator">"wxGenericValidator(&amp; %VARIABLE%)"</string>
<string name="proxy-Tooltip text">"Include tests for clearances between pad to pads"</string>
<string name="proxy-Data variable">""</string>
<string name="proxy-Data validator">""</string>
<string name="proxy-Data source">""</string>
<string name="proxy-Data class name">""</string>
<string name="proxy-Data class implementation filename">""</string>
......@@ -932,7 +907,7 @@
<string name="proxy-Custom ctor arguments">""</string>
</document>
<document>
<string name="title">"wxCheckBox: ID_CHECKBOX3"</string>
<string name="title">"wxCheckBox: ID_CHECKBOX7"</string>
<string name="type">"dialog-control-document"</string>
<string name="filename">""</string>
<string name="icon-name">"checkbox"</string>
......@@ -942,8 +917,8 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbCheckBoxProxy"</string>
<string name="proxy-Id name">"ID_CHECKBOX3"</string>
<long name="proxy-Id value">10020</long>
<string name="proxy-Id name">"ID_CHECKBOX7"</string>
<long name="proxy-Id value">10021</long>
<string name="proxy-Name">""</string>
<string name="proxy-Class">"wxCheckBox"</string>
<string name="proxy-Base class">"wxCheckBox"</string>
......@@ -951,13 +926,13 @@
<bool name="proxy-Separate files">0</bool>
<string name="proxy-Implementation filename">""</string>
<string name="proxy-Header filename">""</string>
<string name="proxy-Member variable name">"m_UnconnectedTestCtrl"</string>
<string name="proxy-Label">"Unconnected"</string>
<string name="proxy-Member variable name">"m_ZonesTestCtrl"</string>
<string name="proxy-Label">"Zones"</string>
<bool name="proxy-Initial value">0</bool>
<string name="proxy-Help text">""</string>
<string name="proxy-Tooltip text">"Find unconnected pads and tracks"</string>
<string name="proxy-Data variable">"s_UnconnectedTestOpt"</string>
<string name="proxy-Data validator">"wxGenericValidator(&amp; %VARIABLE%)"</string>
<string name="proxy-Tooltip text">"Include zones in clearance or unconnected tests"</string>
<string name="proxy-Data variable">""</string>
<string name="proxy-Data validator">""</string>
<string name="proxy-Data source">""</string>
<string name="proxy-Data class name">""</string>
<string name="proxy-Data class implementation filename">""</string>
......@@ -996,7 +971,7 @@
<string name="proxy-Custom ctor arguments">""</string>
</document>
<document>
<string name="title">"wxCheckBox: ID_CHECKBOX7"</string>
<string name="title">"wxCheckBox: ID_CHECKBOX3"</string>
<string name="type">"dialog-control-document"</string>
<string name="filename">""</string>
<string name="icon-name">"checkbox"</string>
......@@ -1004,10 +979,10 @@
<long name="owns-file">1</long>
<long name="title-mode">0</long>
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="created">"30/11/2007"</string>
<string name="proxy-type">"wbCheckBoxProxy"</string>
<string name="proxy-Id name">"ID_CHECKBOX7"</string>
<long name="proxy-Id value">10021</long>
<string name="proxy-Id name">"ID_CHECKBOX3"</string>
<long name="proxy-Id value">10011</long>
<string name="proxy-Name">""</string>
<string name="proxy-Class">"wxCheckBox"</string>
<string name="proxy-Base class">"wxCheckBox"</string>
......@@ -1015,13 +990,13 @@
<bool name="proxy-Separate files">0</bool>
<string name="proxy-Implementation filename">""</string>
<string name="proxy-Header filename">""</string>
<string name="proxy-Member variable name">"m_ZonesTestCtrl"</string>
<string name="proxy-Label">"Zones"</string>
<string name="proxy-Member variable name">"m_UnconnectedTestCtrl"</string>
<string name="proxy-Label">"Unconnected pads"</string>
<bool name="proxy-Initial value">0</bool>
<string name="proxy-Help text">""</string>
<string name="proxy-Tooltip text">"Include zones in clearance or unconnected tests"</string>
<string name="proxy-Data variable">"s_ZonesTestOpt"</string>
<string name="proxy-Data validator">"wxGenericValidator(&amp; %VARIABLE%)"</string>
<string name="proxy-Tooltip text">"Find unconnected pads"</string>
<string name="proxy-Data variable">""</string>
<string name="proxy-Data validator">""</string>
<string name="proxy-Data source">""</string>
<string name="proxy-Data class name">""</string>
<string name="proxy-Data class implementation filename">""</string>
......@@ -1097,7 +1072,7 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbButtonProxy"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnStartdrcClick|||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnStartdrcClick|||DrcDialog"</string>
<string name="proxy-Id name">"ID_STARTDRC"</string>
<long name="proxy-Id value">10006</long>
<string name="proxy-Name">""</string>
......@@ -1164,7 +1139,7 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbButtonProxy"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnListUnconnectedClick|||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnListUnconnectedClick|||DrcDialog"</string>
<string name="proxy-Id name">"ID_LIST_UNCONNECTED"</string>
<long name="proxy-Id value">10003</long>
<string name="proxy-Name">""</string>
......@@ -1231,7 +1206,7 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbButtonProxy"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnDeleteAllClick|||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnDeleteAllClick|||DrcDialog"</string>
<string name="proxy-Id name">"ID_DELETE_ALL"</string>
<long name="proxy-Id value">10005</long>
<string name="proxy-Name">""</string>
......@@ -1241,7 +1216,7 @@
<bool name="proxy-Separate files">0</bool>
<string name="proxy-Implementation filename">""</string>
<string name="proxy-Header filename">""</string>
<string name="proxy-Member variable name">""</string>
<string name="proxy-Member variable name">"m_DeleteAllButton"</string>
<string name="proxy-Label">"Delete All Markers"</string>
<bool name="proxy-Default">0</bool>
<string name="proxy-Help text">""</string>
......@@ -1511,8 +1486,8 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbForeignCtrlProxy"</string>
<string name="event-handler-0">"wxEVT_LEFT_DCLICK|OnLeftDClickClearance|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-1">"wxEVT_RIGHT_UP|OnRightUpClearance|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_LEFT_DCLICK|OnLeftDClickClearance|NONE||DrcDialog"</string>
<string name="event-handler-1">"wxEVT_RIGHT_UP|OnRightUpClearance|NONE||DrcDialog"</string>
<string name="proxy-Id name">"ID_CLEARANCE_LIST"</string>
<long name="proxy-Id value">10001</long>
<string name="proxy-Name">""</string>
......@@ -1585,8 +1560,8 @@
<long name="locked">0</long>
<string name="created">"25/11/2007"</string>
<string name="proxy-type">"wbForeignCtrlProxy"</string>
<string name="event-handler-0">"wxEVT_LEFT_DCLICK|OnLeftDClickUnconnected|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-1">"wxEVT_RIGHT_UP|OnRightUpUnconnected|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_LEFT_DCLICK|OnLeftDClickUnconnected|NONE||DrcDialog"</string>
<string name="event-handler-1">"wxEVT_RIGHT_UP|OnRightUpUnconnected|NONE||DrcDialog"</string>
<string name="proxy-Id name">"ID_UNCONNECTED_LIST"</string>
<long name="proxy-Id value">10009</long>
<string name="proxy-Name">""</string>
......@@ -1692,7 +1667,7 @@
<long name="locked">1</long>
<string name="created">"13/11/2007"</string>
<string name="proxy-type">"wbButtonProxy"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnCancelClick|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnCancelClick|NONE||DrcDialog"</string>
<string name="proxy-Id name">"wxID_CANCEL"</string>
<long name="proxy-Id value">5101</long>
<string name="proxy-Name">""</string>
......@@ -1759,7 +1734,7 @@
<long name="locked">1</long>
<string name="created">"26/11/2007"</string>
<string name="proxy-type">"wbButtonProxy"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnOkClick|NONE||WinEDA_DrcFrame"</string>
<string name="event-handler-0">"wxEVT_COMMAND_BUTTON_CLICKED|OnOkClick|NONE||DrcDialog"</string>
<string name="proxy-Id name">"wxID_OK"</string>
<long name="proxy-Id value">5100</long>
<string name="proxy-Name">""</string>
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2004-2007 Jean-Pierre Charras, jean-pierre.charras@inpg.fr
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2007 Kicad Developers, see change_log.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
*/
/****************************/
/* DRC control */
/****************************/
......@@ -17,56 +44,154 @@
/* variables locales */
class WinEDA_DrcFrame;
WinEDA_DrcFrame* DrcFrame;
class DrcDialog;
//#define WXYIELD() wxYield()
#define WXYIELD() do { } while(0) // nothing
#include "dialog_drc.cpp"
/* saving drc options */
static bool s_Pad2PadTestOpt = true;
static bool s_UnconnectedTestOpt = true;
static bool s_ZonesTestOpt = false;
static bool s_CreateRptFileOpt = false;
static FILE* s_RptFile = NULL;
static wxString s_RptFilename;
/******************************************************/
void WinEDA_PcbFrame::Install_Test_DRC_Frame( wxDC* DC )
/******************************************************/
static int ErrorsDRC_Count;
static MARKER* current_marqueur; /* Pour gestion des marqueurs sur pcb */
/* install a dialog box to handle the general DRC control
*/
{
m_drc->ShowDialog();
}
static bool AbortDrc, DrcInProgress = FALSE;
static int spot_cX, spot_cY; /* position d'elements a tester */
static int finx, finy; // coord relatives de l'extremite du segm de reference
static int segm_angle; // angle d'inclinaison du segment de reference en 0,1 degre
static int segm_long; // longueur du segment de reference
static int xcliplo, ycliplo, xcliphi, ycliphi; /* coord de la surface de securite du segment a comparer */
/* Routines Locales */
static int Pad_to_Pad_Isol( D_PAD* pad_ref, D_PAD* pad, const int dist_min );
static bool Test_Pad_to_Pads_Drc( WinEDA_BasePcbFrame* frame,
wxDC* DC,
D_PAD* pad_ref,
LISTE_PAD* start_buffer,
LISTE_PAD* end_buffer,
int max_size,
bool show_err );
static int TestClearanceSegmToPad( const D_PAD* pad_to_test, int seg_width, int isol );
static int TestMarginToCircle( int cx, int cy, int rayon, int longueur );
static int Tst_Ligne( int x1, int y1, int x2, int y2 );
void DRC::ShowDialog()
{
updatePointers();
static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb,
TRACK* pt_ref, BOARD_ITEM* pt_item, int errnumber );
if( !m_ui )
{
printf("creating new DrcFrame\n");
m_ui = new DrcDialog( this, m_mainWindow );
}
static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb,
D_PAD* pad1, D_PAD* pad2 );
// @todo enter retentitive data into the panel.
// m_RptFilenameCtrl->SetValue(s_RptFilename);
m_ui->Show(true);
// int rval = m_ui->ShowModal();
#if defined(DEBUG)
// printf("dialog rval=%d wxID_OK=%d\n", rval, wxID_OK );
#endif
// if( rval == wxID_OK )
{
// @todo capture the UI entered data into the DRC_TESTER here
/*
s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked();
s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked();
s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked();
s_CreateRptFileOpt = m_CreateRptCtrl->IsChecked();
wxBoxSizer* m_MainSizer;
wxBoxSizer* m_CommandSizer;
wxStaticText* m_ClearenceTitle;
wxTextCtrl* m_SetClearance;
wxCheckBox* m_CreateRptCtrl;
wxTextCtrl* m_RptFilenameCtrl;
wxButton* m_BrowseButton;
wxCheckBox* m_Pad2PadTestCtrl;
wxCheckBox* m_UnconnectedTestCtrl;
wxCheckBox* m_ZonesTestCtrl;
wxButton* m_DeleteCurrentMarkerButton;
DRCLISTBOX* m_ClearanceListBox;
DRCLISTBOX* m_UnconnectedListBox;
wxStdDialogButtonSizer* StdDialogButtonSizer;
*/
}
// m_ui->Destroy();
// m_ui = 0;
}
/*********************************************************/
void DrcDialog::DelDRCMarkers( wxCommandEvent& event )
/*********************************************************/
{
m_Parent->Erase_Marqueurs();
m_Parent->ReDrawPanel();
}
/****************************************************/
void DrcDialog::CmdDrc()
/****************************************************/
{
wxString reportName;
if( m_CreateRptCtrl->IsChecked() ) // Create a file rpt
{
reportName = m_RptFilenameCtrl->GetValue();
if( reportName.IsEmpty() )
{
wxCommandEvent junk;
OnButtonBrowseRptFileClick( junk );
}
reportName = m_RptFilenameCtrl->GetValue();
}
g_DesignSettings.m_TrackClearence =
ReturnValueFromTextCtrl( *m_SetClearance, m_Parent->m_InternalUnits );
m_tester->SetSettings( m_Pad2PadTestCtrl->IsChecked(),
m_UnconnectedTestCtrl->IsChecked(),
m_ZonesTestCtrl->IsChecked(),
reportName, m_CreateRptCtrl->IsChecked() );
m_Parent->Erase_Marqueurs();
m_Parent->ReDrawPanel();
SetCursor( wxCursor( wxCURSOR_WATCH ) );
// run all the tests, with no UI at this time.
m_tester->RunTests();
// Generate the report
if( !reportName.IsEmpty() )
{
FILE* fp = wxFopen( reportName, wxT( "w" ) );
m_tester->WriteReport( fp );
fclose(fp);
// @todo put up message box saying we created the report
//msg.Printf( _( "Report file <%s> created\n" ), s_RptFilename.GetData() );
}
SetCursor( wxCursor( wxCURSOR_WATCH ) );
// @todo set the list counts in the DRCLISTITEMS here.
/*******************************************/
/* DRC functions */
/*******************************************/
#include "dialog_drc.cpp"
printf("done with tests\n");
}
/***************************************************************/
void DrcDialog::ListUnconnectedPads( wxCommandEvent& event )
/***************************************************************/
{
m_tester->testUnconnected();
// @todo do report here
}
const wxString& DRC_ITEM::GetErrorText() const
......@@ -94,182 +219,1157 @@ wxString DRC_ITEM::ShowCoord( const wxPoint& aPos )
}
DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
{
m_mainWindow = aPcbWindow;
m_drawPanel = aPcbWindow->DrawPanel;
m_pcb = aPcbWindow->m_Pcb;
/***************************************************************/
void WinEDA_DrcFrame::ListUnconnectedPads( wxCommandEvent& event )
/***************************************************************/
// establish initial values for everything:
m_doPad2PadTest = true;
m_doUnconnectedTest = true;
m_doZonesTest = false;
m_doCreateRptFile = false;
// m_rptFilename set to empty by its constructor
m_errorCount = 0;
m_currentMarker = 0;
m_spotcx = 0;
m_spotcy = 0;
m_finx = 0;
m_finy = 0;
m_segmAngle = 0;
m_segmLength = 0;
m_xcliplo = 0;
m_ycliplo = 0;
m_xcliphi = 0;
m_ycliphi = 0;
m_unconnectedCount = 0;
m_drawPanel = 0;
}
/***********************************************************************/
int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
/***********************************************************************/
{
if( (m_Parent->m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 )
updatePointers();
if( !doTrackDrc( aRefSegm, aList ) )
{
m_Parent->Compile_Ratsnest( m_DC, TRUE );
wxString msg = m_currentMarker->GetReporter().ShowText();
m_mainWindow->Affiche_Message( msg );
return BAD_DRC;
}
if( m_Parent->m_Pcb->m_Ratsnest == NULL )
return;
CHEVELU* Ratsnest = m_Parent->m_Pcb->m_Ratsnest;
int draw_mode = GR_SURBRILL | GR_OR;
WinEDA_DrawPanel* panel = m_Parent->DrawPanel;
int ii;
wxString msg;
double convert = 0.0001;
return OK_DRC;
}
msg = _( "Look for active routes\n" );
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
m_UnconnectedCount = 0;
for( ii = m_Parent->m_Pcb->GetNumRatsnests(); ii > 0; Ratsnest++, ii-- )
void DRC::WriteReport( FILE* fp )
{
fprintf( fp, "Drc report for %s\n",
CONV_TO_UTF8( m_mainWindow->GetScreen()->m_FileName ) );
char line[256];
fprintf( fp, "Created on %s\n", DateAndTime( line ) );
// write report here
int errors = 0;
if( errors )
fprintf( fp, "** End DRC: %d errors **\n", errors );
else if( m_unconnectedCount == 0 )
fprintf( fp, "** End Drc: No Error **\n" );
}
void DRC::RunTests()
{
// erase the MARKERs here.
m_pcb->DeleteMARKERs();
// test pad to pad clearances, nothing to do with tracks, vias or zones.
if( m_doPad2PadTest )
testPad2Pad();
// test track and via clearnces to other tracks, pads, and vias
testTracks();
// test zone clearances to other zones, pads, tracks, and vias
if( m_doZonesTest )
testZones();
// find and gather unconnected pads.
if( m_doUnconnectedTest )
testUnconnected();
}
void DRC::testTracks()
{
for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm=segm->Next() )
{
if( (Ratsnest->status & CH_ACTIF) == 0 )
if( !doTrackDrc( segm, segm->Next() ) )
{
wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker );
m_currentMarker = 0;
}
}
}
void DRC::testPad2Pad()
{
LISTE_PAD* pad_list_start = CreateSortedPadListByXCoord( m_pcb );
LISTE_PAD* pad_list_limit = &pad_list_start[m_pcb->m_NbPads];
LISTE_PAD* ppad;
// find the max size of the pads (used to stop the test)
int max_size = 0;
for( ppad = pad_list_start; ppad<pad_list_limit; ppad++ )
{
D_PAD* pad = *ppad;
if( pad->m_Rayon > max_size )
max_size = pad->m_Rayon;
}
// Test the pads
for( ppad = pad_list_start; ppad<pad_list_limit; ppad++ )
{
D_PAD* pad = *ppad;
if( !doPadToPadsDrc( pad, ppad, pad_list_limit, max_size ) )
{
wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker );
m_currentMarker = 0;
}
}
free( pad_list_start );
}
void DRC::testUnconnected()
{
if( (m_pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 )
{
wxClientDC dc( m_mainWindow->DrawPanel );
m_mainWindow->Compile_Ratsnest( &dc, TRUE );
}
if( m_pcb->m_Ratsnest == NULL )
return;
m_unconnectedCount = 0;
CHEVELU* rat = m_pcb->m_Ratsnest;
for( int i=0; i<m_pcb->GetNumRatsnests(); ++i, ++rat )
{
if( (rat->status & CH_ACTIF) == 0 )
continue;
m_UnconnectedCount++;
if( m_UnconnectedCount == 1 )
m_unconnectedCount++;
D_PAD* padStart = rat->pad_start;
D_PAD* padEnd = rat->pad_end;
MARKER* marker = fillMarker( padStart, padEnd, DRCE_UNCONNECTED_PADS, NULL );
m_pcb->Add( marker );
}
}
void DRC::testZones()
{
TRACK* zoneSeg;
/* this was for display purposes, don't know that we need it anymore
m_pcb->m_NbSegmZone = 0;
for( zoneSeg = m_pcb->m_Zone; zoneSeg; zoneSeg = zoneSeg->Next() )
++m_pcb->m_NbSegmZone;
*/
for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg=zoneSeg->Next() )
{
// m_logWindow->AppendText( _( "Unconnected found:\n" ) );
// Test zoneSeg with other zone segments and with all pads
if( !doTrackDrc( zoneSeg, zoneSeg->Next() ) )
{
wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker );
m_currentMarker = 0;
}
D_PAD* pad = Ratsnest->pad_start;
pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode );
// Test zoneSeg with all track segments
int tmp = m_pcb->m_NbPads;
wxString pad_name = pad->ReturnStringPadName();
wxString module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text;
m_pcb->m_NbPads = 0; // Pads already tested: disable pad test
bool rc = doTrackDrc( zoneSeg, m_pcb->m_Track );
m_pcb->m_NbPads = tmp;
msg.Printf( _( "%d > Pad %s (%s) @ %.4f,%.4f and " ), m_UnconnectedCount,
pad_name.GetData(), module_name.GetData(),
pad->m_Pos.x * convert, pad->m_Pos.y * convert );
if( !rc )
{
wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker );
m_currentMarker = 0;
}
}
}
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
pad = Ratsnest->pad_end;
pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode );
MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER* fillMe )
{
wxString textA = aTrack->MenuText( m_pcb );
wxString textB = aItem->MenuText( m_pcb );
pad_name = pad->ReturnStringPadName();
module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text;
wxPoint position;
msg.Printf( _( "Pad %s (%s) @ %.4f,%.4f\n" ),
pad_name.GetData(), module_name.GetData(),
pad->m_Pos.x * convert, pad->m_Pos.y * convert );
if( aItem->Type() == TYPEPAD )
position = aItem->GetPosition();
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
else if( aItem->Type() == TYPEVIA )
position = aItem->GetPosition();
else if( aItem->Type() == TYPETRACK )
{
TRACK* track = (TRACK*) aItem;
wxPoint endPos = track->m_End;
// either of aItem's start or end will be used for the marker position
// first assume start, then swith to end if needed. decision made on
// distance from end of aTrack.
position = track->m_Start;
double dToEnd = hypot( endPos.x - aTrack->m_End.x,
endPos.y - aTrack->m_End.y );
double dToStart = hypot( position.x - aTrack->m_End.x,
position.y - aTrack->m_End.y );
if( dToEnd < dToStart )
position = endPos;
}
if( m_UnconnectedCount )
msg.Printf( _( "Active routes: %d\n" ), m_UnconnectedCount );
if( fillMe )
fillMe->SetData( aErrorCode, position,
textA, aTrack->GetPosition(),
textB, aItem->GetPosition() );
else
msg = _( "OK! (No active routes)\n" );
fillMe = new MARKER( aErrorCode, position,
textA, aTrack->GetPosition(),
textB, aItem->GetPosition() );
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
return fillMe;
}
/****************************************************/
void WinEDA_DrcFrame::TestDrc( wxCommandEvent& event )
/****************************************************/
MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe )
{
int errors;
wxString msg;
wxString textA = aPad->MenuText( m_pcb );
wxString textB = bPad->MenuText( m_pcb );
if( !DrcInProgress )
wxPoint posA = aPad->GetPosition();
wxPoint posB = bPad->GetPosition();
if( fillMe )
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB );
else
fillMe = new MARKER( aErrorCode, posA, textA, posA, textB, posB );
return fillMe;
}
/***********************************************************************/
bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
/***********************************************************************/
{
TRACK* track;
int dx, dy; // utilise pour calcul des dim x et dim y des segments
int w_dist;
int layerMask;
int net_code_ref;
int org_X, org_Y; // Origine sur le PCB des axes du repere centre sur
// l'origine du segment de reference
wxPoint shape_pos;
org_X = aRefSeg->m_Start.x;
org_Y = aRefSeg->m_Start.y;
m_finx = dx = aRefSeg->m_End.x - org_X;
m_finy = dy = aRefSeg->m_End.y - org_Y;
layerMask = aRefSeg->ReturnMaskLayer();
net_code_ref = aRefSeg->GetNet();
m_segmAngle = 0;
// for a non horizontal or vertical segment Compute the segment angle
// in tenths of degrees and its length
if( dx || dy )
{
// Compute the segment angle in 0,1 degrees
m_segmAngle = ArcTangente( dy, dx );
// Compute the segment length: we build an equivalent rotated segment,
// this segment is horizontal, therefore dx = length
RotatePoint( &dx, &dy, m_segmAngle ); // dx = length, dy = 0
}
m_segmLength = dx;
/******************************************/
/* Phase 1 : test DRC track to pads : */
/******************************************/
D_PAD pseudo_pad( (MODULE*) NULL );
// Compute the min distance to pads
w_dist = aRefSeg->m_Width >> 1;
for( int ii=0; ii<m_pcb->m_NbPads; ++ii )
{
D_PAD* pad = m_pcb->m_Pads[ii];
/* No problem if pads are on an other layer,
* But if a drill hole exists (a pad on a single layer can have a hole!)
* we must test the hole
*/
if( (pad->m_Masque_Layer & layerMask ) == 0 )
{
/* We must test the pad hole. In order to use the function "checkClearanceSegmToPad",
* a pseudo pad is used, with a shape and a size like the hole
*/
if( pad->m_Drill.x == 0 )
continue;
pseudo_pad.m_Size = pad->m_Drill;
pseudo_pad.SetPosition( pad->GetPosition() );
pseudo_pad.m_PadShape = pad->m_DrillShape;
pseudo_pad.m_Orient = pad->m_Orient;
pseudo_pad.ComputeRayon(); // compute the ray length
m_spotcx = pseudo_pad.GetPosition().x - org_X;
m_spotcy = pseudo_pad.GetPosition().y - org_Y;
if( !checkClearanceSegmToPad( &pseudo_pad, w_dist,
g_DesignSettings.m_TrackClearence ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, pad,
DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker );
return false;
}
continue;
}
/* The pad must be in a net (i.e pt_pad->GetNet() != 0 )
* but no problem if the pad netcode is the current netcode (same net)
*/
if( pad->GetNet() && // the pad must be connected
net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok
continue;
// DRC for the pad
shape_pos = pad->ReturnShapePos();
m_spotcx = shape_pos.x - org_X;
m_spotcy = shape_pos.y - org_Y;
if( !checkClearanceSegmToPad( pad, w_dist, g_DesignSettings.m_TrackClearence ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, pad,
DRCE_TRACK_NEAR_PAD, m_currentMarker );
return false;
}
}
/***********************************************/
/* Phase 2: test DRC with other track segments */
/***********************************************/
// At this point the reference segment is the X axis
// Test the reference segment with other track segments
for( track=aStart; track; track=track->Next() )
{
// coord des extremites du segment teste dans le repere modifie
int x0;
int y0;
int xf;
int yf;
// No problem if segments have the same net code:
if( net_code_ref == track->GetNet() )
continue;
// No problem if segment are on different layers :
if( ( layerMask & track->ReturnMaskLayer() ) == 0 )
continue;
// the minimum distance = clearance plus half the reference track
// width plus half the other track's width
w_dist = aRefSeg->m_Width >> 1;
w_dist += track->m_Width >> 1;
w_dist += g_DesignSettings.m_TrackClearence;
// If the reference segment is a via, we test it here
if( aRefSeg->Type() == TYPEVIA )
{
int orgx, orgy; // origine du repere d'axe X = segment a comparer
int angle = 0; // angle du segment a tester;
orgx = track->m_Start.x;
orgy = track->m_Start.y;
dx = track->m_End.x - orgx;
dy = track->m_End.y - orgy;
x0 = aRefSeg->m_Start.x - orgx;
y0 = aRefSeg->m_Start.y - orgy;
if( track->Type() == TYPEVIA )
{
// Test distance between two vias
if( (int) hypot( x0, y0 ) < w_dist )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_VIA_NEAR_VIA, m_currentMarker );
return false;
}
}
else // test via to segment
{
// Compute l'angle
angle = ArcTangente( dy, dx );
// Compute new coordinates ( the segment become horizontal)
RotatePoint( &dx, &dy, angle );
RotatePoint( &x0, &y0, angle );
if( !checkMarginToCircle( x0, y0, w_dist, dx ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_VIA_NEAR_TRACK, m_currentMarker );
return false;
}
}
continue;
}
/* We compute x0,y0, xf,yf = starting and ending point coordinates for the segment to test
* in the new axis : the new X axis is the reference segment
* We must translate and rotate the segment to test
*/
x0 = track->m_Start.x - org_X;
y0 = track->m_Start.y - org_Y;
xf = track->m_End.x - org_X;
yf = track->m_End.y - org_Y;
RotatePoint( &x0, &y0, m_segmAngle );
RotatePoint( &xf, &yf, m_segmAngle );
if( track->Type() == TYPEVIA )
{
if( checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
continue;
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_NEAR_VIA, m_currentMarker );
return false;
}
/* We have changed axis:
* the reference segment is Horizontal.
* 3 cases : the segment to test can be parallel, perpendicular or have an other direction
*/
if( y0 == yf ) // parallel segments
{
if( abs( y0 ) >= w_dist )
continue;
if( x0 > xf )
EXCHG( x0, xf ); /* pour que x0 <= xf */
if( x0 > (-w_dist) && x0 < (m_segmLength + w_dist) ) /* possible error drc */
{
/* Fine test : we consider the rounded shape of the ends */
if( x0 >= 0 && x0 <= m_segmLength )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS1, m_currentMarker );
return false;
}
if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS2, m_currentMarker );
return false;
}
}
if( xf > (-w_dist) && xf < (m_segmLength + w_dist) )
{
/* Fine test : we consider the rounded shape of the ends */
if( xf >= 0 && xf <= m_segmLength )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS3, m_currentMarker );
return false;
}
if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS4, m_currentMarker );
return false;
}
}
if( x0 <=0 && xf >= 0 )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_UNKNOWN1, m_currentMarker );
return false;
}
}
else if( x0 == xf ) // perpendicular segments
{
if( ( x0 <= (-w_dist) ) || ( x0 >= (m_segmLength + w_dist) ) )
continue;
// Test if segments are crossing
if( y0 > yf )
EXCHG( y0, yf );
if( (y0 < 0) && (yf > 0) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACKS_CROSSING, m_currentMarker );
return false;
}
// At this point the drc error is due to an end near a reference segm end
if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM1, m_currentMarker );
return false;
}
if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM2, m_currentMarker );
return false;
}
}
else // segments quelconques entre eux */
{
// calcul de la "surface de securite du segment de reference
// First rought 'and fast) test : the track segment is like a rectangle
m_xcliplo = m_ycliplo = -w_dist;
m_xcliphi = m_segmLength + w_dist;
m_ycliphi = w_dist;
// A fine test is needed because a serment is not exactly a
// rectangle, it has rounded ends
if( !checkLine( x0, y0, xf, yf ) )
{
/* 2eme passe : the track has rounded ends.
* we must a fine test for each rounded end and the
* rectangular zone
*/
m_xcliplo = 0;
m_xcliphi = m_segmLength;
if( !checkLine( x0, y0, xf, yf ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM3, m_currentMarker );
return false;
}
else // The drc error is due to the starting or the ending point of the reference segment
{
// Test the starting and the ending point
int angle, rx0, ry0, rxf, ryf;
x0 = track->m_Start.x;
y0 = track->m_Start.y;
xf = track->m_End.x;
yf = track->m_End.y;
dx = xf - x0;
dy = yf - y0;
/* Compute the segment orientation (angle) en 0,1 degre */
angle = ArcTangente( dy, dx );
/* Compute the segment lenght: dx = longueur */
RotatePoint( &dx, &dy, angle );
/* Comute the reference segment coordinates relatives to a
* X axis = current tested segment
*/
rx0 = aRefSeg->m_Start.x - x0;
ry0 = aRefSeg->m_Start.y - y0;
rxf = aRefSeg->m_End.x - x0;
ryf = aRefSeg->m_End.y - y0;
RotatePoint( &rx0, &ry0, angle );
RotatePoint( &rxf, &ryf, angle );
if( !checkMarginToCircle( rx0, ry0, w_dist, dx ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM4, m_currentMarker );
return false;
}
if( !checkMarginToCircle( rxf, ryf, w_dist, dx ) )
{
++m_errorCount;
m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM5, m_currentMarker );
return false;
}
}
}
}
}
return true;
}
/*****************************************************************************/
bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
int max_size )
/*****************************************************************************/
{
int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS;
int x_limite = max_size + g_DesignSettings.m_TrackClearence +
aRefPad->m_Rayon + aRefPad->GetPosition().x;
for( LISTE_PAD* pad_list=aStart; pad_list<aEnd; ++pad_list )
{
D_PAD* pad = *pad_list;
if( pad == aRefPad )
continue;
/* We can stop the test when pad->m_Pos.x > x_limite
* because the list is sorted by X values */
if( pad->m_Pos.x > x_limite )
break;
/* No probleme if pads are on different copper layers */
if( (pad->m_Masque_Layer & layerMask ) == 0 )
continue;
/* The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
* But no problem if pads have the same netcode (same net)*/
if( pad->GetNet() && (aRefPad->GetNet() == pad->GetNet()) )
continue;
/* No problem if pads are from the same footprint
* and have the same pad number ( equivalent pads ) */
if( (pad->m_Parent == aRefPad->m_Parent) && (pad->m_NumPadName == aRefPad->m_NumPadName) )
continue;
if( !checkClearancePadToPad( aRefPad, pad, g_DesignSettings.m_TrackClearence ) )
{
// here we have a drc error!
++m_errorCount;
m_currentMarker = fillMarker( aRefPad, pad,
DRCE_PAD_NEAR_PAD1, m_currentMarker );
return false;
}
}
return true;
}
/**************************************************************************************/
bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_min )
/***************************************************************************************/
{
wxPoint rel_pos;
int dist;;
wxPoint shape_pos;
int pad_angle;
rel_pos = aPad->ReturnShapePos();
shape_pos = aRefPad->ReturnShapePos();
// rel_pos is pad position relative to the aRefPad position
rel_pos.x -= shape_pos.x;
rel_pos.y -= shape_pos.y;
dist = (int) hypot( rel_pos.x, rel_pos.y );
bool diag = true;
/* tst rapide: si les cercles exinscrits sont distants de dist_min au moins,
* il n'y a pas de risque: */
if( (dist - aRefPad->m_Rayon - aPad->m_Rayon) >= dist_min )
return OK_DRC;
/* Ici les pads sont proches et les cercles exinxcrits sont trop proches
* Selon les formes relatives il peut y avoir ou non erreur */
bool swap_pads = false;
if( (aRefPad->m_PadShape != CIRCLE) && (aPad->m_PadShape == CIRCLE) )
swap_pads = true;
else if( (aRefPad->m_PadShape != OVALE) && (aPad->m_PadShape == OVALE) )
swap_pads = true;
if( swap_pads )
{
EXCHG( aRefPad, aPad );
rel_pos.x = -rel_pos.x;
rel_pos.y = -rel_pos.y;
}
switch( aRefPad->m_PadShape )
{
case CIRCLE: // aRefPad is like a track segment with a null lenght
m_segmLength = 0;
m_segmAngle = 0;
m_finx = m_finy = 0;
m_spotcx = rel_pos.x;
m_spotcy = rel_pos.y;
diag = checkClearanceSegmToPad( aPad, aRefPad->m_Rayon, dist_min );
break;
case RECT:
RotatePoint( &rel_pos.x, &rel_pos.y, aRefPad->m_Orient );
pad_angle = aRefPad->m_Orient + aPad->m_Orient; // pad_angle = pad orient relative to the aRefPad orient
NORMALIZE_ANGLE_POS( pad_angle );
if( aPad->m_PadShape == RECT )
{
wxSize size = aPad->m_Size;
if( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800) ||
(pad_angle == 2700) )
{
if( (pad_angle == 900) || (pad_angle == 2700) )
{
EXCHG( size.x, size.y );
}
// Test DRC:
diag = false;
rel_pos.x = ABS( rel_pos.x );
rel_pos.y = ABS( rel_pos.y );
if( ( rel_pos.x - ( (size.x + aRefPad->m_Size.x) / 2 ) ) >= dist_min )
diag = true;
if( ( rel_pos.y - ( (size.y + aRefPad->m_Size.y) / 2 ) ) >= dist_min )
diag = true;
}
else // Any other orient
{
/* TODO : any orient ... */
}
}
break;
case OVALE: /* an oval pad is like a track segment */
{
/* Create and test a track segment with same dimensions */
int segm_width;
m_segmAngle = aRefPad->m_Orient; // Segment orient.
if( aRefPad->m_Size.y < aRefPad->m_Size.x ) /* We suppose the pad is an horizontal oval */
{
segm_width = aRefPad->m_Size.y;
m_segmLength = aRefPad->m_Size.x - aRefPad->m_Size.y;
}
else // it was a vertical oval, change to a rotated horizontal one
{
segm_width = aRefPad->m_Size.x;
m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x;
m_segmAngle += 900;
}
/* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */
int sx = -m_segmLength / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment
RotatePoint( &sx, &sy, m_segmAngle ); // True start point coordinate of the equivalent segment
m_spotcx = rel_pos.x + sx;
m_spotcy = rel_pos.y + sy; // pad position / segment origin
m_finx = -sx;
m_finy = -sy; // end of segment coordinate
diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min );
break;
}
default:
/* TODO...*/
break;
}
return diag;
}
bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min )
{
int p_dimx;
int p_dimy; // half the dimension of the pad
int orient;
int x0, y0, xf, yf;
int seuil;
int deltay;
seuil = w_segm + dist_min;
p_dimx = pad_to_test->m_Size.x >> 1;
p_dimy = pad_to_test->m_Size.y >> 1;
if( pad_to_test->m_PadShape == CIRCLE )
{
/* calcul des coord centre du pad dans le repere axe X confondu
* avec le segment en tst */
RotatePoint( &m_spotcx, &m_spotcy, m_segmAngle );
return checkMarginToCircle( m_spotcx, m_spotcy, seuil + p_dimx, m_segmLength );
}
else
{
/* calcul de la "surface de securite" du pad de reference */
m_xcliplo = m_spotcx - seuil - p_dimx;
m_ycliplo = m_spotcy - seuil - p_dimy;
m_xcliphi = m_spotcx + seuil + p_dimx;
m_ycliphi = m_spotcy + seuil + p_dimy;
x0 = y0 = 0;
xf = m_finx;
yf = m_finy;
orient = pad_to_test->m_Orient;
RotatePoint( &x0, &y0, m_spotcx, m_spotcy, -orient );
RotatePoint( &xf, &yf, m_spotcx, m_spotcy, -orient );
if( checkLine( x0, y0, xf, yf ) )
return true;
/* Erreur DRC : analyse fine de la forme de la pastille */
switch( pad_to_test->m_PadShape )
{
default:
return false;
case OVALE:
/* test de la pastille ovale ramenee au type ovale vertical */
if( p_dimx > p_dimy )
{
EXCHG( p_dimx, p_dimy );
orient += 900;
if( orient >= 3600 )
orient -= 3600;
}
deltay = p_dimy - p_dimx;
/* ici: p_dimx = rayon,
* delta = dist centre cercles a centre pad */
/* Test du rectangle separant les 2 demi cercles */
m_xcliplo = m_spotcx - seuil - p_dimx;
m_ycliplo = m_spotcy - w_segm - deltay;
m_xcliphi = m_spotcx + seuil + p_dimx;
m_ycliphi = m_spotcy + w_segm + deltay;
if( !checkLine( x0, y0, xf, yf ) )
return false;
/* test des 2 cercles */
x0 = m_spotcx; /* x0,y0 = centre du cercle superieur du pad ovale */
y0 = m_spotcy + deltay;
RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient );
RotatePoint( &x0, &y0, m_segmAngle );
if( !checkMarginToCircle( x0, y0, p_dimx + seuil, m_segmLength ) )
return false;
x0 = m_spotcx; /* x0,y0 = centre du cercle inferieur du pad ovale */
y0 = m_spotcy - deltay;
RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient );
RotatePoint( &x0, &y0, m_segmAngle );
if( !checkMarginToCircle( x0, y0, p_dimx + seuil, m_segmLength ) )
return false;
break;
case RECT: /* 2 rectangle + 4 1/4 cercles a tester */
/* Test du rectangle dimx + seuil, dimy */
m_xcliplo = m_spotcx - p_dimx - seuil;
m_ycliplo = m_spotcy - p_dimy;
m_xcliphi = m_spotcx + p_dimx + seuil;
m_ycliphi = m_spotcy + p_dimy;
if( !checkLine( x0, y0, xf, yf ) )
{
return false;
}
/* Test du rectangle dimx , dimy + seuil */
m_xcliplo = m_spotcx - p_dimx;
m_ycliplo = m_spotcy - p_dimy - seuil;
m_xcliphi = m_spotcx + p_dimx;
m_ycliphi = m_spotcy + p_dimy + seuil;
if( !checkLine( x0, y0, xf, yf ) )
{
return false;
}
/* test des 4 cercles ( surface d'solation autour des sommets */
/* test du coin sup. gauche du pad */
x0 = m_spotcx - p_dimx;
y0 = m_spotcy - p_dimy;
RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient );
RotatePoint( &x0, &y0, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) )
{
return false;
}
/* test du coin sup. droit du pad */
x0 = m_spotcx + p_dimx;
y0 = m_spotcy - p_dimy;
RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient );
RotatePoint( &x0, &y0, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) )
{
return false;
}
/* test du coin inf. gauche du pad */
x0 = m_spotcx - p_dimx;
y0 = m_spotcy + p_dimy;
RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient );
RotatePoint( &x0, &y0, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) )
{
return false;
}
/* test du coin inf. droit du pad */
x0 = m_spotcx + p_dimx;
y0 = m_spotcy + p_dimy;
RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient );
RotatePoint( &x0, &y0, m_segmAngle );
if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) )
{
return false;
}
break;
}
}
return true;
}
/**********************************************************************/
bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur )
/**********************************************************************/
{
if( abs( cy ) > radius )
return true;
if( (cx >= -radius ) && ( cx <= (longueur + radius) ) )
{
if( (cx >= 0) && (cx <= longueur) )
return false;
if( cx > longueur )
cx -= longueur;
if( hypot( cx, cy ) < radius )
return false;
}
return true;
}
/**********************************************/
/* int Tst_Ligne(int x1,int y1,int x2,int y2) */
/**********************************************/
static inline int USCALE( unsigned arg, unsigned num, unsigned den )
{
int ii;
ii = (int) ( ( (double) arg * num ) / den );
return ii;
}
#define WHEN_OUTSIDE return true
#define WHEN_INSIDE
bool DRC::checkLine( int x1, int y1, int x2, int y2 )
{
int temp;
if( x1 > x2 )
{
EXCHG( x1, x2 );
EXCHG( y1, y2 );
}
if( (x2 < m_xcliplo) || (x1 > m_xcliphi) )
{
WHEN_OUTSIDE;
}
if( y1 < y2 )
{
if( (y2 < m_ycliplo) || (y1 > m_ycliphi) )
{
WHEN_OUTSIDE;
}
if( y1 < m_ycliplo )
{
temp = USCALE( (x2 - x1), (m_ycliplo - y1), (y2 - y1) );
if( (x1 += temp) > m_xcliphi )
{
WHEN_OUTSIDE;
}
y1 = m_ycliplo;
WHEN_INSIDE;
}
if( y2 > m_ycliphi )
{
temp = USCALE( (x2 - x1), (y2 - m_ycliphi), (y2 - y1) );
if( (x2 -= temp) < m_xcliplo )
{
WHEN_OUTSIDE;
}
y2 = m_ycliphi;
WHEN_INSIDE;
}
if( x1 < m_xcliplo )
{
temp = USCALE( (y2 - y1), (m_xcliplo - x1), (x2 - x1) );
y1 += temp;
x1 = m_xcliplo;
WHEN_INSIDE;
}
if( x2 > m_xcliphi )
{
temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) );
y2 -= temp;
x2 = m_xcliphi;
WHEN_INSIDE;
}
}
else
{
if( (y1 < m_ycliplo) || (y2 > m_ycliphi) )
{
WHEN_OUTSIDE;
}
if( y1 > m_ycliphi )
{
if( m_CreateRptCtrl->IsChecked() ) // Create a file rpt
temp = USCALE( (x2 - x1), (y1 - m_ycliphi), (y1 - y2) );
if( (x1 += temp) > m_xcliphi )
{
s_RptFilename = m_RptFilenameCtrl->GetValue();
if( s_RptFilename.IsEmpty() )
OnButtonBrowseRptFileClick( event );
if( !s_RptFilename.IsEmpty() )
s_RptFile = wxFopen( s_RptFilename, wxT( "w" ) );
else
s_RptFile = NULL;
WHEN_OUTSIDE;
}
if( s_RptFile )
y1 = m_ycliphi;
WHEN_INSIDE;
}
if( y2 < m_ycliplo )
{
fprintf( s_RptFile, "Drc report for %s\n",
CONV_TO_UTF8( m_Parent->m_CurrentScreen->m_FileName ) );
char line[256];
fprintf( s_RptFile, "Created on %s\n", DateAndTime( line ) );
temp = USCALE( (x2 - x1), (m_ycliplo - y2), (y1 - y2) );
if( (x2 -= temp) < m_xcliplo )
{
WHEN_OUTSIDE;
}
s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked();
s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked();
s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked();
AbortDrc = FALSE;
// m_logWindow->Clear();
g_DesignSettings.m_TrackClearence =
ReturnValueFromTextCtrl( *m_SetClearance, m_Parent->m_InternalUnits );
/* Test DRC errors (clearance errors, bad connections .. */
errors = m_Parent->Test_DRC( m_DC, m_Pad2PadTestCtrl->IsChecked(),
m_ZonesTestCtrl->IsChecked() );
/* Search for active routes (unconnected pads) */
if( m_UnconnectedTestCtrl->IsChecked() )
ListUnconnectedPads( event );
else
m_UnconnectedCount = 0;
if( errors )
msg.Printf( _( "** End Drc: %d errors **\n" ), errors );
else if( m_UnconnectedCount == 0 )
msg = _( "** End Drc: No Error **\n" );
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
if( s_RptFile )
y2 = m_ycliplo;
WHEN_INSIDE;
}
if( x1 < m_xcliplo )
{
msg.Printf( _( "Report file <%s> created\n" ), s_RptFilename.GetData() );
// m_logWindow->AppendText( msg );
fclose( s_RptFile );
s_RptFile = NULL;
temp = USCALE( (y1 - y2), (m_xcliplo - x1), (x2 - x1) );
y1 -= temp;
x1 = m_xcliplo;
WHEN_INSIDE;
}
if( x2 > m_xcliphi )
{
temp = USCALE( (y1 - y2), (x2 - m_xcliphi), (x2 - x1) );
y2 += temp;
x2 = m_xcliphi;
WHEN_INSIDE;
}
}
else
wxBell();
}
/*********************************************************/
void WinEDA_DrcFrame::DelDRCMarkers( wxCommandEvent& event )
/*********************************************************/
{
if( !DrcInProgress )
if( ( (x2 + x1)/2 <= m_xcliphi ) && ( (x2 + x1)/2 >= m_xcliplo ) \
&& ( (y2 + y1)/2 <= m_ycliphi ) && ( (y2 + y1)/2 >= m_ycliplo ) )
{
m_Parent->Erase_Marqueurs();
m_Parent->DrawPanel->ReDraw( m_DC, TRUE );
return false;
}
else
wxBell();
return true;
}
/******************************************************/
void WinEDA_PcbFrame::Install_Test_DRC_Frame( wxDC* DC )
/******************************************************/
/* install a dialog box to handle the general DRC control
*/
{
AbortDrc = FALSE;
DrcFrame = new WinEDA_DrcFrame( NULL, this, DC ); // @todo
DrcFrame->ShowModal();
DrcFrame->Destroy();
DrcFrame = NULL;
}
#if 0
//----< new stuff above this line, old stuff below >------------------------
/* saving drc options */
static bool s_Pad2PadTestOpt = true;
static bool s_UnconnectedTestOpt = true;
static bool s_ZonesTestOpt = false;
static bool s_CreateRptFileOpt = false;
static FILE* s_RptFile = NULL;
static wxString s_RptFilename;
static int ErrorsDRC_Count;
static MARKER* current_marqueur; /* Pour gestion des marqueurs sur pcb */
static bool AbortDrc, DrcInProgress = FALSE;
static int spot_cX, spot_cY; /* position d'elements a tester */
static int finx, finy; // coord relatives de l'extremite du segm de reference
static int segm_angle; // angle d'inclinaison du segment de reference en 0,1 degre
static int segm_long; // longueur du segment de reference
static int xcliplo, ycliplo, xcliphi, ycliphi; /* coord de la surface de securite du segment a comparer */
/************************************************************************/
......@@ -285,7 +1385,8 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
int flag_err_Drc;
TRACK* pt_segm;
D_PAD* pad;
MARKER* Marqueur;
MARQUEUR* Marqueur;
EDA_BaseStruct* PtStruct;
wxString Line;
#define PRINT_NB_PAD_POS 42
......@@ -314,9 +1415,7 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
Affiche_1_Parametre( this, PRINT_PAD_ERR_POS, wxT( "Pad Err" ), wxT( "0" ), LIGHTRED );
if( DrcFrame )
{
// DrcFrame->m_logWindow->AppendText( _( "Tst Pad to Pad\n" ) );
}
DrcFrame->m_logWindow->AppendText( _( "Tst Pad to Pad\n" ) );
LISTE_PAD* pad_list_start = CreateSortedPadListByXCoord( m_Pcb );
LISTE_PAD* pad_list_limit = &pad_list_start[m_Pcb->m_NbPads];
......@@ -347,8 +1446,13 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
}
Line.Printf( wxT( "%d" ), ErrorsDRC_Count );
Affiche_1_Parametre( this, PRINT_PAD_ERR_POS, wxEmptyString, Line, LIGHTRED );
Marqueur->Pnext = m_Pcb->m_Drawings;
Marqueur->Pback = m_Pcb;
m_Pcb->Add( Marqueur );
PtStruct = m_Pcb->m_Drawings;
if( PtStruct )
PtStruct->Pback = Marqueur;
m_Pcb->m_Drawings = Marqueur;
}
}
......@@ -361,7 +1465,8 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
Affiche_1_Parametre( this, PRINT_TRACK_ERR_POS, _( "Track Err" ), wxT( "0" ), LIGHTRED );
pt_segm = m_Pcb->m_Track;
// if( DrcFrame ) DrcFrame->m_logWindow->AppendText( _( "Tst Tracks\n" ) );
if( DrcFrame )
DrcFrame->m_logWindow->AppendText( _( "Tst Tracks\n" ) );
for( ii = 0, old_net = -1, jj = 0;
pt_segm != NULL;
......@@ -373,7 +1478,7 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
if( jj == 0 )
{
jj = 10;
WXYIELD();
wxYield();
if( AbortDrc )
{
AbortDrc = FALSE; break;
......@@ -407,8 +1512,13 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
DisplayError( this, wxT( "Test_Drc(): internal err" ) );
return ErrorsDRC_Count;
}
Marqueur->Pnext = m_Pcb->m_Drawings;
Marqueur->Pback = m_Pcb;
m_Pcb->Add( Marqueur );
PtStruct = m_Pcb->m_Drawings;
if( PtStruct )
PtStruct->Pback = Marqueur;
m_Pcb->m_Drawings = Marqueur;
GRSetDrawMode( DC, GR_OR );
pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED );
......@@ -428,7 +1538,8 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
Affiche_1_Parametre( this, PRINT_NB_ZONESEGM_POS, _( "SegmNb" ), Line, RED );
Affiche_1_Parametre( this, PRINT_ZONE_ERR_POS, _( "Zone Err" ), wxT( "0" ), LIGHTRED );
// if( DrcFrame ) DrcFrame->m_logWindow->AppendText( _( "Tst Zones\n" ) );
if( DrcFrame )
DrcFrame->m_logWindow->AppendText( _( "Tst Zones\n" ) );
pt_segm = (TRACK*) m_Pcb->m_Zone;
......@@ -442,7 +1553,7 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
if( jj == 0 )
{
jj = 100;
WXYIELD();
wxYield();
if( AbortDrc )
{
AbortDrc = FALSE;
......@@ -480,8 +1591,13 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
DisplayError( this, wxT( "Test_Drc(): internal err" ) );
return ErrorsDRC_Count;
}
Marqueur->Pnext = m_Pcb->m_Drawings;
Marqueur->Pback = m_Pcb;
m_Pcb->Add( Marqueur );
PtStruct = m_Pcb->m_Drawings;
if( PtStruct )
PtStruct->Pback = Marqueur;
m_Pcb->m_Drawings = Marqueur;
GRSetDrawMode( DC, GR_OR );
pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED );
......@@ -505,8 +1621,14 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
DisplayError( this, wxT( "Test_Drc(): internal err" ) );
return ErrorsDRC_Count;
}
Marqueur->Pnext = m_Pcb->m_Drawings;
Marqueur->Pback = m_Pcb;
m_Pcb->Add( Marqueur );
PtStruct = m_Pcb->m_Drawings;
if( PtStruct )
PtStruct->Pback = Marqueur;
m_Pcb->m_Drawings = Marqueur;
GRSetDrawMode( DC, GR_OR );
pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED );
......@@ -522,6 +1644,163 @@ int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone )
}
/***************************************************************/
void DrcDialog::ListUnconnectedPads( wxCommandEvent& event )
/***************************************************************/
{
if( (m_Parent->m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 )
{
m_Parent->Compile_Ratsnest( m_DC, TRUE );
}
if( m_Parent->m_Pcb->m_Ratsnest == NULL )
return;
CHEVELU* Ratsnest = m_Parent->m_Pcb->m_Ratsnest;
int draw_mode = GR_SURBRILL | GR_OR;
WinEDA_DrawPanel* panel = m_Parent->DrawPanel;
int ii;
wxString msg;
double convert = 0.0001;
msg = _( "Look for active routes\n" );
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
m_UnconnectedCount = 0;
for( ii = m_Parent->m_Pcb->GetNumRatsnests(); ii > 0; Ratsnest++, ii-- )
{
if( (Ratsnest->status & CH_ACTIF) == 0 )
continue;
m_UnconnectedCount++;
if( m_UnconnectedCount == 1 )
{
// m_logWindow->AppendText( _( "Unconnected found:\n" ) );
}
D_PAD* pad = Ratsnest->pad_start;
pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode );
wxString pad_name = pad->ReturnStringPadName();
wxString module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text;
msg.Printf( _( "%d > Pad %s (%s) @ %.4f,%.4f and " ), m_UnconnectedCount,
pad_name.GetData(), module_name.GetData(),
pad->m_Pos.x * convert, pad->m_Pos.y * convert );
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
pad = Ratsnest->pad_end;
pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode );
pad_name = pad->ReturnStringPadName();
module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text;
msg.Printf( _( "Pad %s (%s) @ %.4f,%.4f\n" ),
pad_name.GetData(), module_name.GetData(),
pad->m_Pos.x * convert, pad->m_Pos.y * convert );
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
}
if( m_UnconnectedCount )
msg.Printf( _( "Active routes: %d\n" ), m_UnconnectedCount );
else
msg = _( "OK! (No active routes)\n" );
// m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
}
/****************************************************/
void DrcDialog::TestDrc( wxCommandEvent& event )
/****************************************************/
{
int errors;
wxString msg;
if( !DrcInProgress )
{
if( m_CreateRptCtrl->IsChecked() ) // Create a file rpt
{
s_RptFilename = m_RptFilenameCtrl->GetValue();
if( s_RptFilename.IsEmpty() )
OnButtonBrowseRptFileClick( event );
if( !s_RptFilename.IsEmpty() )
s_RptFile = wxFopen( s_RptFilename, wxT( "w" ) );
else
s_RptFile = NULL;
}
if( s_RptFile )
{
fprintf( s_RptFile, "Drc report for %s\n",
CONV_TO_UTF8( m_Parent->m_CurrentScreen->m_FileName ) );
char line[256];
fprintf( s_RptFile, "Created on %s\n", DateAndTime( line ) );
}
s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked();
s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked();
s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked();
AbortDrc = FALSE;
m_logWindow->Clear();
g_DesignSettings.m_TrackClearence =
ReturnValueFromTextCtrl( *m_SetClearance, m_Parent->m_InternalUnits );
/* Test DRC errors (clearance errors, bad connections .. */
errors = m_Parent->Test_DRC( m_DC, m_Pad2PadTestCtrl->IsChecked(
), m_ZonesTestCtrl->IsChecked() );
/* Search for active routes (unconnected pads) */
if( m_UnconnectedTestCtrl->IsChecked() )
ListUnconnectedPads( event );
else
m_UnconnectedCount = 0;
if( errors )
msg.Printf( _( "** End Drc: %d errors **\n" ), errors );
else if( m_UnconnectedCount == 0 )
msg = _( "** End Drc: No Error **\n" );
m_logWindow->AppendText( msg );
if( s_RptFile )
fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) );
if( s_RptFile )
{
msg.Printf( _( "Report file <%s> created\n" ), s_RptFilename.GetData() );
m_logWindow->AppendText( msg );
fclose( s_RptFile );
s_RptFile = NULL;
}
}
else
wxBell();
}
/*********************************************************/
void DrcDialog::DelDRCMarkers( wxCommandEvent& event )
/*********************************************************/
{
m_Parent->Erase_Marqueurs();
m_Parent->DrawPanel->ReDraw( m_DC, TRUE );
}
/***********************************************************************/
int Drc( WinEDA_BasePcbFrame* frame, wxDC* DC,
TRACK* pt_segment, TRACK* StartBuffer, int show_err )
......@@ -1535,7 +2814,7 @@ static inline int USCALE( unsigned arg, unsigned num, unsigned den )
{
int ii;
ii = (int) ( ( (float) arg * num ) / den );
ii = (int) ( ( (double) arg * num ) / den );
return ii;
}
......@@ -1646,3 +2925,4 @@ static int Tst_Ligne( int x1, int y1, int x2, int y2 )
return OK_DRC;
}
#endif
......@@ -29,9 +29,30 @@
#include "fctsys.h"
#define OK_DRC 0
#define BAD_DRC 1
/// DRC error codes:
#define DRCE_ 1
#define DRCE_UNCONNECTED_PADS 2
#define DRCE_TRACK_NEAR_THROUGH_HOLE 3 ///< thru hole is too close to track
#define DRCE_TRACK_NEAR_PAD 4 ///< pad too close to track
#define DRCE_TRACK_NEAR_VIA 5 ///< track too close to via
#define DRCE_VIA_NEAR_VIA 6 ///< via too close to via
#define DRCE_VIA_NEAR_TRACK 7 ///< via too close to track
#define DRCE_TRACK_ENDS1 8 ///< @todo say what this problem is
#define DRCE_TRACK_ENDS2 9 ///< @todo say what this problem is
#define DRCE_TRACK_ENDS3 10 ///< @todo say what this problem is
#define DRCE_TRACK_ENDS4 11 ///< @todo say what this problem is
#define DRCE_TRACK_UNKNOWN1 12 ///< @todo check source code and change this comment
#define DRCE_TRACKS_CROSSING 13 ///< tracks are crossing
#define DRCE_ENDS_PROBLEM1 14 ///< track ends are too close
#define DRCE_ENDS_PROBLEM2 15 ///< track ends are too close
#define DRCE_ENDS_PROBLEM3 16 ///< track ends are too close
#define DRCE_ENDS_PROBLEM4 17 ///< track ends are too close
#define DRCE_ENDS_PROBLEM5 18 ///< track ends are too close
#define DRCE_PAD_NEAR_PAD1 19 ///< pad too close to pad
/**
......@@ -53,13 +74,21 @@ public:
virtual wxString ShowHtml() const = 0;
/**
* Function ShowText
* translates this object into a text string suitable for showing
* in the status panel.
* @return wxString - the simple non-html text.
*/
virtual wxString ShowText() const = 0;
/**
* Function ShowText
* translates this object into a text string suitable for saving
* to disk in a report.
* @return wxString - the simple non-html text.
*/
virtual wxString ShowText() const = 0;
virtual wxString ShowReport() const = 0;
/**
......@@ -94,9 +123,23 @@ protected:
public:
DRC_ITEM() :
m_ErrorCode(0)
{
}
DRC_ITEM( int aErrorCode, const wxPoint& aIssuePos,
const wxString& aText, const wxString& bText,
const wxPoint& aPos, const wxPoint& bPos )
{
SetData( aErrorCode, aIssuePos,
aText, bText,
aPos, bPos );
}
void SetData( int aErrorCode, const wxPoint& aIssuePos,
const wxString& aText, const wxString& bText,
const wxPoint& aPos, const wxPoint& bPos )
{
m_ErrorCode = aErrorCode;
m_Pos = aIssuePos;
......@@ -106,6 +149,7 @@ public:
m_BPos = bPos;
}
//-----<Interface REPORT_ISSUE>---------------------------------------
/**
......@@ -136,6 +180,25 @@ public:
{
wxString ret;
ret.Printf( wxT("%s %s: %s AND %s: %s"),
GetErrorText().GetData(),
ShowCoord( m_APos ).GetData(), m_AText.GetData(),
ShowCoord( m_BPos ).GetData(), m_BText.GetData() );
return ret;
}
/**
* Function ShowText
* translates this object into a text string suitable for saving
* to disk in a report.
* @return wxString - the simple non-html text.
*/
wxString ShowReport() const
{
wxString ret;
ret.Printf( wxT("%s\n %s: %s\n %s: %s\n"),
GetErrorText().GetData(),
ShowCoord( m_APos ).GetData(), m_AText.GetData(),
......@@ -144,9 +207,10 @@ public:
return ret;
}
/**
* Function GetPosition
* @return const wxPoint& - the position of this report item within
* @return wxPoint& - the position of this report item within
* the drawing.
*/
const wxPoint& GetPosition() const
......@@ -176,30 +240,32 @@ public:
class WinEDA_DrawPanel;
class MARKER;
class DrcDialog;
/// A smart pointer to a DRC_ITEM
//typedef OWNER<DRC_ITEM> DRC_ITEM_OWNER;
/// A list of DRC_ITEM_PTRs
typedef std::vector<DRC_ITEM*> DRC_LIST;
/**
* Class DRC_TESTER
* performs all the DRC tests, and can optionally generate a DRC test report
* to a disk file. This class is given access to the windows and the BOARD
* that it needs via its constructor or access functions.
* Class DRC
* is the Design Rule Checker, and performs all the DRC tests. The output of
* the checking goes to the BOARD file in the form of two MARKER lists. Those
* two lists are displayable in the drc dialog box. And they can optionally
* be sent to a text file on disk.
* This class is given access to the windows and the BOARD
* that it needs via its constructor or public access functions.
*/
class DRC_TESTER
class DRC
{
protected:
friend class DrcDialog;
private:
// protected or private functions() are lowercase first character.
bool m_doPad2PadTest;
bool m_doUnconnectedTest;
bool m_doZonesTest;
bool m_doCreateRptFile;
FILE* m_rptFile;
wxString m_rptFilename;
int m_errorCount;
......@@ -214,7 +280,7 @@ protected:
int m_finy; // coord relatives de l'extremite du segm de reference
int m_segmAngle; // angle d'inclinaison du segment de reference en 0,1 degre
int m_segmLong; // longueur du segment de reference
int m_segmLength; // length of the reference segment
int m_xcliplo;
int m_ycliplo;
......@@ -223,77 +289,203 @@ protected:
int m_unconnectedCount;
DRC_LIST* m_drcList;
WinEDA_PcbFrame* m_mainWindow;
WinEDA_DrawPanel* m_drawPanel;
BOARD* m_pcb;
DrcDialog* m_ui;
public:
DRC_TESTER()
/**
* Function updatePointers
* is a private helper function used to update needed pointers from the
* one pointer which is known not to change, m_mainWindow.
*/
void updatePointers()
{
m_doPad2PadTest = true;
m_doUnconnectedTest = true;
m_doZonesTest = false;
m_doCreateRptFile = false;
// update my pointers, m_mainWindow is the only unchangable one
m_drawPanel = m_mainWindow->DrawPanel;
m_pcb = m_mainWindow->m_Pcb;
}
/**
* Function fillMarker
* optionally creates a marker and fills it in with information,
* but does not add it to the BOARD. Use this to report any kind of
* DRC problem, or unconnected pad problem.
*
* @param aTrack The reference track
* @param aItem Another item on the BOARD, such as a SEGVIA, SEGZONE,
* or TRACK.
* @param aErrorCode A categorizing identifier for the particular type
* of error that is being reported.
* @param fillMe A MARKER* which is to be filled in, or NULL if one is to
* first be allocated, then filled.
*/
MARKER* fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER* fillMe );
MARKER* fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe );
//-----<categorical group tests>-----------------------------------------
void testTracks();
void testPad2Pad();
void testUnconnected();
void testZones();
//-----<single "item" tests>-----------------------------------------
/**
* Function doPadToPadsDrc
* tests the clearance between aRefPad and other pads.
* The pad list must be sorted by x coordinate.
* @param aRefPad The pad to test
* @param aStart The start of the pad list to test against
* @param aEnd Marks the end of the list and is not included
* @param max_size The size of the biggest pad (used to stop the test when the X distance is > max_size)
*/
bool doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart,
LISTE_PAD* aEnd, int max_size );
/**
* Function DoTrackDrc
* tests the current segment.
* @param aRefSeg The segment to test
* @param aStart The head of a list of tracks to test against (usually BOARD::m_Track)
* @return bool - true if no poblems, else false and m_currentMarker is
* filled in with the problem information.
*/
bool doTrackDrc( TRACK* aRefSeg, TRACK* aStart );
//-----<single tests>----------------------------------------------
/**
* Function checkClearancePadToPad
* @param aRefPad The reference pad to check
* @param aPad Another pad to check against
* @return bool - true if clearance between aRefPad and pad is >= dist_min, else false
*/
bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_min );
/**
* Function checkClearanceSegmToPad
* check the distance from a pad to segment. This function uses several
* instance variable not passed in:
* segmLength = length of the segment being tested
* segmAngle = angle d'inclinaison du segment;
* finx, finy = end coordinate of the segment
* spot_cX, spot_cY = position of pad / origin of segment
* @param pad_to_test Is the pad involved in the check
* @param w_segm Hhalf width of the segment to test
* @param dist_min Is the minimum clearance needed
*
* @return false distance >= dist_min,
* true if distance < dist_min
*/
bool checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min );
m_rptFile = 0;
m_errorCount = 0;
/**
* Function checkMarginToCircle
* @todo this translation is no good, fix this:
* calculates the distance from a circle (via or round end of track) to the
* segment of reference on the right hand side.
*
* @param cx The x coordinate of the circle's center
* @param cy The y coordinate of the circle's center
* @param radius A "keep out" radius centered over the circle
* @param length The length of the segment (i.e. coordinate of end)
* @return bool - true if distance >= radius, else
* false when distance < radius
*/
static bool checkMarginToCircle( int cx, int cy, int radius, int length );
m_currentMarker = 0;
m_aboartDRC = false;
m_drcInProgress = false;
m_spotcx = 0;
m_spotcy = 0;
m_finx = 0;
m_finy = 0; // coord relatives de l'extremite du segm de reference
/**
* Function checkLine
* tests to see if one track is in contact with another track.
*
* Cette routine controle si la ligne (x1,y1 x2,y2) a une partie s'inscrivant
* dans le cadre (xcliplo,ycliplo xcliphi,ycliphi) (variables globales,
* locales a ce fichier)
*/
bool checkLine( int x1, int y1, int x2, int y2 );
m_segmAngle = 0; // angle d'inclinaison du segment de reference en 0,1 degre
m_segmLong = 0; // longueur du segment de reference
//-----</single tests>---------------------------------------------
m_xcliplo = 0;
m_ycliplo = 0;
m_xcliphi = 0;
m_ycliphi = 0; // coord de la surface de securite du segment a comparer
public:
DRC( WinEDA_PcbFrame* aPcbWindow );
m_unconnectedCount = 0;
m_drcList = new DRC_LIST();
/**
* Function Drc
* tests the current segment and returns the result and displays the error
* in the status panel only if one exists.
* @param aRefSeg The current segment to test.
* @param aList The track list to test (usually m_Pcb->m_Track)
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
int Drc( TRACK* aRefSeg, TRACK* aList );
m_drawPanel = 0;
for( int i=0; i<12; ++i )
/**
* Function DrcBlind
* tests the current segment and returns the result. Any error is not
* displayed in the status panel.
* @param aRefSeg The current segment to test.
* @param aList The track list to test (usually m_Pcb->m_Track)
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
int DrcBlind( TRACK* aRefSeg, TRACK* aList )
{
DRC_ITEM* ditem = new DRC_ITEM( 2, wxPoint(12000,3000),
wxString( wxT("A item") ), wxString( wxT("B item") ),
wxPoint(12000,3000), wxPoint(13000,3000));
updatePointers();
m_drcList->push_back( ditem );
}
return doTrackDrc( aRefSeg, aList ) ? OK_DRC : BAD_DRC;
}
/**
* Function SetTests
* sets all the test flags and may be called before running the tests.
* Function ShowDialog
* opens a dialog and prompts the user, then if a test run button is
* clicked, runs the test(s) and creates the MARKERS.
*/
void ShowDialog();
/**
* Function SetSettings
* saves all the UI or test settings and may be called before running the tests.
* @param aPad2PadTest Tells whether to test pad to pad distances.
* @param aUnconnectedTest Tells whether to list unconnected pads.
* @param aZonesTest Tells whether to test zones.
* @param aRptFilename If non-Empty, is the name of the file to
* save the report to. If Empty, means save no report.
* @param aReportName A string telling the disk file report name entered.
* @param aSaveReport A boolean telling whether to generate disk file report.
*/
void SetTests( bool aPad2PadTest, bool aUnconnectedTest, bool aZonesTest, const wxString& aRptFilename )
void SetSettings( bool aPad2PadTest, bool aUnconnectedTest,
bool aZonesTest, const wxString& aReportName, bool aSaveReport )
{
m_doPad2PadTest = aPad2PadTest;
m_doUnconnectedTest = aUnconnectedTest;
m_doZonesTest = aZonesTest;
m_rptFilename = aRptFilename;
if( m_rptFilename.IsEmpty() )
m_doCreateRptFile = false;
else
m_doCreateRptFile = true;
m_rptFilename = aReportName;
m_doCreateRptFile = aSaveReport;
}
void RunTests();
/**
* Function WriteReport
* outputs the MARKER items with commentary to an open text file.
* @param fpOut The text file to write the report to.
*/
void WriteReport( FILE* fpOut );
};
......
/***************************************************************/
/* Edition des pistes: Routines de modification de dimensions: */
/* Modif de largeurs de segment, piste, net , zone et diam Via */
/***************************************************************/
/***************************************************************/
/* Edition des pistes: Routines de modification de dimensions: */
/* Modif de largeurs de segment, piste, net , zone et diam Via */
/***************************************************************/
#include "fctsys.h"
#include "gr_basic.h"
......@@ -15,17 +15,18 @@
/* Routines Locales */
/*********************************************************************/
int WinEDA_PcbFrame::Edit_TrackSegm_Width(wxDC * DC, TRACK * pt_segm)
int WinEDA_PcbFrame::Edit_TrackSegm_Width( wxDC* DC, TRACK* pt_segm )
/*********************************************************************/
/* Routine to modify one track segment width or one via diameter.
Basic routine used by other routines when editing tracks or vias
*/
* Basic routine used by other routines when editing tracks or vias
*/
{
int errdrc = OK_DRC;
int old_w, consigne ;
int errdrc = OK_DRC;
int old_w, consigne;
DrawPanel->CursorOff(DC); // Erase cursor shape
pt_segm->Draw(DrawPanel, DC, GR_XOR) ; // Erase old track shape
DrawPanel->CursorOff( DC ); // Erase cursor shape
pt_segm->Draw( DrawPanel, DC, GR_XOR ); // Erase old track shape
/* Test DRC and width change */
old_w = pt_segm->m_Width;
......@@ -35,122 +36,137 @@ int old_w, consigne ;
consigne = pt_segm->m_Width = g_DesignSettings.m_CurrentViaSize;
}
if ( old_w < consigne) /* DRC utile puisque augm de dimension */
if( old_w < consigne ) /* DRC utile puisque augm de dimension */
{
if(Drc_On) errdrc = Drc(this, DC, pt_segm, m_Pcb->m_Track,1);
if(errdrc == BAD_DRC) pt_segm->m_Width = old_w;
else GetScreen()->SetModify();
if( Drc_On )
errdrc = m_drc->Drc( pt_segm, m_Pcb->m_Track );
if( errdrc == BAD_DRC )
pt_segm->m_Width = old_w;
else
GetScreen()->SetModify();
}
else
GetScreen()->SetModify(); /* Correction systematiquement faite si reduction */
else GetScreen()->SetModify(); /* Correction systematiquement faite si reduction */
pt_segm->Draw(DrawPanel, DC, GR_OR) ; // Display new track shape
DrawPanel->CursorOn(DC); // Display cursor shape
return(errdrc);
pt_segm->Draw( DrawPanel, DC, GR_OR ); // Display new track shape
DrawPanel->CursorOn( DC ); // Display cursor shape
return errdrc;
}
/*****************************************************************/
void WinEDA_PcbFrame::Edit_Track_Width(wxDC * DC,TRACK * pt_segm)
void WinEDA_PcbFrame::Edit_Track_Width( wxDC* DC, TRACK* pt_segm )
/*****************************************************************/
{
int ii;
TRACK * pt_track;
int errdrc;
int nb_segm, nb_segm_modifies = 0, nb_segm_non_modifies = 0;
int ii;
TRACK* pt_track;
int errdrc;
int nb_segm, nb_segm_modifies = 0, nb_segm_non_modifies = 0;
if( pt_segm == NULL) return;
if( pt_segm == NULL )
return;
pt_track = Marque_Une_Piste(this, DC, pt_segm, &nb_segm, 0);
for(ii = 0; ii < nb_segm; ii++, pt_track = (TRACK*) pt_track->Pnext)
pt_track = Marque_Une_Piste( this, DC, pt_segm, &nb_segm, 0 );
for( ii = 0; ii < nb_segm; ii++, pt_track = (TRACK*) pt_track->Pnext )
{
pt_track->SetState(BUSY,OFF);
errdrc = Edit_TrackSegm_Width(DC, pt_track);
if(errdrc == BAD_DRC) nb_segm_non_modifies++;
else nb_segm_modifies++;
pt_track->SetState( BUSY, OFF );
errdrc = Edit_TrackSegm_Width( DC, pt_track );
if( errdrc == BAD_DRC )
nb_segm_non_modifies++;
else
nb_segm_modifies++;
}
}
/***********************************************************/
void WinEDA_PcbFrame::Edit_Net_Width(wxDC * DC, int Netcode)
void WinEDA_PcbFrame::Edit_Net_Width( wxDC* DC, int Netcode )
/***********************************************************/
{
TRACK *pt_segm;
int errdrc;
int nb_segm_modifies = 0;
int nb_segm_non_modifies = 0;
TRACK* pt_segm;
int errdrc;
int nb_segm_modifies = 0;
int nb_segm_non_modifies = 0;
if (Netcode <= 0 ) return;
if( Netcode <= 0 )
return;
if( ! IsOK(this, _("Change track width (entire NET) ?") ) ) return;
if( !IsOK( this, _( "Change track width (entire NET) ?" ) ) )
return;
/* balayage des segments */
for( pt_segm = m_Pcb->m_Track; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
{
if ( Netcode != pt_segm->GetNet() ) /* mauvaise piste */
continue ;
if( Netcode != pt_segm->GetNet() ) /* mauvaise piste */
continue;
/* piste d'un net trouvee */
errdrc = Edit_TrackSegm_Width(DC, pt_segm);
if(errdrc == BAD_DRC) nb_segm_non_modifies++;
else nb_segm_modifies++;
errdrc = Edit_TrackSegm_Width( DC, pt_segm );
if( errdrc == BAD_DRC )
nb_segm_non_modifies++;
else
nb_segm_modifies++;
}
}
/*************************************************************************/
bool WinEDA_PcbFrame::Resize_Pistes_Vias(wxDC * DC, bool Track, bool Via)
bool WinEDA_PcbFrame::Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via )
/*************************************************************************/
/* remet a jour la largeur des pistes et/ou le diametre des vias
Si piste == 0 , pas de cht sur les pistes
Si via == 0 , pas de cht sur les vias
*/
* Si piste == 0 , pas de cht sur les pistes
* Si via == 0 , pas de cht sur les vias
*/
{
TRACK * pt_segm ;
int errdrc;
int nb_segm_modifies = 0;
int nb_segm_non_modifies = 0;
TRACK* pt_segm;
int errdrc;
int nb_segm_modifies = 0;
int nb_segm_non_modifies = 0;
if ( Track && Via)
if( Track && Via )
{
if( ! IsOK(this, _("Edit All Tracks and Vias Sizes")) ) return FALSE;
if( !IsOK( this, _( "Edit All Tracks and Vias Sizes" ) ) )
return FALSE;
}
else if ( Via )
else if( Via )
{
if( ! IsOK(this, _("Edit All Via Sizes")) ) return FALSE;
if( !IsOK( this, _( "Edit All Via Sizes" ) ) )
return FALSE;
}
else if( Track )
{
if( ! IsOK(this, _("Edit All Track Sizes")) ) return FALSE;
if( !IsOK( this, _( "Edit All Track Sizes" ) ) )
return FALSE;
}
pt_segm = m_Pcb->m_Track ;
for ( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
pt_segm = m_Pcb->m_Track;
for( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
{
if( pt_segm->Type() == TYPEVIA ) /* mise a jour du diametre de la via */
{
if ( Via )
if( Via )
{
errdrc = Edit_TrackSegm_Width(DC, pt_segm);
if(errdrc == BAD_DRC) nb_segm_non_modifies++;
else nb_segm_modifies++;
errdrc = Edit_TrackSegm_Width( DC, pt_segm );
if( errdrc == BAD_DRC )
nb_segm_non_modifies++;
else
nb_segm_modifies++;
}
}
else /* mise a jour de la largeur du segment */
{
if ( Track )
if( Track )
{
errdrc = Edit_TrackSegm_Width(DC, pt_segm);
if(errdrc == BAD_DRC) nb_segm_non_modifies++;
else nb_segm_modifies++;
errdrc = Edit_TrackSegm_Width( DC, pt_segm );
if( errdrc == BAD_DRC )
nb_segm_non_modifies++;
else
nb_segm_modifies++;
}
}
}
if ( nb_segm_modifies ) return TRUE;
if( nb_segm_modifies )
return TRUE;
return FALSE;
}
......@@ -123,8 +123,9 @@ void WinEDA_PcbFrame::ExChange_Track_Layer( TRACK* pt_segm, wxDC* DC )
else if( pt_segm->GetLayer() == l2 )
pt_segm->SetLayer( l1 );
if( (Drc_On) && ( Drc( this, DC, pt_segm, m_Pcb->m_Track, 1 ) == BAD_DRC ) )
{ /* Annulation du changement */
if( Drc_On && BAD_DRC==m_drc->Drc( pt_segm, m_Pcb->m_Track ) )
{
/* Annulation du changement */
ii = 0; pt_segm = pt_track;
for( ; ii < nb_segm; ii++, pt_segm = (TRACK*) pt_segm->Pnext )
{
......@@ -197,12 +198,13 @@ void WinEDA_PcbFrame::Other_Layer_Route( TRACK* track, wxDC* DC )
/* Is the current segment Ok (no DRC error) ? */
if( Drc_On )
{
if( Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 ) == BAD_DRC )
if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track ) )
/* DRC error, the change layer is not made */
return;
if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() ) // We must handle 2 segments
{
if( Drc( this, DC, g_CurrentTrackSegment->Back(), m_Pcb->m_Track, 1 ) == BAD_DRC )
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), m_Pcb->m_Track ) )
return;
}
}
......@@ -248,7 +250,7 @@ void WinEDA_PcbFrame::Other_Layer_Route( TRACK* track, wxDC* DC )
Via->SetLayerPair( COPPER_LAYER_N, LAYER_CMP_N );
}
if( Drc_On &&( Drc( this, DC, Via, m_Pcb->m_Track, 1 ) == BAD_DRC ) )
if( Drc_On && BAD_DRC==m_drc->Drc( Via, m_Pcb->m_Track ) )
{
/* DRC fault: the Via cannot be placed here ... */
delete Via;
......
......@@ -11,14 +11,13 @@
#include "autorout.h"
#include "protos.h"
#include "drc_stuff.h"
/* Routines Locales */
static void Exit_Editrack( WinEDA_DrawPanel* panel, wxDC* DC );
void ShowNewTrackWhenMovingCursor( WinEDA_DrawPanel* panel,
wxDC* DC, bool erase );
static int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC,
TRACK* ptfinsegment );
static void ComputeBreakPoint( TRACK* track, int n );
static TRACK* DeleteNullTrackSegments( BOARD* pcb, TRACK* track, int* segmcount );
static void EnsureEndTrackOnPad( D_PAD* Pad );
......@@ -160,22 +159,27 @@ TRACK* WinEDA_PcbFrame::Begin_Route( TRACK* track, wxDC* DC )
g_CurrentTrackSegment->Display_Infos( this );
SetCurItem( g_CurrentTrackSegment );
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
if( Drc_On && (Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 ) == BAD_DRC) )
if( Drc_On )
{
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track ) )
{
return g_CurrentTrackSegment;
}
}
}
else /* Track in progress : segment coordinates are updated by ShowNewTrackWhenMovingCursor*/
{
/* Tst for a D.R.C. error: */
if( Drc_On )
{
if( Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 ) == BAD_DRC )
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track ) )
return NULL;
if( g_TwoSegmentTrackBuild // We must handle 2 segments
&& g_CurrentTrackSegment->Back() )
{
if( Drc( this, DC, g_CurrentTrackSegment->Back(), m_Pcb->m_Track, 1 ) == BAD_DRC )
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), m_Pcb->m_Track ) )
return NULL;
}
}
......@@ -196,7 +200,7 @@ TRACK* WinEDA_PcbFrame::Begin_Route( TRACK* track, wxDC* DC )
if( g_Raccord_45_Auto )
{
if( Add_45_degrees_Segment( this, DC, g_CurrentTrackSegment ) != 0 )
if( Add_45_degrees_Segment( DC, g_CurrentTrackSegment ) != 0 )
g_TrackSegmentCount++;
}
Track = g_CurrentTrackSegment->Copy();
......@@ -229,7 +233,7 @@ TRACK* WinEDA_PcbFrame::Begin_Route( TRACK* track, wxDC* DC )
/**************************************************************************/
int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm )
int WinEDA_PcbFrame::Add_45_degrees_Segment( wxDC* DC, TRACK* pt_segm )
/***************************************************************************/
/* rectifie un virage a 90 et le modifie par 2 coudes a 45
......@@ -260,9 +264,9 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm
return 0;
}
pas_45 = frame->GetScreen()->GetGrid().x / 2;
pas_45 = GetScreen()->GetGrid().x / 2;
if( pas_45 < pt_segm->m_Width )
pas_45 = frame->GetScreen()->GetGrid().x;
pas_45 = GetScreen()->GetGrid().x;
while( pas_45 < pt_segm->m_Width )
pas_45 *= 2;
......@@ -309,7 +313,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm
else
NewTrack->m_End.x -= pas_45;
if( Drc_On && (Drc( frame, DC, pt_segm, frame->m_Pcb->m_Track, 1 ) == BAD_DRC) )
if( Drc_On && BAD_DRC==m_drc->Drc( pt_segm, m_Pcb->m_Track ) )
{
delete NewTrack;
return 0;
......@@ -317,7 +321,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm
Previous->m_End = NewTrack->m_Start;
pt_segm->m_Start = NewTrack->m_End;
NewTrack->Insert( frame->m_Pcb, Previous );
NewTrack->Insert( m_Pcb, Previous );
return 1;
}
......@@ -345,7 +349,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm
else
NewTrack->m_End.y -= pas_45;
if( Drc_On && (Drc( frame, DC, NewTrack, frame->m_Pcb->m_Track, 1 ) == BAD_DRC) )
if( Drc_On && BAD_DRC==m_drc->Drc( NewTrack, m_Pcb->m_Track ) )
{
delete NewTrack;
return 0;
......@@ -353,7 +357,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm
Previous->m_End = NewTrack->m_Start;
pt_segm->m_Start = NewTrack->m_End;
NewTrack->Insert( frame->m_Pcb, Previous );
NewTrack->Insert( m_Pcb, Previous );
return 1;
}
......@@ -378,7 +382,7 @@ void WinEDA_PcbFrame::End_Route( TRACK* track, wxDC* DC )
if( track == NULL )
return;
if( Drc_On && Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 )==BAD_DRC )
if( Drc_On && BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track) )
return;
/* Sauvegarde des coord du point terminal de la piste */
......
......@@ -75,7 +75,7 @@ void WinEDA_PcbFindFrame::FindItem( wxCommandEvent& event )
if( marker )
{
foundItem = marker;
locate_pos = marker->m_Pos;
locate_pos = marker->GetPosition();
}
}
else
......@@ -89,7 +89,7 @@ void WinEDA_PcbFindFrame::FindItem( wxCommandEvent& event )
if( StartCount > s_ItemCount )
{
foundItem = module;
locate_pos = module->m_Pos;
locate_pos = module->GetPosition();
s_ItemCount++;
break;
}
......
......@@ -351,5 +351,6 @@ void WinEDA_PcbFrame::Erase_Marqueurs()
{
m_Pcb->DeleteMARKERs();
GetScreen()->SetModify();
}
......@@ -783,14 +783,14 @@ bool WinEDA_PcbFrame::PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC )
// DRC control:
if( Drc_On )
{
errdrc = Drc( this, DC, Track, m_Pcb->m_Track, 1 );
errdrc = m_drc->Drc( Track, m_Pcb->m_Track );
if( errdrc == BAD_DRC )
return FALSE;
/* Redraw the dragged segments */
pt_drag = g_DragSegmentList;
for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext )
{
errdrc = Drc( this, DC, pt_drag->m_Segm, m_Pcb->m_Track, 1 );
errdrc = m_drc->Drc( pt_drag->m_Segm, m_Pcb->m_Track );
if( errdrc == BAD_DRC )
return FALSE;
}
......
......@@ -11,6 +11,7 @@
#include "bitmaps.h"
#include "protos.h"
#include "id.h"
#include "drc_stuff.h"
/*******************************/
......@@ -192,6 +193,8 @@ WinEDA_PcbFrame::WinEDA_PcbFrame( wxWindow* father, WinEDA_App* parent,
m_SelTrackWidthBox_Changed = FALSE;
m_SelViaSizeBox_Changed = FALSE;
m_drc = new DRC( this ); // these 2 objects point to each other
m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill;
m_DisplayPadFill = DisplayOpt.DisplayPadFill;
m_DisplayPadNum = DisplayOpt.DisplayPadNum;
......@@ -237,6 +240,7 @@ WinEDA_PcbFrame::~WinEDA_PcbFrame()
{
m_Parent->m_PcbFrame = NULL;
m_CurrentScreen = ScreenPcb;
delete m_drc;
}
......
......@@ -380,8 +380,8 @@ static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
int cY = (g_GridRoutingSize * row_source) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.y;
int dx = pt_cur_ch->pad_start->m_Size.x / 2;
int dy = pt_cur_ch->pad_start->m_Size.y / 2;
int px = pt_cur_ch->pad_start->m_Pos.x;
int py = pt_cur_ch->pad_start->m_Pos.y;
int px = pt_cur_ch->pad_start->GetPosition().x;
int py = pt_cur_ch->pad_start->GetPosition().y;
if( ( (pt_cur_ch->pad_start->m_Orient / 900) & 1 ) != 0 )
EXCHG( dx, dy );
......@@ -392,8 +392,8 @@ static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
cY = (g_GridRoutingSize * row_target) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.y;
dx = pt_cur_ch->pad_end->m_Size.x / 2;
dy = pt_cur_ch->pad_end->m_Size.y / 2;
px = pt_cur_ch->pad_end->m_Pos.x;
py = pt_cur_ch->pad_end->m_Pos.y;
px = pt_cur_ch->pad_end->GetPosition().x;
py = pt_cur_ch->pad_end->GetPosition().y;
if( ( (pt_cur_ch->pad_end->m_Orient / 900) & 1 ) != 0 )
EXCHG( dx, dy );
......@@ -968,14 +968,13 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,
/* Replacement sur le centre du pad si hors grille */
dx1 = g_CurrentTrackSegment->m_End.x - g_CurrentTrackSegment->m_Start.x;
dy1 = g_CurrentTrackSegment->m_End.y - g_CurrentTrackSegment->m_Start.y;
dx0 = pt_cur_ch->pad_end->m_Pos.x - g_CurrentTrackSegment->m_Start.x;
dy0 = pt_cur_ch->pad_end->m_Pos.y - g_CurrentTrackSegment->m_Start.y;
dx0 = pt_cur_ch->pad_end->GetPosition().x - g_CurrentTrackSegment->m_Start.x;
dy0 = pt_cur_ch->pad_end->GetPosition().y - g_CurrentTrackSegment->m_Start.y;
/* si aligne: modif du point origine */
if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) /* Alignes ! */
{
g_CurrentTrackSegment->m_Start.x = pt_cur_ch->pad_end->m_Pos.x;
g_CurrentTrackSegment->m_Start.y = pt_cur_ch->pad_end->m_Pos.y;
g_CurrentTrackSegment->m_Start = pt_cur_ch->pad_end->GetPosition();
}
else /* Creation d'un segment suppl raccord */
{
......@@ -983,10 +982,9 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,
g_TrackSegmentCount++;
NewTrack->Insert( pcb, g_CurrentTrackSegment );
g_CurrentTrackSegment->m_Start.x = pt_cur_ch->pad_end->m_Pos.x;
g_CurrentTrackSegment->m_Start.y = pt_cur_ch->pad_end->m_Pos.y;
NewTrack->m_Start.x = g_CurrentTrackSegment->m_End.x;
NewTrack->m_Start.y = g_CurrentTrackSegment->m_End.y;
g_CurrentTrackSegment->m_Start = pt_cur_ch->pad_end->GetPosition();
NewTrack->m_Start = g_CurrentTrackSegment->m_End;
g_CurrentTrackSegment = NewTrack;
}
......@@ -1053,26 +1051,25 @@ static void Place_Piste_en_Buffer( WinEDA_PcbFrame* pcbframe, wxDC* DC )
dy1 = g_CurrentTrackSegment->m_End.y - g_CurrentTrackSegment->m_Start.y;
/* Replacement sur le centre du pad si hors grille */
dx0 = pt_cur_ch->pad_start->m_Pos.x - g_CurrentTrackSegment->m_Start.x;
dy0 = pt_cur_ch->pad_start->m_Pos.y - g_CurrentTrackSegment->m_Start.y;
dx0 = pt_cur_ch->pad_start->GetPosition().x - g_CurrentTrackSegment->m_Start.x;
dy0 = pt_cur_ch->pad_start->GetPosition().y - g_CurrentTrackSegment->m_Start.y;
/* si aligne: modif du point origine */
if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) /* Alignes ! */
{
g_CurrentTrackSegment->m_End.x = pt_cur_ch->pad_start->m_Pos.x;
g_CurrentTrackSegment->m_End.y = pt_cur_ch->pad_start->m_Pos.y;
g_CurrentTrackSegment->m_End = pt_cur_ch->pad_start->GetPosition();
}
else /* Creation d'un segment suppl raccord */
{
TRACK* NewTrack = g_CurrentTrackSegment->Copy();
NewTrack->Insert( pcbframe->m_Pcb, g_CurrentTrackSegment );
NewTrack->m_End.x = pt_cur_ch->pad_start->m_Pos.x;
NewTrack->m_End.y = pt_cur_ch->pad_start->m_Pos.y;
NewTrack->m_Start.x = g_CurrentTrackSegment->m_End.x;
NewTrack->m_Start.y = g_CurrentTrackSegment->m_End.y;
NewTrack->m_End = pt_cur_ch->pad_start->GetPosition();
NewTrack->m_Start = g_CurrentTrackSegment->m_End;
g_CurrentTrackSegment = NewTrack; g_TrackSegmentCount++;
g_CurrentTrackSegment = NewTrack;
g_TrackSegmentCount++;
}
......
......@@ -40,7 +40,6 @@ static void Display_Zone_Netname( WinEDA_PcbFrame* frame );
static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC );
static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code );
static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer );
/* Local variables */
static bool Zone_Debug = FALSE;
......@@ -1037,7 +1036,7 @@ void WinEDA_PcbFrame::Fill_Zone( wxDC* DC )
/* Create the thermal reliefs */
g_DesignSettings.m_CurrentTrackWidth = lp_tmp;
if( Zone_Exclude_Pads && s_Zone_Create_Thermal_Relief )
Genere_Pad_Connexion( this, DC, GetScreen()->m_Active_Layer );
Genere_Pad_Connexion( DC, GetScreen()->m_Active_Layer );
g_DesignSettings.m_TrackClearence = save_isol;
......@@ -1313,7 +1312,7 @@ int Propagation( WinEDA_PcbFrame* frame )
/*****************************************************************************/
static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer )
bool WinEDA_PcbFrame::Genere_Pad_Connexion( wxDC* DC, int layer )
/*****************************************************************************/
/* Create the thermal relief for each pad in the zone:
......@@ -1329,16 +1328,16 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer )
int sommet[4][2];
wxString msg;
if( frame->m_Pcb->m_Zone == NULL )
if( m_Pcb->m_Zone == NULL )
return FALSE; /* error: no zone */
if( frame->m_Pcb->m_Zone->m_TimeStamp != s_TimeStamp ) /* error: this is not the new zone */
if( m_Pcb->m_Zone->m_TimeStamp != s_TimeStamp ) /* error: this is not the new zone */
return FALSE;
/* Count the pads, i.e. the thermal relief to create count, and displays it */
Affiche_1_Parametre( frame, 50, wxT( "NPads" ), wxT( " " ), CYAN );
pt_liste_pad = (LISTE_PAD*) frame->m_Pcb->m_Pads;
for( ii = 0, Npads = 0; ii < frame->m_Pcb->m_NbPads; ii++, pt_liste_pad++ )
Affiche_1_Parametre( this, 50, wxT( "NPads" ), wxT( " " ), CYAN );
pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads;
for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ )
{
pt_pad = *pt_liste_pad;
......@@ -1353,12 +1352,12 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer )
}
msg.Printf( wxT( "%d" ), Npads );
Affiche_1_Parametre( frame, -1, wxEmptyString, msg, CYAN );
Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN );
/* Create the thermal reliefs */
Affiche_1_Parametre( frame, 57, wxT( "Pads" ), wxT( " " ), CYAN );
pt_liste_pad = (LISTE_PAD*) frame->m_Pcb->m_Pads;
for( ii = 0, Npads = 0; ii < frame->m_Pcb->m_NbPads; ii++, pt_liste_pad++ )
Affiche_1_Parametre( this, 57, wxT( "Pads" ), wxT( " " ), CYAN );
pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads;
for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ )
{
pt_pad = *pt_liste_pad;
......@@ -1370,11 +1369,17 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer )
continue;
/* Create the theram relief for the current pad */
Npads++; msg.Printf( wxT( "%d" ), Npads );
Affiche_1_Parametre( frame, -1, wxEmptyString, msg, CYAN );
cX = pt_pad->m_Pos.x; cY = pt_pad->m_Pos.y;
Npads++;
msg.Printf( wxT( "%d" ), Npads );
Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN );
cX = pt_pad->GetPosition().x;
cY = pt_pad->GetPosition().y;
dx = pt_pad->m_Size.x / 2;
dy = pt_pad->m_Size.y / 2;
dx += g_DesignSettings.m_TrackClearence + g_GridRoutingSize;
dy += g_DesignSettings.m_TrackClearence + g_GridRoutingSize;
......@@ -1395,7 +1400,7 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer )
{
RotatePoint( &sommet[jj][0], &sommet[jj][1], angle );
pt_track = new SEGZONE( frame->m_Pcb );
pt_track = new SEGZONE( m_Pcb );
pt_track->SetLayer( layer );
pt_track->m_Width = g_DesignSettings.m_CurrentTrackWidth;
......@@ -1407,20 +1412,22 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer )
pt_track->m_TimeStamp = s_TimeStamp;
/* Test if the segment is allowed */
if( Drc( frame, DC, pt_track, frame->m_Pcb->m_Track, 0 ) == BAD_DRC )
if( BAD_DRC==m_drc->DrcBlind( pt_track, m_Pcb->m_Track ) )
{
delete pt_track; continue;
delete pt_track;
continue;
}
/* Search for a zone segment */
loctrack = Locate_Zone( frame->m_Pcb->m_Zone, pt_track->m_End, layer );
loctrack = Locate_Zone( m_Pcb->m_Zone, pt_track->m_End, layer );
if( (loctrack == NULL) || (loctrack->m_TimeStamp != s_TimeStamp) )
{
delete pt_track; continue;
delete pt_track;
continue;
}
pt_track->Insert( frame->m_Pcb, NULL );
pt_track->Draw( frame->DrawPanel, DC, GR_OR );
pt_track->Insert( m_Pcb, NULL );
pt_track->Draw( DrawPanel, DC, GR_OR );
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment