From 6d856f60a6639c33a64b00d2af8f0ab85ab27406 Mon Sep 17 00:00:00 2001 From: charras Date: Sun, 14 Dec 2008 19:45:05 +0000 Subject: [PATCH] Pcbnew: Added display a short net name on vias and pads. Also, code cleaning --- change_log.txt | 8 + common/basicframe.cpp | 3 - common/common_plot_functions.cpp | 2 +- common/drawtxt.cpp | 159 ++++--- common/worksheet.cpp | 7 +- cvpcb/CMakeLists.txt | 2 +- cvpcb/makefile.include | 4 + eeschema/class_drawsheet.cpp | 4 +- eeschema/class_hierarchical_PIN_sheet.cpp | 5 +- eeschema/class_pin.cpp | 12 +- eeschema/class_text-label.cpp | 15 +- eeschema/classes_body_items.cpp | 4 +- eeschema/eelayer.cpp | 10 +- eeschema/eelibs_draw_components.cpp | 6 +- eeschema/libfield.cpp | 6 +- eeschema/plot.cpp | 18 +- eeschema/protos.h | 2 +- gerbview/trpiste.cpp | 4 +- include/build_version.h | 4 +- include/colors.h | 1 + include/common.h | 37 +- internat/fr/kicad.mo | Bin 167569 -> 167306 bytes internat/fr/kicad.po | 210 +++++---- pcbnew/CMakeLists.txt | 1 + pcbnew/affiche.cpp | 2 +- pcbnew/class_board.cpp | 12 +- pcbnew/class_board_item.cpp | 10 +- pcbnew/class_equipot.cpp | 46 +- pcbnew/class_equipot.h | 48 +- pcbnew/class_pad.cpp | 549 ++++------------------ pcbnew/class_pad.h | 28 +- pcbnew/class_pad_draw_functions.cpp | 466 ++++++++++++++++++ pcbnew/class_text_mod.cpp | 2 +- pcbnew/class_track.cpp | 286 +++++------ pcbnew/class_track.h | 2 +- pcbnew/class_zone.cpp | 6 +- pcbnew/dialog_copper_zones.cpp | 6 +- pcbnew/dialog_pad_properties.cpp | 6 +- pcbnew/export_gencad.cpp | 13 +- pcbnew/ioascii.cpp | 2 +- pcbnew/makefile.include | 1 + pcbnew/move-drag_pads.cpp | 2 +- pcbnew/netlist.cpp | 6 +- pcbnew/ratsnest.cpp | 10 +- pcbnew/router.cpp | 2 +- pcbnew/solve.cpp | 2 +- pcbnew/specctra_export.cpp | 6 +- pcbnew/surbrill.cpp | 6 +- pcbnew/tracepcb.cpp | 7 + pcbnew/xchgmod.cpp | 22 +- pcbnew/zones_by_polygon.cpp | 4 +- 51 files changed, 1151 insertions(+), 925 deletions(-) create mode 100644 pcbnew/class_pad_draw_functions.cpp diff --git a/change_log.txt b/change_log.txt index 8f113da386..3955480b58 100644 --- a/change_log.txt +++ b/change_log.txt @@ -5,6 +5,14 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. +2008-Dec-14 UPDATE Jean-Pierre Charras +================================================================================ +++pcbnew + Display a short net name on vias and pads (if zoom level allows it). + Short net names are net names without hierarchy path + Add m_ShortNetname and change m_Netname to private in classes D_PAD and EQUIPOT + + 2008-Dec-08 UPDATE Wayne Stambaugh ================================================================================ ++all diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 47af273274..7de4f03b33 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -138,9 +138,6 @@ void WinEDA_BasicFrame::PrintMsg( const wxString& text ) /******************************************************/ { SetStatusText( text ); -#ifdef DEBUG - printf( "%s\n", (const char*) text.mb_str() ); -#endif } diff --git a/common/common_plot_functions.cpp b/common/common_plot_functions.cpp index 10a6afed23..80f28a5143 100644 --- a/common/common_plot_functions.cpp +++ b/common/common_plot_functions.cpp @@ -92,7 +92,7 @@ void PlotWorkSheet( int format_plot, BASE_SCREEN* screen ) int ii, jj, xg, yg, ipas, gxpas, gypas; wxSize PageSize; wxPoint pos, ref; - int color; + EDA_Colors color; Ki_WorkSheetData* WsItem; int conv_unit = screen->GetInternalUnits() / 1000; /* Scale to convert dimension in 1/1000 in into internal units * (1/1000 inc for EESchema, 1/10000 for pcbnew */ diff --git a/common/drawtxt.cpp b/common/drawtxt.cpp index 348a746081..46d4df5ae5 100644 --- a/common/drawtxt.cpp +++ b/common/drawtxt.cpp @@ -21,22 +21,23 @@ /* fonctions locales : */ -/****************************************************************************/ -void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, - const wxPoint& Pos, int gcolor, const wxString& Text, - int orient, const wxSize& Size, int h_justify, int v_justify, int width ) -/*****************************************************************************/ +/****************************************************************************************************/ +void DrawGraphicText( WinEDA_DrawPanel* aPanel, wxDC* DC, + const wxPoint& aPos, enum EDA_Colors aColor, const wxString& aText, + int aOrient, const wxSize& aSize, int aH_justify, int aV_justify, int aWidth ) +/****************************************************************************************************/ -/* Draw a graphic text (like module texts) - * Text = text to draw - * Pos = text position (according to h_justify, v_justify) - * Size = text size (size.x or size.y can be < 0 for mirrored texts) - * orient = angle in 0.1 degree - * mode_color = GR_OR, GR_XOR.. - * h_justify = horizontal justification (Left, center, right) - * v_justify = vertical justification (bottom, center, top) - * width = line width (pen width) (default = 0) - * if width < 0 : draw segments in sketch mode, width = abs(width) +/** Function DrawGraphicText + * Draw a graphic text (like module texts) + * @param aPanel = the current DrawPanel + * @param aPos = text position (according to aH_justify, aV_justify) + * @param aColor (enum EDA_Colors) = text color + * @param aText = text to draw + * @param aOrient = angle in 0.1 degree + * @param aSize = text size (size.x or size.y can be < 0 for mirrored texts) + * @param aH_justify = horizontal justification (Left, center, right) + * @param aV_justify = vertical justification (bottom, center, top) + * @param aWidth = line aWidth (pen aWidth) (default = 0) */ { int ii, kk, nbchar, AsciiCode, endcar; @@ -52,29 +53,29 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, int coord[100]; // Buffer coordinate used to draw polylines (char shapes) bool sketch_mode = FALSE; - zoom = panel->GetZoom(); + zoom = aPanel->GetZoom(); - size_h = Size.x; - size_v = Size.y; + size_h = aSize.x; + size_v = aSize.y; - if( width < 0 ) + if( aWidth < 0 ) { - width = -width; + aWidth = -aWidth; sketch_mode = TRUE; } kk = 0; ptr = 0; /* ptr = text index */ - nbchar = Text.Len(); + nbchar = aText.Len(); if( nbchar == 0 ) return; espacement = (10 * size_h ) / 9; // this is the pitch between chars - ox = cX = Pos.x; - oy = cY = Pos.y; + ox = cX = aPos.x; + oy = cY = aPos.y; /* Do not draw the text if out of draw area! */ - if( panel ) + if( aPanel ) { int xm, ym, ll, xc, yc; int textsize = ABS( espacement ); @@ -83,10 +84,10 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, xc = GRMapX( cX ); yc = GRMapY( cY ); - x0 = panel->m_ClipBox.GetX() - ll; - y0 = panel->m_ClipBox.GetY() - ll; - xm = panel->m_ClipBox.GetRight() + ll; - ym = panel->m_ClipBox.GetBottom() + ll; + x0 = aPanel->m_ClipBox.GetX() - ll; + y0 = aPanel->m_ClipBox.GetY() - ll; + xm = aPanel->m_ClipBox.GetRight() + ll; + ym = aPanel->m_ClipBox.GetBottom() + ll; if( xc < x0 ) return; @@ -105,9 +106,9 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, ux0 = uy0 = 0; /* Decalage du centre du texte / coord de ref */ - if( (orient == 0) || (orient == 1800) ) /* Horizontal Text */ + if( (aOrient == 0) || (aOrient == 1800) ) /* Horizontal Text */ { - switch( h_justify ) + switch( aH_justify ) { case GR_TEXT_HJUSTIFY_CENTER: break; @@ -121,7 +122,7 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, break; } - switch( v_justify ) + switch( aV_justify ) { case GR_TEXT_VJUSTIFY_CENTER: break; @@ -137,7 +138,7 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, } else /* Vertical Text */ { - switch( h_justify ) + switch( aH_justify ) { case GR_TEXT_HJUSTIFY_CENTER: break; @@ -151,7 +152,7 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, break; } - switch( v_justify ) + switch( aV_justify ) { case GR_TEXT_VJUSTIFY_CENTER: break; @@ -172,10 +173,10 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, ox = cX - dx; oy = cY + dy; - if( (Size.x / zoom) == 0 ) + if( (aSize.x / zoom) == 0 ) return; - if( ABS( (Size.x / zoom) ) < 3 ) /* chars trop petits pour etre dessines */ + if( ABS( (aSize.x / zoom) ) < 3 ) /* chars trop petits pour etre dessines */ { /* le texte est symbolise par une barre */ dx = (espacement * nbchar) / 2; dy = size_v / 2; /* Decalage du debut du texte / centre */ @@ -186,10 +187,10 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, dx += cX; dy = cY; - RotatePoint( &ux0, &uy0, cX, cY, orient ); - RotatePoint( &dx, &dy, cX, cY, orient ); + RotatePoint( &ux0, &uy0, cX, cY, aOrient ); + RotatePoint( &dx, &dy, cX, cY, aOrient ); - GRLine( &panel->m_ClipBox, DC, ux0, uy0, dx, dy, width, gcolor ); + GRLine( &aPanel->m_ClipBox, DC, ux0, uy0, dx, dy, aWidth, aColor ); return; } @@ -204,15 +205,15 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, dx += cX; dy = cY; - RotatePoint( &ux0, &uy0, cX, cY, orient ); - RotatePoint( &dx, &dy, cX, cY, orient ); + RotatePoint( &ux0, &uy0, cX, cY, aOrient ); + RotatePoint( &dx, &dy, cX, cY, aOrient ); DC->SetTextForeground( wxColour( - ColorRefs[gcolor].r, - ColorRefs[gcolor].g, - ColorRefs[gcolor].b ) ); + ColorRefs[aColor].r, + ColorRefs[aColor].g, + ColorRefs[aColor].b ) ); - DC->DrawRotatedText( Text, GRMapX( ux0 ), GRMapY( uy0 ), (double) orient / 10.0 ); + DC->DrawRotatedText( Text, GRMapX( ux0 ), GRMapY( uy0 ), (double) aOrient / 10.0 ); return; #endif @@ -220,13 +221,13 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, { x0 = 0; y0 = 0; #if defined(wxUSE_UNICODE) && defined(KICAD_CYRILLIC) - AsciiCode = Text.GetChar(ptr) & 0x7FF; + AsciiCode = aText.GetChar(ptr) & 0x7FF; if ( AsciiCode > 0x40F && AsciiCode < 0x450 ) // big small Cyr AsciiCode = utf8_to_ascii[AsciiCode - 0x410] & 0xFF; else AsciiCode = AsciiCode & 0xFF; #else - AsciiCode = Text.GetChar( ptr ) & 255; + AsciiCode = aText.GetChar( ptr ) & 0xFF; #endif ptcar = graphic_fonte_shape[AsciiCode]; /* ptcar pointe la description * du caractere a dessiner */ @@ -245,20 +246,20 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, case 'U': if( ii && (plume == 'D' ) ) { - if( width <= 1 ) - GRPoly( &panel->m_ClipBox, DC, ii / 2, coord, 0, 0, - gcolor, gcolor ); + if( aWidth <= 1 ) + GRPoly( &aPanel->m_ClipBox, DC, ii / 2, coord, 0, 0, + aColor, aColor ); else if( sketch_mode ) { int ik, * coordptr; coordptr = coord; for( ik = 0; ik < (ii - 2); ik += 2, coordptr += 2 ) - GRCSegm( &panel->m_ClipBox, DC, *coordptr, *(coordptr + 1), - *(coordptr + 2), *(coordptr + 3), width, gcolor ); + GRCSegm( &aPanel->m_ClipBox, DC, *coordptr, *(coordptr + 1), + *(coordptr + 2), *(coordptr + 3), aWidth, aColor ); } else - GRPoly( &panel->m_ClipBox, DC, ii / 2, coord, 0, - width, gcolor, gcolor ); + GRPoly( &aPanel->m_ClipBox, DC, ii / 2, coord, 0, + aWidth, aColor, aColor ); } plume = f_cod; ii = 0; break; @@ -279,7 +280,7 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, k2 = (k2 * size_h) / 9; dx = k2 + ox; dy = k1 + oy; - RotatePoint( &dx, &dy, cX, cY, orient ); + RotatePoint( &dx, &dy, cX, cY, aOrient ); coord[ii++] = dx; coord[ii++] = dy; break; @@ -299,13 +300,21 @@ void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, /******************************************************************************************/ -void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, - const wxString& Text, - int orient, const wxSize& Size, int h_justify, int v_justify ) +void PlotGraphicText( int aFormat_plot, const wxPoint& aPos, enum EDA_Colors aColor, + const wxString& aText, + int aOrient, const wxSize& aSize, int aH_justify, int aV_justify ) /******************************************************************************************/ -/* - * id DrawGraphicText, for plot graphic text +/** Function PlotGraphicText + * same as DrawGraphicText, but plot graphic text insteed of draw it + * @param aFormat_plot = plot format (PLOT_FORMAT_POST, PLOT_FORMAT_HPGL, PLOT_FORMAT_GERBER) + * @param aPos = text position (according to aH_justify, aV_justify) + * @param aColor (enum EDA_Colors) = text color + * @param aText = text to draw + * @param aOrient = angle in 0.1 degree + * @param aSize = text size (size.x or size.y can be < 0 for mirrored texts) + * @param aH_justify = horizontal justification (Left, center, right) + * @param aV_justify = vertical justification (bottom, center, top) */ { int kk, nbchar, end, AsciiCode; @@ -319,7 +328,7 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, void (*FctPlume)( wxPoint pos, int state ); - switch( format_plot ) + switch( aFormat_plot ) { case PLOT_FORMAT_POST: FctPlume = LineTo_PS; @@ -334,11 +343,11 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, return; } - if( gcolor >= 0 && IsPostScript( format_plot ) ) - SetColorMapPS( gcolor ); + if( aColor >= 0 && IsPostScript( aFormat_plot ) ) + SetColorMapPS( aColor ); - size_h = Size.x; - size_v = Size.y; + size_h = aSize.x; + size_v = aSize.y; if( size_h == 0 ) size_h = DEFAULT_SIZE_TEXT; if( size_v == 0 ) @@ -348,11 +357,11 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, ptr = 0; /* ptr = text index */ /* calcul de la position du debut des textes: ox et oy */ - nbchar = Text.Len(); + nbchar = aText.Len(); espacement = (10 * size_h ) / 9; - ox = cX = Pos.x; - oy = cY = Pos.y; + ox = cX = aPos.x; + oy = cY = aPos.y; /* Calcul du cadrage du texte */ dx = (espacement * nbchar) / 2; @@ -360,9 +369,9 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, ux0 = uy0 = 0; /* Decalage du centre du texte / ccord de ref */ - if( (orient == 0) || (orient == 1800) ) /* Texte Horizontal */ + if( (aOrient == 0) || (aOrient == 1800) ) /* Texte Horizontal */ { - switch( h_justify ) + switch( aH_justify ) { case GR_TEXT_HJUSTIFY_CENTER: break; @@ -376,7 +385,7 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, break; } - switch( v_justify ) + switch( aV_justify ) { case GR_TEXT_VJUSTIFY_CENTER: break; @@ -392,7 +401,7 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, } else /* Texte Vertical */ { - switch( h_justify ) + switch( aH_justify ) { case GR_TEXT_HJUSTIFY_CENTER: break; @@ -406,7 +415,7 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, break; } - switch( v_justify ) + switch( aV_justify ) { case GR_TEXT_VJUSTIFY_CENTER: break; @@ -432,13 +441,13 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, while( kk++ < nbchar ) { #if defined(wxUSE_UNICODE) && defined(KICAD_CYRILLIC) - AsciiCode = Text.GetChar(ptr) & 0x7FF; + AsciiCode = aText.GetChar(ptr) & 0x7FF; if ( AsciiCode > 0x40F && AsciiCode < 0x450 ) // big small Cyr AsciiCode = utf8_to_ascii[AsciiCode - 0x410] & 0xFF; else AsciiCode = AsciiCode & 0xFF; #else - AsciiCode = Text.GetChar( ptr ) & 0xFF; + AsciiCode = aText.GetChar( ptr ) & 0xFF; #endif ptcar = graphic_fonte_shape[AsciiCode]; /* ptcar pointe la description * du caractere a dessiner */ @@ -469,7 +478,7 @@ void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, dx = k2 + ox; dy = k1 + oy; - RotatePoint( &dx, &dy, orient ); + RotatePoint( &dx, &dy, aOrient ); FctPlume( wxPoint( cX + dx, cY + dy ), plume ); x0 = k2; diff --git a/common/worksheet.cpp b/common/worksheet.cpp index 858a676b17..c6cb1dd202 100644 --- a/common/worksheet.cpp +++ b/common/worksheet.cpp @@ -26,7 +26,8 @@ void WinEDA_DrawFrame::TraceWorkSheet( wxDC* DC, BASE_SCREEN* screen, int line_w Ki_PageDescr* Sheet = screen->m_CurrentSheetDesc; int ii, jj, xg, yg, ipas, gxpas, gypas; wxPoint pos; - int refx, refy, Color; + int refx, refy; + EDA_Colors Color; wxString Line; Ki_WorkSheetData* WsItem; int scale = m_InternalUnits / 1000; @@ -240,8 +241,8 @@ void WinEDA_DrawFrame::TraceWorkSheet( wxDC* DC, BASE_SCREEN* screen, int line_w break; case WS_UPPER_SEGMENT: case WS_LEFT_SEGMENT: - WS_MostUpperLine.m_Posy = - WS_MostUpperLine.m_Endy = + WS_MostUpperLine.m_Posy = + WS_MostUpperLine.m_Endy = WS_MostLeftLine.m_Posy = STAMP_OY; pos.y = (refy - WsItem->m_Posy)* scale; case WS_SEGMENT: diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 0fe8e6160c..2077ab6408 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -16,7 +16,6 @@ set(CVPCB_SRCS dialog_display_options.cpp displayframe.cpp genequiv.cpp -# genorcad.cpp init.cpp listboxes.cpp listlib.cpp @@ -41,6 +40,7 @@ set(CVPCB_EXTRA_SRCS ../pcbnew/class_mire.cpp ../pcbnew/class_module.cpp ../pcbnew/class_pad.cpp + ../pcbnew/class_pad_draw_functions.cpp ../pcbnew/class_pcb_text.cpp ../pcbnew/class_text_mod.cpp ../pcbnew/class_track.cpp diff --git a/cvpcb/makefile.include b/cvpcb/makefile.include index aeb9095029..7b94040622 100644 --- a/cvpcb/makefile.include +++ b/cvpcb/makefile.include @@ -46,6 +46,7 @@ OBJECTS = $(TARGET).o \ class_board.o \ class_module.o \ class_pad.o \ + class_pad_draw_functions.o\ class_text_mod.o \ class_edge_mod.o \ class_equipot.o \ @@ -104,6 +105,9 @@ class_track.o: ../pcbnew/class_track.cpp class_pad.o: ../pcbnew/class_pad.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp +class_pad_draw_functions.o: ../pcbnew/class_pad_draw_functions.cpp + $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp + class_module.o: ../pcbnew/class_module.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp diff --git a/eeschema/class_drawsheet.cpp b/eeschema/class_drawsheet.cpp index 23b375b16d..ab0e5c4936 100644 --- a/eeschema/class_drawsheet.cpp +++ b/eeschema/class_drawsheet.cpp @@ -316,7 +316,7 @@ void DrawSheetStruct::Draw( WinEDA_DrawPanel* panel, wxDC* DC, Text = wxT( "Sheet: " ) + m_SheetName; DrawGraphicText( panel, DC, - wxPoint( pos.x, pos.y - 8 ), txtcolor, + wxPoint( pos.x, pos.y - 8 ), (EDA_Colors) txtcolor, Text, TEXT_ORIENT_HORIZ, wxSize( m_SheetNameSize, m_SheetNameSize ), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM, LineWidth ); @@ -328,7 +328,7 @@ void DrawSheetStruct::Draw( WinEDA_DrawPanel* panel, wxDC* DC, Text = wxT( "File: " ) + m_FileName; DrawGraphicText( panel, DC, wxPoint( pos.x, pos.y + m_Size.y + 4 ), - txtcolor, + (EDA_Colors) txtcolor, Text, TEXT_ORIENT_HORIZ, wxSize( m_FileNameSize, m_FileNameSize ), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP, LineWidth ); diff --git a/eeschema/class_hierarchical_PIN_sheet.cpp b/eeschema/class_hierarchical_PIN_sheet.cpp index 382026de39..052a44a73f 100644 --- a/eeschema/class_hierarchical_PIN_sheet.cpp +++ b/eeschema/class_hierarchical_PIN_sheet.cpp @@ -72,14 +72,15 @@ void Hierarchical_PIN_Sheet_Struct::Draw( WinEDA_DrawPanel* panel, wxDC* DC, con /********************************************************************************************/ /* Routine de dessin des Labels type hierarchie */ { - int side, txtcolor; + int side; + EDA_Colors txtcolor; int posx, tposx, posy, size2; wxSize size; int NbSegm, coord[20]; int LineWidth = g_DrawMinimunLineWidth; if( Color >= 0 ) - txtcolor = Color; + txtcolor = (EDA_Colors)Color; else txtcolor = ReturnLayerColor( m_Layer ); GRSetDrawMode( DC, DrawMode ); diff --git a/eeschema/class_pin.cpp b/eeschema/class_pin.cpp index ca1ba83ef6..9e1fc43d22 100644 --- a/eeschema/class_pin.cpp +++ b/eeschema/class_pin.cpp @@ -244,7 +244,7 @@ void LibDrawPin::DrawPinTexts( WinEDA_DrawPanel* panel, wxString PinText; int PinTextBarPos[256]; int PinTextBarCount; - int NameColor, NumColor; + EDA_Colors NameColor, NumColor; int PinTxtLen; wxSize PinNameSize( m_PinNameSize, m_PinNameSize ); @@ -257,8 +257,8 @@ void LibDrawPin::DrawPinTexts( WinEDA_DrawPanel* panel, /* Get the num and name colors */ if( (Color < 0) && (m_Selected & IS_SELECTED) ) Color = g_ItemSelectetColor; - NameColor = Color == -1 ? ReturnLayerColor( LAYER_PINNAM ) : Color; - NumColor = Color == -1 ? ReturnLayerColor( LAYER_PINNUM ) : Color; + NameColor = (EDA_Colors) (Color == -1 ? ReturnLayerColor( LAYER_PINNAM ) : Color); + NumColor = (EDA_Colors) (Color == -1 ? ReturnLayerColor( LAYER_PINNUM ) : Color); /* Create the pin num string */ ReturnPinStringNum( StringPinNum ); @@ -563,7 +563,7 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos, wxString PinText; int PinTextBarPos[256]; int PinTextBarCount; - int NameColor, NumColor; + EDA_Colors NameColor, NumColor; int PinTxtLen = 0; wxSize PinNameSize = wxSize( m_PinNameSize, m_PinNameSize ); wxSize PinNumSize = wxSize( m_PinNumSize, m_PinNumSize ); @@ -571,8 +571,8 @@ void LibDrawPin::PlotPinTexts( wxPoint& pin_pos, && g_PlotPSColorOpt; /* Get the num and name colors */ - NameColor = plot_color ? ReturnLayerColor( LAYER_PINNAM ) : -1; - NumColor = plot_color ? ReturnLayerColor( LAYER_PINNUM ) : -1; + NameColor = (EDA_Colors) (plot_color ? ReturnLayerColor( LAYER_PINNAM ) : -1); + NumColor = (EDA_Colors) (plot_color ? ReturnLayerColor( LAYER_PINNUM ) : -1); /* Create the pin num string */ ReturnPinStringNum( StringPinNum ); diff --git a/eeschema/class_text-label.cpp b/eeschema/class_text-label.cpp index afb7c6041e..a4fb90fe8f 100644 --- a/eeschema/class_text-label.cpp +++ b/eeschema/class_text-label.cpp @@ -123,11 +123,11 @@ void SCH_TEXT::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, /* Texts type Comment (text on layer "NOTE") have 4 directions, and the Text origin is the first letter */ { - int color; + EDA_Colors color; int width = MAX( m_Width, g_DrawMinimunLineWidth ); if( Color >= 0 ) - color = Color; + color = (EDA_Colors)Color; else color = ReturnLayerColor( m_Layer ); GRSetDrawMode( DC, DrawMode ); @@ -331,13 +331,14 @@ void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offs */ { int Poly[40]; - int ii, color; + int ii; + EDA_Colors color; wxPoint AnchorPos = m_Pos + offset;; int width = MAX( m_Width, g_DrawMinimunLineWidth ); if( Color >= 0 ) - color = Color; + color = (EDA_Colors)Color; else color = ReturnLayerColor( m_Layer ); @@ -464,13 +465,15 @@ void SCH_GLOBALLABEL::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& dr */ { int Poly[20]; - int offset, color, HalfSize; + int offset; + EDA_Colors color; + int HalfSize; wxPoint AnchorPos = m_Pos + draw_offset;; int width = MAX( m_Width, g_DrawMinimunLineWidth ); if( Color >= 0 ) - color = Color; + color = (EDA_Colors)Color; else color = ReturnLayerColor( m_Layer ); diff --git a/eeschema/classes_body_items.cpp b/eeschema/classes_body_items.cpp index 761f468340..16d8ff0d08 100644 --- a/eeschema/classes_body_items.cpp +++ b/eeschema/classes_body_items.cpp @@ -161,7 +161,7 @@ void LibDrawText::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOff * transformation matrix causes xy axes to be flipped. */ int t1 = (aTransformMatrix[0][0] != 0) ^ (m_Horiz != 0); - DrawGraphicText( aPanel, aDC, pos1, color, m_Text, + DrawGraphicText( aPanel, aDC, pos1, (EDA_Colors) color, m_Text, t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT, m_Size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, linewidth ); @@ -337,7 +337,7 @@ void LibDrawField::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, const wxPoint& aOf wxString* text = aData ? (wxString*) aData : &m_Text; GRSetDrawMode( aDC, aDrawMode ); DrawGraphicText( aPanel, aDC, text_pos, - color, text->GetData(), + (EDA_Colors) color, text->GetData(), m_Orient ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ, m_Size, m_HJustify, m_VJustify, linewidth ); diff --git a/eeschema/eelayer.cpp b/eeschema/eelayer.cpp index 523c671c3b..5fc21ea63d 100644 --- a/eeschema/eelayer.cpp +++ b/eeschema/eelayer.cpp @@ -418,12 +418,12 @@ void SeedLayers() } -/*******************************/ -int ReturnLayerColor( int Layer ) -/*******************************/ +/***************************************/ +EDA_Colors ReturnLayerColor( int Layer ) +/****************************************/ { if( g_LayerDescr.Flags == 0 ) - return g_LayerDescr.LayerColor[Layer]; + return (EDA_Colors) g_LayerDescr.LayerColor[Layer]; else - return g_LayerDescr.CommonColor; + return (EDA_Colors) g_LayerDescr.CommonColor; } diff --git a/eeschema/eelibs_draw_components.cpp b/eeschema/eelibs_draw_components.cpp index 704c54e8bd..214825ea0c 100644 --- a/eeschema/eelibs_draw_components.cpp +++ b/eeschema/eelibs_draw_components.cpp @@ -249,8 +249,8 @@ void SCH_CMP_FIELD::Draw( WinEDA_DrawPanel* panel, * DrawMode: mode de trace */ { - int orient, color; - + int orient; + EDA_Colors color; wxPoint pos; /* Position des textes */ SCH_COMPONENT* DrawLibItem = (SCH_COMPONENT*) m_Parent; int hjustify, vjustify; @@ -304,7 +304,7 @@ void SCH_CMP_FIELD::Draw( WinEDA_DrawPanel* panel, if( !m_AddExtraText || (m_FieldId != REFERENCE) ) { - DrawGraphicText( panel, DC, pos, color, m_Text.GetData(), + DrawGraphicText( panel, DC, pos, color, m_Text, orient ? TEXT_ORIENT_VERT : TEXT_ORIENT_HORIZ, m_Size, hjustify, vjustify, LineWidth ); diff --git a/eeschema/libfield.cpp b/eeschema/libfield.cpp index 63611dfb16..cd19b9c025 100644 --- a/eeschema/libfield.cpp +++ b/eeschema/libfield.cpp @@ -131,7 +131,7 @@ static void ShowMoveField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) void WinEDA_LibeditFrame::PlaceField( wxDC* DC, LibDrawField* Field ) /*******************************************************************/ { - int color; + EDA_Colors color; if( Field == NULL ) return; @@ -183,7 +183,7 @@ void WinEDA_LibeditFrame::EditField( wxDC* DC, LibDrawField* Field ) { wxString Text; wxString title; - int color; + EDA_Colors color; int LineWidth = MAX( Field->m_Width, g_DrawMinimunLineWidth ); if( Field == NULL ) @@ -253,7 +253,7 @@ void WinEDA_LibeditFrame::RotateField( wxDC* DC, LibDrawField* Field ) * sinon Modif du champ pointe par la souris */ { - int color; + EDA_Colors color; if( Field == NULL ) return; diff --git a/eeschema/plot.cpp b/eeschema/plot.cpp index 2da6d7ed2d..b60c1cf4da 100644 --- a/eeschema/plot.cpp +++ b/eeschema/plot.cpp @@ -183,7 +183,7 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem ) LibEDA_BaseStruct* DEntry; EDA_LibComponentStruct* Entry; int TransMat[2][2], Multi, convert; - int CharColor = -1; + EDA_Colors CharColor = UNSPECIFIED_COLOR; wxPoint pos; bool draw_bgfill = false; @@ -377,7 +377,8 @@ static void PlotTextField( SCH_COMPONENT* DrawLibItem, wxPoint textpos; /* Position des textes */ SCH_CMP_FIELD* field = DrawLibItem->GetField( FieldNumber ); int hjustify, vjustify; - int orient, color = -1; + int orient; + EDA_Colors color = UNSPECIFIED_COLOR; if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt ) color = ReturnLayerColor( field->GetLayer() ); @@ -454,7 +455,7 @@ static void PlotPinSymbol( const wxPoint & pos, int len, int orient, int Shape ) */ { int MapX1, MapY1, x1, y1; - int color; + EDA_Colors color = UNSPECIFIED_COLOR; color = ReturnLayerColor( LAYER_PIN ); @@ -567,7 +568,7 @@ void PlotTextStruct( EDA_BaseStruct* Struct ) int pX, pY, Shape = 0, Orient = 0, offset; wxSize Size; wxString Text; - int color = -1; + EDA_Colors color = UNSPECIFIED_COLOR; switch( Struct->Type() ) { @@ -680,12 +681,13 @@ void PlotTextStruct( EDA_BaseStruct* Struct ) } -/***********************************************************/ +/***********************************************************************/ static void PlotSheetLabelStruct( Hierarchical_PIN_Sheet_Struct* Struct ) -/***********************************************************/ +/***********************************************************************/ /* Routine de dessin des Sheet Labels type hierarchie */ { - int side, txtcolor = -1; + int side; + EDA_Colors txtcolor = UNSPECIFIED_COLOR; int posx, tposx, posy, size, size2; int coord[16]; @@ -760,7 +762,7 @@ void PlotSheetStruct( DrawSheetStruct* Struct ) /* Routine de dessin du bloc type hierarchie */ { Hierarchical_PIN_Sheet_Struct* SheetLabelStruct; - int txtcolor = -1; + EDA_Colors txtcolor = UNSPECIFIED_COLOR; wxSize size; wxString Text; wxPoint pos; diff --git a/eeschema/protos.h b/eeschema/protos.h index 17abb4f23d..fa6521f9d5 100644 --- a/eeschema/protos.h +++ b/eeschema/protos.h @@ -197,7 +197,7 @@ void RedrawOneStruct(WinEDA_DrawPanel * panel, wxDC * DC, SCH_ITEM *Struct, int /* EELAYER.CPP */ /**************/ void SeedLayers(); -int ReturnLayerColor(int Layer); +EDA_Colors ReturnLayerColor(int Layer); void DisplayColorSetupFrame(WinEDA_DrawFrame * parent, const wxPoint & pos); /*************/ diff --git a/gerbview/trpiste.cpp b/gerbview/trpiste.cpp index d0f5b0f9c1..1cece1a715 100644 --- a/gerbview/trpiste.cpp +++ b/gerbview/trpiste.cpp @@ -21,7 +21,7 @@ void Draw_Track_Buffer( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, int draw_ int printmasklayer ) /***************************************************************************************************/ -/* Function to draw the tracks (i.e Sports or lines) in gerbview +/* Function to draw the tracks (i.e Spots or lines) in gerbview * Polygons are not handled here (there are in Pcb->m_Zone) * @param DC = device context to draw * @param Pcb = Board to draw (only Pcb->m_Track is used) @@ -266,7 +266,7 @@ void Affiche_DCodes_Pistes( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, int d } DrawGraphicText( panel, DC, - pos, g_DCodesColor, Line, + pos, (EDA_Colors) g_DCodesColor, Line, orient, wxSize( width, width ), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER ); } diff --git a/include/build_version.h b/include/build_version.h index 8805e413a6..c4e02ac6af 100644 --- a/include/build_version.h +++ b/include/build_version.h @@ -9,7 +9,7 @@ COMMON_GLOBL wxString g_BuildVersion # include "config.h" (wxT(KICAD_SVN_VERSION)) # else - (wxT("(20081124-unstable)")) /* main program version */ + (wxT("(20081214-unstable)")) /* main program version */ # endif #endif ; @@ -20,7 +20,7 @@ COMMON_GLOBL wxString g_BuildAboutVersion # include "config.h" (wxT(KICAD_ABOUT_VERSION)) # else - (wxT("(20081124-unstable)")) /* svn date & rev (normally overridden) */ + (wxT("(20081214-unstable)")) /* svn date & rev (normally overridden) */ # endif #endif ; diff --git a/include/colors.h b/include/colors.h index 3b9816d729..0601ea37c3 100644 --- a/include/colors.h +++ b/include/colors.h @@ -46,6 +46,7 @@ static inline int GetAlpha( int aColor ) enum EDA_Colors { + UNSPECIFIED_COLOR = -1, BLACK = 0, BLUE, GREEN, diff --git a/include/common.h b/include/common.h index c898c8e7b0..3644ebf85d 100644 --- a/include/common.h +++ b/include/common.h @@ -427,14 +427,37 @@ double round( double aNumber ); /**************/ /* DRAWTXT.CPP */ /**************/ -void DrawGraphicText( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& pos, - int mode_color, const wxString& Text, - int orient, const wxSize& char_size, - int h_justify, int v_justify, int width = 0 ); +/** Function DrawGraphicText + * Draw a graphic text (like module texts) + * @param aPanel = the current DrawPanel + * @param aPos = text position (according to h_justify, v_justify) + * @param aColor (enum EDA_Colors) = text color + * @param aText = text to draw + * @param aOrient = angle in 0.1 degree + * @param aSize = text size (size.x or size.y can be < 0 for mirrored texts) + * @param aH_justify = horizontal justification (Left, center, right) + * @param aV_justify = vertical justification (bottom, center, top) + * @param aWidth = line width (pen width) (default = 0) + * if width < 0 : draw segments in sketch mode, width = abs(width) + */ +void DrawGraphicText( WinEDA_DrawPanel* aPanel, wxDC* aDC, + const wxPoint& aPos, enum EDA_Colors aColor, const wxString& aText, + int aOrient, const wxSize& aSize, int aH_justify, int aV_justify, int aWidth = 0); -void PlotGraphicText( int format_plot, const wxPoint& Pos, int gcolor, - const wxString& Text, - int orient, const wxSize& Size, int h_justify, int v_justify ); +/** Function PlotGraphicText + * same as DrawGraphicText, but plot graphic text insteed of draw it + * @param aFormat_plot = plot format (PLOT_FORMAT_POST, PLOT_FORMAT_HPGL, PLOT_FORMAT_GERBER) + * @param aPos = text position (according to aH_justify, aV_justify) + * @param aColor (enum EDA_Colors) = text color + * @param aText = text to draw + * @param aOrient = angle in 0.1 degree + * @param aSize = text size (size.x or size.y can be < 0 for mirrored texts) + * @param aH_justify = horizontal justification (Left, center, right) + * @param aV_justify = vertical justification (bottom, center, top) + */ +void PlotGraphicText( int aFormat_plot, const wxPoint& aPos, enum EDA_Colors aColor, + const wxString& aText, + int aOrient, const wxSize& aSize, int aH_justify, int aV_justify ); /***************/ /* CONFIRM.CPP */ diff --git a/internat/fr/kicad.mo b/internat/fr/kicad.mo index c07a67c197a540027b5942b9219c311879659428..686572b88f376a3fecc0b38242a85c02185a05f3 100644 GIT binary patch delta 50247 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 CxLywc delta 50500 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 diff --git a/internat/fr/kicad.po b/internat/fr/kicad.po index ccb310d898..65d339d50b 100644 --- a/internat/fr/kicad.po +++ b/internat/fr/kicad.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: kicad\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-12-11 17:20+0100\n" -"PO-Revision-Date: 2008-12-11 18:52+0100\n" +"POT-Creation-Date: 2008-12-12 22:29+0100\n" +"PO-Revision-Date: 2008-12-12 22:31+0100\n" "Last-Translator: \n" "Language-Team: kicad team \n" "MIME-Version: 1.0\n" @@ -24,7 +24,7 @@ msgstr "" #: pcbnew/clean.cpp:180 msgid "Delete unconnected tracks:" -msgstr "Suppression Pistes non connectées" +msgstr "Suppression Pistes non connectées:" #: pcbnew/clean.cpp:197 msgid "ViaDef" @@ -1618,34 +1618,26 @@ msgid "Enable Auto Delete old Track" msgstr "Autoriser l'effacement automatique des pistes" #: pcbnew/pcbframe.cpp:457 -msgid "Do not Show Zones" -msgstr "Ne pas montrer Zones" - -#: pcbnew/pcbframe.cpp:457 -msgid "Show Zones" -msgstr "Montrer Zones" - -#: pcbnew/pcbframe.cpp:463 msgid "Show Pads Sketch mode" msgstr "Afficher pastilles en contour" -#: pcbnew/pcbframe.cpp:464 +#: pcbnew/pcbframe.cpp:458 msgid "Show pads filled mode" msgstr "Afficher pastilles en mode plein" -#: pcbnew/pcbframe.cpp:470 +#: pcbnew/pcbframe.cpp:464 msgid "Show Tracks Sketch mode" msgstr "Afficher pistes en contour" -#: pcbnew/pcbframe.cpp:471 +#: pcbnew/pcbframe.cpp:465 msgid "Show Tracks filled mode" msgstr "Afficher pistes en mode plein" -#: pcbnew/pcbframe.cpp:477 +#: pcbnew/pcbframe.cpp:471 msgid "Normal Contrast Mode Display" msgstr "Mode d'affichage Contraste normal" -#: pcbnew/pcbframe.cpp:478 +#: pcbnew/pcbframe.cpp:472 msgid "Hight Contrast Mode Display" msgstr "Mode d'affichage Haut Contraste" @@ -2457,15 +2449,27 @@ msgstr "Montrer le chevelu du module pendant déplacement" msgid "Enable Auto Del Track" msgstr "Autoriser l'effacement automatique des pistes" -#: pcbnew/tool_pcb.cpp:379 +#: pcbnew/tool_pcb.cpp:374 +msgid "Show filled areas in zones" +msgstr "Afficher les surfaces remplies dans les zones" + +#: pcbnew/tool_pcb.cpp:377 +msgid "Do not show filled areas in zones" +msgstr "Ne pas fficher les surfaces remplies dans les zones" + +#: pcbnew/tool_pcb.cpp:380 +msgid "Show outlines of filled areas only in zones" +msgstr "Afficher uniquement les contours des surfaces remplies dans les zones" + +#: pcbnew/tool_pcb.cpp:385 msgid "Show Pads Sketch" msgstr "Afficher pastilles en contour" -#: pcbnew/tool_pcb.cpp:383 +#: pcbnew/tool_pcb.cpp:389 msgid "Show Tracks Sketch" msgstr "Afficher Pistes en Contour" -#: pcbnew/tool_pcb.cpp:398 +#: pcbnew/tool_pcb.cpp:404 msgid "" "Display/remove auxiliary vertical toolbar (tools for micro wave applications)\n" " This is a experimental feature (under development)" @@ -2473,79 +2477,79 @@ msgstr "" "Affiche/supprime le toolbar vertical auxiliaire (outils pour applications micro-ondes)\n" "C'est un outil expérimental (en cours de développement)" -#: pcbnew/tool_pcb.cpp:428 +#: pcbnew/tool_pcb.cpp:434 msgid "Net highlight" msgstr "Surbrillance des équipotentielles" -#: pcbnew/tool_pcb.cpp:433 +#: pcbnew/tool_pcb.cpp:439 msgid "Display local ratsnest (pad or module)" msgstr "Afficher le chevelu local (pastilles ou modules)" -#: pcbnew/tool_pcb.cpp:439 +#: pcbnew/tool_pcb.cpp:445 msgid "Add modules" msgstr "Addition de Modules" -#: pcbnew/tool_pcb.cpp:443 +#: pcbnew/tool_pcb.cpp:449 msgid "Add tracks and vias" msgstr "Ajouter pistes et vias" -#: pcbnew/tool_pcb.cpp:447 +#: pcbnew/tool_pcb.cpp:453 msgid "Add zones" msgstr "Addition de Zones" -#: pcbnew/tool_pcb.cpp:452 +#: pcbnew/tool_pcb.cpp:458 msgid "Add graphic line or polygon" msgstr "Addition de lignes ou polygones graphiques" -#: pcbnew/tool_pcb.cpp:456 +#: pcbnew/tool_pcb.cpp:462 msgid "Add graphic circle" msgstr "Addition de graphiques (Cercle)" -#: pcbnew/tool_pcb.cpp:460 +#: pcbnew/tool_pcb.cpp:466 msgid "Add graphic arc" msgstr "Addition de graphiques (Arc de Cercle)" -#: pcbnew/tool_pcb.cpp:464 +#: pcbnew/tool_pcb.cpp:470 msgid "Add text" msgstr "Ajout de Texte" -#: pcbnew/tool_pcb.cpp:469 +#: pcbnew/tool_pcb.cpp:475 msgid "Add dimension" msgstr "Ajout des cotes" -#: pcbnew/tool_pcb.cpp:473 +#: pcbnew/tool_pcb.cpp:479 msgid "Add layer alignment target" msgstr "Ajouter Mire de superposition" -#: pcbnew/tool_pcb.cpp:478 +#: pcbnew/tool_pcb.cpp:484 msgid "Delete items" msgstr "Suppression d'éléments" -#: pcbnew/tool_pcb.cpp:483 +#: pcbnew/tool_pcb.cpp:489 msgid "Offset adjust for drill and place files" msgstr "Ajuste offset pour fichier de perçage et placement" -#: pcbnew/tool_pcb.cpp:511 +#: pcbnew/tool_pcb.cpp:517 msgid "Create line of specified length for microwave applications" msgstr "Creation de lignes de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:517 +#: pcbnew/tool_pcb.cpp:523 msgid "Create gap of specified length for microwave applications" msgstr "Creation de gaps de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:525 +#: pcbnew/tool_pcb.cpp:531 msgid "Create stub of specified length for microwave applications" msgstr "Creation de stub de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:531 +#: pcbnew/tool_pcb.cpp:537 msgid "Create stub (arc) of specified length for microwave applications" msgstr "Creation de stub (arc) de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:538 +#: pcbnew/tool_pcb.cpp:544 msgid "Create a polynomial shape for microwave applications" msgstr "Creation de formes polynomiales (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:579 +#: pcbnew/tool_pcb.cpp:585 msgid "" "Auto track width: when starting on an existing track use its width\n" "otherwise, use current width setting" @@ -2553,19 +2557,19 @@ msgstr "" "Largeur de piste automatique: si on démarre sur une piste existante, utiliser sa largeur\n" " sinon utiliser la largeur courante" -#: pcbnew/tool_pcb.cpp:604 +#: pcbnew/tool_pcb.cpp:610 msgid "Auto" msgstr "Auto" -#: pcbnew/tool_pcb.cpp:608 +#: pcbnew/tool_pcb.cpp:614 msgid "Zoom " msgstr "Zoom " -#: pcbnew/tool_pcb.cpp:643 +#: pcbnew/tool_pcb.cpp:649 msgid "User Grid" msgstr "Grille perso" -#: pcbnew/tool_pcb.cpp:759 +#: pcbnew/tool_pcb.cpp:765 msgid "+/- to switch" msgstr "+/- pour commuter" @@ -3392,7 +3396,7 @@ msgstr "Grille %.1f" msgid "Grid %.3f" msgstr "Grille %.3f" -#: pcbnew/dialog_copper_zones.cpp:288 +#: pcbnew/dialog_copper_zones.cpp:285 msgid "" "Error :\n" "you must choose a copper min thickness value bigger than 0.001 inch or 0.00254 mm)" @@ -3400,7 +3404,7 @@ msgstr "" "Erreur :\n" "vous devez choisir une valeur pour l'épaisseur de cuivre dans les freins thermiques plus grande que 0,001 pouce (ou 0,00254 mm)" -#: pcbnew/dialog_copper_zones.cpp:313 +#: pcbnew/dialog_copper_zones.cpp:308 msgid "" "Error :\n" "you must choose a copper bridge value for thermal reliefs bigger than the min zone thickness" @@ -3408,11 +3412,11 @@ msgstr "" "Erreur :\n" "vous devez choisir une valeur pour l'épaisseur de cuivre dans les freins thermiques plus grande que l'épaisseur de cuivre minimum des zones" -#: pcbnew/dialog_copper_zones.cpp:325 +#: pcbnew/dialog_copper_zones.cpp:320 msgid "Error : you must choose a layer" msgstr "Erreur. Vous devez choisir une couche" -#: pcbnew/dialog_copper_zones.cpp:337 +#: pcbnew/dialog_copper_zones.cpp:332 msgid "Error : you must choose a net name" msgstr "Erreur. Vous devez choisir une équipotentielle" @@ -4072,7 +4076,7 @@ msgid "Pen Number" msgstr "Numéro de plume" #: pcbnew/dialog_gendrill.cpp:239 -#: pcbnew/dialog_general_options.cpp:376 +#: pcbnew/dialog_general_options.cpp:385 msgid "Options:" msgstr "Options :" @@ -4282,96 +4286,96 @@ msgstr "Larg. piste: %s Diam Vias : %s" msgid "Drc error, cancelled" msgstr "Erreur DRC, annulation" -#: pcbnew/dialog_general_options.cpp:288 +#: pcbnew/dialog_general_options.cpp:297 msgid "No Display" msgstr "Pas d'affichage" -#: pcbnew/dialog_general_options.cpp:291 +#: pcbnew/dialog_general_options.cpp:300 msgid "Display Polar Coord" msgstr "Affichage coord Polaires" -#: pcbnew/dialog_general_options.cpp:300 +#: pcbnew/dialog_general_options.cpp:309 msgid "millimeters" msgstr "millimètres" -#: pcbnew/dialog_general_options.cpp:302 +#: pcbnew/dialog_general_options.cpp:311 msgid "Units" msgstr "Unités" -#: pcbnew/dialog_general_options.cpp:309 +#: pcbnew/dialog_general_options.cpp:318 msgid "Small" msgstr "Petit" -#: pcbnew/dialog_general_options.cpp:310 +#: pcbnew/dialog_general_options.cpp:319 msgid "Big" msgstr "Grand" -#: pcbnew/dialog_general_options.cpp:312 +#: pcbnew/dialog_general_options.cpp:321 msgid "Cursor" msgstr "Curseur" -#: pcbnew/dialog_general_options.cpp:324 +#: pcbnew/dialog_general_options.cpp:333 msgid "Number of Layers:" msgstr "Nombre de Couches:" -#: pcbnew/dialog_general_options.cpp:340 +#: pcbnew/dialog_general_options.cpp:349 msgid "Max Links:" msgstr "Liens max:" -#: pcbnew/dialog_general_options.cpp:356 +#: pcbnew/dialog_general_options.cpp:365 msgid "Auto Save (minuts):" msgstr "Sauveg. Auto (min)" -#: pcbnew/dialog_general_options.cpp:385 +#: pcbnew/dialog_general_options.cpp:394 msgid "Drc ON" msgstr "Drc ACTIVE" -#: pcbnew/dialog_general_options.cpp:394 +#: pcbnew/dialog_general_options.cpp:403 msgid "Show Ratsnest" msgstr "Montrer le chevelu général" -#: pcbnew/dialog_general_options.cpp:401 +#: pcbnew/dialog_general_options.cpp:410 msgid "Show Mod Ratsnest" msgstr "Montrer le chevelu du module" -#: pcbnew/dialog_general_options.cpp:408 +#: pcbnew/dialog_general_options.cpp:417 msgid "Tracks Auto Del" msgstr "Auto Supp. Pistes" -#: pcbnew/dialog_general_options.cpp:415 +#: pcbnew/dialog_general_options.cpp:424 msgid "Track only 45 degrees" msgstr "Piste à 45° seulement" -#: pcbnew/dialog_general_options.cpp:422 +#: pcbnew/dialog_general_options.cpp:431 msgid "Segments 45 Only" msgstr "Segments 45 seulement" -#: pcbnew/dialog_general_options.cpp:429 +#: pcbnew/dialog_general_options.cpp:438 msgid "Auto PAN" msgstr "Auto PAN" -#: pcbnew/dialog_general_options.cpp:437 +#: pcbnew/dialog_general_options.cpp:446 msgid "Double Segm Track" msgstr "2 segments pour piste" -#: pcbnew/dialog_general_options.cpp:450 -#: pcbnew/dialog_general_options.cpp:465 +#: pcbnew/dialog_general_options.cpp:459 +#: pcbnew/dialog_general_options.cpp:474 msgid "When creating tracks" msgstr "En creation de pistes" -#: pcbnew/dialog_general_options.cpp:453 +#: pcbnew/dialog_general_options.cpp:462 msgid "Magnetic Pads" msgstr " Pads magnétiques" -#: pcbnew/dialog_general_options.cpp:460 +#: pcbnew/dialog_general_options.cpp:469 msgid "control the capture of the pcb cursor when the mouse cursor enters a pad area" msgstr "Contrôle la capture du curseur pcb quand le curseuir souris est sur un pad" -#: pcbnew/dialog_general_options.cpp:468 +#: pcbnew/dialog_general_options.cpp:477 msgid "Magnetic Tracks" msgstr "Pistes Magnétiques" -#: pcbnew/dialog_general_options.cpp:475 +#: pcbnew/dialog_general_options.cpp:484 msgid "control the capture of the pcb cursor when the mouse cursor enters a track" msgstr "Contrôle la capture du curseur pcb quand le curseuir souris est sur une piste" @@ -4533,60 +4537,48 @@ msgid "Others Options:" msgstr "Autres Options:" #: pcbnew/dialog_copper_zones_base.cpp:118 -msgid "Show filled areas in sketch mode" -msgstr "Afficher les surfaces remplies en mode contour" - -#: pcbnew/dialog_copper_zones_base.cpp:120 -msgid "" -"If enabled, filled areas in is this zone will be displayed as non filled polygons.\n" -"If disabled, filled areas in is this zone will be displayed as \"solid\" areas (normal mode)." -msgstr "" -"Si activé, les surfaces remplies dans cette zone seront affichées comme des polygones non remplis.\n" -"Si désactivé, les surfaces remplies dans cette zone seront affichées comme des surfaces \"solides\"." - -#: pcbnew/dialog_copper_zones_base.cpp:124 msgid "Zone clearance value" msgstr "Valeur isolation zone" -#: pcbnew/dialog_copper_zones_base.cpp:131 +#: pcbnew/dialog_copper_zones_base.cpp:125 msgid "Zone min thickness value" msgstr "Valeur épaisseur min pour zone" -#: pcbnew/dialog_copper_zones_base.cpp:136 +#: pcbnew/dialog_copper_zones_base.cpp:130 msgid "Value of minimun thickness of filled areas" msgstr "Valeur de l'épaisseur minimum des zones remplies" -#: pcbnew/dialog_copper_zones_base.cpp:156 +#: pcbnew/dialog_copper_zones_base.cpp:150 msgid "Export Setup to others zones" msgstr "Exporter options vers autres zones" -#: pcbnew/dialog_copper_zones_base.cpp:157 +#: pcbnew/dialog_copper_zones_base.cpp:152 msgid "Export this zone setup to all others copper zones" msgstr "Exporter ces options vers les autres zones de cuivre" -#: pcbnew/dialog_copper_zones_base.cpp:161 +#: pcbnew/dialog_copper_zones_base.cpp:156 #: pcbnew/dialog_pad_properties_base.cpp:91 #: pcbnew/zone_filling_deprecated_algorithm.cpp:310 msgid "Ok" msgstr "Ok" -#: pcbnew/dialog_copper_zones_base.cpp:172 +#: pcbnew/dialog_copper_zones_base.cpp:171 msgid "Nets Display Options:" msgstr "Options d'Affichage des Nets" -#: pcbnew/dialog_copper_zones_base.cpp:174 +#: pcbnew/dialog_copper_zones_base.cpp:173 msgid "Alphabetic" msgstr "Alphabetique" -#: pcbnew/dialog_copper_zones_base.cpp:174 +#: pcbnew/dialog_copper_zones_base.cpp:173 msgid "Advanced" msgstr "Avancé" -#: pcbnew/dialog_copper_zones_base.cpp:176 +#: pcbnew/dialog_copper_zones_base.cpp:175 msgid "Net sorting:" msgstr "Tri des Equipotentielles:" -#: pcbnew/dialog_copper_zones_base.cpp:178 +#: pcbnew/dialog_copper_zones_base.cpp:177 msgid "" "Nets can be sorted:\n" "By alphabetic order\n" @@ -4596,11 +4588,11 @@ msgstr "" "Paur ordre alphabétique\n" "Par nombre de pads dans les équipotentielles (avancé)" -#: pcbnew/dialog_copper_zones_base.cpp:182 +#: pcbnew/dialog_copper_zones_base.cpp:181 msgid "Filter" msgstr "Filtre" -#: pcbnew/dialog_copper_zones_base.cpp:187 +#: pcbnew/dialog_copper_zones_base.cpp:186 msgid "" "Pattern in advanced mode, to filter net names in list\n" "Net names matching this pattern are not displayed" @@ -6402,11 +6394,11 @@ msgstr "Ajout Composant" msgid "Add Wire" msgstr "Ajouter Fils" -#: eeschema/libarch.cpp:66 +#: eeschema/libarch.cpp:68 msgid "Failed to create archive lib file " msgstr "Impossible de créer le fichier librairie archive " -#: eeschema/libarch.cpp:73 +#: eeschema/libarch.cpp:75 msgid "Failed to create doc lib file " msgstr "Impossible de créer le fichier lib document" @@ -6511,7 +6503,7 @@ msgstr "Oriente Composant" msgid "Footprint " msgstr "Empreinte: " -#: eeschema/onrightclick.cpp:322 +#: eeschema/onrightclick.cpp:323 #, c-format msgid "Unit %d %c" msgstr "Unité %d %c" @@ -10426,15 +10418,15 @@ msgstr "Texte Module invisible" msgid "Anchors" msgstr "Ancres" -#: pcbnew/set_color.h:432 +#: pcbnew/set_color.h:423 msgid "Show Noconnect" msgstr "Montrer Non Conn" -#: pcbnew/set_color.h:441 +#: pcbnew/set_color.h:432 msgid "Show Modules Cmp" msgstr "Afficher Modules Cmp" -#: pcbnew/set_color.h:450 +#: pcbnew/set_color.h:441 msgid "Show Modules Cu" msgstr "Afficher Modules Cu" @@ -10474,7 +10466,7 @@ msgstr "Type Err(%d): %s
  • %s: %s
  • %s: %s
" msgid "ErrType(%d): %s
  • %s: %s
" msgstr "ErrType(%d): %s
  • %s: %s
" -#: pcbnew/dialog_copper_zones_base.h:101 +#: pcbnew/dialog_copper_zones_base.h:99 msgid "Fill Zones Options" msgstr "Options de Remplissage de Zone" @@ -10798,6 +10790,20 @@ msgstr "Imprimer" msgid "Create SVG file" msgstr "Créer Fichier SVG" +#~ msgid "Do not Show Zones" +#~ msgstr "Ne pas montrer Zones" +#~ msgid "Show Zones" +#~ msgstr "Montrer Zones" +#~ msgid "" +#~ "If enabled, filled areas in is this zone will be displayed as non filled " +#~ "polygons.\n" +#~ "If disabled, filled areas in is this zone will be displayed as \"solid\" " +#~ "areas (normal mode)." +#~ msgstr "" +#~ "Si activé, les surfaces remplies dans cette zone seront affichées comme " +#~ "des polygones non remplis.\n" +#~ "Si désactivé, les surfaces remplies dans cette zone seront affichées " +#~ "comme des surfaces \"solides\"." #~ msgid "grid user" #~ msgstr "grille user" diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 5ec8e7220c..863edd76aa 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -28,6 +28,7 @@ set(PCBNEW_SRCS class_mire.cpp class_module.cpp class_pad.cpp + class_pad_draw_functions.cpp classpcb.cpp class_pcb_text.cpp class_text_mod.cpp diff --git a/pcbnew/affiche.cpp b/pcbnew/affiche.cpp index 76f4b1f0a2..16fb1137b0 100644 --- a/pcbnew/affiche.cpp +++ b/pcbnew/affiche.cpp @@ -32,7 +32,7 @@ void Affiche_Infos_Equipot( int netcode, WinEDA_BasePcbFrame* frame ) equipot = frame->m_Pcb->FindNet( netcode ); if( equipot ) - Affiche_1_Parametre( frame, 1, _( "Net Name" ), equipot->m_Netname, RED ); + Affiche_1_Parametre( frame, 1, _( "Net Name" ), equipot->GetNetname(), RED ); else Affiche_1_Parametre( frame, 1, _( "No Net (not connected)" ), wxEmptyString, RED ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index af34b08b5b..ad25c9132c 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -835,7 +835,7 @@ EQUIPOT* BOARD::FindNet( const wxString & aNetname ) const { for( EQUIPOT* net = m_Equipots; net; net=net->Next() ) { - if( net->m_Netname == aNetname ) + if( net->GetNetname() == aNetname ) return net; } } @@ -882,7 +882,7 @@ int s_SortByNames(const void * ptr1, const void * ptr2) { EQUIPOT* item1 = * (EQUIPOT**) ptr1; EQUIPOT* item2 = * (EQUIPOT**) ptr2; - return item1->m_Netname.CmpNoCase(item2->m_Netname); + return item1->GetNetname().CmpNoCase(item2->GetNetname()); } // Sort nets by decreasing pad count @@ -892,7 +892,7 @@ int s_SortByNodes(const void * ptr1, const void * ptr2) EQUIPOT* item2 = * (EQUIPOT**) ptr2; if ( (item1->m_NbNodes - item2->m_NbNodes) != 0 ) return - (item1->m_NbNodes - item2->m_NbNodes); - return item1->m_Netname.CmpNoCase(item2->m_Netname); + return item1->GetNetname().CmpNoCase(item2->GetNetname()); } @@ -912,7 +912,7 @@ int BOARD::ReturnSortedNetnamesList( wxArrayString & aNames, const int aSort_Typ /* count items to list and sort */ for( net = m_Equipots; net; net=net->Next() ) { - if ( net->m_Netname.IsEmpty() ) continue; + if ( net->GetNetname().IsEmpty() ) continue; NetCount++; } @@ -922,7 +922,7 @@ int BOARD::ReturnSortedNetnamesList( wxArrayString & aNames, const int aSort_Typ EQUIPOT* * net_ptr_list = (EQUIPOT* *) MyMalloc( NetCount * sizeof(* net_ptr_list) ); for( ii = 0, net = m_Equipots; net; net=net->Next() ) { - if ( net->m_Netname.IsEmpty() ) continue; + if ( net->GetNetname().IsEmpty() ) continue; net_ptr_list[ii] = net; ii++; } @@ -945,7 +945,7 @@ int BOARD::ReturnSortedNetnamesList( wxArrayString & aNames, const int aSort_Typ for( ii = 0; ii < NetCount; ii++ ) { net = net_ptr_list[ii]; - aNames.Add(net->m_Netname); + aNames.Add(net->GetNetname()); } MyFree(net_ptr_list); diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index 240b518893..ceef22f1d7 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -56,7 +56,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const switch( item->Type() ) { case TYPE_EQUIPOT: - text << _( "Net" ) << ( (EQUIPOT*) item )->m_Netname << wxT( " " ) << + text << _( "Net" ) << ( (EQUIPOT*) item )->GetNetname() << wxT( " " ) << ( (EQUIPOT*) item )->GetNet(); break; @@ -130,7 +130,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const net = aPcb->FindNet( ((TRACK*)item)->GetNet() ); if( net ) { - text << wxT( " [" ) << net->m_Netname << wxT( "]" ); + text << wxT( " [" ) << net->GetNetname() << wxT( "]" ); } text << _( " on " ) << aPcb->GetLayerName( item->GetLayer() ).Trim() << wxT(" ") << _("Net:") << ((TRACK*)item)->GetNet() @@ -160,7 +160,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const net = aPcb->FindNet( ( (ZONE_CONTAINER*) item )->GetNet() ); if( net ) { - text << wxT( " [" ) << net->m_Netname << wxT( "]" ); + text << wxT( " [" ) << net->GetNetname() << wxT( "]" ); } } else // A netcode < 0 is an error flag (Netname not found or area not initialised) @@ -182,7 +182,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const net = aPcb->FindNet( ( (SEGZONE*) item )->GetNet() ); if( net ) { - text << wxT( " [" ) << net->m_Netname << wxT( "]" ); + text << wxT( " [" ) << net->GetNetname() << wxT( "]" ); } text << _( " on " ) << aPcb->GetLayerName( item->GetLayer() ).Trim(); break; @@ -202,7 +202,7 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const net = aPcb->FindNet( via->GetNet() ); if( net ) { - text << wxT( " [" ) << net->m_Netname << wxT( "]" ); + text << wxT( " [" ) << net->GetNetname() << wxT( "]" ); } text << wxChar(' ') << _("Net:") << via->GetNet(); diff --git a/pcbnew/class_equipot.cpp b/pcbnew/class_equipot.cpp index 4866e91d23..522443b5a9 100644 --- a/pcbnew/class_equipot.cpp +++ b/pcbnew/class_equipot.cpp @@ -26,7 +26,7 @@ EQUIPOT::EQUIPOT( BOARD_ITEM* aParent ) : BOARD_ITEM( aParent, TYPE_EQUIPOT ) { SetNet( 0 ); - m_NbNodes = m_NbLink = m_NbNoconn = 0; + m_NbNodes = m_NbLink = m_NbNoconn = 0; m_Masque_Layer = 0; m_Masque_Plan = 0; m_ForceWidth = 0; @@ -44,15 +44,16 @@ EQUIPOT::~EQUIPOT() } - wxPoint& EQUIPOT::GetPosition() { static wxPoint dummy; + return dummy; } + /*********************************************************/ -int EQUIPOT:: ReadEquipotDescr( FILE* File, int* LineNum ) +int EQUIPOT:: ReadDescr( FILE* File, int* LineNum ) /*********************************************************/ /* Routine de lecture de 1 descr Equipotentielle. @@ -90,31 +91,52 @@ int EQUIPOT:: ReadEquipotDescr( FILE* File, int* LineNum ) } +/**************************************/ bool EQUIPOT::Save( FILE* aFile ) const +/**************************************/ { if( GetState( DELETED ) ) return true; - bool rc = false; + bool success = false; fprintf( aFile, "$EQUIPOT\n" ); - fprintf( aFile, "Na %d \"%.16s\"\n", GetNet(), CONV_TO_UTF8( m_Netname ) ); + fprintf( aFile, "Na %d \"%s\"\n", GetNet(), CONV_TO_UTF8( m_Netname ) ); fprintf( aFile, "St %s\n", "~" ); if( m_ForceWidth ) fprintf( aFile, "Lw %d\n", m_ForceWidth ); - if( fprintf( aFile, "$EndEQUIPOT\n" ) != sizeof("$EndEQUIPOT\n")-1 ) + if( fprintf( aFile, "$EndEQUIPOT\n" ) != sizeof("$EndEQUIPOT\n") - 1 ) goto out; - rc = true; + success = true; out: - return rc; + return success; +} + +/** + * Function SetNetname + * @param const wxString : the new netname + */ +void EQUIPOT::SetNetname( const wxString & aNetname ) +{ + m_Netname = aNetname; + m_ShortNetname = m_Netname.AfterLast( '/' ); +} + + +/** function Draw + * we actually could show a NET, simply show all the tracks and pads or net name on pad and vias + */ +void EQUIPOT::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int aDrawMode, const wxPoint& offset ) +{ } #if defined(DEBUG) + /** * Function Show * is used to output the object tree, currently for debugging only. @@ -126,9 +148,9 @@ void EQUIPOT::Show( int nestLevel, std::ostream& os ) { // for now, make it look like XML: NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << - " name=\"" << m_Netname.mb_str() << '"' << - " netcode=\"" << GetNet() << "\"/>\n"; + " name=\"" << m_Netname.mb_str() << '"' << + " netcode=\"" << GetNet() << "\"/>\n"; } + + #endif - - diff --git a/pcbnew/class_equipot.h b/pcbnew/class_equipot.h index 1b84250256..1ee87baba3 100644 --- a/pcbnew/class_equipot.h +++ b/pcbnew/class_equipot.h @@ -1,22 +1,21 @@ -/*************************************************************************/ -/* classe EQUIPOT: definition des elements relatifs aux equipotentielles */ -/*************************************************************************/ - - -/* Representation des descriptions des equipotentielles */ +/*************************************************/ +/* classe EQUIPOT: Class to handle info on nets */ +/*************************************************/ class EQUIPOT : public BOARD_ITEM { private: - int m_NetCode; // numero de code interne du net + int m_NetCode; // this is a number equivalent to the net name + // Used for fast comparisons in rastnest and DRC computations. + wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema + wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout public: - wxString m_Netname; // nom du net int status; // no route, hight light... - int m_NbNodes; // nombre de pads appartenant au net - int m_NbLink; // nombre de chevelus - int m_NbNoconn; // nombre de chevelus actifs + int m_NbNodes; // Pads count for this net + int m_NbLink; // Ratsnets count for this net + int m_NbNoconn; // Ratsnets remaining to route count int m_Masque_Layer; // couches interdites (bit 0 = layer 0...) int m_Masque_Plan; // couches mises en plan de cuivre int m_ForceWidth; // specific width (O = default width) @@ -41,7 +40,7 @@ public: wxPoint& GetPosition(); /* Readind and writing data on files */ - int ReadEquipotDescr( FILE* File, int* LineNum ); + int ReadDescr( FILE* File, int* LineNum ); /** * Function Save @@ -52,11 +51,11 @@ public: bool Save( FILE* aFile ) const; + /** function Draw + * @todo we actually could show a NET, simply show all the tracks and pads or net name on pad and vias + */ void Draw( WinEDA_DrawPanel* panel, wxDC* DC, - int aDrawMode, const wxPoint& offset = ZeroOffset ) - { - // @todo we actually could show a NET, simply show all the tracks and pads - } + int aDrawMode, const wxPoint& offset = ZeroOffset ); /** @@ -66,6 +65,23 @@ public: int GetNet() const { return m_NetCode; } void SetNet( int aNetCode ) { m_NetCode = aNetCode; } + /** + * Function GetNetname + * @return const wxString * , a pointer to the full netname + */ + wxString GetNetname() const { return m_Netname; } + /** + * Function GetShortNetname + * @return const wxString * , a pointer to the short netname + */ + wxString GetShortNetname() const { return m_ShortNetname; } + + /** + * Function SetNetname + * @param const wxString : the new netname + */ + void SetNetname( const wxString & aNetname ); + /** * Function GetClass diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index b6186584c3..60f0d5507b 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -3,24 +3,12 @@ /************************************************/ #include "fctsys.h" -#include "gr_basic.h" -#include "wxstruct.h" #include "common.h" #include "pcbnew.h" #include "trigo.h" #include "id.h" // ID_TRACK_BUTT -#ifdef PCBNEW -#include "drag.h" -#endif - -#ifdef CVPCB -#include "cvpcb.h" - -#endif - -#include "protos.h" /*******************************/ /* classe D_PAD : constructeur */ @@ -30,7 +18,7 @@ D_PAD::D_PAD( MODULE* parent ) : BOARD_CONNECTED_ITEM( parent, TYPE_PAD ) { m_NumPadName = 0; m_Masque_Layer = CUIVRE_LAYER; - m_DrillShape = PAD_CIRCLE; // Drill shape = circle + m_DrillShape = PAD_CIRCLE; // Drill shape = circle m_Size.x = m_Size.y = 500; @@ -41,9 +29,9 @@ D_PAD::D_PAD( MODULE* parent ) : BOARD_CONNECTED_ITEM( parent, TYPE_PAD ) m_PadShape = PAD_CIRCLE; // forme CERCLE, PAD_RECT PAD_OVAL PAD_TRAPEZOID ou libre m_Attribut = PAD_STANDARD; // NORMAL, PAD_SMD, PAD_CONN, Bit 7 = STACK - m_Orient = 0; // en 1/10 degres + m_Orient = 0; // en 1/10 degres - SetSubRatsnest(0); + SetSubRatsnest( 0 ); ComputeRayon(); } @@ -72,8 +60,8 @@ void D_PAD::ComputeRayon() case PAD_RECT: case PAD_TRAPEZOID: - m_Rayon = (int) (sqrt( (double) m_Size.y * m_Size.y - + (double) 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; } } @@ -87,10 +75,10 @@ void D_PAD::ComputeRayon() EDA_Rect D_PAD::GetBoundingBox() { // Calculate area: - ComputeRayon(); // calculate the radius of the area, considered as a circle - EDA_Rect area; - area.SetOrigin(m_Pos); - area.Inflate(m_Rayon, m_Rayon); + ComputeRayon(); // calculate the radius of the area, considered as a circle + EDA_Rect area; + area.SetOrigin( m_Pos ); + area.Inflate( m_Rayon, m_Rayon ); return area; } @@ -171,6 +159,18 @@ void D_PAD::SetPadName( const wxString& name ) m_Padname[ii] = 0; } +/**************************************************/ +void D_PAD::SetNetname( const wxString & aNetname ) +/**************************************************/ +/** + * Function SetNetname + * @param const wxString : the new netname + */ +{ + m_Netname = aNetname; + m_ShortNetname = m_Netname.AfterLast( '/' ); +} + /********************************/ void D_PAD::Copy( D_PAD* source ) @@ -184,10 +184,10 @@ void D_PAD::Copy( D_PAD* source ) memcpy( m_Padname, source->m_Padname, sizeof(m_Padname) ); /* nom de la pastille */ SetNet( source->GetNet() ); /* Numero de net pour comparaisons rapides */ - m_Drill = source->m_Drill; // Diametre de percage + m_Drill = source->m_Drill; // Diametre de percage m_DrillShape = source->m_DrillShape; m_Offset = source->m_Offset; // Offset de la forme - m_Size = source->m_Size; // Dimension ( pour orient 0 ) + m_Size = source->m_Size; // Dimension ( pour orient 0 ) m_DeltaSize = source->m_DeltaSize; // delta sur formes rectangle -> trapezes m_Pos0 = source->m_Pos0; // Coord relatives a l'ancre du pad en // orientation 0 @@ -199,416 +199,7 @@ void D_PAD::Copy( D_PAD* source ) SetSubRatsnest( 0 ); SetSubNet( 0 ); m_Netname = source->m_Netname; -} - - -/*******************************************************************************************/ -void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoint& offset ) -/*******************************************************************************************/ - -/** Draw a pad: - * @param DC = device context - * @param offset = draw offset - * @param draw_mode = mode: GR_OR, GR_XOR, GR_AND... - */ -{ - int ii; - int color = 0; - int ux0, uy0, - dx, dx0, dy, dy0, - rotdx, - delta_cx, delta_cy, - xc, yc; - int angle; - wxPoint coord[4]; - int zoom; - int fillpad = 0; - wxPoint shape_pos; - - if ( m_Flags & DO_NOT_DRAW ) - return; - - wxASSERT( panel ); - - WinEDA_BasePcbFrame* frame = (WinEDA_BasePcbFrame*) panel->m_Parent; - - PCB_SCREEN* screen = frame->GetScreen(); - - zoom = screen->GetZoom(); - - if( frame->m_DisplayPadFill == FILLED ) - fillpad = 1; - -#ifdef PCBNEW - if( m_Flags & IS_MOVED ) - fillpad = 0; -#endif - - if( m_Masque_Layer & CMP_LAYER ) - color = g_PadCMPColor; - - if( m_Masque_Layer & CUIVRE_LAYER ) - color |= g_PadCUColor; - - if( color == 0 ) /* Not on copper layer */ - { - switch( m_Masque_Layer & ~ALL_CU_LAYERS ) - { - case ADHESIVE_LAYER_CU: - color = g_DesignSettings.m_LayerColor[ADHESIVE_N_CU]; - break; - - case ADHESIVE_LAYER_CMP: - color = g_DesignSettings.m_LayerColor[ADHESIVE_N_CMP]; - break; - - case SOLDERPASTE_LAYER_CU: - color = g_DesignSettings.m_LayerColor[SOLDERPASTE_N_CU]; - break; - - case SOLDERPASTE_LAYER_CMP: - color = g_DesignSettings.m_LayerColor[SOLDERPASTE_N_CMP]; - break; - - case SILKSCREEN_LAYER_CU: - color = g_DesignSettings.m_LayerColor[SILKSCREEN_N_CU]; - break; - - case SILKSCREEN_LAYER_CMP: - color = g_DesignSettings.m_LayerColor[SILKSCREEN_N_CMP]; - break; - - case SOLDERMASK_LAYER_CU: - color = g_DesignSettings.m_LayerColor[SOLDERMASK_N_CU]; - break; - - case SOLDERMASK_LAYER_CMP: - color = g_DesignSettings.m_LayerColor[SOLDERMASK_N_CMP]; - break; - - case DRAW_LAYER: - color = g_DesignSettings.m_LayerColor[DRAW_N]; - break; - - case COMMENT_LAYER: - color = g_DesignSettings.m_LayerColor[COMMENT_N]; - break; - - case ECO1_LAYER: - color = g_DesignSettings.m_LayerColor[ECO1_N]; - break; - - case ECO2_LAYER: - color = g_DesignSettings.m_LayerColor[ECO2_N]; - break; - - case EDGE_LAYER: - color = g_DesignSettings.m_LayerColor[EDGE_N]; - break; - - default: - color = DARKGRAY; - break; - } - } - - - // if PAD_SMD pad and high contrast mode - if( (m_Attribut==PAD_SMD || m_Attribut==PAD_CONN) && DisplayOpt.ContrastModeDisplay ) - { - // when routing tracks - if( frame && frame->m_ID_current_state == ID_TRACK_BUTT ) - { - int routeTop = screen->m_Route_Layer_TOP; - int routeBot = screen->m_Route_Layer_BOTTOM; - - // if routing between copper and component layers, - // or the current layer is one of said 2 external copper layers, - // then highlight only the current layer. - if( ((1<m_Active_Layer) & (CUIVRE_LAYER | CMP_LAYER)) ) - { - if( !IsOnLayer( screen->m_Active_Layer ) ) - { - color &= ~MASKCOLOR; - color |= DARKDARKGRAY; - } - } - - // else routing between an internal signal layer and some other layer. - // grey out all PAD_SMD pads not on current or the single selected - // external layer. - else if( !IsOnLayer( screen->m_Active_Layer ) - && !IsOnLayer( routeTop ) - && !IsOnLayer( routeBot ) ) - { - color &= ~MASKCOLOR; - color |= DARKDARKGRAY; - } - } - - // when not edting tracks, show PAD_SMD components not on active layer as greyed out - else - { - if( !IsOnLayer( screen->m_Active_Layer ) ) - { - color &= ~MASKCOLOR; - color |= DARKDARKGRAY; - } - } - } - - if( draw_mode & GR_SURBRILL ) - { - if( draw_mode & GR_AND ) - color &= ~HIGHT_LIGHT_FLAG; - else - color |= HIGHT_LIGHT_FLAG; - } - - if( color & HIGHT_LIGHT_FLAG ) - color = ColorRefs[color & MASKCOLOR].m_LightColor; - - GRSetDrawMode( DC, draw_mode ); /* mode de trace */ - - /* calcul du centre des pads en coordonnees Ecran : */ - shape_pos = ReturnShapePos(); - ux0 = shape_pos.x - offset.x; - uy0 = shape_pos.y - offset.y; - xc = ux0; - yc = uy0; - - /* le trace depend de la rotation de l'empreinte */ - - dx = dx0 = m_Size.x >> 1; - dy = dy0 = m_Size.y >> 1; /* demi dim dx et dy */ - - angle = m_Orient; - - bool DisplayIsol = DisplayOpt.DisplayPadIsol; - if( ( m_Masque_Layer & ALL_CU_LAYERS ) == 0 ) - DisplayIsol = FALSE; - - switch( m_PadShape & 0x7F ) - { - case PAD_CIRCLE: - if( fillpad ) - GRFilledCircle( &panel->m_ClipBox, DC, xc, yc, dx, 0, color, color ); - else - GRCircle( &panel->m_ClipBox, DC, xc, yc, dx, 0, color ); - - if( DisplayIsol ) - { - GRCircle( &panel->m_ClipBox, - DC, - xc, - yc, - dx + g_DesignSettings.m_TrackClearence, - 0, - color ); - } - break; - - case PAD_OVAL: - /* calcul de l'entraxe de l'ellipse */ - if( dx > dy ) /* ellipse horizontale */ - { - delta_cx = dx - dy; - delta_cy = 0; - rotdx = m_Size.y; - } - else /* ellipse verticale */ - { - delta_cx = 0; - delta_cy = dy - dx; - rotdx = m_Size.x; - } - RotatePoint( &delta_cx, &delta_cy, angle ); - - if( fillpad ) - { - GRFillCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, - rotdx, color ); - } - else - { - GRCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, - rotdx, color ); - } - - /* Trace de la marge d'isolement */ - if( DisplayIsol ) - { - rotdx = rotdx + g_DesignSettings.m_TrackClearence + g_DesignSettings.m_TrackClearence; - - GRCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, - rotdx, color ); - } - break; - - case PAD_RECT: - case PAD_TRAPEZOID: - { - int ddx, ddy; - ddx = m_DeltaSize.x >> 1; - ddy = m_DeltaSize.y >> 1; /* demi dim dx et dy */ - - coord[0].x = -dx - ddy; - coord[0].y = +dy + ddx; - - coord[1].x = -dx + ddy; - coord[1].y = -dy - ddx; - - coord[2].x = +dx - ddy; - coord[2].y = -dy + ddx; - - coord[3].x = +dx + ddy; - coord[3].y = +dy - ddx; - - for( ii = 0; ii < 4; ii++ ) - { - RotatePoint( &coord[ii].x, &coord[ii].y, angle ); - coord[ii].x = coord[ii].x + ux0; - coord[ii].y = coord[ii].y + uy0; - } - - GRClosedPoly( &panel->m_ClipBox, DC, 4, (int*) coord, fillpad, color, color ); - - if( DisplayIsol ) - { - dx += g_DesignSettings.m_TrackClearence; - dy += g_DesignSettings.m_TrackClearence; - - coord[0].x = -dx - ddy; - coord[0].y = dy + ddx; - - coord[1].x = -dx + ddy; - coord[1].y = -dy - ddx; - - coord[2].x = dx - ddy; - coord[2].y = -dy + ddx; - - coord[3].x = dx + ddy; - coord[3].y = dy - ddx; - - for( ii = 0; ii < 4; ii++ ) - { - RotatePoint( &coord[ii].x, &coord[ii].y, angle ); - coord[ii].x = coord[ii].x + ux0; - coord[ii].y = coord[ii].y + uy0; - } - - GRClosedPoly( &panel->m_ClipBox, DC, 4, (int*) coord, 0, color, color ); - } - } - break; - - - default: - break; - } - - /* Draw the pad hole */ - int cx0 = m_Pos.x - offset.x; - int cy0 = m_Pos.y - offset.y; - int hole = m_Drill.x >> 1; - - if( fillpad && hole ) - { - bool blackpenstate = false; - if ( g_IsPrinting ) - { - blackpenstate = GetGRForceBlackPenState( ); - GRForceBlackPen( false ); - color = WHITE; - } - else - color = BLACK; // or DARKGRAY; - - if( draw_mode != GR_XOR ) - GRSetDrawMode( DC, GR_COPY ); - else - GRSetDrawMode( DC, GR_XOR ); - - switch( m_DrillShape ) - { - case PAD_CIRCLE: - if( (hole / zoom) > 1 ) /* draw hole if its size is enought */ - GRFilledCircle( &panel->m_ClipBox, DC, cx0, cy0, hole, 0, color, color ); - break; - - case PAD_OVAL: - dx = m_Drill.x >> 1; - dy = m_Drill.y >> 1; /* demi dim dx et dy */ - - /* calcul de l'entraxe de l'ellipse */ - if( m_Drill.x > m_Drill.y ) /* ellipse horizontale */ - { - delta_cx = dx - dy; delta_cy = 0; - rotdx = m_Drill.y; - } - else /* ellipse verticale */ - { - delta_cx = 0; delta_cy = dy - dx; - rotdx = m_Drill.x; - } - RotatePoint( &delta_cx, &delta_cy, angle ); - - GRFillCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, - rotdx, color ); - break; - - default: - break; - } - if ( g_IsPrinting ) - GRForceBlackPen( blackpenstate ); - } - - GRSetDrawMode( DC, draw_mode ); - - /* Trace du symbole "No connect" ( / ou \ ou croix en X) si necessaire : */ - if( m_Netname.IsEmpty() && DisplayOpt.DisplayPadNoConn ) - { - dx0 = MIN( dx0, dy0 ); - int nc_color = BLUE; - - if( m_Masque_Layer & CMP_LAYER ) /* Trace forme \ */ - GRLine( &panel->m_ClipBox, DC, cx0 - dx0, cy0 - dx0, - cx0 + dx0, cy0 + dx0, 0, nc_color ); - - if( m_Masque_Layer & CUIVRE_LAYER ) /* Trace forme / */ - GRLine( &panel->m_ClipBox, DC, cx0 + dx0, cy0 - dx0, - cx0 - dx0, cy0 + dx0, 0, nc_color ); - } - - /* Draw the pad number */ - if( frame && !frame->m_DisplayPadNum ) - return; - - dx = MIN( m_Size.x, m_Size.y ); /* dx = text size */ - if( (dx / zoom) > 12 ) /* size must be enought to draw 2 chars */ - { - wxString buffer; - - ReturnStringPadName( buffer ); - dy = buffer.Len(); - - /* Draw text with an angle between -90 deg and + 90 deg */ - NORMALIZE_ANGLE_90( angle ); - if( dy < 2 ) - dy = 2; /* text min size is 2 char */ - - dx = (dx * 9 ) / (dy * 13 ); /* Text size ajusted to pad size */ - - DrawGraphicText( panel, DC, wxPoint( ux0, uy0 ), - WHITE, buffer, angle, wxSize( dx, dx ), - GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER ); - } + m_ShortNetname = source->m_ShortNetname; } @@ -668,9 +259,9 @@ int D_PAD::ReadDescr( FILE* File, int* LineNum ) PtLine++; nn = sscanf( PtLine, " %s %d %d %d %d %d", - BufCar, &m_Size.x, &m_Size.y, - &m_DeltaSize.x, &m_DeltaSize.y, - &m_Orient ); + BufCar, &m_Size.x, &m_Size.y, + &m_DeltaSize.x, &m_DeltaSize.y, + &m_Orient ); ll = 0xFF & BufCar[0]; @@ -698,7 +289,7 @@ int D_PAD::ReadDescr( FILE* File, int* LineNum ) case 'D': BufCar[0] = 0; nn = sscanf( PtLine, "%d %d %d %s %d %d", &m_Drill.x, - &m_Offset.x, &m_Offset.y, BufCar, &dx, &dy ); + &m_Offset.x, &m_Offset.y, BufCar, &dx, &dy ); m_Drill.y = m_Drill.x; m_DrillShape = PAD_CIRCLE; @@ -714,7 +305,7 @@ int D_PAD::ReadDescr( FILE* File, int* LineNum ) case 'A': nn = sscanf( PtLine, "%s %s %X", BufLine, BufCar, - &m_Masque_Layer ); + &m_Masque_Layer ); /* Contenu de BufCar non encore utilise ( reserve pour evolutions * ulterieures */ @@ -735,7 +326,7 @@ int D_PAD::ReadDescr( FILE* File, int* LineNum ) /* Lecture du netname */ ReadDelimitedText( BufLine, PtLine, sizeof(BufLine) ); - m_Netname = CONV_FROM_UTF8( StrPurge( BufLine ) ); + SetNetname(CONV_FROM_UTF8( StrPurge( BufLine ) )); break; case 'P': @@ -763,10 +354,10 @@ bool D_PAD::Save( FILE* aFile ) const if( GetState( DELETED ) ) return true; - bool rc = false; + bool rc = false; // check the return values for first and last fprints() in this function - if( fprintf( aFile, "$PAD\n" ) != sizeof("$PAD\n")-1 ) + if( fprintf( aFile, "$PAD\n" ) != sizeof("$PAD\n") - 1 ) goto out; switch( m_PadShape ) @@ -790,8 +381,8 @@ bool D_PAD::Save( FILE* aFile ) const } fprintf( aFile, "Sh \"%.4s\" %c %d %d %d %d %d\n", - m_Padname, cshape, m_Size.x, m_Size.y, - m_DeltaSize.x, m_DeltaSize.y, m_Orient ); + m_Padname, cshape, m_Size.x, m_Size.y, + m_DeltaSize.x, m_DeltaSize.y, m_Orient ); fprintf( aFile, "Dr %d %d %d", m_Drill.x, m_Offset.x, m_Offset.y ); if( m_DrillShape == PAD_OVAL ) @@ -826,7 +417,7 @@ bool D_PAD::Save( FILE* aFile ) const fprintf( aFile, "Po %d %d\n", m_Pos0.x, m_Pos0.y ); - if( fprintf( aFile, "$EndPAD\n" ) != sizeof("$EndPAD\n")-1 ) + if( fprintf( aFile, "$EndPAD\n" ) != sizeof("$EndPAD\n") - 1 ) goto out; rc = true; @@ -836,7 +427,6 @@ out: } - /******************************************************/ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame ) /******************************************************/ @@ -853,7 +443,8 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame ) static const wxString Msg_Pad_Layer[9] = { - wxT( "??? " ), wxT( "cmp " ), wxT( "cu " ), wxT( "cmp+cu " ), wxT( "int " ), + wxT( "??? " ), wxT( "cmp " ), wxT( "cu " ), wxT( "cmp+cu " ), wxT( + "int " ), wxT( "cmp+int " ), wxT( "cu+int " ), wxT( "all " ), wxT( "No copp" ) }; @@ -880,7 +471,7 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame ) pos += 10; #if 1 // Used only to debug connectivity calculations Line.Printf( wxT( "%d-%d-%d " ), GetSubRatsnest(), GetSubNet(), m_ZoneSubnet ); - Affiche_1_Parametre( frame, pos, wxT("L-P-Z"), Line, DARKGREEN ); + Affiche_1_Parametre( frame, pos, wxT( "L-P-Z" ), Line, DARKGREEN ); #endif wxString LayerInfo; @@ -962,8 +553,13 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame ) pos += 6; int attribut = m_Attribut & 15; - if ( attribut > 3 ) attribut = 3; - Affiche_1_Parametre( frame, pos, Msg_Pad_Shape[m_PadShape],Msg_Pad_Attribut[attribut], DARKGREEN ); + if( attribut > 3 ) + attribut = 3; + Affiche_1_Parametre( frame, + pos, + Msg_Pad_Shape[m_PadShape], + Msg_Pad_Attribut[attribut], + DARKGREEN ); valeur_param( m_Size.x, Line ); pos += 6; @@ -992,7 +588,7 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame ) int module_orient = module ? module->m_Orient : 0; if( module_orient ) Line.Printf( wxT( "%3.1f(+%3.1f)" ), - (float) (m_Orient - module_orient) / 10, (float) module_orient / 10 ); + (float) ( m_Orient - module_orient ) / 10, (float) module_orient / 10 ); else Line.Printf( wxT( "%3.1f" ), (float) m_Orient / 10 ); pos += 8; @@ -1011,7 +607,7 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame ) // see class_pad.h bool D_PAD::IsOnLayer( int aLayer ) const { - return (1<m_PadShape - padcmp->m_PadShape) ) return diff; @@ -1099,11 +695,20 @@ static const char* ShowPadType( int aPadType ) { switch( aPadType ) { - case PAD_CIRCLE: return "circle"; - case PAD_OVAL: return "oval"; - case PAD_RECT: return "rect"; - case PAD_TRAPEZOID: return "trap"; - default: return "??unknown??"; + case PAD_CIRCLE: + return "circle"; + + case PAD_OVAL: + return "oval"; + + case PAD_RECT: + return "rect"; + + case PAD_TRAPEZOID: + return "trap"; + + default: + return "??unknown??"; } } @@ -1112,11 +717,20 @@ static const char* ShowPadAttr( int aPadAttr ) { switch( aPadAttr ) { - case PAD_STANDARD: return "STD"; - case PAD_SMD: return "SMD"; - case PAD_CONN: return "CONN"; - case PAD_HOLE_NOT_PLATED: return "HOLE"; - default: return "??unkown??"; + case PAD_STANDARD: + return "STD"; + + case PAD_SMD: + return "SMD"; + + case PAD_CONN: + return "CONN"; + + case PAD_HOLE_NOT_PLATED: + return "HOLE"; + + default: + return "??unkown??"; } } @@ -1138,11 +752,11 @@ void D_PAD::Show( int nestLevel, std::ostream& os ) // for now, make it look like XML: NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << - " shape=\"" << ShowPadType( m_PadShape ) << '"' << - " attr=\"" << ShowPadAttr( m_Attribut ) << '"' << - " num=\"" << padname << '"' << - " net=\"" << m_Netname.mb_str() << '"' << - " netcode=\"" << GetNet() << '"' << + " shape=\"" << ShowPadType( m_PadShape ) << '"' << + " attr=\"" << ShowPadAttr( m_Attribut ) << '"' << + " num=\"" << padname << '"' << + " net=\"" << m_Netname.mb_str() << '"' << + " netcode=\"" << GetNet() << '"' << " layerMask=\"" << layerMask << '"' << m_Pos << "/>\n"; // NestedSpace( nestLevel+1, os ) << m_Text.mb_str() << '\n'; @@ -1150,4 +764,5 @@ void D_PAD::Show( int nestLevel, std::ostream& os ) // NestedSpace( nestLevel, os ) << "\n"; } + #endif diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 83eff82da4..173169c8a2 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -12,6 +12,8 @@ class D_PAD : public BOARD_CONNECTED_ITEM { private: int m_NetCode; // Net number for fast comparisons + wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema + wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout public: @@ -25,8 +27,6 @@ public: */ }; - wxString m_Netname; /* Net Name */ - int m_Masque_Layer; // Bitwise layer :1= copper layer, 15= cmp, // 2..14 = internal layers // 16 .. 31 = technical layers @@ -73,6 +73,30 @@ public: D_PAD* Next() { return (D_PAD*) Pnext; } + + /** + * Function GetNetname + * @return const wxString * , a pointer to the full netname + */ + wxString GetNetname() const { return m_Netname; } + /** + * Function GetShortNetname + * @return const wxString * , a pointer to the short netname + */ + wxString GetShortNetname() const { return m_ShortNetname; } + + /** + * Function SetNetname + * @param const wxString : the new netname + */ + void SetNetname( const wxString & aNetname ); + + /** + * Function GetShape + * @return the shape of this pad. + */ + int GetShape( ) { return (m_PadShape & 0xFF); } + /** * Function GetPosition * returns the position of this object. diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp new file mode 100644 index 0000000000..bab88b0d6f --- /dev/null +++ b/pcbnew/class_pad_draw_functions.cpp @@ -0,0 +1,466 @@ +/*******************************************************/ +/* class_pad_draw_function.cpp : functionsto draw pads */ +/*******************************************************/ + +#include "fctsys.h" +#include "gr_basic.h" + +#include "common.h" +#include "pcbnew.h" +#include "trigo.h" +#include "id.h" // ID_TRACK_BUTT + + +/*******************************************************************************************/ +void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoint& offset ) +/*******************************************************************************************/ + +/** Draw a pad: + * @param DC = device context + * @param offset = draw offset + * @param draw_mode = mode: GR_OR, GR_XOR, GR_AND... + */ +{ + int ii; + int color = 0; + int ux0, uy0, + dx, dx0, dy, dy0, + rotdx, + delta_cx, delta_cy, + xc, yc; + int angle; + wxPoint coord[4]; + int zoom; + int fillpad = 0; + wxPoint shape_pos; + + if( m_Flags & DO_NOT_DRAW ) + return; + + wxASSERT( panel ); + + zoom = panel->GetZoom(); + + WinEDA_BasePcbFrame* frame = (WinEDA_BasePcbFrame*) panel->m_Parent; + PCB_SCREEN* screen = frame->GetScreen(); + if( frame->m_DisplayPadFill == FILLED ) + fillpad = 1; + +#ifdef PCBNEW + if( m_Flags & IS_MOVED ) + fillpad = 0; +#endif + + if( m_Masque_Layer & CMP_LAYER ) + color = g_PadCMPColor; + + if( m_Masque_Layer & CUIVRE_LAYER ) + color |= g_PadCUColor; + + if( color == 0 ) /* Not on copper layer */ + { + switch( m_Masque_Layer & ~ALL_CU_LAYERS ) + { + case ADHESIVE_LAYER_CU: + color = g_DesignSettings.m_LayerColor[ADHESIVE_N_CU]; + break; + + case ADHESIVE_LAYER_CMP: + color = g_DesignSettings.m_LayerColor[ADHESIVE_N_CMP]; + break; + + case SOLDERPASTE_LAYER_CU: + color = g_DesignSettings.m_LayerColor[SOLDERPASTE_N_CU]; + break; + + case SOLDERPASTE_LAYER_CMP: + color = g_DesignSettings.m_LayerColor[SOLDERPASTE_N_CMP]; + break; + + case SILKSCREEN_LAYER_CU: + color = g_DesignSettings.m_LayerColor[SILKSCREEN_N_CU]; + break; + + case SILKSCREEN_LAYER_CMP: + color = g_DesignSettings.m_LayerColor[SILKSCREEN_N_CMP]; + break; + + case SOLDERMASK_LAYER_CU: + color = g_DesignSettings.m_LayerColor[SOLDERMASK_N_CU]; + break; + + case SOLDERMASK_LAYER_CMP: + color = g_DesignSettings.m_LayerColor[SOLDERMASK_N_CMP]; + break; + + case DRAW_LAYER: + color = g_DesignSettings.m_LayerColor[DRAW_N]; + break; + + case COMMENT_LAYER: + color = g_DesignSettings.m_LayerColor[COMMENT_N]; + break; + + case ECO1_LAYER: + color = g_DesignSettings.m_LayerColor[ECO1_N]; + break; + + case ECO2_LAYER: + color = g_DesignSettings.m_LayerColor[ECO2_N]; + break; + + case EDGE_LAYER: + color = g_DesignSettings.m_LayerColor[EDGE_N]; + break; + + default: + color = DARKGRAY; + break; + } + } + + + // if PAD_SMD pad and high contrast mode + if( (m_Attribut==PAD_SMD || m_Attribut==PAD_CONN) && DisplayOpt.ContrastModeDisplay ) + { + // when routing tracks + if( frame && frame->m_ID_current_state == ID_TRACK_BUTT ) + { + int routeTop = screen->m_Route_Layer_TOP; + int routeBot = screen->m_Route_Layer_BOTTOM; + + // if routing between copper and component layers, + // or the current layer is one of said 2 external copper layers, + // then highlight only the current layer. + if( ( (1 << routeTop) | (1 << routeBot) ) == (CUIVRE_LAYER | CMP_LAYER) + || ( (1 << screen->m_Active_Layer) & (CUIVRE_LAYER | CMP_LAYER) ) ) + { + if( !IsOnLayer( screen->m_Active_Layer ) ) + { + color &= ~MASKCOLOR; + color |= DARKDARKGRAY; + } + } + // else routing between an internal signal layer and some other layer. + // grey out all PAD_SMD pads not on current or the single selected + // external layer. + else if( !IsOnLayer( screen->m_Active_Layer ) + && !IsOnLayer( routeTop ) + && !IsOnLayer( routeBot ) ) + { + color &= ~MASKCOLOR; + color |= DARKDARKGRAY; + } + } + // when not edting tracks, show PAD_SMD components not on active layer as greyed out + else + { + if( !IsOnLayer( screen->m_Active_Layer ) ) + { + color &= ~MASKCOLOR; + color |= DARKDARKGRAY; + } + } + } + + if( draw_mode & GR_SURBRILL ) + { + if( draw_mode & GR_AND ) + color &= ~HIGHT_LIGHT_FLAG; + else + color |= HIGHT_LIGHT_FLAG; + } + + if( color & HIGHT_LIGHT_FLAG ) + color = ColorRefs[color & MASKCOLOR].m_LightColor; + + GRSetDrawMode( DC, draw_mode ); /* mode de trace */ + + /* calcul du centre des pads en coordonnees Ecran : */ + shape_pos = ReturnShapePos(); + ux0 = shape_pos.x - offset.x; + uy0 = shape_pos.y - offset.y; + xc = ux0; + yc = uy0; + + /* le trace depend de la rotation de l'empreinte */ + + dx = dx0 = m_Size.x >> 1; + dy = dy0 = m_Size.y >> 1; /* demi dim dx et dy */ + + angle = m_Orient; + + bool DisplayIsol = DisplayOpt.DisplayPadIsol; + if( ( m_Masque_Layer & ALL_CU_LAYERS ) == 0 ) + DisplayIsol = FALSE; + + switch( GetShape() ) + { + case PAD_CIRCLE: + if( fillpad ) + GRFilledCircle( &panel->m_ClipBox, DC, xc, yc, dx, 0, color, color ); + else + GRCircle( &panel->m_ClipBox, DC, xc, yc, dx, 0, color ); + + if( DisplayIsol ) + { + GRCircle( &panel->m_ClipBox, + DC, + xc, + yc, + dx + g_DesignSettings.m_TrackClearence, + 0, + color ); + } + break; + + case PAD_OVAL: + /* calcul de l'entraxe de l'ellipse */ + if( dx > dy ) /* ellipse horizontale */ + { + delta_cx = dx - dy; + delta_cy = 0; + rotdx = m_Size.y; + } + else /* ellipse verticale */ + { + delta_cx = 0; + delta_cy = dy - dx; + rotdx = m_Size.x; + } + RotatePoint( &delta_cx, &delta_cy, angle ); + + if( fillpad ) + { + GRFillCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, + ux0 - delta_cx, uy0 - delta_cy, + rotdx, color ); + } + else + { + GRCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, + ux0 - delta_cx, uy0 - delta_cy, + rotdx, color ); + } + + /* Trace de la marge d'isolement */ + if( DisplayIsol ) + { + rotdx = rotdx + g_DesignSettings.m_TrackClearence + g_DesignSettings.m_TrackClearence; + + GRCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, + ux0 - delta_cx, uy0 - delta_cy, + rotdx, color ); + } + break; + + case PAD_RECT: + case PAD_TRAPEZOID: + { + int ddx, ddy; + ddx = m_DeltaSize.x >> 1; + ddy = m_DeltaSize.y >> 1; /* demi dim dx et dy */ + + coord[0].x = -dx - ddy; + coord[0].y = +dy + ddx; + + coord[1].x = -dx + ddy; + coord[1].y = -dy - ddx; + + coord[2].x = +dx - ddy; + coord[2].y = -dy + ddx; + + coord[3].x = +dx + ddy; + coord[3].y = +dy - ddx; + + for( ii = 0; ii < 4; ii++ ) + { + RotatePoint( &coord[ii].x, &coord[ii].y, angle ); + coord[ii].x = coord[ii].x + ux0; + coord[ii].y = coord[ii].y + uy0; + } + + GRClosedPoly( &panel->m_ClipBox, DC, 4, (int*) coord, fillpad, color, color ); + + if( DisplayIsol ) + { + dx += g_DesignSettings.m_TrackClearence; + dy += g_DesignSettings.m_TrackClearence; + + coord[0].x = -dx - ddy; + coord[0].y = dy + ddx; + + coord[1].x = -dx + ddy; + coord[1].y = -dy - ddx; + + coord[2].x = dx - ddy; + coord[2].y = -dy + ddx; + + coord[3].x = dx + ddy; + coord[3].y = dy - ddx; + + for( ii = 0; ii < 4; ii++ ) + { + RotatePoint( &coord[ii].x, &coord[ii].y, angle ); + coord[ii].x = coord[ii].x + ux0; + coord[ii].y = coord[ii].y + uy0; + } + + GRClosedPoly( &panel->m_ClipBox, DC, 4, (int*) coord, 0, color, color ); + } + } + break; + + + default: + break; + } + + /* Draw the pad hole */ + int cx0 = m_Pos.x - offset.x; + int cy0 = m_Pos.y - offset.y; + int hole = m_Drill.x >> 1; + + if( fillpad && hole ) + { + bool blackpenstate = false; + if( g_IsPrinting ) + { + blackpenstate = GetGRForceBlackPenState(); + GRForceBlackPen( false ); + color = WHITE; + } + else + color = BLACK; // or DARKGRAY; + + if( draw_mode != GR_XOR ) + GRSetDrawMode( DC, GR_COPY ); + else + GRSetDrawMode( DC, GR_XOR ); + + switch( m_DrillShape ) + { + case PAD_CIRCLE: + if( (hole / zoom) > 1 ) /* draw hole if its size is enought */ + GRFilledCircle( &panel->m_ClipBox, DC, cx0, cy0, hole, 0, color, color ); + break; + + case PAD_OVAL: + dx = m_Drill.x >> 1; + dy = m_Drill.y >> 1; /* demi dim dx et dy */ + + /* calcul de l'entraxe de l'ellipse */ + if( m_Drill.x > m_Drill.y ) /* ellipse horizontale */ + { + delta_cx = dx - dy; delta_cy = 0; + rotdx = m_Drill.y; + } + else /* ellipse verticale */ + { + delta_cx = 0; delta_cy = dy - dx; + rotdx = m_Drill.x; + } + RotatePoint( &delta_cx, &delta_cy, angle ); + + GRFillCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, + ux0 - delta_cx, uy0 - delta_cy, + rotdx, color ); + break; + + default: + break; + } + + if( g_IsPrinting ) + GRForceBlackPen( blackpenstate ); + } + + GRSetDrawMode( DC, draw_mode ); + + /* Trace du symbole "No connect" ( / ou \ ou croix en X) si necessaire : */ + if( m_Netname.IsEmpty() && DisplayOpt.DisplayPadNoConn ) + { + dx0 = MIN( dx0, dy0 ); + int nc_color = BLUE; + + if( m_Masque_Layer & CMP_LAYER ) /* Trace forme \ */ + GRLine( &panel->m_ClipBox, DC, cx0 - dx0, cy0 - dx0, + cx0 + dx0, cy0 + dx0, 0, nc_color ); + + if( m_Masque_Layer & CUIVRE_LAYER ) /* Trace forme / */ + GRLine( &panel->m_ClipBox, DC, cx0 + dx0, cy0 - dx0, + cx0 - dx0, cy0 + dx0, 0, nc_color ); + } + + /* Draw the pad number */ + if( frame && !frame->m_DisplayPadNum ) + return; + + wxPoint tpos0 = wxPoint( ux0, uy0 ); // Position of the centre of text + wxPoint tpos = tpos0; + wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x + int len; + if( GetShape() == PAD_CIRCLE ) + angle = 0; + AreaSize = m_Size; + if( m_Size.y > m_Size.x ) + { + angle += 900; + AreaSize.x = m_Size.y; + AreaSize.y = m_Size.x; + } + + if( !m_Netname.IsEmpty() ) // if there is a netname, provides room to display this netname + { + AreaSize.y /= 2; // Text used only the upper area of the pad. The lower area displays the net name + tpos.y -= AreaSize.y / 2; + } + + // Calculate the position of text, that is the middle point of the upper area of the pad + RotatePoint( &tpos, wxPoint( ux0, uy0 ), angle ); + + /* Draw text with an angle between -90 deg and + 90 deg */ + int t_angle = angle; + NORMALIZE_ANGLE_90( t_angle ); + + /* Note: in next calculations, texte size is calculated for 3 or more chars. + Of course, pads nimbers and nets names can have less than 3 chars. + but after some tries, i found this is gives the best look + */ + #define MIN_CHAR_COUNT 3 + wxString buffer; + ReturnStringPadName( buffer ); + len = buffer.Len(); + len = MAX( len, MIN_CHAR_COUNT); + + int tsize = min( AreaSize.y, AreaSize.x / len ); + #define CHAR_SIZE_MIN 5 + if( (tsize / zoom) >= CHAR_SIZE_MIN ) // Not drawable in size too small. + { + tsize = (int) (tsize * 0.8); // reserve room for marges and segments thickness + + DrawGraphicText( panel, DC, tpos, + WHITE, buffer, t_angle, wxSize( tsize, tsize ), + GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, tsize / 8 ); + } + + // display the short netname + len = m_ShortNetname.Len(); + if (len == 0 ) + return; + len = MAX( len, MIN_CHAR_COUNT); + tsize = min( AreaSize.y, AreaSize.x / len ); + + if( (tsize / zoom) >= CHAR_SIZE_MIN ) // Not drawable in size too small. + { + tpos = tpos0; + tpos.y += AreaSize.y / 2; + RotatePoint( &tpos, wxPoint( ux0, uy0 ), angle ); + + tsize = (int) (tsize * 0.8); // reserve room for marges and segments thickness + DrawGraphicText( panel, DC, tpos, + WHITE, m_ShortNetname, t_angle, wxSize( tsize, tsize ), + GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, tsize / 8 ); + } +} + diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index a3a476c6fd..ef01dd821b 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -411,7 +411,7 @@ void TEXTE_MODULE::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const size.x = -size.x; /* Trace du texte */ - DrawGraphicText( panel, DC, pos, color, m_Text, + DrawGraphicText( panel, DC, pos, (enum EDA_Colors) color, m_Text, orient, size, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, width ); } diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 9f99fd1eea..81f8bb1e7f 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -38,6 +38,7 @@ void DbgDisplayTrackInfos( TRACK* track ) wxMessageBox( msg ); } + #endif @@ -50,13 +51,12 @@ static bool ShowClearance( const TRACK* aTrack ) { // maybe return true for tracks and vias, not for zone segments return !(aTrack->m_Flags & DRAW_ERASED) - && DisplayOpt.DisplayTrackIsol - && aTrack->GetLayer() <= LAST_COPPER_LAYER - && ( aTrack->Type() == TYPE_TRACK || aTrack->Type() == TYPE_VIA ); + && DisplayOpt.DisplayTrackIsol + && aTrack->GetLayer() <= LAST_COPPER_LAYER + && ( aTrack->Type() == TYPE_TRACK || aTrack->Type() == TYPE_VIA ); } - /**********************************************************/ TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) : BOARD_CONNECTED_ITEM( aParent, idtype ) @@ -138,16 +138,16 @@ TRACK* TRACK::Copy() const * Function GetDrillValue * calculate the drill value for vias (m-Drill if > 0, or default drill value for the board * @return real drill_value -*/ + */ int TRACK::GetDrillValue() const { - if ( Type() != TYPE_VIA ) + if( Type() != TYPE_VIA ) return 0; - if ( m_Drill >= 0 ) + if( m_Drill >= 0 ) return m_Drill; - if ( m_Shape == VIA_MICROVIA ) + if( m_Shape == VIA_MICROVIA ) return g_DesignSettings.m_MicroViaDrill; return g_DesignSettings.m_ViaDrill; @@ -222,7 +222,7 @@ int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) EDA_Rect TRACK::GetBoundingBox() { // end of track is round, this is its radius, rounded up - int radius = ( m_Width+1 )/2; + int radius = ( m_Width + 1 ) / 2; int ymax; int xmax; @@ -247,7 +247,7 @@ EDA_Rect TRACK::GetBoundingBox() } else { - radius = ( m_Width+1 )/2; + radius = ( m_Width + 1 ) / 2; ymax = MAX( m_Start.y, m_End.y ); xmax = MAX( m_Start.x, m_End.x ); @@ -269,7 +269,7 @@ EDA_Rect TRACK::GetBoundingBox() xmin -= radius; // return a rectangle which is [pos,dim) in nature. therefore the +1 - EDA_Rect ret( wxPoint( xmin, ymin ), wxSize( xmax-xmin+1, ymax-ymin+1 ) ); + EDA_Rect ret( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) ); return ret; } @@ -416,14 +416,14 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* Pcb ) * @return the item found in the linked list (or NULL if no track) */ { - TRACK* track; + TRACK* track; if( Type() == TYPE_ZONE ) track = Pcb->m_Zone; else track = Pcb->m_Track; - for( ; track; track = track->Next() ) + for( ; track; track = track->Next() ) { if( GetNet() <= track->GetNet() ) return track; @@ -509,7 +509,7 @@ TRACK* TRACK::GetEndNetCode( int NetCode ) bool TRACK::Save( FILE* aFile ) const { - int type = 0; + int type = 0; if( Type() == TYPE_VIA ) type = 1; @@ -518,17 +518,16 @@ bool TRACK::Save( FILE* aFile ) const return true; fprintf( aFile, "Po %d %d %d %d %d %d %d\n", m_Shape, - m_Start.x, m_Start.y, m_End.x, m_End.y, m_Width, m_Drill ); + m_Start.x, m_Start.y, m_End.x, m_End.y, m_Width, m_Drill ); fprintf( aFile, "De %d %d %d %lX %X\n", - m_Layer, type, GetNet(), - m_TimeStamp, ReturnStatus() ); + m_Layer, type, GetNet(), + m_TimeStamp, ReturnStatus() ); return true; } - /*********************************************************************/ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoint& notUsed ) /*********************************************************************/ @@ -545,9 +544,8 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin if( m_Flags & DRAW_ERASED ) // draw in background color, used by classs TRACK in gerbview { color = g_DrawBgColor; - D(printf("DRAW_ERASED in Track::Draw, g_DrawBgColor=%04X\n", g_DrawBgColor );) + D( printf( "DRAW_ERASED in Track::Draw, g_DrawBgColor=%04X\n", g_DrawBgColor ); ) } - else { color = g_DesignSettings.m_LayerColor[m_Layer]; @@ -586,8 +584,8 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin if( m_Shape == S_CIRCLE ) { - rayon = (int) hypot( (double) (m_End.x - m_Start.x), - (double) (m_End.y - m_Start.y) ); + rayon = (int) hypot( (double) ( m_End.x - m_Start.x ), + (double) ( m_End.y - m_Start.y ) ); if( (l_piste / zoom) < L_MIN_DESSIN ) { GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color ); @@ -606,7 +604,7 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin else { GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, - m_Width, color ); + m_Width, color ); } } return; @@ -615,27 +613,27 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin if( (l_piste / zoom) < L_MIN_DESSIN ) { GRLine( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, 0, color ); + m_End.x, m_End.y, 0, color ); return; } if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) { GRCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, m_Width, color ); + m_End.x, m_End.y, m_Width, color ); } else { GRFillCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, m_Width, color ); + m_End.x, m_End.y, m_Width, color ); } // Show clearance for tracks, not for zone segments if( ShowClearance( this ) ) { GRCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, - m_Width + (g_DesignSettings.m_TrackClearence * 2), color ); + m_End.x, m_End.y, + m_Width + (g_DesignSettings.m_TrackClearence * 2), color ); } } @@ -685,97 +683,115 @@ void SEGVIA::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoi rayon = zoom; GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color ); - if( rayon > (4 * zoom) ) + if( rayon <= (4 * zoom) ) // Size too small: cannot be drawn + return; + + int drill_rayon = GetDrillValue() / 2; + int inner_rayon = rayon - (2 * zoom); + + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + inner_rayon, color ); + + // Draw the via hole if the display option allows it + if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW ) { - int drill_rayon = GetDrillValue() / 2; - int inner_rayon = rayon - (2 * zoom); - - GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, - inner_rayon, color ); - - // Draw the via hole if the display option allows it - if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW ) + if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) // Display all drill holes requested + || ( (drill_rayon > 0 ) && !IsDrillDefault() ) ) // Or Display non default holes requested { - if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) || // Display all drill holes requested - ( (drill_rayon > 0 ) && ! IsDrillDefault() ) ) // Or Display non default holes requested + if( drill_rayon < inner_rayon ) // We can show the via hole { - if( drill_rayon < inner_rayon ) // We can show the via hole - { - GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, - drill_rayon, color ); - } + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + drill_rayon, color ); } } - - if( DisplayOpt.DisplayTrackIsol ) - GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, - rayon + g_DesignSettings.m_TrackClearence, color ); - - // for Micro Vias, draw a partial cross : - // X on component layer, or + on copper layer - // (so we can see 2 superimposed microvias ): - if( Shape() == VIA_MICROVIA ) - { - int ax, ay, bx, by; - - if( IsOnLayer(COPPER_LAYER_N) ) - { - ax = rayon; ay = 0; - bx = drill_rayon; by = 0; - } - else - { - ax = ay = (rayon * 707) / 1000; - bx = by = (drill_rayon * 707) / 1000; - } - - /* lines | or \ */ - GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay, - m_Start.x - bx , m_Start.y - by, 0, color ); - GRLine( &panel->m_ClipBox, DC, m_Start.x + bx , m_Start.y + by, - m_Start.x + ax , m_Start.y + ay, 0, color ); - - /* lines - or / */ - GRLine( &panel->m_ClipBox, DC, m_Start.x + ay, m_Start.y - ax , - m_Start.x + by, m_Start.y - bx, 0, color ); - GRLine( &panel->m_ClipBox, DC, m_Start.x - by, m_Start.y + bx , - m_Start.x - ay, m_Start.y + ax, 0, color ); - } - - // for Buried Vias, draw a partial line : - // orient depending on layer pair - // (so we can see superimposed buried vias ): - if( Shape() == VIA_BLIND_BURIED ) - { - int ax = 0, ay = rayon, bx = 0, by = drill_rayon; - int layer_top, layer_bottom; - - ((SEGVIA*)this)->ReturnLayerPair(&layer_top, &layer_bottom); - - /* lines for the top layer */ - RotatePoint( &ax, &ay, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount); - RotatePoint( &bx, &by, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount); - GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay, - m_Start.x - bx , m_Start.y - by, 0, color ); - - /* lines for the bottom layer */ - ax = 0; ay = rayon; bx = 0; by = drill_rayon; - RotatePoint( &ax, &ay, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount); - RotatePoint( &bx, &by, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount); - GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay, - m_Start.x - bx , m_Start.y - by, 0, color ); - } } -} + if( DisplayOpt.DisplayTrackIsol ) + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + rayon + g_DesignSettings.m_TrackClearence, color ); + + // for Micro Vias, draw a partial cross : + // X on component layer, or + on copper layer + // (so we can see 2 superimposed microvias ): + if( Shape() == VIA_MICROVIA ) + { + int ax, ay, bx, by; + + if( IsOnLayer( COPPER_LAYER_N ) ) + { + ax = rayon; ay = 0; + bx = drill_rayon; by = 0; + } + else + { + ax = ay = (rayon * 707) / 1000; + bx = by = (drill_rayon * 707) / 1000; + } + + /* lines | or \ */ + GRLine( &panel->m_ClipBox, DC, m_Start.x - ax, m_Start.y - ay, + m_Start.x - bx, m_Start.y - by, 0, color ); + GRLine( &panel->m_ClipBox, DC, m_Start.x + bx, m_Start.y + by, + m_Start.x + ax, m_Start.y + ay, 0, color ); + + /* lines - or / */ + GRLine( &panel->m_ClipBox, DC, m_Start.x + ay, m_Start.y - ax, + m_Start.x + by, m_Start.y - bx, 0, color ); + GRLine( &panel->m_ClipBox, DC, m_Start.x - by, m_Start.y + bx, + m_Start.x - ay, m_Start.y + ax, 0, color ); + } + + // for Buried Vias, draw a partial line : + // orient depending on layer pair + // (so we can see superimposed buried vias ): + if( Shape() == VIA_BLIND_BURIED ) + { + int ax = 0, ay = rayon, bx = 0, by = drill_rayon; + int layer_top, layer_bottom; + + ( (SEGVIA*) this )->ReturnLayerPair( &layer_top, &layer_bottom ); + + /* lines for the top layer */ + RotatePoint( &ax, &ay, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount ); + RotatePoint( &bx, &by, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount ); + GRLine( &panel->m_ClipBox, DC, m_Start.x - ax, m_Start.y - ay, + m_Start.x - bx, m_Start.y - by, 0, color ); + + /* lines for the bottom layer */ + ax = 0; ay = rayon; bx = 0; by = drill_rayon; + RotatePoint( &ax, &ay, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount ); + RotatePoint( &bx, &by, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount ); + GRLine( &panel->m_ClipBox, DC, m_Start.x - ax, m_Start.y - ay, + m_Start.x - bx, m_Start.y - by, 0, color ); + } + + // Display the short netname: + if( GetNet() == 0 ) + return; + EQUIPOT* net = ((BOARD*)GetParent())->FindNet( GetNet() ); + if( net == NULL ) + return; + + int len = net->GetShortNetname().Len(); + + // calculate a good size for the text (fixed to 9 pixels, if possible) + int tsize = m_Width / len; + if( ( tsize / zoom) >= 6 ) + { + tsize = (tsize * 8) / 10; // small reduction to give a better look, inside via + DrawGraphicText( panel, DC, m_Start, + WHITE, net->GetShortNetname(), 0, wxSize( tsize, tsize ), + GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, tsize / 8 ); + } +} // see class_track.h void TRACK::Display_Infos( WinEDA_DrawFrame* frame ) { - wxString msg; - int text_pos; - BOARD* board = ((WinEDA_PcbFrame*)frame)->m_Pcb; + wxString msg; + int text_pos; + BOARD* board = ( (WinEDA_PcbFrame*) frame )->m_Pcb; #ifdef RATSNET_DEBUG DbgDisplayTrackInfos( this ); @@ -807,15 +823,15 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame ) if( Type() == TYPE_TRACK - || Type() == TYPE_ZONE - || Type() == TYPE_VIA ) + || Type() == TYPE_ZONE + || Type() == TYPE_VIA ) { /* Display NetName pour les segments de piste type cuivre */ EQUIPOT* equipot = board->FindNet( GetNet() ); if( equipot ) - msg = equipot->m_Netname; + msg = equipot->GetNetname(); else msg = wxT( "" ); @@ -841,7 +857,7 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame ) #if defined(DEBUG) /* Display the flags */ - msg.Printf( wxT("0x%08X"), m_Flags ); + msg.Printf( wxT( "0x%08X" ), m_Flags ); Affiche_1_Parametre( frame, text_pos, _( "Flags" ), msg, BLUE ); text_pos += 8; @@ -919,7 +935,7 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) if( Type() == TYPE_VIA ) /* VIA rencontree */ { return (double) spot_cX * spot_cX + (double) spot_cY * spot_cY <= - (double) radius * radius; + (double) radius * radius; } else { @@ -930,6 +946,7 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) return false; } + /** * Function HitTest (overlayed) * tests if the given EDA_Rect intersect this object. @@ -937,7 +954,7 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) * @param refArea : the given EDA_Rect * @return bool - true if a hit, else false */ - bool TRACK::HitTest( EDA_Rect& refArea ) +bool TRACK::HitTest( EDA_Rect& refArea ) { if( refArea.Inside( m_Start ) ) return true; @@ -965,7 +982,7 @@ void TRACK::Show( int nestLevel, std::ostream& os ) " layer=\"" << m_Layer << '"' << " width=\"" << m_Width << '"' << " flags=\"" << m_Flags << '"' << - " status=\"" << GetState(-1) << '"' << + " status=\"" << GetState( -1 ) << '"' << // " drill=\"" << GetDrillValue() << '"' << " netcode=\"" << GetNet() << "\">" << @@ -1007,9 +1024,9 @@ void SEGVIA::Show( int nestLevel, std::ostream& os ) break; } - int topLayer; - int botLayer; - BOARD* board = (BOARD*) m_Parent; + int topLayer; + int botLayer; + BOARD* board = (BOARD*) m_Parent; ReturnLayerPair( &topLayer, &botLayer ); @@ -1019,7 +1036,7 @@ void SEGVIA::Show( int nestLevel, std::ostream& os ) if( board ) os << " layers=\"" << board->GetLayerName( topLayer ).Trim().mb_str() << "," - << board->GetLayerName( botLayer ).Trim().mb_str() << '"'; + << board->GetLayerName( botLayer ).Trim().mb_str() << '"'; os << " width=\"" << m_Width << '"' << " drill=\"" << GetDrillValue() << '"' << @@ -1035,33 +1052,34 @@ wxString TRACK::ShowState( int stateBits ) wxString ret; if( stateBits & CHAIN ) - ret << wxT(" | CHAIN"); + ret << wxT( " | CHAIN" ); if( stateBits & SEGM_AR ) - ret << wxT(" | SEGM_AR"); + ret << wxT( " | SEGM_AR" ); if( stateBits & SEGM_FIXE ) - ret << wxT(" | SEGM_FIXE"); + ret << wxT( " | SEGM_FIXE" ); if( stateBits & EDIT ) - ret << wxT(" | EDIT"); + ret << wxT( " | EDIT" ); if( stateBits & DRAG ) - ret << wxT(" | DRAG"); + ret << wxT( " | DRAG" ); if( stateBits & SURBRILL ) - ret << wxT(" | SURBRILL"); + ret << wxT( " | SURBRILL" ); if( stateBits & NO_TRACE ) - ret << wxT(" | NO_TRACE"); + ret << wxT( " | NO_TRACE" ); if( stateBits & DELETED ) - ret << wxT(" | DELETED"); + ret << wxT( " | DELETED" ); if( stateBits & BUSY ) - ret << wxT(" | BUSY"); - if( stateBits & END_ONPAD) - ret << wxT(" | END_ONPAD"); - if( stateBits & BEGIN_ONPAD) - ret << wxT(" | BEGIN_ONPAD"); - if( stateBits & FLAG0) - ret << wxT(" | FLAG0"); + ret << wxT( " | BUSY" ); + if( stateBits & END_ONPAD ) + ret << wxT( " | END_ONPAD" ); + if( stateBits & BEGIN_ONPAD ) + ret << wxT( " | BEGIN_ONPAD" ); + if( stateBits & FLAG0 ) + ret << wxT( " | FLAG0" ); if( stateBits & FLAG1 ) - ret << wxT(" | FLAG1"); + ret << wxT( " | FLAG1" ); return ret; } + #endif diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index d63b43eeb5..5dd731077b 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -26,7 +26,7 @@ private: public: - int m_Width; // 0 = line, > 0 = tracks, bus ... + int m_Width; // Thickness of track, or via diameter wxPoint m_Start; // Line start point wxPoint m_End; // Line end point int m_Shape; // vias: shape and type, Track = shape.. diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 871f26633d..7e142a1bd8 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -71,7 +71,7 @@ void ZONE_CONTAINER::SetNet( int anet_code ) { EQUIPOT* net = ( (BOARD*) m_Parent )->FindNet( anet_code ); if( net ) - m_Netname = net->m_Netname; + m_Netname = net->GetNetname(); else m_Netname.Empty(); } @@ -875,7 +875,7 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame ) EQUIPOT* equipot = ( (WinEDA_PcbFrame*) frame )->m_Pcb->FindNet( GetNet() ); if( equipot ) - msg = equipot->m_Netname; + msg = equipot->GetNetname(); else msg = wxT( "" ); } @@ -1047,7 +1047,7 @@ bool ZONE_CONTAINER::SetNetNameFromNetCode( void ) EQUIPOT* net; if ( m_Parent && (net = ((BOARD*)m_Parent)->FindNet( GetNet()) ) ) { - m_Netname = net->m_Netname; + m_Netname = net->GetNetname(); return true; } diff --git a/pcbnew/dialog_copper_zones.cpp b/pcbnew/dialog_copper_zones.cpp index 61f27f818f..7d1b3b7fd0 100644 --- a/pcbnew/dialog_copper_zones.cpp +++ b/pcbnew/dialog_copper_zones.cpp @@ -195,7 +195,7 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event ) { for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ ) { - if( ListNetName[ii] == equipot->m_Netname ) + if( ListNetName[ii] == equipot->GetNetname() ) { m_ListNetNameSelection->SetSelection( ii ); m_ListNetNameSelection->EnsureVisible( ii ); @@ -340,7 +340,7 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab g_Zone_Default_Setting.m_NetcodeSelection = 0; for( net = m_Parent->m_Pcb->m_Equipots; net; net = net->Next() ) { - if( net->m_Netname == net_name ) + if( net->GetNetname() == net_name ) { g_Zone_Default_Setting.m_NetcodeSelection = net->GetNet(); break; @@ -392,7 +392,7 @@ void dialog_copper_zone::OnNetSortingOptionSelected( wxCommandEvent& event ) { for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ ) { - if( ListNetName[ii] == equipot->m_Netname ) + if( ListNetName[ii] == equipot->GetNetname() ) { m_ListNetNameSelection->SetSelection( ii ); m_ListNetNameSelection->EnsureVisible( ii ); diff --git a/pcbnew/dialog_pad_properties.cpp b/pcbnew/dialog_pad_properties.cpp index 874472b879..e6ed43ceb1 100644 --- a/pcbnew/dialog_pad_properties.cpp +++ b/pcbnew/dialog_pad_properties.cpp @@ -84,7 +84,7 @@ DialogPadProperties::DialogPadProperties( WinEDA_BasePcbFrame* parent, D_PAD* Pa if( m_CurrentPad ) { - Current_PadNetName = m_CurrentPad->m_Netname; + Current_PadNetName = m_CurrentPad->GetNetname(); g_Current_PadName = m_CurrentPad->ReturnStringPadName(); } } @@ -511,7 +511,7 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event ) } m_CurrentPad->SetPadName( g_Current_PadName ); - if( m_CurrentPad->m_Netname != Current_PadNetName ) + if( m_CurrentPad->GetNetname() != Current_PadNetName ) { if( Current_PadNetName.IsEmpty() ) m_CurrentPad->SetNet( 0 ); @@ -521,7 +521,7 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event ) if( net ) { RastnestIsChanged = true; - m_CurrentPad->m_Netname = Current_PadNetName; + m_CurrentPad->SetNetname( Current_PadNetName ); m_CurrentPad->SetNet( net->GetNet() ); } else diff --git a/pcbnew/export_gencad.cpp b/pcbnew/export_gencad.cpp index 563a7654d1..f58358531b 100644 --- a/pcbnew/export_gencad.cpp +++ b/pcbnew/export_gencad.cpp @@ -442,15 +442,16 @@ void CreateSignalsSection( FILE* file, BOARD* pcb ) for( equipot = pcb->m_Equipots; equipot != NULL; equipot = equipot->Next() ) { - if( equipot->m_Netname == wxEmptyString ) // dummy equipot (non connexion) + if( equipot->GetNetname() == wxEmptyString ) // dummy equipot (non connexion) { - equipot->m_Netname << wxT( "NoConnection" ) << NbNoConn++; + wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++; + equipot->SetNetname(msg); ; } if( equipot->GetNet() <= 0 ) // dummy equipot (non connexion) continue; - msg = wxT( "\nSIGNAL " ) + equipot->m_Netname; + msg = wxT( "\nSIGNAL " ) + equipot->GetNetname(); fputs( CONV_TO_UTF8( msg ), file ); fputs( "\n", file ); @@ -587,8 +588,8 @@ void CreateRoutesSection( FILE* file, BOARD* pcb ) old_netcode = track->GetNet(); EQUIPOT* equipot = pcb->FindNet( track->GetNet() ); wxString netname; - if( equipot && (equipot->m_Netname != wxEmptyString) ) - netname = equipot->m_Netname; + if( equipot && (equipot->GetNetname() != wxEmptyString) ) + netname = equipot->GetNetname(); else netname = wxT( "_noname_" ); fprintf( file, "\nROUTE %s\n", CONV_TO_UTF8( netname ) ); @@ -649,7 +650,7 @@ void CreateDevicesSection( FILE* file, BOARD* pcb ) for( pad = module->m_Pads; pad != NULL; pad = pad->Next() ) { fprintf( file, "PINDESCR %.4s", pad->m_Padname ); - if( pad->m_Netname == wxEmptyString ) + if( pad->GetNetname() == wxEmptyString ) fputs( " NoConn\n", file ); else fprintf( file, " %.4s\n", pad->m_Padname ); diff --git a/pcbnew/ioascii.cpp b/pcbnew/ioascii.cpp index e742e132e6..711ec52223 100644 --- a/pcbnew/ioascii.cpp +++ b/pcbnew/ioascii.cpp @@ -808,7 +808,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) { EQUIPOT* Equipot = new EQUIPOT( m_Pcb ); m_Pcb->m_Equipots.PushBack( Equipot ); - Equipot->ReadEquipotDescr( File, &LineNum ); + Equipot->ReadDescr( File, &LineNum ); continue; } diff --git a/pcbnew/makefile.include b/pcbnew/makefile.include index fac8b1872c..52e9b74a90 100644 --- a/pcbnew/makefile.include +++ b/pcbnew/makefile.include @@ -49,6 +49,7 @@ OBJECTS= $(TARGET).o classpcb.o\ class_mire.o\ class_cotation.o\ class_pad.o \ + class_pad_draw_functions.o\ class_equipot.o \ class_module.o \ class_edge_mod.o \ diff --git a/pcbnew/move-drag_pads.cpp b/pcbnew/move-drag_pads.cpp index 4b8f94f24b..879bcb6085 100644 --- a/pcbnew/move-drag_pads.cpp +++ b/pcbnew/move-drag_pads.cpp @@ -206,7 +206,7 @@ void WinEDA_BasePcbFrame::AddPad( MODULE* Module, bool draw ) /* Mise a jour des caract de la pastille : */ Import_Pad_Settings( Pad, false ); - Pad->m_Netname.Empty(); + Pad->SetNetname(wxEmptyString); Pad->m_Pos = GetScreen()->m_Curseur; diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index 81fe8a8e7b..d02eea318a 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -296,7 +296,7 @@ void ReadPcbNetlist( WinEDA_PcbFrame* aFrame, PtPad = Module->m_Pads; for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Next() ) { - PtPad->m_Netname = wxEmptyString; + PtPad->SetNetname( wxEmptyString ); } } continue; @@ -597,9 +597,9 @@ int SetPadNetName( wxWindow* frame, char* Text, MODULE* Module ) { /* trouve */ trouve = TRUE; if( *TextNetName != '?' ) - pad->m_Netname = CONV_FROM_UTF8( TextNetName ); + pad->SetNetname( CONV_FROM_UTF8( TextNetName ) ); else - pad->m_Netname.Empty(); + pad->SetNetname( wxEmptyString); } } diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index d62f7319b1..8807f1464a 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -880,7 +880,7 @@ void WinEDA_BasePcbFrame::recalcule_pad_net_code() pad_courant = &m_Pcb->m_Pads[0]; for( ; ii > 0; pad_courant++, ii-- ) { - if( (*pad_courant)->m_Netname.IsEmpty() ) // pad not connected + if( (*pad_courant)->GetNetname().IsEmpty() ) // pad not connected { (*pad_courant)->SetNet( 0 ); continue; @@ -892,7 +892,7 @@ void WinEDA_BasePcbFrame::recalcule_pad_net_code() pad_ref = &m_Pcb->m_Pads[0]; while( pad_ref < pad_courant ) { - if( (*pad_ref)->m_Netname == (*pad_courant)->m_Netname ) + if( (*pad_ref)->GetNetname() == (*pad_courant)->GetNetname() ) break; // sont du meme met pad_ref++; @@ -926,7 +926,7 @@ void WinEDA_BasePcbFrame::recalcule_pad_net_code() // Set the net_code for this equipot and reset other values equipot->SetNet(ii); equipot->m_NbNodes = 0; - equipot->m_Netname.Empty(); + equipot->SetNetname(wxEmptyString); BufPtEquipot[ii] = equipot; } @@ -950,9 +950,9 @@ void WinEDA_BasePcbFrame::recalcule_pad_net_code() equipot = BufPtEquipot[net]; equipot->m_NbNodes++; - if( equipot->m_Netname.IsEmpty() ) + if( equipot->GetNetname().IsEmpty() ) { - equipot->m_Netname = (*pad_courant)->m_Netname; + equipot->SetNetname((*pad_courant)->GetNetname()); } } diff --git a/pcbnew/router.cpp b/pcbnew/router.cpp index 34e86c209b..c169f21020 100644 --- a/pcbnew/router.cpp +++ b/pcbnew/router.cpp @@ -189,7 +189,7 @@ void Out_Pads( BOARD* Pcb, FILE* outfile ) wxString Line; EQUIPOT* equipot = Pcb->FindNet( netcode ); Line.Printf( wxT( "Warning: %d pad, net %s" ), - nb_pads, equipot->m_Netname.GetData() ); + nb_pads, equipot->GetNetname().GetData() ); DisplayError( NULL, Line, 20 ); } fprintf( outfile, "r %d %d %d %d %d %d 1 1\n", diff --git a/pcbnew/solve.cpp b/pcbnew/solve.cpp index 28fb396a76..028357c988 100644 --- a/pcbnew/solve.cpp +++ b/pcbnew/solve.cpp @@ -245,7 +245,7 @@ int WinEDA_PcbFrame::Solve( wxDC* DC, int two_sides ) pt_equipot = m_Pcb->FindNet( current_net_code ); if( pt_equipot ) { - msg.Printf( wxT( "[%8.8s]" ), pt_equipot->m_Netname.GetData() ); + msg.Printf( wxT( "[%8.8s]" ), pt_equipot->GetNetname().GetData() ); Affiche_1_Parametre( this, 1, wxT( "Net route" ), msg, BROWN ); msg.Printf( wxT( "%d / %d" ), Ncurrent, Ntotal ); Affiche_1_Parametre( this, 12, wxT( "Activity" ), msg, BROWN ); diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 302f5850a3..af492f0a12 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1076,7 +1076,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) { int netcode = equipot->GetNet(); if( netcode > 0 ) - nets[ netcode ]->net_id = CONV_TO_UTF8( equipot->m_Netname ); + nets[ netcode ]->net_id = CONV_TO_UTF8( equipot->GetNetname() ); } items.Collect( aBoard, scanMODULEs ); @@ -1253,7 +1253,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) old_netcode = netcode; EQUIPOT* equipot = aBoard->FindNet( netcode ); wxASSERT( equipot ); - netname = CONV_TO_UTF8( equipot->m_Netname ); + netname = CONV_TO_UTF8( equipot->GetNetname() ); } WIRE* wire = new WIRE( wiring ); @@ -1315,7 +1315,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) EQUIPOT* equipot = aBoard->FindNet( netcode ); wxASSERT( equipot ); - dsnVia->net_id = CONV_TO_UTF8( equipot->m_Netname ); + dsnVia->net_id = CONV_TO_UTF8( equipot->GetNetname() ); dsnVia->via_type = T_protect; // @todo, this should be configurable } diff --git a/pcbnew/surbrill.cpp b/pcbnew/surbrill.cpp index 3ee6a4a2b8..00070096d0 100644 --- a/pcbnew/surbrill.cpp +++ b/pcbnew/surbrill.cpp @@ -45,11 +45,11 @@ void WinEDA_PcbFrame::Liste_Equipot( wxCommandEvent& event ) { wxString Line; /* calcul adr relative du nom de la pastille reference de la piste */ - if( !WildCompareString( msg, Equipot->m_Netname, FALSE ) ) + if( !WildCompareString( msg, Equipot->GetNetname(), FALSE ) ) continue; Line.Printf( wxT( "net_code = %3.3d [%.16s] " ), Equipot->GetNet(), - Equipot->m_Netname.GetData() ); + Equipot->GetNetname().GetData() ); List->Append( Line ); } @@ -65,7 +65,7 @@ void WinEDA_PcbFrame::Liste_Equipot( wxCommandEvent& event ) for( jj = 0; Equipot != NULL; Equipot = (EQUIPOT*) Equipot->Next() ) { /* calcul adr relative du nom de la pastille reference de la piste */ - if( !WildCompareString( msg, Equipot->m_Netname, FALSE ) ) + if( !WildCompareString( msg, Equipot->GetNetname(), FALSE ) ) continue; if( ii == jj ) diff --git a/pcbnew/tracepcb.cpp b/pcbnew/tracepcb.cpp index 8a48674363..75a9a3fa4f 100644 --- a/pcbnew/tracepcb.cpp +++ b/pcbnew/tracepcb.cpp @@ -190,6 +190,13 @@ void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* DC, { m_markers[i]->Draw( aPanel, DC, aDrawMode ); } + + // Draw equipots info + for( EQUIPOT* net = m_Equipots; net; net = net->Next() ) + { + if ( net->GetNet() != 0 ) // no net if 0 + net->Draw( aPanel, DC, aDrawMode ); + } } diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index b267f3057f..12c599862e 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -516,7 +516,7 @@ MODULE* WinEDA_BasePcbFrame::Exchange_Module( wxWindow* winaff, */ { wxPoint oldpos;/* memorisation temporaire pos curseur */ - D_PAD* pt_pad, * pt_old_pad; + D_PAD* pad, * old_pad; if( (OldModule->Type() != TYPE_MODULE) || (NewModule->Type() != TYPE_MODULE) ) @@ -553,19 +553,19 @@ MODULE* WinEDA_BasePcbFrame::Exchange_Module( wxWindow* winaff, NewModule->m_Path = OldModule->m_Path; /* mise a jour des netnames ( lorsque c'est possible) */ - pt_pad = NewModule->m_Pads; - for( ; pt_pad != NULL; pt_pad = pt_pad->Next() ) + pad = NewModule->m_Pads; + for( ; pad != NULL; pad = pad->Next() ) { - pt_pad->m_Netname = wxEmptyString; - pt_pad->SetNet( 0 ); - pt_old_pad = OldModule->m_Pads; - for( ; pt_old_pad != NULL; pt_old_pad = pt_old_pad->Next() ) + pad->SetNetname( wxEmptyString ); + pad->SetNet( 0 ); + old_pad = OldModule->m_Pads; + for( ; old_pad != NULL; old_pad = old_pad->Next() ) { - if( strnicmp( pt_pad->m_Padname, pt_old_pad->m_Padname, - sizeof(pt_pad->m_Padname) ) == 0 ) + if( strnicmp( pad->m_Padname, old_pad->m_Padname, + sizeof(pad->m_Padname) ) == 0 ) { - pt_pad->m_Netname = pt_old_pad->m_Netname; - pt_pad->SetNet( pt_old_pad->GetNet() ); + pad->SetNetname(old_pad->GetNetname() ); + pad->SetNet( old_pad->GetNet() ); } } } diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 1d5a4f4770..b79b0d5c06 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -801,7 +801,7 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container g_Zone_Default_Setting.ExportSetting( *zone_container); EQUIPOT* net = m_Pcb->FindNet( g_Zone_Default_Setting.m_NetcodeSelection ); if( net ) // net === NULL should not occur - zone_container->m_Netname = net->m_Netname; + zone_container->m_Netname = net->GetNetname(); // Combine zones if possible : @@ -897,7 +897,7 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v } } else - msg = net->m_Netname; + msg = net->GetNetname(); } else msg = _( "No Net" );