work in progress about ERC and markers in eeschema

This commit is contained in:
charras 2009-07-07 17:50:02 +00:00
parent 0d2ee0c023
commit 6d930edec3
20 changed files with 594 additions and 1001 deletions

View File

@ -4,71 +4,76 @@
**********************************************************************************/
/* file class_marker_base.cpp
*/
*/
#include "fctsys.h"
#include "gr_basic.h"
#include "class_base_screen.h"
#include "common.h"
#include "macros.h"
#include "class_drawpanel.h"
#include "class_marker_base.h"
/* Default bitmap shape for markers */
static char Default_MarkerBitmap[] =
// Default marquer shape:
#define M_SHAPE_SCALE 6 // default scaling factor for MarkerShapeCorners coordinates
#define CORNERS_COUNT 8
// corners of the default shape
static wxPoint MarkerShapeCorners[CORNERS_COUNT] =
{
12, 12, /* x and y size of the bitmap */
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* bitmap: 1 = color, 0 = notrace */
1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0,
1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
wxPoint( 0, 0 ),
wxPoint( 8, 1 ),
wxPoint( 4, 3 ),
wxPoint( 13, 8 ),
wxPoint( 9, 9 ),
wxPoint( 8, 13 ),
wxPoint( 3, 4 ),
wxPoint( 1, 8 )
};
/*******************/
/* Classe MARKER_BASE */
/*******************/
void MARKER_BASE::init()
{
m_Bitmap = NULL;
m_MarkerType = 0;
m_Color = RED;
m_Bitmap = Default_MarkerBitmap;
m_Size.x = Default_MarkerBitmap[0];
m_Size.y = Default_MarkerBitmap[1];
m_MarkerType = 0;
m_Color = RED;
for( unsigned ii = 0; ii < CORNERS_COUNT; ii++ )
{
wxPoint corner = MarkerShapeCorners[ii];
m_Corners.push_back( corner );
m_Size.x = MAX( m_Size.x, corner.x);
m_Size.y = MAX( m_Size.y, corner.y);
}
}
MARKER_BASE::MARKER_BASE( )
MARKER_BASE::MARKER_BASE()
{
m_ScalingFactor = M_SHAPE_SCALE;
init();
}
MARKER_BASE::MARKER_BASE( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos )
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos )
{
m_ScalingFactor = M_SHAPE_SCALE;
init();
SetData( aErrorCode,aMarkerPos,
aText, aPos,
bText, bPos );
SetData( aErrorCode, aMarkerPos,
aText, aPos,
bText, bPos );
}
MARKER_BASE::MARKER_BASE( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos )
{
init();
MARKER_BASE::MARKER_BASE( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos )
{
m_ScalingFactor = M_SHAPE_SCALE;
init();
SetData( aErrorCode, aMarkerPos, aText, aPos );
}
@ -80,96 +85,70 @@ MARKER_BASE::~MARKER_BASE()
void MARKER_BASE::SetData( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos )
const wxString& aText, const wxPoint& aPos,
const wxString& bText, const wxPoint& bPos )
{
m_Pos = aMarkerPos;
m_drc.SetData( aErrorCode,
aText, bText, aPos, bPos );
// @todo: switch on error code to set error code specific color, and possibly bitmap.
m_Color = WHITE;
aText, bText, aPos, bPos );
}
void MARKER_BASE::SetData( int aErrorCode, const wxPoint& aMarkerPos,
const wxString& aText, const wxPoint& aPos )
const wxString& aText, const wxPoint& aPos )
{
m_Pos = aMarkerPos;
m_drc.SetData( aErrorCode,
aText, aPos );
// @todo: switch on error code to set error code specific color, and possibly bitmap.
m_Color = WHITE;
aText, aPos );
}
/**********************************************/
bool MARKER_BASE::HitTestMarker( const wxPoint& refPos )
/**********************************************/
{
// the MARKER_BASE is 12 pixels by 12 pixels, but is not resized with zoom, so
// as zoom changes, the effective real size (in user units) of the MARKER_BASE changes.
int dx = refPos.x - m_Pos.x;
int dy = refPos.y - m_Pos.y;
wxSize TrueSize = m_Size;
if ( ActiveScreen )
{
ActiveScreen->Unscale( TrueSize );
}
wxPoint pos = m_Pos;
int dx = refPos.x - pos.x;
int dy = refPos.y - pos.y;
wxSize Realsize = m_Size;
Realsize.x *= m_ScalingFactor;
Realsize.y *= m_ScalingFactor;
/* is refPos in the box: Marker size to right an bottom,
or size/2 to left or top */
if( dx <= TrueSize.x && dy <= TrueSize.y &&
dx >= -TrueSize.x/2 && dy >= -TrueSize.y/2 )
* or size/2 to left or top */
if( dx <= Realsize.x && dy <= Realsize.y
&& dx >= -Realsize.x / 2 && dy >= -Realsize.y / 2 )
return true;
else
return false;
}
/**********************************************************************/
void MARKER_BASE::DrawMarker( WinEDA_DrawPanel* panel, wxDC* DC, int DrawMode,
const wxPoint& offset )
void MARKER_BASE::DrawMarker( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
const wxPoint& aOffset )
/**********************************************************************/
/*
* Trace un repere sur l'ecran au point de coordonnees PCB pos
* Le marqueur est defini par un tableau de 2 + (lig*col) elements:
* 1er element: dim nbre ligne
* 2er element: dim nbre col
* suite: lig * col elements a 0 ou 1 : si 1 mise a color du pixel
/** Function DrawMarker
* The shape is the polygon defined in m_Corners (array of wxPoints)
*/
{
int ii, jj;
char* pt_bitmap = m_Bitmap;
wxPoint corners[CORNERS_COUNT];
if( pt_bitmap == NULL ) return;
GRSetDrawMode( aDC, aDrawMode );
GRSetDrawMode( DC, DrawMode );
wxPoint pos = m_Pos;
pos.x = GRMapX( pos.x );
pos.y = GRMapY( pos.y );
/* Get the bitmap size */
m_Size.x = *(pt_bitmap++);
m_Size.y = *(pt_bitmap++);
/* Draw the bitmap */
for( ii = 0; ii < m_Size.x; ii++ )
for( unsigned ii = 0; ii < m_Corners.size(); ii++ )
{
for( jj = 0; jj < m_Size.y; jj++, pt_bitmap++ )
{
if( *pt_bitmap )
GRSPutPixel( &panel->m_ClipBox, DC,
pos.x + ii, pos.y + jj, m_Color );
}
corners[ii] = m_Corners[ii];
corners[ii].x *= m_ScalingFactor;
corners[ii].y *= m_ScalingFactor;
corners[ii] += m_Pos + aOffset;
}
GRClosedPoly( &aPanel->m_ClipBox, aDC, CORNERS_COUNT, corners,
true, // = Filled
0, // outline width
m_Color, // outline color
m_Color // fill collor
);
}

View File

