bug solved: netlist calculations could crash eeschema under very rare circumstances. See also changelog

This commit is contained in:
charras 2008-08-22 14:48:30 +00:00
parent c10fdc422b
commit 88b1c9b7d3
8 changed files with 1303 additions and 713 deletions

View File

@ -5,6 +5,15 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2008-Aug-22 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+eeschema:
bug solved: netlist calculations could crash eeschema under very rare circumstances.
recent bug solved: background filled shapes (filled but not solid: texts are readables inside shapes)
were drawn (and plotted) as filled (solid) shapes
enhancements needed for plotting background filled shapes, in color mode
(cannot be filled in black and white mode)
2008-Aug-18 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:

View File

@ -238,7 +238,7 @@ class LibDrawArc : public LibEDA_BaseStruct
{
public:
int m_Rayon;
bool m_Fill;
int m_Fill; // NO_FILL, FILLED_SHAPE or FILLED_WITH_BG_BODYCOLOR
int t1, t2; /* position des 2 extremites de l'arc en 0,1 degres */
wxPoint m_ArcStart, m_ArcEnd; /* position des 2 extremites de l'arc en coord reelles*/
@ -259,7 +259,7 @@ class LibDrawCircle : public LibEDA_BaseStruct
{
public:
int m_Rayon;
bool m_Fill;
int m_Fill;
public:
LibDrawCircle();
@ -299,7 +299,7 @@ class LibDrawSquare : public LibEDA_BaseStruct
{
public:
wxPoint m_End;
bool m_Fill;
int m_Fill;
public:
LibDrawSquare();
@ -337,7 +337,7 @@ class LibDrawPolyline : public LibEDA_BaseStruct
public:
int n;
int* PolyList;
bool m_Fill;
int m_Fill;
public:
LibDrawPolyline();

View File

@ -36,7 +36,7 @@ static int LastNetCode, LastBusNetCode;
static int s_PassNumber;
#if defined(DEBUG)
#if defined (DEBUG)
#include <iostream>
const char* ShowType( NetObjetType aType )
{
@ -44,22 +44,52 @@ const char* ShowType( NetObjetType aType )
switch( aType )
{
case NET_SEGMENT: ret = "segment"; break;
case NET_BUS: ret = "bus"; break;
case NET_JONCTION: ret = "junction"; break;
case NET_LABEL: ret = "label"; break;
case NET_HIERLABEL: ret = "hierlabel"; break;
case NET_GLOBLABEL: ret = "glabel"; break;
case NET_BUSLABELMEMBER: ret = "buslblmember"; break;
case NET_HIERBUSLABELMEMBER: ret = "hierbuslblmember"; break;
case NET_GLOBBUSLABELMEMBER: ret = "gbuslblmember"; break;
case NET_SHEETBUSLABELMEMBER: ret = "sbuslblmember"; break;
case NET_SHEETLABEL: ret = "sheetlabel"; break;
case NET_PINLABEL: ret = "pinlabel"; break;
case NET_PIN: ret = "pin"; break;
case NET_NOCONNECT: ret = "noconnect"; break;
default: ret = "??"; break;
case NET_SEGMENT:
ret = "segment"; break;
case NET_BUS:
ret = "bus"; break;
case NET_JONCTION:
ret = "junction"; break;
case NET_LABEL:
ret = "label"; break;
case NET_HIERLABEL:
ret = "hierlabel"; break;
case NET_GLOBLABEL:
ret = "glabel"; break;
case NET_BUSLABELMEMBER:
ret = "buslblmember"; break;
case NET_HIERBUSLABELMEMBER:
ret = "hierbuslblmember"; break;
case NET_GLOBBUSLABELMEMBER:
ret = "gbuslblmember"; break;
case NET_SHEETBUSLABELMEMBER:
ret = "sbuslblmember"; break;
case NET_SHEETLABEL:
ret = "sheetlabel"; break;
case NET_PINLABEL:
ret = "pinlabel"; break;
case NET_PIN:
ret = "pin"; break;
case NET_NOCONNECT:
ret = "noconnect"; break;
default:
ret = "??"; break;
}
return ret;
}
@ -67,10 +97,11 @@ const char* ShowType( NetObjetType aType )
void ObjetNetListStruct::Show( std::ostream& out, int ndx )
{
wxString path = m_SheetList.PathHumanReadable();
out << "<netItem ndx=\"" << ndx << '"' <<
" type=\"" << ShowType(m_Type) << '"' <<
" type=\"" << ShowType( m_Type ) << '"' <<
" netCode=\"" << GetNet() << '"' <<
" sheet=\"" << CONV_TO_UTF8(path) << '"' <<
" sheet=\"" << CONV_TO_UTF8( path ) << '"' <<
">\n";
out << " <start " << m_Start << "/> <end " << m_End << "/>\n";
@ -86,13 +117,16 @@ void ObjetNetListStruct::Show( std::ostream& out, int ndx )
out << "</netItem>\n";
}
void dumpNetTable()
{
for( int i=0; i<g_NbrObjNet; ++i )
for( int i = 0; i<g_NbrObjNet; ++i )
{
g_TabObjNet[i].Show( std::cout, i );
}
}
#endif
@ -131,6 +165,7 @@ void FreeTabNetList( ObjetNetListStruct* TabNetItems, int NbrNetItems )
case NET_SHEETBUSLABELMEMBER:
case NET_BUSLABELMEMBER:
SAFE_DELETE( TabNetItems[i].m_Label );
//see the note in ConvertBustToMembers
break;
}
@ -143,6 +178,7 @@ void FreeTabNetList( ObjetNetListStruct* TabNetItems, int NbrNetItems )
/*****************************************************/
void* WinEDA_SchematicFrame::BuildNetListBase()
/*****************************************************/
/* Routine qui construit le tableau des elements connectes du projet
* met a jour:
* g_TabObjNet
@ -163,7 +199,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
/* Build the sheet (not screen) list (flattened)*/
EDA_SheetList SheetListList( NULL );
i=0;
i = 0;
/* first pass : count objects used in connectivty calculation */
g_NbrObjNet = 0;
g_TabObjNet = NULL; /* Init pour le 1er passage dans ListeObjetConnection */
@ -190,23 +226,23 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
/* second pass: fill the fields of the structures used in connectivty calculation */
s_PassNumber++;
ObjetNetListStruct* tabObjNet = g_TabObjNet;
sheet = SheetListList.GetFirst();
for( ObjetNetListStruct* tabObjNet = g_TabObjNet;
sheet != NULL; sheet = SheetListList.GetNext() )
for( ; sheet != NULL; sheet = SheetListList.GetNext() )
{
tabObjNet += ListeObjetConnection( sheet, tabObjNet );
int icnt = ListeObjetConnection( sheet, tabObjNet );
tabObjNet += icnt; // tabObjNet points the first free location in g_TabObjNet
}
activity.Empty();
activity << wxT(" ") << _( "NbItems" ) << wxT(" ") << g_NbrObjNet;
activity << wxT( " " ) << _( "NbItems" ) << wxT( " " ) << g_NbrObjNet;
SetStatusText( activity );
/* Sort objects by Sheet */
qsort( g_TabObjNet, g_NbrObjNet, sizeof(ObjetNetListStruct), TriBySheet );
activity << wxT("; ") << _( "Conn" );
activity << wxT( "; " ) << _( "Conn" );
SetStatusText( activity );
sheet = &(g_TabObjNet[0].m_SheetList);
@ -297,20 +333,19 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
}
}
#if defined(NETLIST_DEBUG) && defined(DEBUG)
#if defined (NETLIST_DEBUG) && defined (DEBUG)
std::cout << "\n\nafter sheet local\n\n";
dumpNetTable();
#endif
activity << wxT(" ") << _( "Done" );
activity << wxT( " " ) << _( "Done" );
SetStatusText( activity );
/* Mise a jour des NetCodes des Bus Labels connectes par les Bus */
ConnectBusLabels( g_TabObjNet, g_NbrObjNet );
activity << wxT("; ") << _( "Labels" );
activity << wxT( "; " ) << _( "Labels" );
SetStatusText( activity );
/* Connections des groupes d'objets par labels identiques */
@ -341,16 +376,16 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
}
}
#if defined(NETLIST_DEBUG) && defined(DEBUG)
#if defined (NETLIST_DEBUG) && defined (DEBUG)
std::cout << "\n\nafter sheet global\n\n";
dumpNetTable();
#endif
activity << wxT(" ") << _( "Done" );
activity << wxT( " " ) << _( "Done" );
SetStatusText( activity );
/* Connexion des hierarchies */
activity << wxT("; ") << _( "Hierar." );
activity << wxT( "; " ) << _( "Hierar." );
SetStatusText( activity );
for( i = 0; i<g_NbrObjNet; i++ )
@ -364,16 +399,16 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
qsort( g_TabObjNet, g_NbrObjNet, sizeof(ObjetNetListStruct), TriNetCode );
#if defined(NETLIST_DEBUG) && defined(DEBUG)
#if defined (NETLIST_DEBUG) && defined (DEBUG)
std::cout << "after qsort()\n";
dumpNetTable();
#endif
activity << wxT(" ") << _( "Done" );
activity << wxT( " " ) << _( "Done" );
SetStatusText( activity );
/* Compression des numeros de NetCode a des valeurs consecutives */
activity << wxT("; ") << _( "Sorting Nets" );
activity << wxT( "; " ) << _( "Sorting Nets" );
SetStatusText( activity );
LastNetCode = NetCode = 0;
for( i = 0; i < g_NbrObjNet; i++ )
@ -386,7 +421,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
g_TabObjNet[i].SetNet( NetCode );
}
activity << wxT(" ") << _( "Done" );
activity << wxT( " " ) << _( "Done" );
SetStatusText( activity );
/* Affectation du m_FlagOfConnection en fonction de connection ou non */
@ -457,11 +492,6 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
DrawList = sheetlist->LastScreen()->EEDrawList;
for( ; DrawList; DrawList = DrawList->Pnext )
{
if( ObjNet ){
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
//used for DrawSheetLabels
}
switch( DrawList->Type() )
{
case DRAW_SEGMENT_STRUCT_TYPE:
@ -469,10 +499,11 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
#define STRUCT ( (EDA_DrawLineStruct*) DrawList )
if( ObjNet )
{
if( (STRUCT->GetLayer() != LAYER_BUS)
&& (STRUCT->GetLayer() != LAYER_WIRE) )
if( (STRUCT->GetLayer() != LAYER_BUS) && (STRUCT->GetLayer() != LAYER_WIRE) )
break;
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = STRUCT;
ObjNet[NbrItem].m_Start = STRUCT->m_Start;
ObjNet[NbrItem].m_End = STRUCT->m_End;
@ -494,6 +525,8 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
#define STRUCT ( (DrawJunctionStruct*) DrawList )
if( ObjNet )
{
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = STRUCT;
ObjNet[NbrItem].m_Type = NET_JONCTION;
ObjNet[NbrItem].m_Start = STRUCT->m_Pos;
@ -507,6 +540,8 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
#define STRUCT ( (DrawNoConnectStruct*) DrawList )
if( ObjNet )
{
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = STRUCT;
ObjNet[NbrItem].m_Type = NET_NOCONNECT;
ObjNet[NbrItem].m_Start = STRUCT->m_Pos;
@ -521,6 +556,8 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
ii = IsBusLabel( STRUCT->m_Text );
if( ObjNet )
{
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = STRUCT;
ObjNet[NbrItem].m_Type = NET_LABEL;
@ -547,11 +584,13 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
ii = IsBusLabel( STRUCT->m_Text );
if( ObjNet )
{
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = STRUCT;
ObjNet[NbrItem].m_Type = NET_LABEL;
if( STRUCT->m_Layer == LAYER_GLOBLABEL ) //this is not the simplest way of doing it
ObjNet[NbrItem].m_Type = NET_GLOBLABEL;// (look at the case statement above).
ObjNet[NbrItem].m_Type = NET_GLOBLABEL; // (look at the case statement above).
if( STRUCT->m_Layer == LAYER_HIERLABEL )
ObjNet[NbrItem].m_Type = NET_HIERLABEL;
@ -590,7 +629,7 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
if( DEntry->Type() != COMPONENT_PIN_DRAW_TYPE )
continue;
if( DEntry->m_Unit && (DEntry->m_Unit != DrawLibItem->GetUnitSelection( sheetlist ) ) )
if( DEntry->m_Unit && ( DEntry->m_Unit != DrawLibItem->GetUnitSelection( sheetlist ) ) )
continue;
if( DEntry->m_Convert
@ -605,6 +644,7 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
if( ObjNet )
{
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = DEntry;
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_Type = NET_PIN;
@ -624,6 +664,7 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
/* Il y a un PIN_LABEL Associe */
if( ObjNet )
{
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = NULL;
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_Type = NET_PINLABEL;
@ -649,7 +690,7 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
#undef STRUCT
#define STRUCT ( (DrawSheetStruct*) DrawList )
list = *sheetlist;
list.Push(STRUCT);
list.Push( STRUCT );
SheetLabel = STRUCT->m_Label;
for( ; SheetLabel != NULL;
SheetLabel = (Hierarchical_PIN_Sheet_Struct*) SheetLabel->Pnext )
@ -657,6 +698,7 @@ static int ListeObjetConnection( DrawSheetPath* sheetlist, ObjetNetListStruct* O
ii = IsBusLabel( SheetLabel->m_Text );
if( ObjNet )
{
ObjNet[NbrItem].m_SheetListInclude = *sheetlist;
ObjNet[NbrItem].m_Comp = SheetLabel;
ObjNet[NbrItem].m_SheetList = *sheetlist;
ObjNet[NbrItem].m_Link = DrawList;
@ -743,6 +785,8 @@ static void ConnectBusLabels( ObjetNetListStruct* Label, int NbItems )
}
}
}
/**************************************************/
int IsBusLabel( const wxString& LabelDrawList )
/**************************************************/
@ -883,8 +927,8 @@ static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus )
if( OldNetCode == NewNetCode )
return;
#if defined(NETLIST_DEBUG) && defined(DEBUG)
printf("replacing net %d with %d\n", OldNetCode,NewNetCode);
#if defined (NETLIST_DEBUG) && defined (DEBUG)
printf( "replacing net %d with %d\n", OldNetCode, NewNetCode );
#endif
if( IsBus == 0 ) /* Propagation du NetCode */
@ -941,7 +985,6 @@ static void PointToPointConnect( ObjetNetListStruct* Ref, int IsBus, int start )
netCode = Ref->GetNet();
for( i = start; i < g_NbrObjNet; i++ )
{
if( netTable[i].m_SheetList != Ref->m_SheetList ) //used to be > (why?)
continue;
@ -977,7 +1020,6 @@ static void PointToPointConnect( ObjetNetListStruct* Ref, int IsBus, int start )
}
}
}
else /* Objets type BUS et BUSLABELS ( et JONCTIONS )*/
{
netCode = Ref->m_BusNetCode;
@ -1091,7 +1133,7 @@ static void LabelConnect( ObjetNetListStruct* LabelRef )
ObjetNetListStruct* netTable = g_TabObjNet;
for( int i=0; i<g_NbrObjNet; i++ )
for( int i = 0; i<g_NbrObjNet; i++ )
{
if( netTable[i].GetNet() == LabelRef->GetNet() )
continue;
@ -1103,10 +1145,11 @@ static void LabelConnect( ObjetNetListStruct* LabelRef )
continue;
if( (netTable[i].m_Type == NET_GLOBLABEL
|| netTable[i].m_Type == NET_GLOBBUSLABELMEMBER)
&& netTable[i].m_Type != LabelRef->m_Type)
&& netTable[i].m_Type != LabelRef->m_Type )
//global labels only connect other global labels.
continue;
}
//regular labels are sheet-local;
//NET_HIERLABEL are used to connect sheets.
//NET_LABEL is sheet-local (***)
@ -1121,6 +1164,7 @@ static void LabelConnect( ObjetNetListStruct* LabelRef )
{
if( netTable[i].m_Label->CmpNoCase( *LabelRef->m_Label ) != 0 )
continue;
// Propagation du Netcode a tous les Objets de meme NetCode
if( netTable[i].GetNet() )
PropageNetCode( netTable[i].GetNet(), LabelRef->GetNet(), 0 );
@ -1130,6 +1174,7 @@ static void LabelConnect( ObjetNetListStruct* LabelRef )
}
}
/****************************************************************************/
static int TriNetCode( const void* o1, const void* o2 )
/****************************************************************************/
@ -1144,6 +1189,7 @@ static int TriNetCode( const void* o1, const void* o2 )
return Objet1->GetNet() - Objet2->GetNet();
}
/*****************************************************************************/
static int TriBySheet( const void* o1, const void* o2 )
/*****************************************************************************/
@ -1154,9 +1200,11 @@ static int TriBySheet( const void* o1, const void* o2 )
{
ObjetNetListStruct* Objet1 = (ObjetNetListStruct*) o1;
ObjetNetListStruct* Objet2 = (ObjetNetListStruct*) o2;
return Objet1->m_SheetList.Cmp(Objet2->m_SheetList);
return Objet1->m_SheetList.Cmp( Objet2->m_SheetList );
}
/**********************************************************************/
static void SetUnconnectedFlag( ObjetNetListStruct* ListObj, int NbItems )
/**********************************************************************/
@ -1187,7 +1235,7 @@ static void SetUnconnectedFlag( ObjetNetListStruct* ListObj, int NbItems )
NetItemTst = NetItemRef + 1;
if( (NetItemTst >= Lim)
|| (NetItemRef->GetNet() != NetItemTst->GetNet()) )
|| ( NetItemRef->GetNet() != NetItemTst->GetNet() ) )
{
/* Net analyse: mise a jour de m_FlagOfConnection */
NetEnd = NetItemTst;
@ -1209,7 +1257,7 @@ static void SetUnconnectedFlag( ObjetNetListStruct* ListObj, int NbItems )
for( ; ; NetItemTst++ )
{
if( (NetItemTst >= Lim)
|| (NetItemRef->GetNet() != NetItemTst->GetNet()) )
|| ( NetItemRef->GetNet() != NetItemTst->GetNet() ) )
break;
switch( NetItemTst->m_Type )

View File

@ -219,7 +219,7 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
pos.y = PartY + TransMat[1][0] * Arc->m_Pos.x +
TransMat[1][1] * Arc->m_Pos.y;
MapAngles( &t1, &t2, TransMat );
PlotArc( pos, t1, t2, Arc->m_Rayon, Arc->m_Fill, Arc->m_Width );
PlotArc( pos, t1, t2, Arc->m_Rayon, Arc->m_Fill == FILLED_SHAPE ? true : false, Arc->m_Width );
}
break;
@ -230,7 +230,7 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
TransMat[0][1] * Circle->m_Pos.y;
pos.y = PartY + TransMat[1][0] * Circle->m_Pos.x +
TransMat[1][1] * Circle->m_Pos.y;
PlotCercle( pos, Circle->m_Rayon * 2, Circle->m_Fill, Circle->m_Width );
PlotCercle( pos, Circle->m_Rayon * 2, Circle->m_Fill == FILLED_SHAPE ? true : false, Circle->m_Width );
}
break;
@ -266,7 +266,7 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
y2 = PartY + TransMat[1][0] * Square->m_End.x
+ TransMat[1][1] * Square->m_End.y;
PlotRect( wxPoint(x1, y1), wxPoint(x2, y2), Square->m_Fill, Square->m_Width );
PlotRect( wxPoint(x1, y1), wxPoint(x2, y2), Square->m_Fill == FILLED_SHAPE ? true : false, Square->m_Width );
}
break;
@ -311,7 +311,7 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
TransMat[1][1] * polyline->PolyList[ii * 2 + 1];
}
PlotPoly( ii, Poly, polyline->m_Fill, polyline->m_Width );
PlotPoly( ii, Poly, polyline->m_Fill == FILLED_SHAPE ? true : false, polyline->m_Width );
MyFree( Poly );
}
break;

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -494,7 +494,7 @@ void TEXTE_MODULE::Display_Infos( WinEDA_DrawFrame* frame )
Affiche_1_Parametre( frame, 1, _( "Module" ), Line, DARKCYAN );
Line = m_Text;
Affiche_1_Parametre( frame, 10, _( "Text" ), Line, YELLOW );
Affiche_1_Parametre( frame, 10, _( "Text" ), Line, BROWN );
ii = m_Type;
if( ii > 2 )
@ -510,18 +510,16 @@ void TEXTE_MODULE::Display_Infos( WinEDA_DrawFrame* frame )
ii = m_Layer;
if( ii < NB_LAYERS )
Affiche_1_Parametre( frame, 28, _( "Layer" ), board->GetLayerName( ii ), DARKGREEN );
msg = board->GetLayerName( ii );
else
{
msg.Printf( wxT( "%d" ), ii );
Affiche_1_Parametre( frame, 28, _( "Layer" ), msg, DARKGREEN );
}
Affiche_1_Parametre( frame, 31, _( "Layer" ), msg, DARKGREEN );
msg = wxT( " Yes" );
if( m_Miroir & 1 )
msg = wxT( " No" );
Affiche_1_Parametre( frame, 36, _( "Mirror" ), msg, DARKGREEN );
Affiche_1_Parametre( frame, 37, _( "Mirror" ), msg, DARKGREEN );
msg.Printf( wxT( "%.1f" ), (float) m_Orient / 10 );
Affiche_1_Parametre( frame, 43, _( "Orient" ), msg, DARKGREEN );

View File

@ -237,8 +237,10 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_DRAWING,
_( "End Drawing" ), apply_xpm );
}
aPopMenu->Append( ID_POPUP_PCB_EDIT_DRAWING, _( "Edit Drawing" ) );
aPopMenu->Append( ID_POPUP_PCB_DELETE_DRAWING, _( "Delete Drawing" ) );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_EDIT_DRAWING,
_( "Edit Drawing" ), edit_xpm );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING,
_( "Delete Drawing" ), delete_xpm );
break;
case TYPEZONE: // Item used to fill a zone