@ -5,7 +5,6 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
)
set(EESCHEMA_SRCS
# affiche.cpp
annotate.cpp
annotate_dialog.cpp
backanno.cpp
@ -21,6 +20,7 @@ set(EESCHEMA_SRCS
class_libentry.cpp
class_libentry_fields.cpp
class_library.cpp
class_marker_sch.cpp
class_pin.cpp
class_sch_cmp_field.cpp
class_schematic_items.cpp
@ -62,7 +62,6 @@ set(EESCHEMA_SRCS
edit_component_in_schematic.cpp
edit_label.cpp
eeconfig.cpp
# eecreate.cpp
eelayer.cpp
eelibs_draw_components.cpp
eelibs_read_libraryfiles.cpp

View File

@ -16,6 +16,7 @@
#include "libcmp.h"
#include "general.h"
#include "protos.h"
#include "class_marker_sch.h"
/* Variables Locales */

View File

@ -0,0 +1,127 @@
/***********************************************************************/
/* Methodes de base de gestion des classes des elements de schematique */
/***********************************************************************/
#include "fctsys.h"
#include "class_drawpanel.h"
#include "common.h"
#include "program.h"
#include "general.h"
#include "class_marker_sch.h"
#include "erc.h"
/* Marker are mainly used to show an ERC error
* but they could be used to give a specifi info
*/
const wxChar* NameMarqueurType[] =
{
wxT( "" ),
wxT( "ERC" ),
wxT( "PCB" ),
wxT( "SIMUL" ),
wxT( "?????" )
};
/**************************/
/* class MARKER_SCH */
/**************************/
MARKER_SCH::MARKER_SCH( ) :
SCH_ITEM( NULL, DRAW_MARKER_STRUCT_TYPE ),
MARKER_BASE( )
{
}
MARKER_SCH::MARKER_SCH( const wxPoint& pos, const wxString& text ) :
SCH_ITEM( NULL, DRAW_MARKER_STRUCT_TYPE ),
MARKER_BASE(0, pos, text, pos)
{
}
MARKER_SCH::~MARKER_SCH()
{
}
MARKER_SCH* MARKER_SCH::GenCopy()
{
MARKER_SCH* newitem = new MARKER_SCH( GetPos(), GetErrorText() );
newitem->SetMarkerType( GetMarkerType());
newitem->SetErrorLevel( GetErrorLevel());
return newitem;
}
#if defined(DEBUG)
/**
* Function Show
* is used to output the object tree, currently for debugging only.
* @param nestLevel An aid to prettier tree indenting, and is the level
* of nesting of this object within the overall tree.
* @param os The ostream& to output to.
*/
void MARKER_SCH::Show( int nestLevel, std::ostream& os )
{
// for now, make it look like XML:
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << GetPos()
<< "/>\n";
}
#endif
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool MARKER_SCH::Save( FILE* aFile ) const
{
bool success = true;
wxString msg = GetErrorText();
if( fprintf( aFile, "Kmarq %c %-4d %-4d \"%s\" F=%X\n",
GetMarkerType() + 'A', GetPos().x, GetPos().y,
CONV_TO_UTF8( msg ), GetErrorLevel() ) == EOF )
{
success = false;
}
return success;
}
/****************************************************************************/
void MARKER_SCH::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aDrawMode, int aColor )
/****************************************************************************/
{
EDA_Colors color = (EDA_Colors) m_Color;
EDA_Colors tmp = color;
if( GetMarkerType() == MARK_ERC )
{
color = (GetErrorLevel() == WAR ) ?
(EDA_Colors)g_LayerDescr.LayerColor[LAYER_ERC_WARN] :
(EDA_Colors)g_LayerDescr.LayerColor[LAYER_ERC_ERR];
}
if ( aColor < 0 )
m_Color = color;
else
m_Color = (EDA_Colors) aColor;
DrawMarker( aPanel, aDC, aDrawMode, aOffset );
m_Color = tmp;
}

View File

@ -0,0 +1,84 @@
/***************************************************/
/* classes to handle markers used in schematic ... */
/***************************************************/
#ifndef _CLASS_MARKER_SCH_H_
#define _CLASS_MARKER_SCH_H_
#include "class_marker_base.h"
/* Marker are mainly used to show an ERC error
*/
enum TypeMarker { /* Markers type */
MARK_UNSPEC,
MARK_ERC,
MARK_PCB,
MARK_SIMUL,
MARK_NMAX /* Lats value: end of list */
};
/* Names for corresponding types of markers: */
extern const wxChar* NameMarqueurType[];
class MARKER_SCH : public SCH_ITEM , public MARKER_BASE
{
public:
MARKER_SCH( );
MARKER_SCH( const wxPoint& aPos, const wxString& aText );
~MARKER_SCH();
virtual wxString GetClass() const
{
return wxT( "MARKER_SCH" );
}
MARKER_SCH* GenCopy();
virtual void Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
const wxPoint& aOffset, int aDraw_mode,
int aColor = -1 );
wxString GetErrorText( ) const
{
wxString text = m_drc.GetMainText();
return text;
}
void SetErrorText( wxString aText)
{
SetData( m_drc.GetErrorCode(), GetPos(), aText, GetPos() );
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.sch"
* format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/** Function GetPenSize
* @return the size of the "pen" that be used to draw or plot this item
* for a marker, has no meaning, but it is necessary to satisfy the SCH_ITEM class requirements
*/
virtual int GetPenSize( ) { return 0; };
/** Function HitTest
* @return true if the point aPosRef is within item area
* @param aPosRef = a wxPoint to test
*/
bool HitTest( const wxPoint& aPosRef )
{
return HitTestMarker( aPosRef );
}
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os );
#endif
};
#endif /* _CLASS_MARKER_SCH_H_ */

View File

@ -10,7 +10,6 @@
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "id.h"
#include "protos.h"
@ -23,16 +22,6 @@
/* class DrawBusEntryStruct */
/***************************/
const wxChar* NameMarqueurType[] =
{
wxT( "" ),
wxT( "ERC" ),
wxT( "PCB" ),
wxT( "SIMUL" ),
wxT( "?????" )
};
DrawBusEntryStruct::DrawBusEntryStruct( const wxPoint& pos, int shape, int id ) :
SCH_ITEM( NULL, DRAW_BUSENTRY_STRUCT_TYPE )
{
@ -362,94 +351,6 @@ void DrawNoConnectStruct::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
}
/**************************/
/* class MARKER_SCH */
/**************************/
MARKER_SCH::MARKER_SCH( const wxPoint& pos, const wxString& text ) :
SCH_ITEM( NULL, DRAW_MARKER_STRUCT_TYPE ),
MARKER_BASE(0, pos, text, pos)
{
}
MARKER_SCH::~MARKER_SCH()
{
}
MARKER_SCH* MARKER_SCH::GenCopy()
{
MARKER_SCH* newitem = new MARKER_SCH( GetPos(), GetErrorText() );
newitem->SetMarkerType( GetMarkerType());
newitem->SetErrorLevel( GetErrorLevel());
return newitem;
}
#if defined(DEBUG)
/**
* Function Show
* is used to output the object tree, currently for debugging only.
* @param nestLevel An aid to prettier tree indenting, and is the level
* of nesting of this object within the overall tree.
* @param os The ostream& to output to.
*/
void MARKER_SCH::Show( int nestLevel, std::ostream& os )
{
// for now, make it look like XML:
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << GetPos()
<< "/>\n";
}
#endif
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool MARKER_SCH::Save( FILE* aFile ) const
{
bool success = true;
wxString msg = GetErrorText();
if( fprintf( aFile, "Kmarq %c %-4d %-4d \"%s\" F=%X\n",
GetMarkerType() + 'A', GetPos().x, GetPos().y,
CONV_TO_UTF8( msg ), GetErrorLevel() ) == EOF )
{
success = false;
}
return success;
}
void MARKER_SCH::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int DrawMode, int Color )
{
#define WAR 1 // see erc.cpp
if( GetMarkerType() == MARQ_ERC )
{
if( Color <= 0 )
{
Color = (GetErrorLevel() == WAR ) ?
g_LayerDescr.LayerColor[LAYER_ERC_WARN] :
g_LayerDescr.LayerColor[LAYER_ERC_ERR];
}
}
m_Color = Color;
DrawMarker( panel, DC, DrawMode, offset );
}
/***************************/
/* Class EDA_DrawLineStruct */
/***************************/

View File

@ -5,8 +5,6 @@
#ifndef CLASS_SCHEMATIC_ITEMS_H
#define CLASS_SCHEMATIC_ITEMS_H
#include "class_marker_base.h"
#define DRAWJUNCTION_DIAMETER 32 /* Size (diameter) of junctions between wires */
#define DRAWNOCONNECT_SIZE 48 /* Rayon du symbole No Connexion */
@ -15,19 +13,6 @@
#define BUS_TO_BUS 1
enum TypeMarker { /* Type des Marqueurs */
MARQ_UNSPEC,
MARQ_ERC,
MARQ_PCB,
MARQ_SIMUL,
MARQ_NMAX /* Derniere valeur: fin de tableau */
};
/* Messages correspondants aux types des marqueurs */
extern const wxChar* NameMarqueurType[];
/**
* Class EDA_DrawLineStruct
* is a segment decription base class to describe items which have 2 end
@ -90,63 +75,6 @@ public:
};
class MARKER_SCH : public SCH_ITEM , public MARKER_BASE
{
public:
MARKER_SCH( const wxPoint& aPos, const wxString& aText );
~MARKER_SCH();
virtual wxString GetClass() const
{
return wxT( "MARKER_SCH" );
}
MARKER_SCH* GenCopy();
virtual void Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int draw_mode,
int Color = -1 );
wxString GetErrorText( ) const
{
wxString text = m_drc.GetMainText();
return text;
}
void SetErrorText( wxString aText)
{
SetData( m_drc.GetErrorCode(), GetPos(), aText, GetPos() );
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.sch"
* format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/** Function GetPenSize
* @return the size of the "pen" that be used to draw or plot this item
* for a marker, has no meaning, but it is necessary to satisfy the SCH_ITEM class requirements
*/
virtual int GetPenSize( ) { return 0; };
/** Function HitTest
* @return true if the point aPosRef is within item area
* @param aPosRef = a wxPoint to test
*/
bool HitTest( const wxPoint& aPosRef )
{
return HitTestMarker( aPosRef );
}
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os );
#endif
};
class DrawNoConnectStruct : public SCH_ITEM /* Symboles de non connexion */
{
public:

View File

@ -14,6 +14,8 @@
#include "general.h"
#include "protos.h"
#include "class_marker_sch.h"
/**************************************************************************************/
SCH_ITEM* WinEDA_SchematicFrame:: SchematicGeneralLocateAndDisplay( bool IncludePin )
/**************************************************************************************/

View File

@ -11,6 +11,7 @@
#include "libcmp.h"
#include "general.h"
#include "protos.h"
#include "class_marker_sch.h"
/********************************************************************************/

View File

@ -15,10 +15,12 @@
#include "general.h"
#include "netlist.h"
#include "bitmaps.h"
#include "class_marker_sch.h"
#include "protos.h"
#include "dialog_erc.h"
#include "erc.h"
BEGIN_EVENT_TABLE( DIALOG_ERC, DIALOG_ERC_BASE )
@ -71,7 +73,7 @@ void DIALOG_ERC::OnEraseDrcMarkersClick( wxCommandEvent& event )
/* Delete the old ERC markers, over the whole hierarchy
*/
{
DeleteAllMarkers( MARQ_ERC );
DeleteAllMarkers( MARK_ERC );
m_MessagesList->Clear();
m_Parent->DrawPanel->Refresh();
}
@ -216,3 +218,99 @@ void DIALOG_ERC::ReBuildMatrixPanel()
m_Initialized = TRUE;
}
/** Function DisplayERC_MarkersList
* read the schematic and display the list of ERC markers
*/
void DIALOG_ERC::DisplayERC_MarkersList()
{
EDA_SheetList SheetList;
for( DrawSheetPath* Sheet = SheetList.GetFirst(); Sheet != NULL; Sheet = SheetList.GetNext() )
{
SCH_ITEM* DrawStruct = Sheet->LastDrawList();
for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
{
if( DrawStruct->Type() != DRAW_MARKER_STRUCT_TYPE )
continue;
/* Marqueur trouve */
MARKER_SCH* Marker = (MARKER_SCH*) DrawStruct;
if( Marker->GetMarkerType() != MARK_ERC )
continue;
/* Display diag */
wxString msg;
msg.Printf( _( "sheet %s (loc X=%f" ", Y=%f" "): %s\n" ),
Sheet->PathHumanReadable().GetData(),
(float) Marker->m_Pos.x / 1000, (float) Marker->m_Pos.y / 1000,
Marker->GetErrorText().GetData() );
m_MessagesList->AppendText( msg );
}
}
}
/**************************************************************/
void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event )
/**************************************************************/
/* Remet aux valeurs par defaut la matrice de diagnostic
*/
{
memcpy( DiagErc, DefaultDiagErc, sizeof(DiagErc) );
ReBuildMatrixPanel();
}
/************************************************************/
void DIALOG_ERC::ChangeErrorLevel( wxCommandEvent& event )
/************************************************************/
/* Change the error level for the pressed button, on the matrix table
*/
{
int id, level, ii, x, y;
wxBitmapButton* Butt;
const char** new_bitmap_xpm = NULL;
wxPoint pos;
id = event.GetId();
ii = id - ID_MATRIX_0;
Butt = (wxBitmapButton*) event.GetEventObject();
pos = Butt->GetPosition();
x = ii / PIN_NMAX; y = ii % PIN_NMAX;
level = DiagErc[y][x];
switch( level )
{
case OK:
level = WAR;
new_bitmap_xpm = warning_xpm;
break;
case WAR:
level = ERR;
new_bitmap_xpm = error_xpm;
break;
case ERR:
level = OK;
new_bitmap_xpm = erc_green_xpm;
break;
}
if( new_bitmap_xpm )
{
delete Butt;
Butt = new wxBitmapButton( m_PanelERCOptions, id,
wxBitmap( new_bitmap_xpm ), pos );
m_ButtonList[y][x] = Butt;
DiagErc[y][x] = DiagErc[x][y] = level;
}
}

View File

@ -20,12 +20,6 @@ extern const wxChar* CommentERC_V[];
/* Control identifiers */
#define ID_MATRIX_0 1800
#define OK 0
#define WAR 1
#define ERR 2
#define UNC 3
/*!
* DIALOG_ERC class declaration
*/

View File

@ -1,546 +0,0 @@
/*********************************************************/
/* Modules de creations de Traits, Wires, Bus, Junctions */
/*********************************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "confirm.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "protos.h"
/* Routines Locales */
static void Polyline_in_Ghost( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void Segment_in_Ghost( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void ExitTrace( WinEDA_DrawFrame* frame, wxDC* DC );
static bool IsTerminalPoint( SCH_SCREEN* screen, const wxPoint& pos, int layer );
/*************************************************************/
void WinEDA_SchematicFrame::BeginSegment( wxDC* DC, int type )
/*************************************************************/
/* Routine de Trace de segments ( WIRES, BUS ) pour lesquels chaque segment
* est une structure.
*/
// NOT USED!!!@!@!
{
DrawSegmentStruct* oldsegment, * newsegment;
wxPoint pos = GetScreen()->m_Curseur;
if( GetScreen()->GetCurItem()
&& (GetScreen()->GetCurItem()->m_Flags == 0) )
GetScreen()->SetCurItem( NULL );
if( GetScreen()->GetCurItem() )
{
switch( GetScreen()->GetCurItem()->Type() )
{
case DRAW_SEGMENT_STRUCT_TYPE:
case DRAW_POLYLINE_STRUCT_TYPE:
break;
default:
return;
}
}
oldsegment = newsegment =
(DrawSegmentStruct*) GetScreen()->GetCurItem();
if( !newsegment ) /* 1er point : creation de la 1ere structure */
{
switch( type )
{
default:
newsegment = new DrawSegmentStruct( pos, LAYER_NOTES );
break;
case LAYER_WIRE:
newsegment = new DrawSegmentStruct( pos, LAYER_WIRE );
if( LocatePinEnd( GetScreen()->EEDrawList, pos ) )
newsegment->m_StartIsDangling = FALSE;
break;
case LAYER_BUS:
newsegment = new DrawSegmentStruct( pos, LAYER_BUS );
break;
}
newsegment->m_Flags = IS_NEW;
GetScreen()->SetCurItem( newsegment );
GetScreen()->ManageCurseur = Segment_in_Ghost;
GetScreen()->ForceCloseManageCurseur = ExitTrace;
g_ItemToRepeat = NULL;
}
else /* Trace en cours: Placement d'un point supplementaire */
{
if( (oldsegment->m_Start.x == oldsegment->m_End.x)
&& (oldsegment->m_Start.y == oldsegment->m_End.y) ) /* Structure inutile */
return;
GetScreen()->ManageCurseur( DrawPanel, DC, FALSE );
oldsegment->m_EndIsDangling = FALSE;
/* Creation du segment suivant ou fin de trac<61> si point sur pin, jonction ...*/
if( IsTerminalPoint( GetScreen(), oldsegment->m_End, oldsegment->m_Layer ) )
{
EndSegment( DC ); return;
}
/* Placement en liste generale */
oldsegment->Pnext = GetScreen()->EEDrawList;
g_ItemToRepeat = GetScreen()->EEDrawList = oldsegment;
GetScreen()->CursorOff( DrawPanel, DC ); // Erase schematic cursor
RedrawOneStruct( DrawPanel, DC, oldsegment, GR_DEFAULT_DRAWMODE );
GetScreen()->CursorOn( DrawPanel, DC ); // Display schematic cursor
/* Creation du segment suivant */
newsegment = oldsegment->GenCopy();
newsegment->m_Start = oldsegment->m_End;
newsegment->m_End = pos;
oldsegment->m_Flags = 0;
newsegment->m_Flags = IS_NEW;
GetScreen()->SetCurItem( newsegment );
GetScreen()->ManageCurseur( DrawPanel, DC, FALSE );
newsegment->m_StartIsDangling = FALSE;
newsegment->m_EndIsDangling = TRUE;
}
}
/*************************************************************/
/* Routine de fin de trace d'une struct segment (Wire, Bus */
/*************************************************************/
void WinEDA_SchematicFrame::EndSegment( wxDC* DC )
{
DrawSegmentStruct* segment = (DrawSegmentStruct*) GetScreen()->GetCurItem();
if( GetScreen()->ManageCurseur == NULL )
return;
if( segment == NULL )
return;
if( (segment->m_Flags & IS_NEW) == 0 )
return;
if( (segment->m_Start.x == segment->m_End.x)
&& (segment->m_Start.y == segment->m_End.y) )/* Structure inutile */
{
EraseStruct( segment, (SCH_SCREEN*) GetScreen() );
segment = NULL;
}
else
{
/* Placement en liste generale */
GetScreen()->ManageCurseur( DrawPanel, DC, FALSE );
segment->Pnext = GetScreen()->EEDrawList;
g_ItemToRepeat = GetScreen()->EEDrawList = segment;
segment->m_Flags = 0;
}
/* Fin de trace */
GetScreen()->ManageCurseur = NULL;
GetScreen()->ForceCloseManageCurseur = NULL;
GetScreen()->SetCurItem( NULL );
TestDanglingEnds( GetScreen()->EEDrawList, DC );
SetFlagModify( GetScreen() );
if( segment )
{
GetScreen()->CursorOff( DrawPanel, DC ); // Erase schematic cursor
RedrawOneStruct( DrawPanel, DC, segment, GR_DEFAULT_DRAWMODE );
GetScreen()->CursorOn( DrawPanel, DC ); // Display schematic cursor
}
}
/****************************************************************************/
static void Segment_in_Ghost( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
/****************************************************************************/
/* Dessin du Segment Fantome lors des deplacements du curseur
*/
{
DrawSegmentStruct* segment =
(DrawSegmentStruct*) panel->m_Parent->GetScreen()->GetCurItem();
wxPoint endpos;
int color;
if( segment == NULL )
return;
color = ReturnLayerColor( segment->m_Layer ) ^ HIGHT_LIGHT_FLAG;
endpos = panel->m_Parent->GetScreen()->m_Curseur;
if( g_HVLines ) /* Coerce the line to vertical or horizontal one: */
{
if( ABS( endpos.x - segment->m_Start.x ) < ABS( endpos.y - segment->m_Start.y ) )
endpos.x = segment->m_Start.x;
else
endpos.y = segment->m_Start.y;
}
if( erase ) // Redraw if segment lengtht != 0
{
if( (segment->m_Start.x != segment->m_End.x)
|| (segment->m_Start.y != segment->m_End.y) )
RedrawOneStruct( panel, DC, segment, XOR_MODE, color );
}
segment->m_End = endpos;
// Redraw if segment lengtht != 0
if( (segment->m_Start.x != segment->m_End.x)
|| (segment->m_Start.y != segment->m_End.y) )
RedrawOneStruct( panel, DC, segment, XOR_MODE, color );
}
/*****************************************************************************/
static void Polyline_in_Ghost( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
/*****************************************************************************/
/* Dessin du du Polyline Fantome lors des deplacements du curseur
*/
{
DrawPolylineStruct* NewPoly =
(DrawPolylineStruct*) panel->m_Parent->GetScreen()->GetCurItem();
int color;
wxPoint endpos;
endpos = panel->m_Parent->GetScreen()->m_Curseur;
color = ReturnLayerColor( NewPoly->m_Layer );
GRSetDrawMode( DC, XOR_MODE );
if( g_HVLines )
{
/* Coerce the line to vertical or horizontal one: */
if( ABS( endpos.x - NewPoly->m_Points[NewPoly->m_NumOfPoints * 2 - 2] ) <
ABS( endpos.y - NewPoly->m_Points[NewPoly->m_NumOfPoints * 2 - 1] ) )
endpos.x = NewPoly->m_Points[NewPoly->m_NumOfPoints * 2 - 2];
else
endpos.y = NewPoly->m_Points[NewPoly->m_NumOfPoints * 2 - 1];
}
NewPoly->m_NumOfPoints++;
if( erase )
RedrawOneStruct( panel, DC, NewPoly, XOR_MODE, color );
NewPoly->m_Points[NewPoly->m_NumOfPoints * 2 - 2] = endpos.x;
NewPoly->m_Points[NewPoly->m_NumOfPoints * 2 - 1] = endpos.y;
RedrawOneStruct( panel, DC, NewPoly, XOR_MODE, color );
NewPoly->m_NumOfPoints--;
}
/**********************************************************/
void WinEDA_SchematicFrame::DeleteCurrentSegment( wxDC* DC )
/**********************************************************/
/*
* Routine effacant le dernier trait trace, ou l'element pointe par la souris
*/
{
g_ItemToRepeat = NULL;
if( (GetScreen()->GetCurItem() == NULL)
|| ( (GetScreen()->GetCurItem()->m_Flags & IS_NEW) == 0 ) )
{
return;
}
/* Trace en cours: annulation */
if( GetScreen()->GetCurItem()->Type() == DRAW_POLYLINE_STRUCT_TYPE )
{
Polyline_in_Ghost( DrawPanel, DC, FALSE ); /* Effacement du trace en cours */
}
else
{
Segment_in_Ghost( DrawPanel, DC, FALSE ); /* Effacement du trace en cours */
}
EraseStruct( GetScreen()->GetCurItem(), GetScreen() );
GetScreen()->ManageCurseur = NULL;
GetScreen()->SetCurItem( NULL );
}
/***************************************************************************/
EDA_BaseStruct* WinEDA_SchematicFrame::CreateNewJunctionStruct( wxDC* DC )
/***************************************************************************/
/* Routine to create new connection struct.
*/
{
DrawJunctionStruct* NewConnect;
NewConnect = new DrawJunctionStruct( GetScreen()->m_Curseur );
g_ItemToRepeat = NewConnect;
GetScreen()->CursorOff( DrawPanel, DC ); // Erase schematic cursor
RedrawOneStruct( DrawPanel, DC, NewConnect, GR_DEFAULT_DRAWMODE );
GetScreen()->CursorOn( DrawPanel, DC ); // Display schematic cursor
NewConnect->Pnext = GetScreen()->EEDrawList;
GetScreen()->EEDrawList = NewConnect;
SetFlagModify( GetScreen() );
return NewConnect;
}
/*********************************************************************************/
DrawNoConnectStruct * WinEDA_SchematicFrame::CreateNewNoConnectStruct( wxDC* DC )
/*********************************************************************************/
/*Routine to create new NoConnect struct. ( Symbole de Non Connexion)
*/
{
DrawNoConnectStruct* NewNoConnect;
NewNoConnect = new DrawNoConnectStruct( GetScreen()->m_Curseur );
g_ItemToRepeat = NewNoConnect;
GetScreen()->CursorOff( DrawPanel, DC ); // Erase schematic cursor
RedrawOneStruct( DrawPanel, DC, NewNoConnect, GR_DEFAULT_DRAWMODE );
GetScreen()->CursorOn( DrawPanel, DC ); // Display schematic cursor
NewNoConnect->Pnext = GetScreen()->EEDrawList;
GetScreen()->EEDrawList = NewNoConnect;
SetFlagModify( GetScreen() );
return NewNoConnect;
}
/**********************************************************/
static void ExitTrace( WinEDA_DrawFrame* frame, wxDC* DC )
/**********************************************************/
/* Routine de sortie des menus de trace */
{
BASE_SCREEN* Screen = frame->GetScreen();
if( Screen->GetCurItem() ) /* trace en cours */
{
Screen->ManageCurseur( frame->DrawPanel, DC, FALSE );
Screen->ManageCurseur = NULL;
Screen->ForceCloseManageCurseur = NULL;
EraseStruct( Screen->GetCurItem(), (SCH_SCREEN*) Screen );
Screen->SetCurItem( NULL );
return;
}
else
g_ItemToRepeat = NULL; // Fin de commande generale
}
/***************************************************/
void WinEDA_SchematicFrame::RepeatDrawItem( wxDC* DC )
/***************************************************/
/* Routine de recopie du dernier element dessine
* Les elements duplicables sont
* fils, bus, traits, textes, labels
* Les labels termines par un nombre seront incrementes
*/
{
char Line[256];
int ox = 0, oy = 0;
if( g_ItemToRepeat == NULL )
return;
switch( g_ItemToRepeat->Type() )
{
case DRAW_JUNCTION_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawJunctionStruct*) g_ItemToRepeat )
g_ItemToRepeat = STRUCT->GenCopy();
STRUCT->m_Pos.x += g_RepeatStep.x; ox = STRUCT->m_Pos.x;
STRUCT->m_Pos.y += g_RepeatStep.y; oy = STRUCT->m_Pos.y;
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawNoConnectStruct*) g_ItemToRepeat )
g_ItemToRepeat = STRUCT->GenCopy();
STRUCT->m_Pos.x += g_RepeatStep.x; ox = STRUCT->m_Pos.x;
STRUCT->m_Pos.y += g_RepeatStep.y; oy = STRUCT->m_Pos.y;
break;
case TYPE_SCH_TEXT:
#undef STRUCT
#define STRUCT ( (SCH_TEXT*) g_ItemToRepeat )
g_ItemToRepeat = STRUCT->GenCopy();
STRUCT->m_Pos.x += g_RepeatStep.x; ox = STRUCT->m_Pos.x;
STRUCT->m_Pos.y += g_RepeatStep.y; oy = STRUCT->m_Pos.y;
/*** Increment du numero de label ***/
strcpy( Line, STRUCT->GetText() );
IncrementLabelMember( Line );
STRUCT->m_Text = Line;
break;
case TYPE_SCH_LABEL:
case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL:
#undef STRUCT
#define STRUCT ( (SCH_LABEL*) g_ItemToRepeat )
g_ItemToRepeat = STRUCT->GenCopy();
STRUCT->m_Pos.x += g_RepeatStep.x; ox = STRUCT->m_Pos.x;
STRUCT->m_Pos.y += g_RepeatStep.y; oy = STRUCT->m_Pos.y;
/*** Increment du numero de label ***/
strcpy( Line, STRUCT->GetText() );
IncrementLabelMember( Line );
STRUCT->m_Text = Line;
break;
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawSegmentStruct*) g_ItemToRepeat )
g_ItemToRepeat = STRUCT->GenCopy();
STRUCT->m_Start.x += g_RepeatStep.x; ox = STRUCT->m_Start.x;
STRUCT->m_Start.y += g_RepeatStep.y; oy = STRUCT->m_Start.y;
STRUCT->m_End.x += g_RepeatStep.x;
STRUCT->m_End.y += g_RepeatStep.y;
break;
case DRAW_RACCORD_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawRaccordStruct*) g_ItemToRepeat )
g_ItemToRepeat = STRUCT->GenCopy();
STRUCT->m_Pos.x += g_RepeatStep.x; ox = STRUCT->m_Pos.x;
STRUCT->m_Pos.y += g_RepeatStep.y; oy = STRUCT->m_Pos.y;
break;
default:
g_ItemToRepeat = NULL;
DisplayError( this, "Repeat Type Error", 10 );
break;
}
if( g_ItemToRepeat )
{
g_ItemToRepeat->Pnext = GetScreen()->EEDrawList;
GetScreen()->EEDrawList = g_ItemToRepeat;
TestDanglingEnds( GetScreen()->EEDrawList, NULL );
RedrawOneStruct( DrawPanel, DC, g_ItemToRepeat, GR_DEFAULT_DRAWMODE );
// GetScreen()->Curseur.x = ox; GetScreen()->Curseur.x = oy;
// DrawPanel->MouseTo( DrawPanel->CursorScreenPosition() );
}
}
/******************************************/
void IncrementLabelMember( char* Line )
/******************************************/
/* Routine incrementant les labels, c'est a dire pour les textes finissant
* par un nombre, ajoutant <RepeatDeltaLabel> a ce nombre
*/
{
char* strnum;
int ii;
strnum = Line + strlen( Line ) - 1;
if( !isdigit( *strnum ) )
return;
while( (strnum >= Line) && isdigit( *strnum ) )
strnum--;
strnum++; /* pointe le debut de la chaine des digits */
ii = atoi( strnum ) + g_RepeatDeltaLabel;
sprintf( strnum, "%d", ii );
}
/***************************************************************************/
static bool IsTerminalPoint( SCH_SCREEN* screen, const wxPoint& pos, int layer )
/***************************************************************************/
/* Returne TRUE si pos est un point possible pour terminer automatiquement un
* segment, c'est a dire pour
* - type WIRE, si il y a
* - une jonction
* - ou une pin
* - ou une extr<EFBFBD>mit<EFBFBD> unique de fil
*
* - type BUS, si il y a
* - ou une extr<EFBFBD>mit<EFBFBD> unique de BUS
*/
{
EDA_BaseStruct* item;
LibDrawPin* pin;
DrawLibItemStruct* LibItem = NULL;
Hierarchical_PIN_Sheet_Struct* pinsheet;
wxPoint itempos;
switch( layer )
{
case LAYER_BUS:
item = PickStruct( screen, BUSITEM );
if( item )
return TRUE;
pinsheet = LocateAnyPinSheet( pos, screen->EEDrawList );
if( pinsheet && IsBusLabel( pinsheet->GetText() ) )
{
itempos = pinsheet->m_Pos;
if( (itempos.x == pos.x) && (itempos.y == pos.y) )
return TRUE;
}
break;
case LAYER_NOTES:
item = PickStruct( screen, DRAWITEM );
if( item )
return TRUE;
break;
case LAYER_WIRE:
item = PickStruct( screen, RACCORDITEM | JUNCTIONITEM );
if( item )
return TRUE;
pin = LocateAnyPin( screen->EEDrawList, pos, &LibItem );
if( pin && LibItem )
{
// calcul de la position exacte du point de connexion de la pin,
// selon orientation du composant:
itempos = LibItem->GetScreenCoord( pin->m_Pos );
itempos.x += LibItem->m_Pos.x;
itempos.y += LibItem->m_Pos.y;
if( (itempos.x == pos.x) && (itempos.y == pos.y) )
return TRUE;
}
item = PickStruct( screen, WIREITEM );
if( item )
return TRUE;
item = PickStruct( screen, LABELITEM );
if( item && (item->Type() != TYPE_SCH_TEXT)
&& ( ( (SCH_GLOBALLABEL*) item )->m_Pos.x == pos.x )
&& ( ( (SCH_GLOBALLABEL*) item )->m_Pos.y == pos.y ) )
return TRUE;
pinsheet = LocateAnyPinSheet( pos, screen->EEDrawList );
if( pinsheet && !IsBusLabel( pinsheet->GetText() ) )
{
itempos = pinsheet->m_Pos;
if( (itempos.x == pos.x) && (itempos.y == pos.y) )
return TRUE;
}
break;
default:
break;
}
return FALSE;
}

View File

@ -3,10 +3,8 @@
/**************************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "kicad_string.h"
#include "gestfich.h"
#include "appl_wxstruct.h"
@ -15,14 +13,17 @@
#include "libcmp.h"
#include "general.h"
#include "netlist.h"
#include "protos.h"
#include "bitmaps.h"
#include "class_marker_sch.h"
#include "dialog_erc.h"
#include "erc.h"
/* On teste
* 1 - conflits entre pins connectees ( ex: 2 sorties connectees )
* 2 - les imperatifs minimaux ( 1 entree doit etre connectee a une sortie )
#include "protos.h"
/* ERC tests :
* 1 - conflicts between connected pins ( example: 2 connected outputs )
* 2 - minimal connections requirements ( 1 input *must* be connected to an output, or a passive pin )
*/
@ -35,19 +36,41 @@ static void TestOthersItems( WinEDA_DrawPanel* panel,
ObjetNetListStruct* NetItemRef,
ObjetNetListStruct* NetStart,
int* NetNbItems, int* MinConnexion );
static void TestLabel( WinEDA_DrawPanel* panel,
static void TestLabel( WinEDA_DrawPanel* panel,
ObjetNetListStruct* NetItemRef,
ObjetNetListStruct* StartNet );
/* Variable locales */
/* Local variables */
int WriteFichierERC = FALSE;
/* Tableau des types de conflit :
/*
* Electrical type of pins:
* PIN_INPUT = usual pin input: must be connected
* PIN_OUTPUT = usual output
* PIN_BIDI = input or output (like port for a microprocessor)
* PIN_TRISTATE = tris state bus pin
* PIN_PASSIVE = pin for passive components: must be connected, and can be connected to any pin
* PIN_UNSPECIFIED = unkown electrical properties: creates alway a warning when connected
* PIN_POWER_IN = power input (GND, VCC for ICs). Must be connected to a power output.
* PIN_POWER_OUT = output of a regulator: intended to be connected to power input pins
* PIN_OPENCOLLECTOR = pin type open collector
* PIN_OPENEMITTER = pin type open emitter
* PIN_NC = not connected (must be left open)
*
* Minimal requirements:
* All pins *must* be connected (except PIN_NC).
* When a pin is not connected in schematic, the user must place a "non connected" symbol to this pin.
* This ensures a forgotten connection will be detected.
*/
/* Messages for conflicts :
* PIN_INPUT, PIN_OUTPUT, PIN_BIDI, PIN_TRISTATE, PIN_PASSIVE,
* PIN_UNSPECIFIED, PIN_POWER_IN, PIN_POWER_OUT, PIN_OPENCOLLECTOR,
* PIN_OPENEMITTER, PIN_NC
* These messages are used to show the ERC matrix in ERC dialog
*/
// Messages for matrix rows:
const wxChar* CommentERC_H[] =
{
wxT( "Input Pin...." ),
@ -63,6 +86,8 @@ const wxChar* CommentERC_H[] =
wxT( "No Conn......" ),
NULL
};
// Messages for matrix columns
const wxChar* CommentERC_V[] =
{
wxT( "Input Pin" ),
@ -84,26 +109,27 @@ const wxChar* CommentERC_V[] =
* Can be modified by ERC options.
* at start up: must be loaded by DefaultDiagErc
*/
int DiagErc[PIN_NMAX][PIN_NMAX];
bool DiagErcTableInit; // go to TRUE after DiagErc init
int DiagErc[PIN_NMAX][PIN_NMAX];
bool DiagErcTableInit; // go to TRUE after DiagErc init
/* Default Look up table which gives the diag for a pair of connected pins
* Same as DiagErc, but cannot be modified
* Used to init or reset DiagErc
*/
int DefaultDiagErc[PIN_NMAX][PIN_NMAX] =
{ /* I, O, Bi, 3S, Pas, UnS,PwrI,PwrO, OC, OE, NC */
/* I */ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, WAR },
/* O */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, ERR, ERR, WAR },
/* Bi*/ { OK, OK, OK, OK, OK, WAR, OK, WAR, OK, WAR, WAR },
/* 3S*/ { OK, WAR, OK, OK, OK, WAR, WAR, ERR, WAR, WAR, WAR },
/*Pas*/ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, WAR },
/*UnS */ { WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR },
/*PwrI*/ { OK, OK, OK, WAR, OK, WAR, OK, OK, OK, OK, ERR },
/*PwrO*/ { OK, ERR, WAR, ERR, OK, WAR, OK, ERR, ERR, ERR, WAR },
/* OC */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, OK, OK, WAR },
/* OE */ { OK, ERR, WAR, WAR, OK, WAR, OK, ERR, OK, OK, WAR },
/* NC */ { WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR }
{
/* I, O, Bi, 3S, Pas, UnS,PwrI,PwrO, OC, OE, NC */
/* I */ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, WAR },
/* O */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, ERR, ERR, WAR },
/* Bi*/ { OK, OK, OK, OK, OK, WAR, OK, WAR, OK, WAR, WAR },
/* 3S*/ { OK, WAR, OK, OK, OK, WAR, WAR, ERR, WAR, WAR, WAR },
/*Pas*/ { OK, OK, OK, OK, OK, WAR, OK, OK, OK, OK, WAR },
/*UnS */ { WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR },
/*PwrI*/ { OK, OK, OK, WAR, OK, WAR, OK, OK, OK, OK, ERR },
/*PwrO*/ { OK, ERR, WAR, ERR, OK, WAR, OK, ERR, ERR, ERR, WAR },
/* OC */ { OK, ERR, OK, WAR, OK, WAR, OK, ERR, OK, OK, WAR },
/* OE */ { OK, ERR, WAR, WAR, OK, WAR, OK, ERR, OK, OK, WAR },
/* NC */ { WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR, WAR }
};
@ -123,7 +149,8 @@ int DefaultDiagErc[PIN_NMAX][PIN_NMAX] =
* Nets with the state NOD have no source signal
*/
static int MinimalReq[PIN_NMAX][PIN_NMAX] =
{ /* In, Out, Bi, 3S, Pas, UnS,PwrI,PwrO, OC, OE, NC */
{
/* In, Out, Bi, 3S, Pas, UnS,PwrI,PwrO, OC, OE, NC */
/* In*/ { NOD, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NOC },
/*Out*/ { DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, DRV, NOC },
/* Bi*/ { DRV, DRV, DRV, DRV, DRV, DRV, NOD, DRV, DRV, DRV, NOC },
@ -161,16 +188,16 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
ReAnnotatePowerSymbolsOnly();
if( m_Parent->CheckAnnotate( aMessagesList, false ) )
{
if ( aMessagesList )
if( aMessagesList )
{
aMessagesList->AppendText( _( "Annotation Required!" ) );
aMessagesList->AppendText( wxT("\n") );
aMessagesList->AppendText( _( "Annotation Required!" ) );
aMessagesList->AppendText( wxT( "\n" ) );
}
return;
}
/* Erase all DRC markers */
DeleteAllMarkers( MARQ_ERC );
DeleteAllMarkers( MARK_ERC );
g_EESchemaVar.NbErrorErc = 0;
g_EESchemaVar.NbWarningErc = 0;
@ -183,7 +210,7 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
bool ModifyWires;
ModifyWires = Screen->SchematicCleanUp( NULL );
/* if wire list has changed, delete Udo Redo list to avoid
/* if wire list has changed, delete Undo Redo list to avoid
* pointers on deleted data problems */
if( ModifyWires )
Screen->ClearUndoRedoList();
@ -213,11 +240,12 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
m_SheetName ) == 0 )
{
/* Create a new marker type ERC error*/
MARKER_SCH* Marker =
new MARKER_SCH( ( (DrawSheetStruct*) item_to_test )->m_Pos,
_( "Duplicate Sheet name" ) );
Marker->SetMarkerType( MARQ_ERC );
MARKER_SCH* Marker = new MARKER_SCH();
Marker->SetData( ERCE_DUPLICATE_SHEET_NAME,
( (DrawSheetStruct*) item_to_test )->m_Pos,
_( "Duplicate Sheet name" ),
( (DrawSheetStruct*) item_to_test )->m_Pos );
Marker->SetMarkerType( MARK_ERC );
Marker->SetErrorLevel( ERR );
Marker->SetNext( Screen->EEDrawList );
Screen->EEDrawList = Marker;
@ -262,6 +290,7 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
case NET_PINLABEL:
case NET_GLOBLABEL:
case NET_GLOBBUSLABELMEMBER:
// These items do not create erc problems
break;
@ -269,6 +298,7 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
case NET_HIERBUSLABELMEMBER:
case NET_SHEETLABEL:
case NET_SHEETBUSLABELMEMBER:
// ERC problems when pin sheets do not match hierachical labels.
// Each pin sheet must match a hierachical label
// Each hierachicallabel must match a pin sheet
@ -276,13 +306,15 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
break;
case NET_NOCONNECT:
// ERC problems when a noconnect symbol is connected to more than one pin.
MinConn = NET_NC;
if( NetNbItems != 0 )
Diagnose( m_Parent->DrawPanel,NetItemRef, NULL, MinConn, UNC );
Diagnose( m_Parent->DrawPanel, NetItemRef, NULL, MinConn, UNC );
break;
case NET_PIN:
// Look for ERC problems between pins:
TestOthersItems( m_Parent->DrawPanel,
NetItemRef, StartNet, &NetNbItems, &MinConn );
@ -306,10 +338,10 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
m_LastWarningCount->SetLabel( num );
// Display diags:
DisplayERC_MarkersList( );
DisplayERC_MarkersList();
if ( m_TotalErrCount == 0 )
m_MessagesList->AppendText( _("ERC finished, no error\n"));
if( m_TotalErrCount == 0 )
m_MessagesList->AppendText( _( "ERC finished, no error\n" ) );
// Display new markers:
m_Parent->DrawPanel->Refresh();
@ -337,98 +369,6 @@ void DIALOG_ERC::TestErc( wxTextCtrl* aMessagesList )
}
/** Function DisplayERC_MarkersList
* read the schematic and display the list of ERC markers
*/
void DIALOG_ERC::DisplayERC_MarkersList( )
{
EDA_SheetList SheetList;
for( DrawSheetPath * Sheet = SheetList.GetFirst(); Sheet != NULL; Sheet = SheetList.GetNext() )
{
SCH_ITEM * DrawStruct = Sheet->LastDrawList();
for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
{
if( DrawStruct->Type() != DRAW_MARKER_STRUCT_TYPE )
continue;
/* Marqueur trouve */
MARKER_SCH* Marker = (MARKER_SCH*) DrawStruct;
if( Marker->GetMarkerType() != MARQ_ERC )
continue;
/* Display diag */
wxString msg;
msg.Printf(_("sheet %s: %s\n"),
Sheet->PathHumanReadable().GetData(),
Marker->GetErrorText().GetData() );
m_MessagesList->AppendText( msg );
}
}
}
/**************************************************************/
void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event )
/**************************************************************/
/* Remet aux valeurs par defaut la matrice de diagnostic
*/
{
memcpy( DiagErc, DefaultDiagErc, sizeof(DiagErc) );
ReBuildMatrixPanel();
}
/************************************************************/
void DIALOG_ERC::ChangeErrorLevel( wxCommandEvent& event )
/************************************************************/
/* Change the error level for the pressed button, on the matrix table
*/
{
int id, level, ii, x, y;
wxBitmapButton* Butt;
const char** new_bitmap_xpm = NULL;
wxPoint pos;
id = event.GetId();
ii = id - ID_MATRIX_0;
Butt = (wxBitmapButton*) event.GetEventObject();
pos = Butt->GetPosition();
x = ii / PIN_NMAX; y = ii % PIN_NMAX;
level = DiagErc[y][x];
switch( level )
{
case OK:
level = WAR;
new_bitmap_xpm = warning_xpm;
break;
case WAR:
level = ERR;
new_bitmap_xpm = error_xpm;
break;
case ERR:
level = OK;
new_bitmap_xpm = erc_green_xpm;
break;
}
if( new_bitmap_xpm )
{
delete Butt;
Butt = new wxBitmapButton( m_PanelERCOptions, id,
wxBitmap( new_bitmap_xpm ), pos );
m_ButtonList[y][x] = Butt;
DiagErc[y][x] = DiagErc[x][y] = level;
}
}
/********************************************************/
static void Diagnose( WinEDA_DrawPanel* aPanel,
ObjetNetListStruct* aNetItemRef,
@ -442,17 +382,17 @@ static void Diagnose( WinEDA_DrawPanel* aPanel,
*/
{
MARKER_SCH* Marker = NULL;
wxString DiagLevel;
SCH_SCREEN* screen;
int ii, jj;
wxString DiagLevel;
SCH_SCREEN* screen;
int ii, jj;
if( aDiag == OK )
return;
/* Creation du nouveau marqueur type Erreur ERC */
Marker = new MARKER_SCH( aNetItemRef->m_Start, wxEmptyString );
Marker = new MARKER_SCH();
Marker->SetMarkerType( MARQ_ERC );
Marker->SetMarkerType( MARK_ERC );
Marker->SetErrorLevel( WAR );
screen = aNetItemRef->m_SheetList.LastScreen();
Marker->SetNext( screen->EEDrawList );
@ -466,56 +406,65 @@ static void Diagnose( WinEDA_DrawPanel* aPanel,
if( (aNetItemRef->m_Type == NET_HIERLABEL)
|| (aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER) )
{
msg.Printf( _( "Warning HLabel %s not connected to SheetLabel" ),
aNetItemRef->m_Label->GetData() );
msg.Printf( _( "HLabel %s not connected to SheetLabel" ),
aNetItemRef->m_Label->GetData() );
}
else
msg.Printf( _( "Warning SheetLabel %s not connected to HLabel" ),
aNetItemRef->m_Label->GetData() );
msg.Printf( _( "SheetLabel %s not connected to HLabel" ),
aNetItemRef->m_Label->GetData() );
Marker->SetErrorText(msg);
Marker->SetData( ERCE_HIERACHICAL_LABEL, aNetItemRef->m_Start, msg, aNetItemRef->m_Start );
return;
}
ii = aNetItemRef->m_ElectricalType;
wxString string_pinnum, cmp_ref;
char ascii_buf[5];
char ascii_buf[5];
ascii_buf[4] = 0;
memcpy( ascii_buf, &aNetItemRef->m_PinNum, 4 );
string_pinnum = CONV_FROM_UTF8( ascii_buf );
cmp_ref = wxT("?");
if ( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
cmp_ref = ((SCH_COMPONENT*)aNetItemRef->m_Link)->GetRef( &aNetItemRef->m_SheetList );
cmp_ref = wxT( "?" );
if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
cmp_ref = ( (SCH_COMPONENT*) aNetItemRef->m_Link )->GetRef( &aNetItemRef->m_SheetList );
if( aNetItemTst == NULL )
{
if( aMinConn == NOC ) /* 1 seul element dans le net */
{
msg.Printf( _( "Warning Cmp %s, Pin %s (%s) Unconnected" ),
cmp_ref.GetData(), string_pinnum.GetData(), MsgPinElectricType[ii] );
Marker->SetErrorText(msg);
msg.Printf( _( "Cmp %s, Pin %s (%s) Unconnected" ),
cmp_ref.GetData(), string_pinnum.GetData(), MsgPinElectricType[ii] );
Marker->SetData( ERCE_PIN_NOT_CONNECTED,
aNetItemRef->m_Start,
msg,
aNetItemRef->m_Start );
return;
}
if( aMinConn == NOD ) /* pas de pilotage du net */
{
if ( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
cmp_ref = ((SCH_COMPONENT*)aNetItemRef->m_Link)->GetRef( &aNetItemRef->m_SheetList );
if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
cmp_ref = ( (SCH_COMPONENT*) aNetItemRef->m_Link )->GetRef(
&aNetItemRef->m_SheetList );
msg.Printf(
_( "Warning Cmp %s, Pin %s (%s) not driven (Net %d)" ),
_( "Cmp %s, Pin %s (%s) not driven (Net %d)" ),
cmp_ref.GetData(), string_pinnum.GetData(),
MsgPinElectricType[ii], aNetItemRef->GetNet() );
Marker->SetErrorText(msg);
Marker->SetData( ERCE_PIN_NOT_DRIVEN,
aNetItemRef->m_Start,
msg,
aNetItemRef->m_Start );
return;
}
if( aDiag == UNC )
{
msg.Printf(
_( "Warning More than 1 Pin connected to UnConnect symbol @X=%f"", Y=%f""" ),
(float)Marker->GetPos().x/1000, (float)Marker->GetPos().y/1000);
Marker->SetErrorText(msg);
_( "More than 1 Pin connected to UnConnect symbol" ) );
Marker->SetData( ERCE_NOCONNECT_CONNECTED,
aNetItemRef->m_Start,
msg,
aNetItemRef->m_Start );
return;
}
}
@ -524,25 +473,30 @@ static void Diagnose( WinEDA_DrawPanel* aPanel,
{
jj = aNetItemTst->m_ElectricalType;
DiagLevel = _( "Warning" );
int severity = ERCE_PIN_TO_PIN_WARNING;
if( aDiag == ERR )
{
DiagLevel = _( "Error" );
Marker->SetErrorLevel( ERR );
g_EESchemaVar.NbWarningErc--;
severity = ERCE_PIN_TO_PIN_ERROR;
}
wxString alt_string_pinnum, alt_cmp;
memcpy( ascii_buf, &aNetItemTst->m_PinNum, 4 );
alt_string_pinnum = CONV_FROM_UTF8( ascii_buf );
alt_cmp = wxT("?");
if ( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link )
alt_cmp = ((SCH_COMPONENT*)aNetItemTst->m_Link)->GetRef( &aNetItemTst->m_SheetList );
msg.Printf( _("%s: Cmp %s, Pin %s (%s) connected to Cmp %s, Pin %s (%s) (net %d)" ),
DiagLevel.GetData(),
cmp_ref.GetData(), string_pinnum.GetData(), MsgPinElectricType[ii],
alt_cmp.GetData(), alt_string_pinnum.GetData(),MsgPinElectricType[jj],
aNetItemRef->GetNet() );
Marker->SetErrorText(msg);
alt_cmp = wxT( "?" );
if( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link )
alt_cmp = ( (SCH_COMPONENT*) aNetItemTst->m_Link )->GetRef( &aNetItemTst->m_SheetList );
msg.Printf( _( "%s: Cmp %s, Pin %s (%s) connected to Cmp %s, Pin %s (%s) (net %d)" ),
DiagLevel.GetData(),
cmp_ref.GetData(), string_pinnum.GetData(), MsgPinElectricType[ii],
alt_cmp.GetData(), alt_string_pinnum.GetData(), MsgPinElectricType[jj],
aNetItemRef->GetNet() );
Marker->SetData( severity,
aNetItemRef->m_Start,
msg,
aNetItemRef->m_Start );
}
}
@ -581,7 +535,8 @@ static void TestOthersItems( WinEDA_DrawPanel* panel,
/* Est - on toujours dans le meme net ? */
if( (NetItemTst >= Lim) // fin de liste (donc fin de net)
|| ( NetItemRef->GetNet() != NetItemTst->GetNet() ) ) // fin de net
{ /* Fin de netcode trouve: Tst connexion minimum */
{
/* Fin de netcode trouve: Tst connexion minimum */
if( (*MinConnexion < NET_NC )
&& (local_minconn < NET_NC ) ) /* Not connected or not driven pin */
{
@ -644,12 +599,12 @@ static bool WriteDiagnosticERC( const wxString& FullFileName )
/* Create the Diagnostic file (<xxx>.erc file)
*/
{
SCH_ITEM* DrawStruct;
MARKER_SCH* Marker;
char Line[256];
static FILE* OutErc;
DrawSheetPath* Sheet;
wxString msg;
SCH_ITEM* DrawStruct;
MARKER_SCH* Marker;
char Line[1024];
static FILE* OutErc;
DrawSheetPath* Sheet;
wxString msg;
if( ( OutErc = wxFopen( FullFileName, wxT( "wt" ) ) ) == NULL )
return FALSE;
@ -683,7 +638,7 @@ static bool WriteDiagnosticERC( const wxString& FullFileName )
/* Marqueur trouve */
Marker = (MARKER_SCH*) DrawStruct;
if( Marker->GetMarkerType() != MARQ_ERC )
if( Marker->GetMarkerType() != MARK_ERC )
continue;
/* Write diag marqueur */
@ -704,7 +659,7 @@ static bool WriteDiagnosticERC( const wxString& FullFileName )
}
bool TestLabel_( ObjetNetListStruct* a, ObjetNetListStruct* b )
static bool IsLabelsConnected( ObjetNetListStruct* a, ObjetNetListStruct* b )
{
int at = a->m_Type;
int bt = b->m_Type;
@ -722,7 +677,9 @@ bool TestLabel_( ObjetNetListStruct* a, ObjetNetListStruct* b )
/***********************************************************************/
void TestLabel( WinEDA_DrawPanel* panel, ObjetNetListStruct* NetItemRef, ObjetNetListStruct* StartNet )
void TestLabel( WinEDA_DrawPanel* panel,
ObjetNetListStruct* NetItemRef,
ObjetNetListStruct* StartNet )
/***********************************************************************/
/* Routine controlant qu'un sheetLabel est bien connecte a un Glabel de la
@ -755,11 +712,11 @@ void TestLabel( WinEDA_DrawPanel* panel, ObjetNetListStruct* NetItemRef, ObjetNe
}
return;
}
if( TestLabel_( NetItemRef, NetItemTst ) )
if( IsLabelsConnected( NetItemRef, NetItemTst ) )
erc = 0;
//same thing, different order.
if( TestLabel_( NetItemTst, NetItemRef ) )
if( IsLabelsConnected( NetItemTst, NetItemRef ) )
erc = 0;
}
}

50
eeschema/erc.h Normal file
View File

@ -0,0 +1,50 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2009 Jea-Pierre.Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2009 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
*/
#ifndef _ERC_H
#define _ERC_H
/* For ERC markers: error types (used in diags, and to set the color):
*/
enum errortype
{
OK = 0,
WAR, // Error: severity = warning
ERR, // Error: severity = error
UNC // Error: unconnected pin
};
/// DRC error codes:
#define ERCE_UNSPECIFIED 0
#define ERCE_DUPLICATE_SHEET_NAME 1 //duplicate sheet names within a given sheet
#define ERCE_PIN_NOT_CONNECTED 2 //pin not connected and not no connect symbol
#define ERCE_PIN_NOT_DRIVEN 3 //pin connected to some others pins but no pin to drive it
#define ERCE_PIN_TO_PIN_WARNING 4 //pin connected to an other pin: warning level
#define ERCE_PIN_TO_PIN_ERROR 5 //pin connected to an other pin: error level
#define ERCE_HIERACHICAL_LABEL 6 //mismatch between hierarchical labels and pins sheets
#define ERCE_NOCONNECT_CONNECTED 7 //a no connect symbol is connected to more than 1 pin
#endif // _ERC_H

View File

@ -19,6 +19,7 @@
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "class_marker_sch.h"
/* Variables Locales */
static int s_ItemsCount, s_MarkerCount;

View File

@ -9,6 +9,7 @@
#include "libcmp.h"
#include "general.h"
#include "protos.h"
#include "class_marker_sch.h"
/* in read_from_file_schematic_items_description.cpp */
SCH_ITEM* ReadTextDescr( FILE* aFile, wxString& aMsgDiag, char* aLine,
@ -339,8 +340,8 @@ at line %d, aborted" ),
ii = ReadDelimitedText( BufLine, Line, 256 );
int type = (TypeMarker) ( (Name1[0] & 255) - 'A' );
if( type < 0 )
type = MARQ_UNSPEC;
if( type < 0 || type >= MARK_NMAX)
type = MARK_UNSPEC;
Marker->SetMarkerType( type );
if( ii )
Marker->SetErrorText( CONV_FROM_UTF8( BufLine ) );

View File

@ -12,6 +12,7 @@
#include "trigo.h"
#include "macros.h"
#include "class_drawpickedstruct.h"
#include "class_marker_sch.h"
#include "protos.h"

View File

@ -13,6 +13,7 @@
#include "general.h"
#include "id.h"
#include "protos.h"
#include "class_marker_sch.h"
/* Functions to undo and redo edit commands.
* commmands to undo are in CurrentScreen->m_UndoList

View File

@ -12,11 +12,11 @@ class MARKER_BASE
public:
wxPoint m_Pos; ///< position of the marker
protected:
char* m_Bitmap; ///< Shape (bitmap)
std::vector <wxPoint> m_Corners; ///< Corner list for shape definition (a polygon)
int m_MarkerType; ///< Can be used as a flag
int m_Color; ///< color
wxSize m_Size; ///< Size of the graphic symbol
EDA_Colors m_Color; ///< color
wxSize m_Size; ///< Size of the graphic symbol, used for Hit Tests
int m_ScalingFactor; ///< Scaling factor for m_Size and m_Corners (can set the physical size
DRC_ITEM m_drc;
void init();
@ -65,13 +65,21 @@ public:
}
/** Function SetColor
* Set the color of this marker
*/
void SetColor(EDA_Colors aColor )
{
m_Color = aColor;
}
/** Function to set/get error levels (warning, fatal ..)
* this value is stored in m_MarkerType
*/
void SetErrorLevel(int aErrorLevel )
{
m_MarkerType &= 0xFF00;
m_MarkerType &= 0xFF;
m_MarkerType &= ~0xFF00;
aErrorLevel &= 0xFF;
m_MarkerType |= aErrorLevel << 8;
}
@ -86,7 +94,7 @@ public:
*/
void SetMarkerType(int aMarkerType )
{
m_MarkerType &= 0xFF;
m_MarkerType &= ~0xFF;
aMarkerType &= 0xFF;
m_MarkerType |= aMarkerType;
}

View File

@ -12,7 +12,7 @@
#include "pcbnew.h"
#include "class_marker.h"
#define SCALING_FACTOR 30 // Adjust the actual size of markers, when using default shape
/*******************/
/* Classe MARKER */
@ -22,6 +22,8 @@ MARKER::MARKER( BOARD_ITEM* aParent ) :
BOARD_ITEM( aParent, TYPE_MARKER ),
MARKER_BASE( )
{
m_Color = WHITE;
m_ScalingFactor = SCALING_FACTOR;
}
@ -32,6 +34,8 @@ MARKER::MARKER( int aErrorCode, const wxPoint& aMarkerPos,
MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos )
{
m_Color = WHITE;
m_ScalingFactor = SCALING_FACTOR;
}
MARKER::MARKER( int aErrorCode, const wxPoint& aMarkerPos,
@ -39,6 +43,8 @@ MARKER::MARKER( int aErrorCode, const wxPoint& aMarkerPos,
BOARD_ITEM( NULL, TYPE_MARKER ), // parent set during BOARD::Add()
MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos )
{
m_Color = WHITE;
m_ScalingFactor = SCALING_FACTOR;
}