diff --git a/3d-viewer/3d_canvas.h b/3d-viewer/3d_canvas.h index 43a1f7ed85..d4ad84cebf 100644 --- a/3d-viewer/3d_canvas.h +++ b/3d-viewer/3d_canvas.h @@ -47,7 +47,7 @@ class BOARD_DESIGN_SETTINGS; class EDA_3D_FRAME; class S3D_VERTEX; -class SEGVIA; +class VIA; class D_PAD; // We are using GL lists to store layers and other items @@ -160,8 +160,8 @@ public: void Draw3DGrid( double aGriSizeMM ); void Draw3DAxis(); - void Draw3DViaHole( SEGVIA * aVia ); - void Draw3DPadHole( D_PAD * aPad ); + void Draw3DViaHole( const VIA * aVia ); + void Draw3DPadHole( const D_PAD * aPad ); DECLARE_EVENT_TABLE() }; diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 1afdfe9c27..289d3c3c72 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -257,8 +257,8 @@ void EDA_3D_CANVAS::BuildBoard3DView() // Build a polygon from edge cut items wxString msg; - if( ! pcb->GetBoardPolygonOutlines( bufferPcbOutlines, - allLayerHoles, &msg ) ) + + if( !pcb->GetBoardPolygonOutlines( bufferPcbOutlines, allLayerHoles, &msg ) ) { msg << wxT("\n\n") << _("Unable to calculate the board outlines.\n" @@ -274,7 +274,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() bool hightQualityMode = false; for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; - layer++ ) + ++layer ) { if( layer != LAST_COPPER_LAYER && layer >= g_Parm_3D_Visu.m_CopperLayersCount ) @@ -302,18 +302,19 @@ void EDA_3D_CANVAS::BuildBoard3DView() // Add via hole if( track->Type() == PCB_VIA_T ) { - int shape = track->GetShape(); - int holediameter = track->GetDrillValue(); - int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); + VIA *via = static_cast( track ); + VIATYPE_T viatype = via->GetViaType(); + int holediameter = via->GetDrillValue(); + int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); int hole_outer_radius = (holediameter + thickness) / 2; - if( shape != VIA_THROUGH ) + if( viatype != VIA_THROUGH ) TransformCircleToPolygon( currLayerHoles, - track->GetStart(), hole_outer_radius, + via->GetStart(), hole_outer_radius, segcountLowQuality ); else if( !throughHolesListBuilt ) TransformCircleToPolygon( allLayerHoles, - track->GetStart(), hole_outer_radius, + via->GetStart(), hole_outer_radius, segcountLowQuality ); } } @@ -431,14 +432,16 @@ void EDA_3D_CANVAS::BuildBoard3DView() } // Draw vias holes (vertical cylinders) - for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) + for( const TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) { - if( track->Type() == PCB_VIA_T ) - Draw3DViaHole( (SEGVIA*) track ); + const VIA *via = dynamic_cast(track); + + if( via ) + Draw3DViaHole( via ); } // Draw pads holes (vertical cylinders) - for( MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() ) + for( const MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad != NULL; pad = pad->Next() ) Draw3DPadHole( pad ); @@ -505,6 +508,7 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() // to reduce time calculations // for holes and items which do not need // a fine representation + double correctionFactorLQ = 1.0 / cos( M_PI / (segcountLowQuality * 2) ); CPOLYGONS_LIST bufferPolys; bufferPolys.reserve( 100000 ); // Reserve for large board @@ -514,8 +518,8 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() CPOLYGONS_LIST bufferPcbOutlines; // stores the board main outlines // Build a polygon from edge cut items wxString msg; - if( ! pcb->GetBoardPolygonOutlines( bufferPcbOutlines, - allLayerHoles, &msg ) ) + + if( !pcb->GetBoardPolygonOutlines( bufferPcbOutlines, allLayerHoles, &msg ) ) { msg << wxT("\n\n") << _("Unable to calculate the board outlines.\n" @@ -524,20 +528,19 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() } int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); - for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) - { - // Add via hole - if( track->Type() == PCB_VIA_T ) - { - int shape = track->GetShape(); - int holediameter = track->GetDrillValue(); - int hole_outer_radius = (holediameter + thickness) / 2; - if( shape == VIA_THROUGH ) - TransformCircleToPolygon( allLayerHoles, - track->GetStart(), hole_outer_radius, - segcountLowQuality ); - } + // Add via holes + for( VIA* via = GetFirstVia( pcb->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) + { + VIATYPE_T viatype = via->GetViaType(); + int holediameter = via->GetDrillValue(); + int hole_outer_radius = (holediameter + thickness) / 2; + + if( viatype == VIA_THROUGH ) + TransformCircleToPolygon( allLayerHoles, + via->GetStart(), hole_outer_radius, + segcountLowQuality ); } // draw pads holes @@ -557,7 +560,7 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() allLayerHoles.ExportTo( brdpolysetHoles ); for( LAYER_NUM layer = FIRST_NON_COPPER_LAYER; layer <= LAST_NON_COPPER_LAYER; - layer++ ) + ++layer ) { // Skip user layers, which are not drawn here if( IsUserLayer( layer) ) @@ -606,22 +609,30 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() continue; BuildPadShapeThickOutlineAsPolygon( pad, bufferPolys, - linewidth, - segcountforcircle, correctionFactor ); + linewidth, segcountforcircle, correctionFactor ); } } else module->TransformPadsShapesWithClearanceToPolygon( layer, - bufferPolys, - 0, - segcountforcircle, - correctionFactor ); + bufferPolys, 0, segcountforcircle, correctionFactor ); module->TransformGraphicShapesWithClearanceToPolygonSet( layer, - bufferPolys, - 0, - segcountforcircle, - correctionFactor ); + bufferPolys, 0, segcountforcircle, correctionFactor ); + } + + // Draw non copper zones + if( g_Parm_3D_Visu.GetFlag( FL_ZONE ) ) + { + for( int ii = 0; ii < pcb->GetAreaCount(); ii++ ) + { + ZONE_CONTAINER* zone = pcb->GetArea( ii ); + + if( !zone->IsOnLayer( layer ) ) + continue; + + zone->TransformSolidAreasShapesToPolygonSet( + bufferPolys, segcountLowQuality, correctionFactorLQ ); + } } // bufferPolys contains polygons to merge. Many overlaps . @@ -700,7 +711,7 @@ void EDA_3D_CANVAS::BuildBoard3DAuxLayers() bufferPolys.reserve( 5000 ); // Reserve for items not on board for( LAYER_NUM layer = FIRST_USER_LAYER; layer <= LAST_USER_LAYER; - layer++ ) + ++layer ) { if( !Is3DLayerEnabled( layer ) ) continue; @@ -1047,7 +1058,7 @@ void EDA_3D_CANVAS::Draw3DGrid( double aGriSizeMM ) } -void EDA_3D_CANVAS::Draw3DViaHole( SEGVIA* aVia ) +void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia ) { LAYER_NUM top_layer, bottom_layer; int inner_radius = aVia->GetDrillValue() / 2; @@ -1060,7 +1071,7 @@ void EDA_3D_CANVAS::Draw3DViaHole( SEGVIA* aVia ) SetGLCopperColor(); else { - EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetShape() ); + EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() ); SetGLColor( color ); } @@ -1111,7 +1122,7 @@ void MODULE::ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas, // Draw 3D pads. -void EDA_3D_CANVAS::Draw3DPadHole( D_PAD* aPad ) +void EDA_3D_CANVAS::Draw3DPadHole( const D_PAD* aPad ) { // Draw the pad hole wxSize drillsize = aPad->GetDrillSize(); diff --git a/3d-viewer/3d_frame.cpp b/3d-viewer/3d_frame.cpp index 55058bc911..c1fabb0b7a 100644 --- a/3d-viewer/3d_frame.cpp +++ b/3d-viewer/3d_frame.cpp @@ -81,7 +81,7 @@ END_EVENT_TABLE() EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, const wxString& aTitle, long style ) : - KIWAY_PLAYER( aKiway, aParent, DISPLAY3D_FRAME_TYPE, aTitle, + KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle, wxDefaultPosition, wxDefaultSize, style, wxT( "Frame3D" ) ) { m_canvas = NULL; diff --git a/3d-viewer/vrmlmodelparser.cpp b/3d-viewer/vrmlmodelparser.cpp index 8891a424aa..0e3877eea4 100644 --- a/3d-viewer/vrmlmodelparser.cpp +++ b/3d-viewer/vrmlmodelparser.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2013 Tuomas Vaherkoski * Copyright (C) 2012 Jean-Pierre Charras, jp.charras@wanadoo.fr * Copyright (C) 2011 Wayne Stambaugh - * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -71,7 +71,7 @@ void VRML_MODEL_PARSER::Load( const wxString aFilename ) if ( text == NULL ) continue; - if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Group" ) == 0 ) + if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Transform" ) == 0 || stricmp( text, "Group" ) == 0 ) { while( GetLine( file, line, &LineNum, 512 ) ) { @@ -121,7 +121,7 @@ int VRML_MODEL_PARSER::readMaterial( FILE* file, int* LineNum ) return 0; } - if( stricmp( command, "DEF" ) == 0 || stricmp( command, "Material") == 0) + if( stricmp( command, "DEF" ) == 0 || stricmp( command,"Transform" ) == 0 || stricmp( command, "Material") == 0) { material = new S3D_MATERIAL( GetMaster(), mat_name ); @@ -197,6 +197,9 @@ int VRML_MODEL_PARSER::readChildren( FILE* file, int* LineNum ) { text = strtok( line, sep_chars ); + if( *text == '[' ) + continue; + if( *text == ']' ) return 0; @@ -233,6 +236,11 @@ int VRML_MODEL_PARSER::readShape( FILE* file, int* LineNum ) break; } + if( *text == '{' ) + { + continue; + } + if( stricmp( text, "appearance" ) == 0 ) { readAppearance( file, LineNum ); @@ -267,6 +275,11 @@ int VRML_MODEL_PARSER::readAppearance( FILE* file, int* LineNum ) break; } + if( *text == '{' ) + { + continue; + } + if( stricmp( text, "material" ) == 0 ) { readMaterial( file, LineNum ); @@ -380,6 +393,16 @@ int VRML_MODEL_PARSER::readGeometry( FILE* file, int* LineNum ) break; } + if( stricmp( text, "creaseAngle" ) == 0 ) + { + continue; + } + + if( *text == '{' ) + { + continue; + } + if( stricmp( text, "normalPerVertex" ) == 0 ) { text = strtok( NULL, " ,\t\n\r" ); diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a0c3879f1..161235edd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -623,7 +623,6 @@ add_subdirectory( 3d-viewer ) add_subdirectory( cvpcb ) add_subdirectory( eeschema ) add_subdirectory( gerbview ) -add_subdirectory( kicad ) add_subdirectory( lib_dxf ) add_subdirectory( pcbnew ) add_subdirectory( polygon ) @@ -631,9 +630,11 @@ add_subdirectory( pagelayout_editor ) add_subdirectory( potrace ) add_subdirectory( bitmap2component ) add_subdirectory( pcb_calculator ) +add_subdirectory( kicad ) # should follow pcbnew, eeschema add_subdirectory( tools ) add_subdirectory( utils ) add_subdirectory( qa ) + #add_subdirectory( new ) @@ -653,16 +654,16 @@ add_dependencies( pnsrouter boost ) if ( KICAD_BUILD_STATIC OR KICAD_BUILD_DYNAMIC ) -add_dependencies( pcbnew lib-dependencies ) -add_dependencies( eeschema lib-dependencies ) -add_dependencies( cvpcb lib-dependencies ) -add_dependencies( common lib-dependencies ) -add_dependencies( gal lib-dependencies ) -add_dependencies( pcbcommon lib-dependencies ) -add_dependencies( 3d-viewer lib-dependencies ) -add_dependencies( pcad2kicadpcb lib-dependencies ) -add_dependencies( pl_editor lib-dependencies ) -add_dependencies( pnsrouter lib-dependencies ) + add_dependencies( pcbnew lib-dependencies ) + add_dependencies( eeschema lib-dependencies ) + add_dependencies( cvpcb lib-dependencies ) + add_dependencies( common lib-dependencies ) + add_dependencies( gal lib-dependencies ) + add_dependencies( pcbcommon lib-dependencies ) + add_dependencies( 3d-viewer lib-dependencies ) + add_dependencies( pcad2kicadpcb lib-dependencies ) + add_dependencies( pl_editor lib-dependencies ) + add_dependencies( pnsrouter lib-dependencies ) endif() if ( KICAD_BUILD_DYNAMIC ) diff --git a/CMakeModules/download_avhttp.cmake b/CMakeModules/download_avhttp.cmake index 6fa9f423b4..abc52b7e89 100644 --- a/CMakeModules/download_avhttp.cmake +++ b/CMakeModules/download_avhttp.cmake @@ -38,6 +38,12 @@ # Where the library is to be installed. set( PREFIX ${DOWNLOAD_DIR}/avhttp ) +if( KICAD_SKIP_BOOST ) + set( AVHTTP_DEPEND "" ) +else() + set( AVHTTP_DEPEND "boost" ) +endif() + # Install the AVHTTP header only library ${PREFIX} ExternalProject_Add( avhttp @@ -46,7 +52,7 @@ ExternalProject_Add( avhttp # grab it from a local zip file for now, cmake caller's source dir URL ${CMAKE_CURRENT_SOURCE_DIR}/avhttp-master.zip - DEPENDS boost + DEPENDS ${AVHTTP_DEPEND} CONFIGURE_COMMAND "" diff --git a/CMakeModules/download_boost.cmake b/CMakeModules/download_boost.cmake index 601738413c..4a491ec191 100644 --- a/CMakeModules/download_boost.cmake +++ b/CMakeModules/download_boost.cmake @@ -187,7 +187,7 @@ ExternalProject_Add( boost URL http://downloads.sourceforge.net/project/boost/boost/${BOOST_RELEASE}/boost_${BOOST_VERS}.tar.bz2 DOWNLOAD_DIR "${DOWNLOAD_DIR}" - TIMEOUT 600 # 10 minutes + TIMEOUT 1200 # 20 minutes URL_MD5 ${BOOST_MD5} # If download fails, then enable "LOG_DOWNLOAD ON" and try again. # Upon a second failure with logging enabled, then look at these logs: diff --git a/bitmap2component/bitmap2cmp_gui.cpp b/bitmap2component/bitmap2cmp_gui.cpp index 7b11ffb860..9e8968ecfb 100644 --- a/bitmap2component/bitmap2cmp_gui.cpp +++ b/bitmap2component/bitmap2cmp_gui.cpp @@ -639,7 +639,7 @@ namespace BMP2CMP { static struct IFACE : public KIFACE_I { - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) { @@ -706,8 +706,8 @@ PGM_BASE& Pgm() #endif -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - return start_common(); + return start_common( aCtlBits ); } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 899bb609fa..07da514a8e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -182,10 +182,13 @@ set( COMMON_SRCS html_messagebox.cpp kiface_i.cpp kiway.cpp + kiway_express.cpp kiway_holder.cpp + kiway_player.cpp msgpanel.cpp netlist_keywords.cpp newstroke_font.cpp + prependpath.cpp project.cpp ptree.cpp reporter.cpp diff --git a/common/basicframe.cpp b/common/basicframe.cpp index f8a170211a..91a5c0b4ee 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -62,7 +62,7 @@ static const wxChar entryPerspective[] = wxT( "Perspective" ); -EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, +EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aFrameName ) : wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName ) @@ -107,7 +107,10 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, void EDA_BASE_FRAME::windowClosing( wxCloseEvent& event ) { - SaveSettings( config() ); // virtual, wxFrame specific + wxConfigBase* cfg = config(); + + if( cfg ) + SaveSettings( cfg ); // virtual, wxFrame specific event.Skip(); // we did not "handle" the event, only eavesdropped on it. } @@ -266,7 +269,7 @@ wxConfigBase* EDA_BASE_FRAME::config() { // KICAD_MANAGER_FRAME overrides this wxConfigBase* ret = Kiface().KifaceSettings(); - wxASSERT( ret ); + //wxASSERT( ret ); return ret; } diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp index 2368cb98f7..0164ca628b 100644 --- a/common/common_plotDXF_functions.cpp +++ b/common/common_plotDXF_functions.cpp @@ -570,12 +570,21 @@ void DXF_PLOTTER::Text( const wxPoint& aPos, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ) + bool aBold, + bool aMultilineAllowed ) { - if( textAsLines || containsNonAsciiChars( aText ) ) - /* output text as graphics */ + // Fix me: see how to use DXF text mode for multiline texts + if( aMultilineAllowed && !aText.Contains( wxT( "\n" ) ) ) + aMultilineAllowed = false; // the text has only one line. + + if( textAsLines || containsNonAsciiChars( aText ) || aMultilineAllowed ) + { + // output text as graphics. + // Perhaps miltiline texts could be handled as DXF text entity + // but I do not want spend time about this (JPC) PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, - aWidth, aItalic, aBold ); + aWidth, aItalic, aBold, aMultilineAllowed ); + } else { /* Emit text as a text entity. This loses formatting and shape but it's diff --git a/common/common_plotPDF_functions.cpp b/common/common_plotPDF_functions.cpp index ec9cef66d3..7d75be97d4 100644 --- a/common/common_plotPDF_functions.cpp +++ b/common/common_plotPDF_functions.cpp @@ -741,10 +741,15 @@ void PDF_PLOTTER::Text( const wxPoint& aPos, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ) + bool aBold, + bool aMultilineAllowed ) { + // Fix me: see how to use PDF text mode for multiline texts + if( aMultilineAllowed && !aText.Contains( wxT( "\n" ) ) ) + aMultilineAllowed = false; // the text has only one line. + // Emit native PDF text (if requested) - if( m_textMode != PLOTTEXTMODE_STROKE ) + if( m_textMode != PLOTTEXTMODE_STROKE && !aMultilineAllowed ) { const char *fontname = aItalic ? (aBold ? "/KicadFontBI" : "/KicadFontI") : (aBold ? "/KicadFontB" : "/KicadFont"); @@ -800,10 +805,10 @@ void PDF_PLOTTER::Text( const wxPoint& aPos, } // Plot the stroked text (if requested) - if( m_textMode != PLOTTEXTMODE_NATIVE ) + if( m_textMode != PLOTTEXTMODE_NATIVE || aMultilineAllowed ) { PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, - aWidth, aItalic, aBold ); + aWidth, aItalic, aBold, aMultilineAllowed ); } } diff --git a/common/common_plotPS_functions.cpp b/common/common_plotPS_functions.cpp index 9e1644485b..627f079088 100644 --- a/common/common_plotPS_functions.cpp +++ b/common/common_plotPS_functions.cpp @@ -812,27 +812,32 @@ bool PS_PLOTTER::EndPlot() -void PS_PLOTTER::Text( const wxPoint& aPos, - enum EDA_COLOR_T aColor, - const wxString& aText, - double aOrient, - const wxSize& aSize, - enum EDA_TEXT_HJUSTIFY_T aH_justify, - enum EDA_TEXT_VJUSTIFY_T aV_justify, - int aWidth, - bool aItalic, - bool aBold ) +void PS_PLOTTER::Text( const wxPoint& aPos, + enum EDA_COLOR_T aColor, + const wxString& aText, + double aOrient, + const wxSize& aSize, + enum EDA_TEXT_HJUSTIFY_T aH_justify, + enum EDA_TEXT_VJUSTIFY_T aV_justify, + int aWidth, + bool aItalic, + bool aBold, + bool aMultilineAllowed ) { SetCurrentLineWidth( aWidth ); SetColor( aColor ); + // Fix me: see how to use PS text mode for multiline texts + if( aMultilineAllowed && !aText.Contains( wxT( "\n" ) ) ) + aMultilineAllowed = false; // the text has only one line. + // Draw the native postscript text (if requested) - if( m_textMode == PLOTTEXTMODE_NATIVE ) + if( m_textMode == PLOTTEXTMODE_NATIVE && !aMultilineAllowed ) { const char *fontname = aItalic ? (aBold ? "/KicadFont-BoldOblique" : "/KicadFont-Oblique") - : (aBold ? "/KicadFont-Bold" - : "/KicadFont"); + : (aBold ? "/KicadFont-Bold" + : "/KicadFont"); // Compute the copious tranformation parameters double ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f; @@ -874,16 +879,16 @@ void PS_PLOTTER::Text( const wxPoint& aPos, if( m_textMode == PLOTTEXTMODE_PHANTOM ) { fputsPostscriptString( outputFile, aText ); - DPOINT pos_dev = userToDeviceCoordinates( aPos ); + DPOINT pos_dev = userToDeviceCoordinates( aPos ); fprintf( outputFile, " %g %g phantomshow\n", pos_dev.x, pos_dev.y ); } // Draw the stroked text (if requested) - if( m_textMode != PLOTTEXTMODE_NATIVE ) + if( m_textMode != PLOTTEXTMODE_NATIVE || aMultilineAllowed ) { PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, - aWidth, aItalic, aBold ); + aWidth, aItalic, aBold, aMultilineAllowed ); } } diff --git a/common/common_plotSVG_functions.cpp b/common/common_plotSVG_functions.cpp index b883107c84..e5d00a63e5 100644 --- a/common/common_plotSVG_functions.cpp +++ b/common/common_plotSVG_functions.cpp @@ -478,6 +478,15 @@ void SVG_PLOTTER::PenTo( const wxPoint& pos, char plume ) if( penState == 'Z' ) // here plume = 'D' or 'U' { DPOINT pos_dev = userToDeviceCoordinates( pos ); + + // Ensure we do not use a fill mode when moving tne pen, + // in SVG mode (i;e. we are plotting only basic lines, not a filled area + if( m_fillMode != NO_FILL ) + { + setFillMode( NO_FILL ); + setSVGPlotStyle(); + } + fprintf( outputFile, "SetLabel( info.GetBuildVersion() ); m_staticTextLibVersion->SetLabel( info.GetLibVersion() ); - /* Affects m_titlepanel the parent of some wxStaticText. - * Changing the text afterwards makes it under Windows necessary to call 'Layout()' - * so that the new text gets properly layout. - */ -/* m_staticTextCopyright->GetParent()->Layout(); - m_staticTextBuildVersion->GetParent()->Layout(); - m_staticTextLibVersion->GetParent()->Layout(); -*/ DeleteNotebooks(); CreateNotebooks(); + GetSizer()->SetSizeHints(this); m_auiNotebook->Update(); SetFocus(); diff --git a/common/dialog_about/dialog_about_base.cpp b/common/dialog_about/dialog_about_base.cpp index de343ab237..66cb2f05a2 100644 --- a/common/dialog_about/dialog_about_base.cpp +++ b/common/dialog_about/dialog_about_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Sep 8 2010) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -46,11 +46,13 @@ dialog_about_base::dialog_about_base( wxWindow* parent, wxWindowID id, const wxS m_staticTextLibVersion->Wrap( -1 ); b_apptitleSizer->Add( m_staticTextLibVersion, 0, wxALIGN_CENTER|wxBOTTOM|wxLEFT|wxRIGHT, 5 ); + bSizer3->Add( b_apptitleSizer, 10, wxEXPAND, 5 ); bSizer3->Add( 0, 0, 2, wxEXPAND, 5 ); + bSizer1->Add( bSizer3, 0, wxEXPAND, 5 ); wxStaticLine* m_staticline1; @@ -67,6 +69,7 @@ dialog_about_base::dialog_about_base( wxWindow* parent, wxWindowID id, const wxS m_buttonOK->SetDefault(); bSizer1->Add( m_buttonOK, 0, wxALIGN_CENTER|wxALL, 5 ); + this->SetSizer( bSizer1 ); this->Layout(); diff --git a/common/dialog_about/dialog_about_base.fbp b/common/dialog_about/dialog_about_base.fbp index 2f6951303c..ce0bf7d57d 100644 --- a/common/dialog_about/dialog_about_base.fbp +++ b/common/dialog_about/dialog_about_base.fbp @@ -2,11 +2,13 @@ - + C++ 1 source_name + 0 0 + res UTF-8 connect dialog_about_base @@ -14,73 +16,80 @@ none 1 MyProject - + . - + 1 + 1 + 1 1 + UI 1 0 - - - + 0 + wxAUI_MGR_DEFAULT + + + 1 1 impl_virtual - - - + + + 0 wxID_ANY - + -1,-1 dialog_about_base - + 750,450 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSTAY_ON_TOP - + About... - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - + + + + + + + + + + + + + OnClose - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + bSizer1 wxVERTICAL none @@ -89,7 +98,7 @@ wxEXPAND 0 - + bSizer3 wxHORIZONTAL none @@ -108,53 +117,80 @@ wxALIGN_CENTER|wxALL 1 - - - + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY - - + + 0 + + + 0 + + 1 m_bitmapApp + 1 + + protected - - - - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - + 1 + + Resizable + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -162,7 +198,7 @@ wxEXPAND 10 - + b_apptitleSizer wxVERTICAL none @@ -171,55 +207,82 @@ wxALIGN_CENTER|wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - + + 1 ,90,92,14,70,0 + 0 0 wxID_ANY App Title - - + + 0 + + + 0 + + 1 m_staticTextAppTitle + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -227,55 +290,82 @@ wxALIGN_CENTER|wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY Copyright Info - - + + 0 + + + 0 + + 1 m_staticTextCopyright + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -283,55 +373,82 @@ wxALIGN_CENTER|wxLEFT|wxRIGHT|wxTOP 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY Build Version Info - - + + 0 + + + 0 + + 1 m_staticTextBuildVersion + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -339,55 +456,82 @@ wxALIGN_CENTER|wxBOTTOM|wxLEFT|wxRIGHT 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY Lib Version Info - - + + 0 + + + 0 + + 1 m_staticTextLibVersion + 1 + + protected - - + 1 + + Resizable + 1 + wxALIGN_CENTRE - - - - wxFILTER_NONE - wxDefaultValidator - - - - + + 0 + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -409,53 +553,80 @@ wxEXPAND | wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY - - + + 0 + + + 0 + + 1 m_staticline1 + 1 + + none - - + 1 + + Resizable + 1 + wxLI_HORIZONTAL - - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -463,63 +634,90 @@ wxEXPAND | wxALL 2 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_ANY - + + 0 + + + 0 750,350 + 1 m_auiNotebook + 1 + + protected - - + 1 + + Resizable + 1 + wxAUI_NB_SCROLL_BUTTONS|wxAUI_NB_TAB_FIXED_WIDTH - + -1 - - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -527,56 +725,87 @@ wxALIGN_CENTER|wxALL 0 - - + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 1 + 0 + Dock + 0 + Left 1 - - + + 1 + + 0 0 wxID_CANCEL OK - - + + 0 + + + 0 + + 1 m_buttonOK + 1 + + private - - - - - - + 1 + + Resizable + 1 + + + + 0 + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnOkClick - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/dialog_about/dialog_about_base.h b/common/dialog_about/dialog_about_base.h index 79253e9973..d0485f3575 100644 --- a/common/dialog_about/dialog_about_base.h +++ b/common/dialog_about/dialog_about_base.h @@ -1,15 +1,16 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Sep 8 2010) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#ifndef __dialog_about_base__ -#define __dialog_about_base__ +#ifndef __DIALOG_ABOUT_BASE_H__ +#define __DIALOG_ABOUT_BASE_H__ +#include +#include #include - #include #include #include @@ -37,13 +38,11 @@ class dialog_about_base : public wxDialog wxButton* m_buttonOK; protected: - wxStaticBitmap* m_bitmapApp; wxStaticText* m_staticTextAppTitle; wxStaticText* m_staticTextCopyright; wxStaticText* m_staticTextBuildVersion; wxStaticText* m_staticTextLibVersion; - wxAuiNotebook* m_auiNotebook; // Virtual event handlers, overide them in your derived class @@ -53,9 +52,9 @@ class dialog_about_base : public wxDialog public: - dialog_about_base( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 750,350 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSTAY_ON_TOP ); + dialog_about_base( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 750,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSTAY_ON_TOP ); ~dialog_about_base(); }; -#endif //__dialog_about_base__ +#endif //__DIALOG_ABOUT_BASE_H__ diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 4b7f50fb81..c5fec513ab 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -65,7 +65,7 @@ static const wxString GridColorEntryKeyword( wxT( "GridColor" ) ); static const wxString LastGridSizeIdKeyword( wxT( "_LastGridSize" ) ); -BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, EDA_BASE_FRAME ) +BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, KIWAY_PLAYER ) EVT_MOUSEWHEEL( EDA_DRAW_FRAME::OnMouseEvent ) EVT_MENU_OPEN( EDA_DRAW_FRAME::OnMenuOpen ) EVT_ACTIVATE( EDA_DRAW_FRAME::OnActivate ) @@ -91,7 +91,7 @@ END_EVENT_TABLE() EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aFrameType, + FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString & aFrameName ) : diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 97da020d55..1c253819ba 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -32,14 +32,6 @@ #include // RotatePoint #include // EDA_DRAW_PANEL -// until bzr rev 4476, Y position of vertical justification -// of multiline texts was incorrectly calculated for BOTTOM -// and CENTER vertical justification. (Only the first line was justified) -// If this line is left uncommented, the bug is fixed, but -// creates a (very minor) issue for existing texts, mainly in Pcbnew -// because the text position is sometimes critical. -#define FIX_MULTILINE_VERT_JUSTIF - // Conversion to application internal units defined at build time. #if defined( PCBNEW ) #include @@ -205,7 +197,6 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const if( linecount > 1 ) { -#ifdef FIX_MULTILINE_VERT_JUSTIF int yoffset; linecount -= 1; @@ -224,7 +215,6 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const rect.SetY( rect.GetY() - yoffset ); break; } -#endif } rect.Inflate( thickness / 2 ); @@ -305,7 +295,6 @@ void EDA_TEXT::GetPositionsOfLinesOfMultilineText( offset.y = GetInterline(); -#ifdef FIX_MULTILINE_VERT_JUSTIF if( aLineCount > 1 ) { switch( m_VJustify ) @@ -326,7 +315,7 @@ void EDA_TEXT::GetPositionsOfLinesOfMultilineText( // Rotate the position of the first line // around the center of the multiline text block RotatePoint( &pos, m_Pos, m_Orient ); -#endif + // Rotate the offset lines to increase happened in the right direction RotatePoint( &offset, m_Orient ); diff --git a/common/kiface_i.cpp b/common/kiface_i.cpp index 9432c057cd..3693d1998d 100644 --- a/common/kiface_i.cpp +++ b/common/kiface_i.cpp @@ -94,8 +94,10 @@ static void setSearchPaths( SEARCH_STACK* aDst, KIWAY::FACE_T aId ) } -bool KIFACE_I::start_common() +bool KIFACE_I::start_common( int aCtlBits ) { + m_start_flags = aCtlBits; + m_bm.Init(); m_bm.m_config->Read( showPageLimitsKey, &g_ShowPageLimits ); diff --git a/common/kiway.cpp b/common/kiway.cpp index 577f118e66..13c0072a92 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -22,37 +22,98 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include -#include #include - -// one for each FACE_T -wxDynamicLibrary KIWAY::s_sch_dso; -wxDynamicLibrary KIWAY::s_pcb_dso; +#include +#include +#include +#include +#include +#include +#include -KIWAY::KIWAY() +KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT]; +int KIWAY::m_kiface_version[KIWAY_FACE_COUNT]; + + + +KIWAY::KIWAY( PGM_BASE* aProgram, wxFrame* aTop ): + m_program( aProgram ), + m_top( 0 ) { - memset( &m_kiface, 0, sizeof( m_kiface ) ); + SetTop( aTop ); // hook playerDestroyHandler() into aTop. + + memset( m_player, 0, sizeof( m_player ) ); +} + +// Any event types derived from wxCommandEvt, like wxWindowDestroyEvent, are +// propogated upwards to parent windows if not handled below. Therefor the +// m_top window should receive all wxWindowDestroyEvents originating from +// KIWAY_PLAYERs. It does anyways, but now playerDestroyHandler eavesdrops +// on that event stream looking for KIWAY_PLAYERs being closed. + +void KIWAY::playerDestroyHandler( wxWindowDestroyEvent& event ) +{ + wxWindow* w = event.GetWindow(); + + for( unsigned i=0; iDisconnect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::playerDestroyHandler ), NULL, this ); + } + + if( aTop ) + { + aTop->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( KIWAY::playerDestroyHandler ), NULL, this ); + } + + m_top = aTop; +} + + +const wxString KIWAY::dso_full_path( FACE_T aFaceId ) +{ + const wxChar* name; + switch( aFaceId ) { - case FACE_SCH: return KIFACE_PREFIX wxT( "eeschema" ) KIFACE_SUFFIX; - case FACE_PCB: return KIFACE_PREFIX wxT( "pcbnew" ) KIFACE_SUFFIX; + case FACE_SCH: name = KIFACE_PREFIX wxT( "eeschema" ); break; + case FACE_PCB: name = KIFACE_PREFIX wxT( "pcbnew" ); break; + case FACE_CVPCB: name = KIFACE_PREFIX wxT( "cvpcb" ); break; + case FACE_GERBVIEW: name = KIFACE_PREFIX wxT( "gerbview" ); break; + case FACE_PL_EDITOR: name = KIFACE_PREFIX wxT( "pl_editor" ); break; + + // case FACE_PCB_CALCULATOR: who knows. default: wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) ); return wxEmptyString; } + + wxFileName fn = wxStandardPaths::Get().GetExecutablePath(); + + fn.SetName( name ); + + // Here a "suffix" == an extension with a preceding '.', + // so skip the preceding '.' to get an extension + fn.SetExt( KIFACE_SUFFIX + 1 ); // + 1 => &KIFACE_SUFFIX[1] + + return fn.GetFullPath(); } -*/ PROJECT& KIWAY::Prj() const @@ -63,33 +124,230 @@ PROJECT& KIWAY::Prj() const KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad ) { - switch( aFaceId ) + // Since this will be called from python, cannot assume that code will + // not pass a bad aFaceId. + if( unsigned( aFaceId ) >= DIM( m_kiface ) ) { - case FACE_SCH: - case FACE_PCB: - if( m_kiface[aFaceId] ) - return m_kiface[aFaceId]; + // @todo : throw an exception here for python's benefit, at least that + // way it gets some explanatory text. - default: wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) ); return NULL; } - // DSO with KIFACE has not been loaded yet, does user want to load it? + // return the previously loaded KIFACE, if it was. + if( m_kiface[aFaceId] ) + return m_kiface[aFaceId]; + + // DSO with KIFACE has not been loaded yet, does caller want to load it? if( doLoad ) { - switch( aFaceId ) + wxString dname = dso_full_path( aFaceId ); + + wxDynamicLibrary dso; + + void* addr = NULL; + + if( !dso.Load( dname, wxDL_VERBATIM | wxDL_NOW ) ) { - case FACE_SCH: - break; + // Failure: error reporting UI was done via wxLogSysError(). + // No further reporting required here. + } - case FACE_PCB: - break; + else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL ) + { + // Failure: error reporting UI was done via wxLogSysError(). + // No further reporting required here. + } - default: - ; + else + { + KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr; + + KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, m_program ); + + // KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional. + wxASSERT_MSG( kiface, + wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) ); + + // Give the DSO a single chance to do its "process level" initialization. + // "Process level" specifically means stay away from any projects in there. + if( kiface->OnKifaceStart( m_program, KFCTL_PROJECT_SUITE ) ) + { + // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. + (void) dso.Detach(); + + return m_kiface[aFaceId] = kiface; + } + } + + // In any of the failure cases above, dso.Unload() should be called here + // by dso destructor. + // However: + + // There is a file installation bug. We only look for KIFACE_I's which we know + // to exist, and we did not find one. If we do not find one, this is an + // installation bug. + + wxString msg = wxString::Format( wxT( + "Fatal Installation Bug\nmissing file:\n'%s'\n\nargv[0]:\n'%s'" ), + GetChars( dname ), + GetChars( wxStandardPaths::Get().GetExecutablePath() ) + ); + + // This is a fatal error, one from which we cannot recover, nor do we want + // to protect against in client code which would require numerous noisy + // tests in numerous places. So we inform the user that the installation + // is bad. This exception will likely not get caught until way up in the + // wxApp derivative, at which point the process will exit gracefully. + THROW_IO_ERROR( msg ); + } + + return NULL; +} + + +KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType ) +{ + switch( aFrameType ) + { + case FRAME_SCH: + case FRAME_SCH_LIB_EDITOR: + case FRAME_SCH_VIEWER: + return FACE_SCH; + + case FRAME_PCB: + case FRAME_PCB_MODULE_EDITOR: + case FRAME_PCB_MODULE_VIEWER: + case FRAME_PCB_FOOTPRINT_WIZARD: + case FRAME_PCB_DISPLAY3D: + return FACE_PCB; + + case FRAME_CVPCB: + case FRAME_CVPCB_DISPLAY: + return FACE_CVPCB; + + case FRAME_GERBER: + return FACE_GERBVIEW; + + case FRAME_PL_EDITOR: + return FACE_PL_EDITOR; + + default: + return FACE_T( -1 ); + } +} + + +KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate ) +{ + // Since this will be called from python, cannot assume that code will + // not pass a bad aFrameType. + if( unsigned( aFrameType ) >= DIM( m_player ) ) + { + // @todo : throw an exception here for python's benefit, at least that + // way it gets some explanatory text. + + wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) ); + return NULL; + } + + // return the previously opened window + if( m_player[aFrameType] ) + return m_player[aFrameType]; + + if( doCreate ) + { + FACE_T face_type = KifaceType( aFrameType ); + wxASSERT( face_type != FACE_T(-1) ); + + KIFACE* kiface = KiFACE( face_type ); + wxASSERT( kiface ); + + if( kiface ) + { + KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE ); + wxASSERT( frame ); + + return m_player[aFrameType] = frame; } } return NULL; } + + +bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce ) +{ + // Since this will be called from python, cannot assume that code will + // not pass a bad aFrameType. + if( unsigned( aFrameType ) >= DIM( m_player ) ) + { + // @todo : throw an exception here for python's benefit, at least that + // way it gets some explanatory text. + + wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) ); + return false; + } + + if( m_player[aFrameType] ) + { + if( m_player[aFrameType]->Close( doForce ) ) + { + m_player[aFrameType] = 0; + return true; + } + + return false; + } + + return true; // window is closed already. +} + + +bool KIWAY::PlayersClose( bool doForce ) +{ + bool ret = true; + + for( unsigned i=0; i < DIM( m_player ); ++i ) + { + ret = ret && PlayerClose( FRAME_T( i ), doForce ); + } + + return ret; +} + + +void KIWAY::ExpressMail( FRAME_T aDestination, + MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource ) +{ + KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource ); + + ProcessEvent( mail ); +} + + +bool KIWAY::ProcessEvent( wxEvent& aEvent ) +{ + KIWAY_EXPRESS* mail = dynamic_cast( &aEvent ); + + if( mail ) + { + FRAME_T dest = mail->Dest(); + + // see if recipient is alive + KIWAY_PLAYER* alive = Player( dest, false ); + + if( alive ) + { +#if 1 + return alive->ProcessEvent( aEvent ); +#else + alive->KiwayMailIn( *mail ); + return true; +#endif + } + } + + return false; +} diff --git a/common/kiway_express.cpp b/common/kiway_express.cpp new file mode 100644 index 0000000000..8056f4a37b --- /dev/null +++ b/common/kiway_express.cpp @@ -0,0 +1,60 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +//IMPLEMENT_DYNAMIC_CLASS( KIWAY_EXPRESS, wxEvent ) + + +#if 0 // requires that this code reside in only a single link image, rather than + // in each of kicad.exe, _pcbnew.kiface, and _eeschema.kiface as now. + // In the current case wxEVENT_ID will get a different value in each link + // image. We need to put this into a shared library for common utilization, + // I think that library should be libki.so. I am reluctant to do that now + // because the cost will be finding libki.so at runtime, and we need infrastructure + // to set our LIB_ENV_VAR to the proper place so libki.so can be reliably found. + // All things in due course. +const wxEventType KIWAY_EXPRESS::wxEVENT_ID = wxNewEventType(); +#else +const wxEventType KIWAY_EXPRESS::wxEVENT_ID = 30000; // commmon accross all link images, hopefully unique. +#endif + + +KIWAY_EXPRESS::KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ) : + wxEvent( anOther ) +{ + m_destination = anOther.m_destination; + m_payload = anOther.m_payload; +} + + +KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, MAIL_T aCommand, + const std::string& aPayload, wxWindow* aSource ) : + wxEvent( aCommand, wxEVENT_ID ), + m_destination( aDestination ), + m_payload( aPayload ) +{ + SetEventObject( aSource ); +} + diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp new file mode 100644 index 0000000000..427fdf3a51 --- /dev/null +++ b/common/kiway_player.cpp @@ -0,0 +1,58 @@ + + +#include +#include +#include + + +BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME ) + /* have not been able to get this to work yet: + EVT_KIWAY_EXPRESS( KIWAY_PLAYER::kiway_express ) + Use Connect() in constructor until this can be sorted out. + + OK the problem is KIWAY_PLAYER::wxEVENT_ID not being unique accross all link images. + */ +END_EVENT_TABLE() + + + +KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, + const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, + long aStyle, const wxString& aWdoName ) : + EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), + KIWAY_HOLDER( aKiway ) +{ + DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) + Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); +} + + +KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, + const wxPoint& aPos, const wxSize& aSize, long aStyle, + const wxString& aWdoName ) : + EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), + KIWAY_HOLDER( 0 ) +{ + DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) + Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); +} + + +void KIWAY_PLAYER::kiway_express( KIWAY_EXPRESS& aEvent ) +{ + // logging support +#if defined(DEBUG) + const char* class_name = typeid(this).name(); + + printf( "%s: cmd:%d pay:'%s'\n", class_name, + aEvent.GetEventType(), aEvent.GetPayload().c_str() ); +#endif + + KiwayMailIn( aEvent ); // call the virtual, overload in derived. +} + + +void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) +{ + // overload this. +} diff --git a/common/prependpath.cpp b/common/prependpath.cpp new file mode 100644 index 0000000000..6f68678642 --- /dev/null +++ b/common/prependpath.cpp @@ -0,0 +1,70 @@ + +#include +#include +#include + + + +#if !wxCHECK_VERSION( 3, 0, 0 ) + +// implement missing wx2.8 function until >= wx3.0 pervades. +static wxString wxJoin(const wxArrayString& arr, const wxChar sep, + const wxChar escape = '\\') +{ + size_t count = arr.size(); + if ( count == 0 ) + return wxEmptyString; + + wxString str; + + // pre-allocate memory using the estimation of the average length of the + // strings in the given array: this is very imprecise, of course, but + // better than nothing + str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2); + + if ( escape == wxT('\0') ) + { + // escaping is disabled: + for ( size_t i = 0; i < count; i++ ) + { + if ( i ) + str += sep; + str += arr[i]; + } + } + else // use escape character + { + for ( size_t n = 0; n < count; n++ ) + { + if ( n ) + str += sep; + + for ( wxString::const_iterator i = arr[n].begin(), + end = arr[n].end(); + i != end; + ++i ) + { + const wxChar ch = *i; + if ( ch == sep ) + str += escape; // escape this separator + str += ch; + } + } + } + + str.Shrink(); // release extra memory if we allocated too much + return str; +} +#endif + + +/// Put aPriorityPath in front of all paths in the value of aEnvVar. +const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath ) +{ + wxPathList paths; + + paths.AddEnvList( aEnvVar ); + paths.Insert( aPriorityPath, 0 ); + + return wxJoin( paths, wxPATH_SEP[0] ); +} diff --git a/common/project.cpp b/common/project.cpp index 002bfa7d4f..df43e60a5e 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -30,6 +30,7 @@ #include #include #include +#include // NAMELESS_PROJECT #include #include #include @@ -43,14 +44,13 @@ PROJECT::PROJECT() PROJECT::~PROJECT() { - /* @todo - careful here, this may work, but the virtual destructor may not - be in the same link image as PROJECT. Won't enable this until - we're more stable and destructor is assuredly in same image, i.e. - libki.so +#if 1 + // careful here, this may work, but the virtual destructor may not + // be in the same link image as PROJECT. + for( unsigned i = 0; i cfg( configCreate( aSList, aFileName, aGroupName, FORCE_LOCAL_CONFIG ) ); + std::auto_ptr cfg( configCreate( aSList, aFileName, aGroupName, true ) ); if( !cfg.get() ) { @@ -353,8 +353,7 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aFileName, wxString timestamp = cfg->Read( wxT( "update" ) ); - if( doLoadOnlyIfNew && timestamp.size() && - timestamp == m_pro_date_and_time ) + if( doLoadOnlyIfNew && timestamp.size() && timestamp == m_pro_date_and_time ) { return false; } diff --git a/common/single_top.cpp b/common/single_top.cpp index 19104c4261..2632a32eae 100644 --- a/common/single_top.cpp +++ b/common/single_top.cpp @@ -51,74 +51,8 @@ // The functions we use will cause the program launcher to pull stuff in // during linkage, keep the map file in mind to see what's going into it. - -#if !wxCHECK_VERSION( 3, 0, 0 ) - -// implement missing wx2.8 function until >= wx3.0 pervades. -static wxString wxJoin(const wxArrayString& arr, const wxChar sep, - const wxChar escape = '\\') -{ - size_t count = arr.size(); - if ( count == 0 ) - return wxEmptyString; - - wxString str; - - // pre-allocate memory using the estimation of the average length of the - // strings in the given array: this is very imprecise, of course, but - // better than nothing - str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2); - - if ( escape == wxT('\0') ) - { - // escaping is disabled: - for ( size_t i = 0; i < count; i++ ) - { - if ( i ) - str += sep; - str += arr[i]; - } - } - else // use escape character - { - for ( size_t n = 0; n < count; n++ ) - { - if ( n ) - str += sep; - - for ( wxString::const_iterator i = arr[n].begin(), - end = arr[n].end(); - i != end; - ++i ) - { - const wxChar ch = *i; - if ( ch == sep ) - str += escape; // escape this separator - str += ch; - } - } - } - - str.Shrink(); // release extra memory if we allocated too much - return str; -} -#endif - - -/// Put aPriorityPath in front of all paths in the value of aEnvVar. -const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath ) -{ - wxPathList paths; - - paths.AddEnvList( aEnvVar ); - paths.Insert( aPriorityPath, 0 ); - - return wxJoin( paths, wxPATH_SEP[0] ); -} - - /// Extend LIB_ENV_VAR list with the directory from which I came, prepending it. -void SetLibEnvVar( const wxString& aAbsoluteArgv0 ) +static void set_lib_env_var( const wxString& aAbsoluteArgv0 ) { // POLICY CHOICE 2: Keep same path, so that installer MAY put the // "subsidiary DSOs" in the same directory as the kiway top process modules. @@ -149,6 +83,7 @@ void SetLibEnvVar( const wxString& aAbsoluteArgv0 ) #endif } + // POLICY CHOICE 1: return the full path of the DSO to load from single_top. static const wxString dso_full_path( const wxString& aAbsoluteArgv0 ) { @@ -186,7 +121,7 @@ static const wxString dso_full_path( const wxString& aAbsoluteArgv0 ) // Only a single KIWAY is supported in this single_top top level component, // which is dedicated to loading only a single DSO. -static KIWAY kiway; +KIWAY Kiway( &Pgm() ); // implement a PGM_BASE and a wxApp side by side: @@ -217,21 +152,10 @@ PGM_BASE& Pgm() struct APP_SINGLE_TOP : public wxApp { bool OnInit() // overload wxApp virtual - { - return Pgm().OnPgmInit( this ); - } - - int OnExit() // overload wxApp virtual - { - Pgm().OnPgmExit(); - return wxApp::OnExit(); - } - - int OnRun() // overload wxApp virtual { try { - return wxApp::OnRun(); + return Pgm().OnPgmInit( this ); } catch( const std::exception& e ) { @@ -241,16 +165,49 @@ struct APP_SINGLE_TOP : public wxApp } catch( const IO_ERROR& ioe ) { - wxLogError( wxT( "Unhandled exception class: %s what: %s" ), - GetChars( FROM_UTF8( typeid( ioe ).name() ) ), - GetChars( ioe.errorText ) ); + wxLogError( GetChars( ioe.errorText ) ); } catch(...) { wxLogError( wxT( "Unhandled exception of unknown type" ) ); } - return -1; + Pgm().OnPgmExit(); + + return false; + } + + int OnExit() // overload wxApp virtual + { + return wxApp::OnExit(); + } + + int OnRun() // overload wxApp virtual + { + int ret = -1; + + try + { + ret = wxApp::OnRun(); + } + catch( const std::exception& e ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid(e).name() )), + GetChars( FROM_UTF8( e.what() ) ) );; + } + catch( const IO_ERROR& ioe ) + { + wxLogError( GetChars( ioe.errorText ) ); + } + catch(...) + { + wxLogError( wxT( "Unhandled exception of unknown type" ) ); + } + + Pgm().OnPgmExit(); + + return ret; } /** @@ -307,10 +264,30 @@ static KIFACE_GETTER_FUNC* get_kiface_getter( const wxString& aDSOName ) // No further reporting required here. } - // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. - (void) dso.Detach(); + else + { + // Tell dso's wxDynamicLibrary destructor not to Unload() the program image. + (void) dso.Detach(); - return (KIFACE_GETTER_FUNC*) addr; + return (KIFACE_GETTER_FUNC*) addr; + } + + // There is a file installation bug. We only look for KIFACE_I's which we know + // to exist, and we did not find one. If we do not find one, this is an + // installation bug. + + wxString msg = wxString::Format( wxT( + "Fatal Installation Bug\nmissing file:\n'%s'\n\nargv[0]:\n'%s'" ), + GetChars( aDSOName ), + GetChars( wxStandardPaths::Get().GetExecutablePath() ) + ); + + // This is a fatal error, one from which we cannot recover, nor do we want + // to protect against in client code which would require numerous noisy + // tests in numerous places. So we inform the user that the installation + // is bad. This exception will likely not get caught until way up in the + // wxApp derivative, at which point the process will exit gracefully. + THROW_IO_ERROR( msg ); #else return &KIFACE_GETTER; @@ -339,7 +316,7 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) // Set LIB_ENV_VAR *before* loading the DSO, in case the top-level DSO holding the // KIFACE has hard dependencies on subsidiary DSOs below it. - SetLibEnvVar( absoluteArgv0 ); + set_lib_env_var( absoluteArgv0 ); if( !initPgm() ) return false; @@ -364,22 +341,22 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) // Give the DSO a single chance to do its "process level" initialization. // "Process level" specifically means stay away from any projects in there. - if( !kiface->OnKifaceStart( this ) ) + if( !kiface->OnKifaceStart( this, KFCTL_STANDALONE ) ) return false; // Use KIFACE to create a top window that the KIFACE knows about. // TOP_FRAME is passed on compiler command line from CMake, and is one of - // the types in ID_DRAWFRAME_TYPE. + // the types in FRAME_T. // KIFACE::CreateWindow() is a virtual so we don't need to link to it. // Remember its in the *.kiface DSO. #if 0 // this pulls in EDA_DRAW_FRAME type info, which we don't want in // the single_top link image. KIWAY_PLAYER* frame = dynamic_cast( kiface->CreateWindow( - NULL, TOP_FRAME, &kiway, KFCTL_STANDALONE ) ); + NULL, TOP_FRAME, &Kiway, KFCTL_STANDALONE ) ); #else KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( - NULL, TOP_FRAME, &kiway, KFCTL_STANDALONE ); + NULL, TOP_FRAME, &Kiway, KFCTL_STANDALONE ); #endif App().SetTopWindow( frame ); // wxApp gets a face. @@ -418,8 +395,11 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp ) if( !argv1.GetExt() ) argv1.SetExt( wxT( PGM_DATA_FILE_EXT ) ); - argSet[0] = argv1.GetFullPath(); #endif + argv1.MakeAbsolute(); + + argSet[0] = argv1.GetFullPath(); + if( !Pgm().LockFile( argSet[0] ) ) { wxLogSysError( _( "This file is already open." ) ); @@ -479,9 +459,8 @@ void PGM_SINGLE_TOP::OnPgmExit() saveCommonSettings(); - // write common settings to disk, and destroy everything in PGM_BASE, - // especially wxSingleInstanceCheckerImpl earlier than wxApp and earlier - // than static destruction would. + // Destroy everything in PGM_BASE, especially wxSingleInstanceCheckerImpl + // earlier than wxApp and earlier than static destruction would. PGM_BASE::destroy(); } diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 2e89204780..f36d47ee56 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -81,7 +81,7 @@ if( USE_KIWAY_DLLS ) ${CVPCB_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=CVPCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CVPCB;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL" ) target_link_libraries( cvpcb #singletop # replaces common, giving us restrictive control and link warnings. diff --git a/cvpcb/class_DisplayFootprintsFrame.cpp b/cvpcb/class_DisplayFootprintsFrame.cpp index 8ff1330447..33abb79fc4 100644 --- a/cvpcb/class_DisplayFootprintsFrame.cpp +++ b/cvpcb/class_DisplayFootprintsFrame.cpp @@ -72,7 +72,7 @@ END_EVENT_TABLE() DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, CVPCB_MAINFRAME* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, CVPCB_DISPLAY_FRAME_TYPE, _( "Footprint Viewer" ), + PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME ) { diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index c878e61201..74b79b3567 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -107,7 +107,7 @@ END_EVENT_TABLE() CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) : - KIWAY_PLAYER( aKiway, aParent, CVPCB_FRAME_TYPE, wxT( "CvPCB" ), wxDefaultPosition, + KIWAY_PLAYER( aKiway, aParent, FRAME_CVPCB, wxT( "CvPCB" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, CVPCB_MAINFRAME_NAME ) { m_FrameName = CVPCB_MAINFRAME_NAME; @@ -786,14 +786,10 @@ void CVPCB_MAINFRAME::UpdateTitle() void CVPCB_MAINFRAME::SendMessageToEESCHEMA() { - char cmd[1024]; - int selection; - COMPONENT* Component; - if( m_netlist.IsEmpty() ) return; - selection = m_ListCmp->GetSelection(); + int selection = m_ListCmp->GetSelection(); if ( selection < 0 ) selection = 0; @@ -801,12 +797,14 @@ void CVPCB_MAINFRAME::SendMessageToEESCHEMA() if( m_netlist.GetComponent( selection ) == NULL ) return; - Component = m_netlist.GetComponent( selection ); + COMPONENT* component = m_netlist.GetComponent( selection ); - sprintf( cmd, "$PART: \"%s\"", TO_UTF8( Component->GetReference() ) ); - - SendCommand( MSG_TO_SCH, cmd ); + std::string packet = StrPrintf( "$PART: \"%s\"", TO_UTF8( component->GetReference() ) ); + if( Kiface().IsSingle() ) + SendCommand( MSG_TO_SCH, packet.c_str() ); + else + Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this ); } diff --git a/cvpcb/cvpcb.cpp b/cvpcb/cvpcb.cpp index ebc75ad5ff..78fbebf619 100644 --- a/cvpcb/cvpcb.cpp +++ b/cvpcb/cvpcb.cpp @@ -100,7 +100,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -108,7 +108,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case CVPCB_FRAME_TYPE: + case FRAME_CVPCB: { CVPCB_MAINFRAME* frame = new CVPCB_MAINFRAME( aKiway, aParent ); return frame; @@ -276,13 +276,13 @@ FP_LIB_TABLE GFootprintTable; // we skip setting KISYSMOD here for now. User should set the environment // variable. -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { // This is process level, not project level, initialization of the DSO. // Do nothing in here pertinent to a project! - start_common(); + start_common( aCtlBits ); // Set 3D shape path from environment variable KISYS3DMOD set3DShapesPath( wxT("KISYS3DMOD") ); diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index 8683d50232..538fe34841 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -720,8 +720,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) return 0; } - wxString msg; - msg.Printf( _("File %s saved"), GetChars( fn.GetFullPath() ) ); + wxString msg = wxString::Format( _("File %s saved"), GetChars( fn.GetFullPath() ) ); SetStatusText( msg ); return 1; } diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 87b71aa5f5..b139726841 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -251,7 +251,7 @@ if( USE_KIWAY_DLLS ) ${EESCHEMA_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=SCHEMATIC_FRAME_TYPE;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" ) target_link_libraries( eeschema #singletop # replaces common, giving us restrictive control and link warnings. @@ -345,7 +345,7 @@ else() ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=SCHEMATIC_FRAME_TYPE;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL" ) if( APPLE ) diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp index 6cf39282de..9e64f9219e 100644 --- a/eeschema/controle.cpp +++ b/eeschema/controle.cpp @@ -78,7 +78,7 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KIC return NULL; } - /* Cross probing to Pcbnew if a pin or a component is found */ + // Cross probing to Pcbnew if a pin or a component is found switch( item->Type() ) { case SCH_FIELD_T: @@ -105,6 +105,7 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KIC { // Force display pin information (the previous display could be a component info) MSG_PANEL_ITEMS items; + Pin->GetMsgPanelInfo( items ); if( LibItem ) diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index dcb7788c8d..b8bd39884a 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -29,6 +29,8 @@ #include #include +#include +#include #include #include #include @@ -107,56 +109,95 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) } -void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* objectToSync, SCH_COMPONENT* LibItem ) +std::string FormatProbeItem( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) { - if( objectToSync == NULL ) - return; - - LIB_PIN* Pin = NULL; - char Line[1024]; - - /* Cross probing to Pcbnew if a pin or a component is found */ - switch( objectToSync->Type() ) + // Cross probing to Pcbnew if a pin or a component is found + switch( aComponent->Type() ) { case SCH_FIELD_T: case LIB_FIELD_T: { - if( !LibItem ) + if( !aPart ) break; - sprintf( Line, "$PART: %s", TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - SendCommand( MSG_TO_PCB, Line ); + return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); } break; case SCH_COMPONENT_T: - LibItem = (SCH_COMPONENT*) objectToSync; - sprintf( Line, "$PART: %s", TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - SendCommand( MSG_TO_PCB, Line ); - break; + aPart = (SCH_COMPONENT*) aComponent; + return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); case LIB_PIN_T: - if( !LibItem ) - break; - - Pin = (LIB_PIN*) objectToSync; - - if( Pin->GetNumber() ) { - wxString pinnum; - Pin->PinStringNum( pinnum ); - sprintf( Line, "$PIN: %s $PART: %s", TO_UTF8( pinnum ), - TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - } - else - { - sprintf( Line, "$PART: %s", TO_UTF8( LibItem->GetField( REFERENCE )->GetText() ) ); - } + if( !aPart ) + break; - SendCommand( MSG_TO_PCB, Line ); + LIB_PIN* pin = (LIB_PIN*) aComponent; + + if( pin->GetNumber() ) + { + wxString pinnum; + + pin->PinStringNum( pinnum ); + + return StrPrintf( "$PIN: %s $PART: %s", TO_UTF8( pinnum ), + TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); + } + else + { + return StrPrintf( "$PART: %s", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) ); + } + } break; default: break; } + + return ""; } + + +void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) +{ +#if 1 + wxASSERT( aComponent ); // fix the caller + +#else // WTF? + if( !aComponent ) // caller remains eternally stupid. + return; +#endif + + std::string packet = FormatProbeItem( aComponent, aPart ); + + if( packet.size() ) + { + if( Kiface().IsSingle() ) + SendCommand( MSG_TO_PCB, packet.c_str() ); + else + { + // Typically ExpressMail is going to be s-expression packets, but since + // we have existing interpreter of the cross probe packet on the other + // side in place, we use that here. + Kiway().ExpressMail( FRAME_PCB, MAIL_CROSS_PROBE, packet, this ); + } + } +} + + +void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) +{ + const std::string& payload = mail.GetPayload(); + + switch( mail.Command() ) + { + case MAIL_CROSS_PROBE: + ExecuteRemoteCommand( payload.c_str() ); + break; + + // many many others. + + } +} + diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index c7e72dd048..fafcd90ac5 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -68,7 +68,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd( PGM_BASE* aProgram ) { @@ -79,15 +79,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case LIBEDITOR_FRAME_TYPE: - { - LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, - dynamic_cast( aParent ) ); - return frame; - } - break; - - case SCHEMATIC_FRAME_TYPE: + case FRAME_SCH: { SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent ); @@ -96,9 +88,19 @@ static struct IFACE : public KIFACE_I // Read a default config file in case no project given on command line. frame->LoadProjectFile( wxEmptyString, true ); - // @todo temporary - CreateServer( frame, KICAD_SCH_PORT_SERVICE_NUMBER ); + if( Kiface().IsSingle() ) + { + // only run this under single_top, not under a project manager. + CreateServer( frame, KICAD_SCH_PORT_SERVICE_NUMBER ); + } + return frame; + } + break; + case FRAME_SCH_LIB_EDITOR: + { + LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, + dynamic_cast( aParent ) ); return frame; } break; @@ -152,13 +154,13 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { // This is process level, not project level, initialization of the DSO. // Do nothing in here pertinent to a project! - start_common(); + start_common( aCtlBits ); // Give a default colour for all layers // (actual color will be initialized by config) diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index b8e8f7897a..e4f16b3a8f 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -810,7 +810,7 @@ void LIB_PIN::drawGraphic( EDA_DRAW_PANEL* aPanel, if( aPanel && aPanel->GetParent() ) frame = (EDA_DRAW_FRAME*)aPanel->GetParent(); - if( frame && frame->IsType( SCHEMATIC_FRAME_TYPE ) && + if( frame && frame->IsType( FRAME_SCH ) && ! ((SCH_EDIT_FRAME*)frame)->GetShowAllPins() ) return; diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp index 0eaa7aca20..1a79cba67e 100644 --- a/eeschema/libeditframe.cpp +++ b/eeschema/libeditframe.cpp @@ -190,7 +190,7 @@ END_EVENT_TABLE() #define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" ) LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, SCH_EDIT_FRAME* aParent ) : - SCH_BASE_FRAME( aKiway, aParent, LIBEDITOR_FRAME_TYPE, _( "Library Editor" ), + SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_LIB_EDITOR, _( "Library Editor" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetLibEditFrameName() ) { wxASSERT( aParent ); // LIB_EDIT_FRAME needs a parent, since it peeks up there. diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 086473b394..6d3e006b56 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -64,20 +64,22 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Menu File: wxMenu* fileMenu = new wxMenu; - // New - AddMenuItem( fileMenu, - ID_NEW_PROJECT, - _( "&New Schematic Project" ), - _( "Clear current schematic hierarchy and start a new schematic root sheet" ), - KiBitmap( new_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( fileMenu, + ID_NEW_PROJECT, + _( "&New Schematic Project" ), + _( "Clear current schematic hierarchy and start a new schematic root sheet" ), + KiBitmap( new_xpm ) ); - // Open - text = AddHotkeyName( _( "&Open Schematic Project" ), s_Schematic_Hokeys_Descr, HK_LOAD_SCH ); - AddMenuItem( fileMenu, - ID_LOAD_PROJECT, text, - _( "Open an existing schematic hierarchy" ), - KiBitmap( open_document_xpm ) ); + text = AddHotkeyName( _( "&Open Schematic Project" ), s_Schematic_Hokeys_Descr, HK_LOAD_SCH ); + AddMenuItem( fileMenu, + ID_LOAD_PROJECT, text, + _( "Open an existing schematic hierarchy" ), + KiBitmap( open_document_xpm ) ); + } + // @todo: static probably not OK in multiple open projects. // Open Recent submenu static wxMenu* openRecentMenu; @@ -91,21 +93,21 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() Kiface().GetFileHistory().UseMenu( openRecentMenu ); Kiface().GetFileHistory().AddFilesToMenu( openRecentMenu ); - AddMenuItem( fileMenu, openRecentMenu, - wxID_ANY, _( "Open &Recent" ), - _( "Open a recent opened schematic project" ), - KiBitmap( open_project_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( fileMenu, openRecentMenu, + wxID_ANY, _( "Open &Recent" ), + _( "Open a recent opened schematic project" ), + KiBitmap( open_project_xpm ) ); + } - // Import AddMenuItem( fileMenu, ID_APPEND_PROJECT, _( "&Append Schematic Sheet" ), _( "Append schematic sheet to current project" ), KiBitmap( open_document_xpm ) ); - // Separator fileMenu->AppendSeparator(); - // Save schematic project text = AddHotkeyName( _( "&Save Schematic Project" ), s_Schematic_Hokeys_Descr, HK_SAVE_SCH ); AddMenuItem( fileMenu, @@ -113,31 +115,29 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() _( "Save all sheets in schematic project" ), KiBitmap( save_project_xpm ) ); - // Save current sheet AddMenuItem( fileMenu, ID_UPDATE_ONE_SHEET, _( "Save &Current Sheet Only" ), _( "Save only current schematic sheet" ), KiBitmap( save_xpm ) ); - // Save current sheet as - AddMenuItem( fileMenu, - ID_SAVE_ONE_SHEET_UNDER_NEW_NAME, - _( "Save Current Sheet &As" ), - _( "Save current schematic sheet as..." ), - KiBitmap( save_as_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( fileMenu, + ID_SAVE_ONE_SHEET_UNDER_NEW_NAME, + _( "Save Current Sheet &As" ), + _( "Save current schematic sheet as..." ), + KiBitmap( save_as_xpm ) ); + } - // Separator fileMenu->AppendSeparator(); - // Page settings AddMenuItem( fileMenu, ID_SHEET_SET, _( "Pa&ge Settings" ), _( "Setting for sheet size and frame references" ), KiBitmap( sheetset_xpm ) ); - // Print AddMenuItem( fileMenu, wxID_PRINT, _( "Pri&nt" ), @@ -155,7 +155,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Plot to Clipboard (Windows only) - AddMenuItem( choice_plot_fmt, ID_GEN_COPY_SHEET_TO_CLIPBOARD, _( "Plot to &Clipboard" ), _( "Export drawings to clipboard" ), @@ -243,32 +242,26 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() * using in AddHotkeyName call the option "false" (not a shortcut) */ - // Zoom in text = AddHotkeyName( _( "Zoom &In" ), s_Schematic_Hokeys_Descr, HK_ZOOM_IN, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) ); - // Zoom out text = AddHotkeyName( _( "Zoom &Out" ), s_Schematic_Hokeys_Descr, HK_ZOOM_OUT, IS_ACCELERATOR ); // add accelerator, not a shortcut AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) ); - // Fit on screen text = AddHotkeyName( _( "&Fit on Screen" ), s_Schematic_Hokeys_Descr, HK_ZOOM_AUTO ); AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT, KiBitmap( zoom_fit_in_page_xpm ) ); - // Separator viewMenu->AppendSeparator(); - // Hierarchy AddMenuItem( viewMenu, ID_HIERARCHY, _( "Show &Hierarchical Navigator" ), _( "Navigate hierarchical sheets" ), KiBitmap( hierarchy_nav_xpm ) ); - // Redraw text = AddHotkeyName( _( "&Redraw" ), s_Schematic_Hokeys_Descr, HK_ZOOM_REDRAW ); AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) ); @@ -276,78 +269,66 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // @todo unify IDs wxMenu* placeMenu = new wxMenu; - // Component text = AddHotkeyName( _( "&Component" ), s_Schematic_Hokeys_Descr, HK_ADD_NEW_COMPONENT, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_SCH_PLACE_COMPONENT, text, HELP_PLACE_COMPONENTS, KiBitmap( add_component_xpm ) ); - // Power port text = AddHotkeyName( _( "&Power Port" ), s_Schematic_Hokeys_Descr, HK_ADD_NEW_POWER, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_PLACE_POWER_BUTT, text, HELP_PLACE_POWERPORT, KiBitmap( add_power_xpm ) ); - // Wire text = AddHotkeyName( _( "&Wire" ), s_Schematic_Hokeys_Descr, HK_BEGIN_WIRE, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_WIRE_BUTT, text, HELP_PLACE_WIRE, KiBitmap( add_line_xpm ) ); - // Bus text = AddHotkeyName( _( "&Bus" ), s_Schematic_Hokeys_Descr, HK_BEGIN_BUS, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_BUS_BUTT, text, HELP_PLACE_BUS, KiBitmap( add_bus_xpm ) ); - // Wire to Bus entry text = AddHotkeyName( _( "Wire to Bus &Entry" ), s_Schematic_Hokeys_Descr, HK_ADD_WIRE_ENTRY, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_WIRETOBUS_ENTRY_BUTT, text, HELP_PLACE_WIRE2BUS_ENTRY, KiBitmap( add_line2bus_xpm ) ); - // Bus to Bus entry text = AddHotkeyName( _( "Bus &to Bus Entry" ), s_Schematic_Hokeys_Descr, HK_ADD_BUS_ENTRY, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_BUSTOBUS_ENTRY_BUTT, text, HELP_PLACE_BUS2BUS_ENTRY, KiBitmap( add_bus2bus_xpm ) ); - // No Connect Flag text = AddHotkeyName( _( "&No Connect Flag" ), s_Schematic_Hokeys_Descr, HK_ADD_NOCONN_FLAG, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_NOCONN_BUTT, text, HELP_PLACE_NC_FLAG, KiBitmap( noconn_xpm ) ); - // Net name text = AddHotkeyName( _( "&Label" ), s_Schematic_Hokeys_Descr, HK_ADD_LABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_LABEL_BUTT, text, HELP_PLACE_NETLABEL, KiBitmap( add_line_label_xpm ) ); - // Global label text = AddHotkeyName( _( "Gl&obal Label" ), s_Schematic_Hokeys_Descr, HK_ADD_GLABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_GLABEL_BUTT, text, HELP_PLACE_GLOBALLABEL, KiBitmap( add_glabel_xpm ) ); - // Junction text = AddHotkeyName( _( "&Junction" ), s_Schematic_Hokeys_Descr, HK_ADD_JUNCTION, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_JUNCTION_BUTT, text, HELP_PLACE_JUNCTION, KiBitmap( add_junction_xpm ) ); - // Separator placeMenu->AppendSeparator(); - // Hierarchical label text = AddHotkeyName( _( "&Hierarchical Label" ), s_Schematic_Hokeys_Descr, HK_ADD_HLABEL, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_HIERLABEL_BUTT, @@ -355,38 +336,32 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() KiBitmap( add_hierarchical_label_xpm ) ); - // Hierarchical sheet text = AddHotkeyName( _( "H&ierarchical &Sheet" ), s_Schematic_Hokeys_Descr, HK_ADD_HIER_SHEET, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_SHEET_SYMBOL_BUTT, text, HELP_PLACE_SHEET, KiBitmap( add_hierarchical_subsheet_xpm ) ); - // Import hierarchical sheet AddMenuItem( placeMenu, ID_IMPORT_HLABEL_BUTT, _( "I&mport Hierarchical Label" ), HELP_IMPORT_SHEETPIN, KiBitmap( import_hierarchical_label_xpm ) ); - // Add hierarchical Pin to Sheet AddMenuItem( placeMenu, ID_SHEET_PIN_BUTT, _( "Hierarchical Pi&n to Sheet" ), HELP_PLACE_SHEETPIN, KiBitmap( add_hierar_pin_xpm ) ); - // Separator placeMenu->AppendSeparator(); - // Graphic line or polygon text = AddHotkeyName( _( "Graphic Polyline" ), s_Schematic_Hokeys_Descr, HK_ADD_GRAPHIC_POLYLINE, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_LINE_COMMENT_BUTT, text, HELP_PLACE_GRAPHICLINES, KiBitmap( add_dashed_line_xpm ) ); - // Graphic text text = AddHotkeyName( _( "Graphic Text" ), s_Schematic_Hokeys_Descr, HK_ADD_GRAPHIC_TEXT, IS_ACCELERATOR ); // add an accelerator, not a shortcut AddMenuItem( placeMenu, ID_TEXT_COMMENT_BUTT, text, @@ -437,14 +412,12 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Separator preferencesMenu->AppendSeparator(); - // Save preferences AddMenuItem( preferencesMenu, ID_CONFIG_SAVE, _( "&Save Preferences" ), _( "Save application preferences" ), KiBitmap( save_setup_xpm ) ); - // Read preferences AddMenuItem( preferencesMenu, ID_CONFIG_READ, _( "&Read Preferences" ), @@ -454,22 +427,18 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Menu Tools: wxMenu* toolsMenu = new wxMenu; - // Library editor AddMenuItem( toolsMenu, ID_TO_LIBRARY, _( "Library &Editor" ), HELP_RUN_LIB_EDITOR, KiBitmap( libedit_xpm ) ); - // Library viewer AddMenuItem( toolsMenu, ID_TO_LIBVIEW, _( "Library &Browser" ), HELP_RUN_LIB_VIEWER, KiBitmap( library_browse_xpm ) ); - // Separator toolsMenu->AppendSeparator(); - // Annotate AddMenuItem( toolsMenu, ID_GET_ANNOTATE, _( "&Annotate Schematic" ), HELP_ANNOTATE, @@ -482,24 +451,21 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() _( "Perform electrical rule check" ), KiBitmap( erc_xpm ) ); - // Generate netlist AddMenuItem( toolsMenu, ID_GET_NETLIST, _( "Generate &Netlist File" ), _( "Generate the component netlist file" ), KiBitmap( netlist_xpm ) ); - // Generate bill of materials AddMenuItem( toolsMenu, ID_GET_TOOLS, _( "Generate Bill of &Materials" ), HELP_GENERATE_BOM, KiBitmap( bom_xpm ) ); - // Separator toolsMenu->AppendSeparator(); - //Run CvPcb + // Run CvPcb AddMenuItem( toolsMenu, ID_TO_CVPCB, _( "A&ssign Component Footprint" ), @@ -519,7 +485,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Version info AddHelpVersionInfoMenuEntry( helpMenu ); - // Contents AddMenuItem( helpMenu, wxID_HELP, _( "Eesc&hema Manual" ), @@ -532,7 +497,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() _( "Open \"Getting Started in KiCad\" guide for beginners" ), KiBitmap( help_xpm ) ); - // About Eeschema helpMenu->AppendSeparator(); AddMenuItem( helpMenu, wxID_ABOUT, diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 686efce6de..7908defdc1 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -29,7 +29,7 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aWindowType, const wxString& aTitle, + FRAME_T aWindowType, const wxString& aTitle, const wxPoint& aPosition, const wxSize& aSize, long aStyle, const wxString& aFrameName ) : EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 942bf820e8..3eb8462e9f 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -35,19 +35,6 @@ * They can be renamed and can appear in reports */ -/* set USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR to 0 to use - * a justification relative to the text itself - * i.e. justification relative to an horizontal text - * or to 1 to keep the initial Eeschema behavior - * The initial behavior is: - * For vertical texts, exchange the horizontal and the vertical justification - * The idea is to keep the justification always left or top for instance, - * no matter the text orientation - * This is a bit tricky when you want to change a text field justification - * when the fiels and the component are both rotated 90.0 degrees - */ -#define USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR 0 - #include #include #include @@ -206,7 +193,7 @@ void SCH_FIELD::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, textpos = m_Pos - origin; textpos = parentComponent->GetScreenCoord( textpos ); textpos += parentComponent->GetPosition(); - GRLine( clipbox, DC, origin.x, origin.y, textpos.x, textpos.y, 2, DARKGRAY ); + GRLine( clipbox, DC, origin, textpos, 2, DARKGRAY ); } /* Enable this to draw the bounding box around the text field to validate @@ -281,26 +268,14 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const // Calculate the text bounding box: EDA_RECT rect; - // set USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR to 0 to use - // a justification relative to the text itself - // i.e. justification relative to an horizontal text - // or to 1 to keep the initial behavior -#if (USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR == 1 ) - if( m_Orient == TEXT_ORIENT_VERT ) + if( m_id == REFERENCE ) // multi units have one letter or more added to reference { - // For vertical texts, exchange the horizontal and the vertical justification - // The idea is to keep the justification always left or top for instance, - // no matter the text orientation - SCH_FIELD text( *this ); // Make a local copy to swap justifications + SCH_FIELD text( *this ); // Make a local copy to change text // because GetBoundingBox() is const - int tmp = (int)text.m_VJustify; - NEGATE( tmp ); - text.m_VJustify = (EDA_TEXT_VJUSTIFY_T)text.m_HJustify; - text.m_HJustify = (EDA_TEXT_HJUSTIFY_T)tmp; + text.SetText( GetFullyQualifiedText() ); rect = text.GetTextBox( -1, linewidth ); } else -#endif rect = GetTextBox( -1, linewidth ); // Calculate the bounding box position relative to the component: diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 86a8ed9727..9a7d2a5390 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -1345,7 +1345,7 @@ SCH_SCREEN* SCH_SCREENS::GetNext() } -SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) +SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const { if( aIndex < m_screens.size() ) return m_screens[ aIndex ]; diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 23ef5272c3..230ea77fe3 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -112,7 +112,7 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const } -SCH_SHEET* SCH_SHEET_PATH::Last() +SCH_SHEET* SCH_SHEET_PATH::Last() const { if( m_numSheets ) return m_sheets[m_numSheets - 1]; @@ -121,7 +121,7 @@ SCH_SHEET* SCH_SHEET_PATH::Last() } -SCH_SCREEN* SCH_SHEET_PATH::LastScreen() +SCH_SCREEN* SCH_SHEET_PATH::LastScreen() const { SCH_SHEET* lastSheet = Last(); @@ -132,7 +132,7 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen() } -SCH_ITEM* SCH_SHEET_PATH::LastDrawList() +SCH_ITEM* SCH_SHEET_PATH::LastDrawList() const { SCH_SHEET* lastSheet = Last(); @@ -143,7 +143,7 @@ SCH_ITEM* SCH_SHEET_PATH::LastDrawList() } -SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() +SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() const { SCH_ITEM* item = NULL; @@ -316,7 +316,7 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aInclu } -SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) +SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const { bool hasWrapped = false; bool firstItemFound = false; @@ -349,7 +349,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool } -SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) +SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const { bool hasWrapped = false; bool firstItemFound = false; diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index dcfe9b690a..f6a32fbeb9 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -129,20 +129,20 @@ public: * returns a pointer to the last sheet of the list * One can see the others sheet as the "path" to reach this last sheet */ - SCH_SHEET* Last(); + SCH_SHEET* Last() const; /** * Function LastScreen * @return the SCH_SCREEN relative to the last sheet in list */ - SCH_SCREEN* LastScreen(); + SCH_SCREEN* LastScreen() const; /** * Function LastDrawList * @return a pointer to the first schematic item handled by the * SCH_SCREEN relative to the last sheet in list */ - SCH_ITEM* LastDrawList(); + SCH_ITEM* LastDrawList() const; /** * Get the last schematic item relative to the first sheet in the list. @@ -150,7 +150,7 @@ public: * @return Last schematic item relative to the first sheet in the list if list * is not empty. Otherwise NULL. */ - SCH_ITEM* FirstDrawList(); + SCH_ITEM* FirstDrawList() const; /** * Function Push @@ -248,7 +248,7 @@ public: * is defined. * @return - The next schematic item if found. Otherwise, NULL is returned. */ - SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); + SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const; /** * Find the previous schematic item in this sheet path object. @@ -260,7 +260,7 @@ public: * is defined. * @return - The previous schematic item if found. Otherwise, NULL is returned. */ - SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); + SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const; SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 ); @@ -318,7 +318,7 @@ public: * @return the number of sheets in list: * usually the number of sheets found in the whole hierarchy */ - int GetCount() { return m_count; } + int GetCount() const { return m_count; } /** * Function GetFirst diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index a2fba0988d..fe38369fd4 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -176,7 +176,7 @@ END_EVENT_TABLE() #define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" ) SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): - SCH_BASE_FRAME( aKiway, aParent, SCHEMATIC_FRAME_TYPE, wxT( "Eeschema" ), + SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ), m_item_to_repeat( 0 ) { @@ -764,9 +764,23 @@ void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) { fn.SetExt( PcbFileExtension ); - wxString filename = QuoteFullPath( fn ); + if( Kiface().IsSingle() ) + { + wxString filename = QuoteFullPath( fn ); + ExecuteFile( this, PCBNEW_EXE, filename ); + } + else + { + KIWAY_PLAYER* player = Kiway().Player( FRAME_PCB, false ); // test open already. - ExecuteFile( this, PCBNEW_EXE, filename ); + if( !player ) + { + player = Kiway().Player( FRAME_PCB, true ); + player->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + player->Show( true ); + } + player->Raise(); + } } else { @@ -783,7 +797,22 @@ void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event ) if( fn.IsOk() && fn.FileExists() ) { - ExecuteFile( this, CVPCB_EXE, QuoteFullPath( fn ) ); + if( Kiface().IsSingle() ) + { + ExecuteFile( this, CVPCB_EXE, QuoteFullPath( fn ) ); + } + else + { + KIWAY_PLAYER* player = Kiway().Player( FRAME_CVPCB, false ); // test open already. + + if( !player ) + { + player = Kiway().Player( FRAME_CVPCB, true ); + player->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + player->Show( true ); + } + player->Raise(); + } } else { @@ -802,13 +831,15 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) if( (item == NULL) || (item->GetFlags() != 0) || ( item->Type() != SCH_COMPONENT_T ) ) { - wxMessageBox( _("Error: not a component or no component" ) ); + wxMessageBox( _( "Error: not a component or no component" ) ); return; } component = (SCH_COMPONENT*) item; } + // @todo: should be changed to use Kiway().Player()? + LIB_EDIT_FRAME* libeditFrame = LIB_EDIT_FRAME::GetActiveLibraryEditor();; if( libeditFrame ) { @@ -819,7 +850,9 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) } else { - wxWindow* w = Kiface().CreateWindow( this, LIBEDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + wxWindow* w = kf.CreateWindow( this, FRAME_SCH_LIB_EDITOR, &Kiway(), kf.StartFlags() ); libeditFrame = dynamic_cast( w ); } @@ -1040,3 +1073,4 @@ void SCH_EDIT_FRAME::UpdateTitle() SetTitle( title ); } + diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 3dbb135fc1..62d9fca131 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -27,13 +27,11 @@ */ #include -//#include #include #include #include #include -//#include #include #include diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp index 3963b03dbf..33b05c1bc6 100644 --- a/eeschema/viewlib_frame.cpp +++ b/eeschema/viewlib_frame.cpp @@ -97,7 +97,7 @@ static wxAcceleratorEntry accels[] = LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, SCH_BASE_FRAME* aParent, CMP_LIBRARY* aLibrary, wxSemaphore* aSemaphore, long aStyle ) : - SCH_BASE_FRAME( aKiway, aParent, VIEWER_FRAME_TYPE, _( "Library Browser" ), + SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Library Browser" ), wxDefaultPosition, wxDefaultSize, aStyle, GetLibViewerFrameName() ) { wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt index df67987d6f..7eff8d254e 100644 --- a/gerbview/CMakeLists.txt +++ b/gerbview/CMakeLists.txt @@ -100,7 +100,7 @@ if( USE_KIWAY_DLLS ) ${GERBVIEW_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=GERBER_FRAME_TYPE;BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_GERBER;BUILD_KIWAY_DLL" ) target_link_libraries( gerbview #singletop # replaces common, giving us restrictive control and link warnings. diff --git a/gerbview/class_gbr_screen.h b/gerbview/class_gbr_screen.h index 8be96b21d5..9e89373e53 100644 --- a/gerbview/class_gbr_screen.h +++ b/gerbview/class_gbr_screen.h @@ -26,7 +26,7 @@ public: ~GBR_SCREEN(); - GBR_SCREEN* Next() { return (GBR_SCREEN*) Pnext; } + GBR_SCREEN* Next() const { return static_cast( Pnext ); } // void SetNextZoom(); // void SetPreviousZoom(); diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h index 2989333c0a..70ad0a1164 100644 --- a/gerbview/class_gerber_draw_item.h +++ b/gerbview/class_gerber_draw_item.h @@ -116,8 +116,8 @@ public: */ GERBER_DRAW_ITEM* Copy() const; - GERBER_DRAW_ITEM* Next() const { return (GERBER_DRAW_ITEM*) Pnext; } - GERBER_DRAW_ITEM* Back() const { return (GERBER_DRAW_ITEM*) Pback; } + GERBER_DRAW_ITEM* Next() const { return static_cast( Pnext ); } + GERBER_DRAW_ITEM* Back() const { return static_cast( Pback ); } /** * Function GetLayer diff --git a/gerbview/gerbview.cpp b/gerbview/gerbview.cpp index 4e52f3937a..0423cd6b72 100644 --- a/gerbview/gerbview.cpp +++ b/gerbview/gerbview.cpp @@ -73,7 +73,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -81,7 +81,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case GERBER_FRAME_TYPE: + case FRAME_GERBER: { GERBVIEW_FRAME* frame = new GERBVIEW_FRAME( aKiway, aParent ); @@ -145,9 +145,9 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - start_common(); + start_common( aCtlBits ); // Must be called before creating the main frame in order to // display the real hotkeys in menus or tool tips diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index 1e2b073e8d..b6d6d412e4 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -65,7 +65,7 @@ static const wxString cfgShowBorderAndTitleBlock( wxT( "ShowBorderAndTitleBloc #define GERBVIEW_FRAME_NAME wxT( "GerberFrame" ) GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ): - EDA_DRAW_FRAME( aKiway, aParent, GERBER_FRAME_TYPE, wxT( "GerbView" ), + EDA_DRAW_FRAME( aKiway, aParent, FRAME_GERBER, wxT( "GerbView" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GERBVIEW_FRAME_NAME ) { m_colorsSettings = &g_ColorsSettings; diff --git a/include/base_struct.h b/include/base_struct.h index 8679cfdd5b..9ec7af03c8 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -375,8 +375,8 @@ public: void SetTimeStamp( time_t aNewTimeStamp ) { m_TimeStamp = aNewTimeStamp; } time_t GetTimeStamp() const { return m_TimeStamp; } - EDA_ITEM* Next() const { return (EDA_ITEM*) Pnext; } - EDA_ITEM* Back() const { return (EDA_ITEM*) Pback; } + EDA_ITEM* Next() const { return Pnext; } + EDA_ITEM* Back() const { return Pback; } EDA_ITEM* GetParent() const { return m_Parent; } DHEAD* GetList() const { return m_List; } diff --git a/include/class_board_design_settings.h b/include/class_board_design_settings.h index 31ebfccfe5..67e0c73a88 100644 --- a/include/class_board_design_settings.h +++ b/include/class_board_design_settings.h @@ -7,6 +7,7 @@ #include // NB_COLORS #include +#include #include @@ -19,7 +20,7 @@ class BOARD_DESIGN_SETTINGS public: bool m_MicroViasAllowed; ///< true to allow micro vias bool m_BlindBuriedViaAllowed; ///< true to allow blind/buried vias - int m_CurrentViaType; ///< via type (VIA_BLIND_BURIED, VIA_THROUGH VIA_MICROVIA) + VIATYPE_T m_CurrentViaType; ///< via type (VIA_BLIND_BURIED, VIA_THROUGH VIA_MICROVIA) /// if true, when creating a new track starting on an existing track, use this track width bool m_UseConnectedTrackWidth; diff --git a/include/class_board_item.h b/include/class_board_item.h index d438483502..73dc7a061c 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -106,8 +106,8 @@ public: */ static wxPoint ZeroOffset; - BOARD_ITEM* Next() const { return (BOARD_ITEM*) Pnext; } - BOARD_ITEM* Back() const { return (BOARD_ITEM*) Pback; } + BOARD_ITEM* Next() const { return static_cast( Pnext ); } + BOARD_ITEM* Back() const { return static_cast( Pback ); } BOARD_ITEM* GetParent() const { return (BOARD_ITEM*) m_Parent; } /** diff --git a/include/class_pcb_screen.h b/include/class_pcb_screen.h index e15082be40..59f3f3d592 100644 --- a/include/class_pcb_screen.h +++ b/include/class_pcb_screen.h @@ -31,7 +31,7 @@ public: ~PCB_SCREEN(); - PCB_SCREEN* Next() { return (PCB_SCREEN*) Pnext; } + PCB_SCREEN* Next() const { return static_cast( Pnext ); } void SetNextZoom(); void SetPreviousZoom(); diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index 02a6787679..acf8f20819 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -523,7 +523,7 @@ public: int GetCount() const { return m_screens.size(); } SCH_SCREEN* GetFirst(); SCH_SCREEN* GetNext(); - SCH_SCREEN* GetScreen( unsigned int aIndex ); + SCH_SCREEN* GetScreen( unsigned int aIndex ) const; /** * Function ClearAnnotation diff --git a/include/common.h b/include/common.h index 31d95c897f..ef03ea0e6a 100644 --- a/include/common.h +++ b/include/common.h @@ -610,4 +610,8 @@ void SystemDirsAppend( SEARCH_STACK* aSearchStack ); wxString SearchHelpFileFullPath( const SEARCH_STACK& aSearchStack, const wxString& aBaseName ); +/// Put aPriorityPath in front of all paths in the value of aEnvVar. +const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath ); + + #endif // INCLUDE__COMMON_H_ diff --git a/include/config_params.h b/include/config_params.h index e83899af85..5529fbfce5 100644 --- a/include/config_params.h +++ b/include/config_params.h @@ -49,7 +49,6 @@ #define CONFIG_VERSION 1 -#define FORCE_LOCAL_CONFIG true /** diff --git a/include/draw_frame.h b/include/draw_frame.h index c8067de3d7..9cc2149c15 100644 --- a/include/draw_frame.h +++ b/include/draw_frame.h @@ -118,7 +118,7 @@ protected: public: EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aFrameType, + FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, diff --git a/include/frame_type.h b/include/frame_type.h new file mode 100644 index 0000000000..23411168c6 --- /dev/null +++ b/include/frame_type.h @@ -0,0 +1,32 @@ +#ifndef FRAME_T_H_ +#define FRAME_T_H_ + +/** + * Enum FRAME_T + * is the set of EDA_BASE_FRAME derivatives, typically stored in + * EDA_BASE_FRAME::m_Ident. + */ +enum FRAME_T +{ + FRAME_SCH, + FRAME_SCH_LIB_EDITOR, + FRAME_SCH_VIEWER, + FRAME_PCB, + FRAME_PCB_MODULE_EDITOR, + FRAME_PCB_MODULE_VIEWER, + FRAME_PCB_FOOTPRINT_WIZARD, + FRAME_PCB_DISPLAY3D, + FRAME_CVPCB, + FRAME_CVPCB_DISPLAY, + FRAME_GERBER, + + KIWAY_PLAYER_COUNT, // counts subset of FRAME_T's tracked in class KIWAY + + KICAD_MAIN_FRAME_T = KIWAY_PLAYER_COUNT, + FRAME_PL_EDITOR, + //TEXT_EDITOR_FRAME_T, + + FRAME_T_COUNT +}; + +#endif // FRAME_T_H_ diff --git a/include/geometry/rtree.h b/include/geometry/rtree.h index 6d5a5561d7..4ae5fafae6 100644 --- a/include/geometry/rtree.h +++ b/include/geometry/rtree.h @@ -32,10 +32,10 @@ #define ASSERT assert // RTree uses ASSERT( condition ) #ifndef Min - #define Min std::min + #define rMin std::min #endif // Min #ifndef Max - #define Max std::max + #define rMax std::max #endif // Max // @@ -1326,8 +1326,8 @@ typename RTREE_QUAL::Rect RTREE_QUAL::CombineRect( Rect* a_rectA, Rect* a_rectB for( int index = 0; index < NUMDIMS; ++index ) { - newRect.m_min[index] = Min( a_rectA->m_min[index], a_rectB->m_min[index] ); - newRect.m_max[index] = Max( a_rectA->m_max[index], a_rectB->m_max[index] ); + newRect.m_min[index] = rMin( a_rectA->m_min[index], a_rectB->m_min[index] ); + newRect.m_max[index] = rMax( a_rectA->m_max[index], a_rectB->m_max[index] ); } return newRect; diff --git a/include/kiface_i.h b/include/kiface_i.h index d764c9de35..9fe034603a 100644 --- a/include/kiface_i.h +++ b/include/kiface_i.h @@ -43,7 +43,7 @@ public: // see base class KIFACE in kiway.h for doxygen docs - VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram ) = 0; + VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) = 0; /* { typically call start_common() in your overload @@ -58,7 +58,7 @@ public: } VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent, - int aClassId, KIWAY* aKIWAY, int aCtlBits = 0 ) = 0; + int aClassId, KIWAY* aKIWAY, int aCtlBits ) = 0; VTBL_ENTRY void* IfaceOrAddress( int aDataId ) = 0; @@ -76,7 +76,8 @@ public: */ KIFACE_I( const char* aKifaceName, KIWAY::FACE_T aId ) : m_id( aId ), - m_bm( aKifaceName ) + m_bm( aKifaceName ), + m_start_flags( 0 ) { } @@ -85,7 +86,7 @@ public: protected: /// Common things to do for a top program module, during OnKifaceStart(). - bool start_common(); + bool start_common( int aCtlBits ); /// Common things to do for a top program module, during OnKifaceEnd(); void end_common(); @@ -100,6 +101,18 @@ public: wxConfigBase* KifaceSettings() const { return m_bm.m_config; } + /** + * Function StartFlags + * returns whatever was passed as @a aCtlBits to OnKifaceStart() + */ + int StartFlags() const { return m_start_flags; } + + /** + * Function IsSingle + * is this KIFACE_I running under single_top? + */ + bool IsSingle() const { return m_start_flags & KFCTL_STANDALONE; } + /** * Function GetHelpFileName * returns just the basename portion of the current help file. @@ -116,6 +129,8 @@ private: KIWAY::FACE_T m_id; BIN_MOD m_bm; + + int m_start_flags; ///< flags provided in OnKifaceStart() }; diff --git a/include/kiway.h b/include/kiway.h index b13f8b88e4..9b2ffd6b2d 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -101,6 +101,8 @@ as such! As such, it is OK to use UTF8 characters: #include #include #include +#include +#include #define VTBL_ENTRY virtual @@ -112,25 +114,21 @@ as such! As such, it is OK to use UTF8 characters: // be mangled. #define KIFACE_INSTANCE_NAME_AND_VERSION "KIFACE_1" - #if defined(__linux__) #define LIB_ENV_VAR wxT( "LD_LIBRARY_PATH" ) - #elif defined(__WXMAC__) #define LIB_ENV_VAR wxT( "DYLD_LIBRARY_PATH" ) - #elif defined(__MINGW32__) #define LIB_ENV_VAR wxT( "PATH" ) #endif class wxConfigBase; - - -class KIWAY; class wxWindow; -class PGM_BASE; class wxConfigBase; +class PGM_BASE; +class KIWAY; +class KIWAY_PLAYER; /** @@ -151,6 +149,10 @@ struct KIFACE // order of functions in this listing unless you recompile all clients of // this interface. +#define KFCTL_STANDALONE (1<<0) ///< Am running as a standalone Top. +#define KFCTL_PROJECT_SUITE (1<<1) ///< Am running under a project mgr, possibly with others + + /** * Function OnKifaceStart * is called just once shortly after the DSO is loaded. It is the second @@ -161,13 +163,15 @@ struct KIFACE * * @param aProgram is the process block: PGM_BASE* * + * @param aCtlBits consists of bit flags from the set of KFCTL_* \#defines above. + * * @return bool - true if DSO initialized OK, false if not. When returning * false, the loader may optionally decide to terminate the process or not, * but will not put out any UI because that is the duty of this function to say * why it is returning false. Never return false without having reported * to the UI why. */ - VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram ) = 0; + VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) = 0; /** * Function OnKifaceEnd @@ -176,8 +180,6 @@ struct KIFACE */ VTBL_ENTRY void OnKifaceEnd() = 0; -#define KFCTL_STANDALONE (1<<0) ///< Am running as a standalone Top. - /** * Function CreateWindow * creates a wxWindow for the current project. The caller @@ -199,7 +201,7 @@ struct KIFACE * not contained in the caller's link image. */ VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent, int aClassId, - KIWAY* aKIWAY, int aCtlBits = 0 ) = 0; + KIWAY* aKIWAY, int aCtlBits ) = 0; /** * Function IfaceOrAddress @@ -249,62 +251,120 @@ class KIWAY : public wxEvtHandler { public: - /// DSO players on *this* KIWAY + /// Known KIFACE implementations enum FACE_T { - FACE_SCH, ///< eeschema DSO - // FACE_LIB, - FACE_PCB, ///< pcbnew DSO - // FACE_MOD, + FACE_SCH, ///< eeschema DSO + FACE_PCB, ///< pcbnew DSO FACE_CVPCB, - FACE_BMP2CMP, + + /// count of those above here, which is the subset managed in a KIWAY. + KIWAY_FACE_COUNT, + + FACE_BMP2CMP = KIWAY_FACE_COUNT, FACE_GERBVIEW, FACE_PL_EDITOR, FACE_PCB_CALCULATOR, - FACE_COUNT, ///< how many KIWAY player types + FACE_COUNT }; - /* from edaappl.h, now pgm_base.h, obsoleted by above FACE_T enum. - enum PGM_BASE_T - { - APP_UNKNOWN, - APP_EESCHEMA, - APP_PCBNEW, - APP_CVPCB, - APP_GERBVIEW, - APP_KICAD, - APP_PL_EDITOR, - APP_BM2CMP, - }; - */ + /** + * Function KifaceType + * is a simple mapping function which returns the FACE_T which is known to + * implement @a aFrameType. + * + * @return KIWAY::FACE_T - a valid value or FACE_T(-1) if given a bad aFrameType. + */ + static FACE_T KifaceType( FRAME_T aFrameType ); - // Don't change the order of these VTBL_ENTRYs, add new ones at the end, - // unless you recompile all of KiCad. - VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad ); - VTBL_ENTRY PROJECT& Prj() const; + // If you change the vtable, recompile all of KiCad. - KIWAY(); + /** + * Function KiFACE + * returns the KIFACE* given a FACE_T. If it is not already loaded, the + * KIFACE is loaded and initialized with a call to KIFACE::OnKifaceStart() + */ + VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad = true ); + + /** + * Function Player + * returns the KIWAY_PLAYER* given a FRAME_T. If it is not already created, + * the required KIFACE is found and loaded and initialized if necessary, then + * the KIWAY_PLAYER window is created but not shown. Caller must Show() it. + * If it is already created, then the existing KIWAY_PLAYER* pointer is returned. + * + * @param aFrameType is from enum #FRAME_T. + * @param doCreate when true asks that the player be created if it is not + * already created, false means do not create and maybe return NULL. + * + * @return KIWAY_PLAYER* - a valid opened KIWAY_PLAYER or NULL if there + * is something wrong or doCreate was false and the player has yet to be created. + */ + VTBL_ENTRY KIWAY_PLAYER* Player( FRAME_T aFrameType, bool doCreate = true ); + + /** + * Function PlayerClose + * calls the KIWAY_PLAYER::Close( bool force ) function on the window and + * if not vetoed, returns true, else false. If window actually closes, then + * this KIWAY marks it as not opened internally. + * + * @return bool - true the window is closed and not vetoed, else false. + */ + VTBL_ENTRY bool PlayerClose( FRAME_T aFrameType, bool doForce ); + + /** + * Function PlayersClose + * calls the KIWAY_PLAYER::Close( bool force ) function on all the windows and + * if none are vetoed, returns true, else false. If any window actually closes, then + * this KIWAY marks it as not opened internally. + * + * @return bool - true indicates that all windows closed because none were vetoed, + * false means at least one cast a veto. Any that cast a veto are still open. + */ + VTBL_ENTRY bool PlayersClose( bool doForce ); + + VTBL_ENTRY void ExpressMail( FRAME_T aDestination, MAIL_T aCommand, const std::string& aPayload, wxWindow* aSource=NULL ); + + /** + * Function Prj + * returns the PROJECT associated with this KIWAY. This is here as an + * accessor, so that there is freedom to put the actual PROJECT storage + * in a place decided by the implementation, and not known to the caller. + */ + VTBL_ENTRY PROJECT& Prj() const; + + KIWAY( PGM_BASE* aProgram, wxFrame* aTop = NULL ); + + /// In case aTop may not be known at time of KIWAY construction: + void SetTop( wxFrame* aTop ); + + bool ProcessEvent( wxEvent& aEvent ); // overload virtual private: - /* - /// Get the name of the DSO holding the requested FACE_T. - static const wxString dso_name( FACE_T aFaceId ); - */ + /// Get the full path & name of the DSO holding the requested FACE_T. + static const wxString dso_full_path( FACE_T aFaceId ); - // one for each FACE_T - static wxDynamicLibrary s_sch_dso; - static wxDynamicLibrary s_pcb_dso; - //static wxDynamicLibrary s_cvpcb_dso; // will get merged into pcbnew + /// hooked into m_top in SetTop(), marks child frame as closed. + void playerDestroyHandler( wxWindowDestroyEvent& event ); - KIFACE* m_kiface[FACE_COUNT]; + static KIFACE* m_kiface[KIWAY_FACE_COUNT]; + static int m_kiface_version[KIWAY_FACE_COUNT]; - PROJECT m_project; // do not assume this is here, use Prj(). + PGM_BASE* m_program; + wxFrame* m_top; + + KIWAY_PLAYER* m_player[KIWAY_PLAYER_COUNT]; // from frame_type.h + + PROJECT m_project; // do not assume this is here, use Prj(). }; +extern KIWAY Kiway; // provided by single_top.cpp and kicad.cpp + + /** * Function Pointer KIFACE_GETTER_FUNC * points to the one and only KIFACE export. The export's address @@ -323,4 +383,5 @@ typedef KIFACE* KIFACE_GETTER_FUNC( int* aKIFACEversion, int aKIWAYversion, /// No name mangling. Each KIFACE (DSO/DLL) will implement this once. extern "C" KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, PGM_BASE* aProgram ); + #endif // KIWAY_H_ diff --git a/include/kiway_express.h b/include/kiway_express.h new file mode 100644 index 0000000000..cebc9dfd95 --- /dev/null +++ b/include/kiway_express.h @@ -0,0 +1,105 @@ +#ifndef KIWAY_EXPRESS_H_ +#define KIWAY_EXPRESS_H_ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +// @see http://wiki.wxwidgets.org/Custom_Events_Tutorial + +#include +#include +#include + + +/** + * Class KIWAY_EXPRESS + * carries a payload from one KIWAY_PLAYER to another within a PROJECT. + */ +class KIWAY_EXPRESS : public wxEvent +{ +public: + /** + * Function Dest + * returns the destination player id of the message. + */ + FRAME_T Dest() { return m_destination; } + + /** + * Function Command + * returns the MAIL_T associated with this mail. + */ + MAIL_T Command() + { + return (MAIL_T) GetId(); // re-purposed control id. + } + + /** + * Function Payload + * returns the payload, which can be any text but it typicall self + * identifying s-expression. + */ + const std::string& GetPayload() { return m_payload; } + void SetPayload( const std::string& aPayload ) { m_payload = aPayload; } + + KIWAY_EXPRESS* Clone() const { return new KIWAY_EXPRESS( *this ); } + + //KIWAY_EXPRESS() {} + + KIWAY_EXPRESS( FRAME_T aDestination, + MAIL_T aCommand, + const std::string& aPayload, + wxWindow* aSource = NULL ); + + KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ); + + /// The wxEventType argument to wxEvent() and identifies an event class + /// in a hurry. These wxEventTypes also allow a common class to be used + /// multiple ways. Should be allocated at startup by wxNewEventType(); + static const wxEventType wxEVENT_ID; + + //DECLARE_DYNAMIC_CLASS( KIWAY_EXPRESS ) + +private: + FRAME_T m_destination; ///< could have been a bitmap indicating multiple recipients + std::string m_payload; ///< very often s-expression text, but not always + + // possible new ideas here. +}; + + +typedef void ( wxEvtHandler::*kiwayExpressFunction )( KIWAY_EXPRESS& ); + +#define wxKiwayExressHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(kiwayExpressFunction, &func) + + +#define EVT_KIWAY_EXPRESS( func ) \ + DECLARE_EVENT_TABLE_ENTRY( \ + KIWAY_EXPRESS::wxEVENT_ID, -1, -1, \ + (wxObjectEventFunction) \ + (kiwayExpressFunction) & func, \ + (wxObject*) NULL ), + + +#endif // KIWAY_EXPRESS_H_ + diff --git a/include/kiway_mgr.h b/include/kiway_mgr.h new file mode 100644 index 0000000000..4dde97c65f --- /dev/null +++ b/include/kiway_mgr.h @@ -0,0 +1,68 @@ + +#ifndef KIWAY_MGR_H_ +#define KIWAY_MGR_H_ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#include +#include + + +/** + * Class KIWAY_MGR + * is a container for all KIWAYS [and PROJECTS]. This class needs to work both + * for a C++ project manager and an a wxPython one (after being moved into a + * header later). + */ +class KIWAY_MGR +{ +public: + //KIWAY_MGR(); + // ~KIWAY_MGR(); + + bool OnStart( wxApp* aProcess ); + + void OnEnd(); + + KIWAY& operator[]( int aIndex ) + { + wxASSERT( m_kiways.size() ); // stuffed in OnStart() + return m_kiways[aIndex]; + } + +private: + + // KIWAYs may not be moved once doled out, since window DNA depends on the + // pointer being good forever. + // boost_ptr::vector however never moves the object pointed to. + typedef boost::ptr_vector KIWAYS; + + KIWAYS m_kiways; +}; + +extern KIWAY_MGR Kiways; + +#endif // KIWAY_MGR_H_ diff --git a/include/kiway_player.h b/include/kiway_player.h index b61b6f195c..75b1189053 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -84,6 +84,8 @@ private: }; +class KIWAY_EXPRESS; + /** * Class KIWAY_PLAYER * is a wxFrame capable of the OpenProjectFiles function, meaning it can load @@ -98,21 +100,15 @@ private: class KIWAY_PLAYER : public EDA_BASE_FRAME, public KIWAY_HOLDER { public: - KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, + KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, - long aStyle, const wxString& aWdoName = wxFrameNameStr ) : - EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), - KIWAY_HOLDER( aKiway ) - {} + long aStyle, const wxString& aWdoName = wxFrameNameStr ); /// Don't use this one, only wxformbuilder uses it, and it must be augmented with /// a SetKiway() early in derived constructor. KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, - const wxString& aWdoName = wxFrameNameStr ) : - EDA_BASE_FRAME( aParent, (ID_DRAWFRAME_TYPE) aId, aTitle, aPos, aSize, aStyle, aWdoName ), - KIWAY_HOLDER( 0 ) - {} + const wxString& aWdoName = wxFrameNameStr ); // For the aCtl argument of OpenProjectFiles() @@ -130,7 +126,7 @@ public: *

* Each derived class should handle this in a way specific to its needs. * No prompting is done inside here for any file or project. There should be - * need to call this with aFileList which is empty. However, calling it with + * no need to call this with aFileList which is empty. However, calling it with * a single filename which does not exist should indicate to the implementor * that a new session is being started and that the given name is the desired * name for the data file at time of save. @@ -164,6 +160,67 @@ public: return false; } + + /** + * Function KiwayMailIn + * receives KIWAY_EXPRESS messages from other players. Merely override it + * in derived classes. + */ + virtual void KiwayMailIn( KIWAY_EXPRESS& aEvent ); + + DECLARE_EVENT_TABLE() + +//private: + + /// event handler, routes to virtual KiwayMailIn() + void kiway_express( KIWAY_EXPRESS& aEvent ); }; + +// psuedo code for OpenProjectFiles +#if 0 + +bool OpenProjectFiles( const std::vector& aFileList, int aCtl = 0 ) +{ + if( aFileList.size() != 1 ) + { + complain via UI. + return false + } + + assert( aFileList[0] is absolute ) // bug in single_top.cpp or project manager. + + if (window does not support appending) || !(aCtl & KICTL_OPEN_APPEND) + { + close any currently open project files. + } + + if( aFileList[0] does not exist ) + { + notify user file does not exist. + + create an empty project file + mark file as modified. + + use the default project config file. + } + else + { + load aFileList[0] + + use the project config file for project given by aFileList[0]s full path. + } + + UpdateTitle(); + + show contents. +} + + + +#endif + + + + #endif // KIWAY_PLAYER_H_ diff --git a/include/mail_type.h b/include/mail_type.h new file mode 100644 index 0000000000..9f30d3e284 --- /dev/null +++ b/include/mail_type.h @@ -0,0 +1,16 @@ +#ifndef MAIL_TYPE_H_ +#define MAIL_TYPE_H_ + +/** + * Enum MAIL_T + * is the set of mail types sendable via KIWAY::ExpressMail() and supplied as + * the @a aCommand parameter to that function. Such mail will be received in + * KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) and aEvent.Command() will + * match aCommand to KIWAY::ExpressMail(). + */ +enum MAIL_T +{ + MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing. +}; + +#endif // MAIL_TYPE_H_ diff --git a/include/plot_common.h b/include/plot_common.h index f59a2fbd82..3f0aee4e75 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -568,7 +568,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); protected: virtual void emitSetRGBColor( double r, double g, double b ); }; @@ -633,7 +634,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos, double aScaleFactor ); @@ -702,7 +704,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); protected: FILL_T m_fillMode; // true if the current contour @@ -904,7 +907,8 @@ public: enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, - bool aBold ); + bool aBold, + bool aMultilineAllowed = false ); protected: bool textAsLines; diff --git a/include/sch_base_frame.h b/include/sch_base_frame.h index 27a4193446..261989c89a 100644 --- a/include/sch_base_frame.h +++ b/include/sch_base_frame.h @@ -47,7 +47,7 @@ class SCH_BASE_FRAME : public EDA_DRAW_FRAME { public: SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, - ID_DRAWFRAME_TYPE aWindowType, + FRAME_T aWindowType, const wxString& aTitle, const wxPoint& aPosition, const wxSize& aSize, long aStyle, const wxString & aFrameName ); diff --git a/include/sch_item_struct.h b/include/sch_item_struct.h index e425e1d6b1..5fe90cd69f 100644 --- a/include/sch_item_struct.h +++ b/include/sch_item_struct.h @@ -136,8 +136,8 @@ public: */ virtual void SwapData( SCH_ITEM* aItem ); - SCH_ITEM* Next() { return (SCH_ITEM*) Pnext; } - SCH_ITEM* Back() { return (SCH_ITEM*) Pback; } + SCH_ITEM* Next() const { return static_cast( Pnext ); } + SCH_ITEM* Back() const { return static_cast( Pback ); } /** * Function GetLayer diff --git a/include/view/view_item.h b/include/view/view_item.h index 6540ea3c82..5dfabd7c33 100644 --- a/include/view/view_item.h +++ b/include/view/view_item.h @@ -57,8 +57,8 @@ enum KICAD_T PCB_TEXT_T, ///< class TEXTE_PCB, text on a layer PCB_MODULE_TEXT_T, ///< class TEXTE_MODULE, text in a footprint PCB_MODULE_EDGE_T, ///< class EDGE_MODULE, a footprint edge - PCB_TRACE_T, ///< class TRACKE, a track segment (segment on a copper layer) - PCB_VIA_T, ///< class SEGVIA, a via (like a track segment on a copper layer) + PCB_TRACE_T, ///< class TRACK, a track segment (segment on a copper layer) + PCB_VIA_T, ///< class VIA, a via (like a track segment on a copper layer) PCB_ZONE_T, ///< class SEGZONE, a segment used to fill a zone area (segment on a ///< copper layer) PCB_MARKER_T, ///< class MARKER_PCB, a marker used to show something diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index d6ed9b0ba8..cd23d6fdd1 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -115,7 +115,7 @@ protected: static const LAYER_NUM GAL_LAYER_ORDER[]; public: - PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, + PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aFrameName ); diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index 5f22c1fab7..fea2499c69 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -368,6 +368,8 @@ public: */ virtual void ExecuteRemoteCommand( const char* cmdline ); + void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // virtual overload from KIWAY_PLAYER + void OnLeftClick( wxDC* aDC, const wxPoint& aPosition ); void OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ); bool OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ); diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index e0334d4e6c..24bda1259c 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -44,7 +44,7 @@ class TEXTE_PCB; class MODULE; class TRACK; class SEGZONE; -class SEGVIA; +class VIA; class D_PAD; class TEXTE_MODULE; class PCB_TARGET; @@ -209,6 +209,8 @@ public: */ virtual void ExecuteRemoteCommand( const char* cmdline ); + void KiwayMailIn( KIWAY_EXPRESS& aEvent ); // virtual overload from KIWAY_PLAYER + /** * Function ToPlotter * Open a dialog frame to create plot and drill files diff --git a/include/wxstruct.h b/include/wxstruct.h index dbf8679ef5..73363cceed 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -46,6 +46,7 @@ #include #include #include +#include #ifdef USE_WX_OVERLAY #include @@ -81,26 +82,6 @@ enum id_librarytype { }; -enum ID_DRAWFRAME_TYPE -{ - NOT_INIT_FRAME_TYPE = 0, - SCHEMATIC_FRAME_TYPE, - LIBEDITOR_FRAME_TYPE, - VIEWER_FRAME_TYPE, - PCB_FRAME_TYPE, - MODULE_EDITOR_FRAME_TYPE, - MODULE_VIEWER_FRAME_TYPE, - FOOTPRINT_WIZARD_FRAME_TYPE, - CVPCB_FRAME_TYPE, - CVPCB_DISPLAY_FRAME_TYPE, - GERBER_FRAME_TYPE, - TEXT_EDITOR_FRAME_TYPE, - DISPLAY3D_FRAME_TYPE, - KICAD_MAIN_FRAME_TYPE, - PL_EDITOR_FRAME_TYPE -}; - - /// Custom trace mask to enable and disable auto save tracing. extern const wxChar traceAutoSave[]; @@ -132,7 +113,7 @@ class EDA_BASE_FRAME : public wxFrame void windowClosing( wxCloseEvent& event ); protected: - ID_DRAWFRAME_TYPE m_Ident; ///< Id Type (pcb, schematic, library..) + FRAME_T m_Ident; ///< Id Type (pcb, schematic, library..) wxPoint m_FramePos; wxSize m_FrameSize; @@ -196,7 +177,7 @@ protected: virtual wxString help_name(); public: - EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, + EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aFrameName ); @@ -219,7 +200,7 @@ public: bool IsActive() const { return m_FrameIsActive; } - bool IsType( ID_DRAWFRAME_TYPE aType ) const { return m_Ident == aType; } + bool IsType( FRAME_T aType ) const { return m_Ident == aType; } void GetKicadHelp( wxCommandEvent& event ); diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 2647e93792..1d76b4696b 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -1,12 +1,12 @@ -add_definitions(-DKICAD) +add_definitions( -DKICAD ) -include_directories(BEFORE ${INC_BEFORE}) +include_directories( BEFORE ${INC_BEFORE} ) include_directories( ${INC_AFTER} ) -set(KICAD_SRCS +set( KICAD_SRCS class_treeprojectfiles.cpp class_treeproject_item.cpp commandframe.cpp @@ -19,48 +19,66 @@ set(KICAD_SRCS preferences.cpp prjconfig.cpp project_template.cpp - tree_project_frame.cpp) + tree_project_frame.cpp + ) -if(MINGW) +if( MINGW ) # KICAD_RESOURCES variable is set by the macro. - mingw_resource_compiler(kicad) + mingw_resource_compiler( kicad ) endif() -if(APPLE) - set(KICAD_RESOURCES kicad.icns kicad_doc.icns) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/kicad.icns" - PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/kicad_doc.icns" - PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - set(MACOSX_BUNDLE_ICON_FILE kicad.icns) - set(MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.kicad) - set(MACOSX_BUNDLE_NAME kicad) -endif(APPLE) +if( APPLE ) + set( KICAD_RESOURCES kicad.icns kicad_doc.icns ) + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/kicad.icns" PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/kicad_doc.icns" PROPERTIES + MACOSX_PACKAGE_LOCATION Resources + ) + set( MACOSX_BUNDLE_ICON_FILE kicad.icns ) + set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-eda.kicad ) + set( MACOSX_BUNDLE_NAME kicad ) +endif() -add_executable(kicad WIN32 MACOSX_BUNDLE +add_executable( kicad WIN32 MACOSX_BUNDLE ${KICAD_SRCS} ${KICAD_EXTRA_SRCS} ${KICAD_RESOURCES} ) -if(APPLE) - set_target_properties(kicad PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) - target_link_libraries(kicad +if( UNIX ) + # for build directory: create kiface symlinks so kicad (exe) can be run in-situ + add_custom_target( kiface_sym_links + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/eeschema/_eeschema.kiface" "${CMAKE_BINARY_DIR}/kicad/_eeschema.kiface" + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.kiface" "${CMAKE_BINARY_DIR}/kicad/_pcbnew.kiface" + COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/cvpcb/_cvpcb.kiface" "${CMAKE_BINARY_DIR}/kicad/_cvpcb.kiface" + COMMENT "Making /kicad/" + ) +endif() + + +if( APPLE ) + set_target_properties( kicad PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist + ) + target_link_libraries( kicad common bitmaps polygon ${wxWidgets_LIBRARIES} ) -else(APPLE) - target_link_libraries(kicad +else() + target_link_libraries( kicad common bitmaps polygon ${wxWidgets_LIBRARIES} ${GDI_PLUS_LIBRARIES} ) -endif(APPLE) +endif() + +install( TARGETS kicad + DESTINATION ${KICAD_BIN} + COMPONENT binary + ) -install(TARGETS kicad - DESTINATION ${KICAD_BIN} - COMPONENT binary) diff --git a/kicad/commandframe.cpp b/kicad/commandframe.cpp index ca53048b0c..1dc1b03d6b 100644 --- a/kicad/commandframe.cpp +++ b/kicad/commandframe.cpp @@ -59,7 +59,7 @@ int LAUNCHER_PANEL::GetPanelHeight() const * Function CreateCommandToolbar * create the buttons to call Eeschema CvPcb, Pcbnew and GerbView */ -void LAUNCHER_PANEL::CreateCommandToolbar( void ) +void LAUNCHER_PANEL::CreateCommandToolbar() { wxBitmapButton* btn; diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index 742121c781..44e9488e56 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -28,8 +28,9 @@ */ +#include #include - +#include #include #include #include @@ -40,6 +41,40 @@ #include + +/// Extend LIB_ENV_VAR list with the directory from which I came, prepending it. +static void set_lib_env_var( const wxString& aAbsoluteArgv0 ) +{ + // POLICY CHOICE 2: Keep same path, so that installer MAY put the + // "subsidiary DSOs" in the same directory as the kiway top process modules. + // A subsidiary shared library is one that is not a top level DSO, but rather + // some shared library that a top level DSO needs to even be loaded. It is + // a static link to a shared object from a top level DSO. + + // This directory POLICY CHOICE 2 is not the only dir in play, since LIB_ENV_VAR + // has numerous path options in it, as does DSO searching on linux, windows, and OSX. + // See "man ldconfig" on linux. What's being done here is for quick installs + // into a non-standard place, and especially for Windows users who may not + // know what the PATH environment variable is or how to set it. + + wxFileName fn( aAbsoluteArgv0 ); + + wxString ld_path( LIB_ENV_VAR ); + wxString my_path = fn.GetPath(); + wxString new_paths = PrePendPath( ld_path, my_path ); + + wxSetEnv( ld_path, new_paths ); + +#if defined(DEBUG) + { + wxString test; + wxGetEnv( ld_path, &test ); + printf( "LIB_ENV_VAR:'%s'\n", TO_UTF8( test ) ); + } +#endif +} + + // a dummy to quiet linking with EDA_BASE_FRAME::config(); #include KIFACE_I& Kiface() @@ -62,7 +97,6 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) m_bm.Init(); -#if 0 // copied from single_top.c, possibly for milestone B) wxString absoluteArgv0 = wxStandardPaths::Get().GetExecutablePath(); if( !wxIsAbsolutePath( absoluteArgv0 ) ) @@ -71,14 +105,34 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) return false; } - // Set LIB_ENV_VAR *before* loading the DSO, in case the top-level DSO holding the - // KIFACE has hard dependencies on subsidiary DSOs below it. - SetLibEnvVar( absoluteArgv0 ); -#endif + // Set LIB_ENV_VAR *before* loading the KIFACE DSOs, in case they have hard + // dependencies on subsidiary DSOs below it. + set_lib_env_var( absoluteArgv0 ); if( !initPgm() ) return false; + // Add search paths to feed the PGM_KICAD::SysSearch() function, + // currenly limited in support to only look for project templates + { + SEARCH_STACK bases; + + SystemDirsAppend( &bases ); + + // DBG( bases.Show( (std::string(__func__) + " bases").c_str() );) + + for( unsigned i = 0; i < bases.GetCount(); ++i ) + { + wxFileName fn( bases[i], wxEmptyString ); + + // Add KiCad template file path to search path list. + fn.AppendDir( wxT( "template" ) ); + m_bm.m_search.AddPaths( fn.GetPath() ); + } + + //DBG( m_bm.m_search.Show( (std::string( __func__ ) + " SysSearch()").c_str() );) + } + // Read current setup and reopen last directory if no filename to open on // command line. if( App().argc == 1 ) @@ -95,6 +149,8 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) wxDefaultPosition, wxDefaultSize ); App().SetTopWindow( frame ); + Kiway.SetTop( frame ); + bool prjloaded = false; // true when the project is loaded if( App().argc > 1 ) @@ -197,39 +253,7 @@ void PGM_KICAD::destroy() } -/** - * Class KIWAY_MGR - * is a container for all KIWAYS [and PROJECTS]. This class needs to work both - * for a C++ project manager and an a wxPython one (after being moved into a - * header later). - */ -class KIWAY_MGR -{ -public: - //KIWAY_MGR(); - // ~KIWAY_MGR(); - - bool OnStart( wxApp* aProcess ); - - void OnEnd(); - - KIWAY& operator[]( int aIndex ) - { - wxASSERT( m_kiways.size() ); // stuffed in OnStart() - return m_kiways[aIndex]; - } - -private: - - // KIWAYs may not be moved once doled out, since window DNA depends on the - // pointer being good forever. - // boost_ptr::vector however never moves the object pointed to. - typedef boost::ptr_vector KIWAYS; - - KIWAYS m_kiways; -}; - -static KIWAY_MGR kiways; +KIWAY Kiway( &Pgm() ); /** @@ -240,7 +264,7 @@ struct APP_KICAD : public wxApp { bool OnInit() // overload wxApp virtual { - if( kiways.OnStart( this ) ) + // if( Kiways.OnStart( this ) ) { return Pgm().OnPgmInit( this ); } @@ -249,13 +273,37 @@ struct APP_KICAD : public wxApp int OnExit() // overload wxApp virtual { - kiways.OnEnd(); + // Kiways.OnEnd(); Pgm().OnPgmExit(); return wxApp::OnExit(); } + int OnRun() // overload wxApp virtual + { + try + { + return wxApp::OnRun(); + } + catch( const std::exception& e ) + { + wxLogError( wxT( "Unhandled exception class: %s what: %s" ), + GetChars( FROM_UTF8( typeid(e).name() )), + GetChars( FROM_UTF8( e.what() ) ) );; + } + catch( const IO_ERROR& ioe ) + { + wxLogError( GetChars( ioe.errorText ) ); + } + catch(...) + { + wxLogError( wxT( "Unhandled exception of unknown type" ) ); + } + + return -1; + } + /** * Function MacOpenFile * is specific to MacOSX (not used under Linux or Windows). @@ -275,10 +323,12 @@ IMPLEMENT_APP( APP_KICAD ); // this link image need this function. PROJECT& Prj() { - return kiways[0].Prj(); + return Kiway.Prj(); } +#if 0 // there can be only one in C++ project manager. + bool KIWAY_MGR::OnStart( wxApp* aProcess ) { // The C++ project manager supports only one open PROJECT @@ -292,3 +342,5 @@ bool KIWAY_MGR::OnStart( wxApp* aProcess ) void KIWAY_MGR::OnEnd() { } + +#endif diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index e74c471dc1..32d19c8d37 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -30,6 +30,8 @@ #include #include +#include +#include #include #include #include @@ -39,13 +41,14 @@ #include #include +#define USE_KIFACE 1 -#define TreeFrameWidthEntry wxT( "LeftWinWidth" ) +#define TreeFrameWidthEntry wxT( "LeftWinWidth" ) KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title, const wxPoint& pos, const wxSize& size ) : - EDA_BASE_FRAME( parent, KICAD_MAIN_FRAME_TYPE, title, pos, size, + EDA_BASE_FRAME( parent, KICAD_MAIN_FRAME_T, title, pos, size, KICAD_DEFAULT_DRAWFRAME_STYLE, wxT( "KicadFrame" ) ) { m_leftWinWidth = 60; @@ -152,26 +155,29 @@ void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event ) void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { - int px, py; - - UpdateFileHistory( m_ProjectFileName.GetFullPath(), &Pgm().GetFileHistory() ); - - if( !IsIconized() ) // save main frame position and size + if( Kiway.PlayersClose( false ) ) { - GetPosition( &px, &py ); - m_FramePos.x = px; - m_FramePos.y = py; + int px, py; - GetSize( &px, &py ); - m_FrameSize.x = px; - m_FrameSize.y = py; + UpdateFileHistory( m_ProjectFileName.GetFullPath(), &Pgm().GetFileHistory() ); + + if( !IsIconized() ) // save main frame position and size + { + GetPosition( &px, &py ); + m_FramePos.x = px; + m_FramePos.y = py; + + GetSize( &px, &py ); + m_FrameSize.x = px; + m_FrameSize.y = py; + } + + Event.SetCanVeto( true ); + + m_LeftWin->Show( false ); + + Destroy(); } - - Event.SetCanVeto( true ); - - m_LeftWin->Show( false ); - - Destroy(); } @@ -238,10 +244,21 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event ) legacy_board.SetExt( LegacyPcbFileExtension ); kicad_board.SetExt( KiCadPcbFileExtension ); - if( !legacy_board.FileExists() || kicad_board.FileExists() ) - Execute( this, PCBNEW_EXE, QuoteFullPath( kicad_board ) ); - else - Execute( this, PCBNEW_EXE, QuoteFullPath( legacy_board ) ); + wxFileName& board = ( !legacy_board.FileExists() || kicad_board.FileExists() ) ? + kicad_board : legacy_board; + +#if USE_KIFACE + KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_PCB, true ); + frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); + frame->Show( true ); + } + frame->Raise(); +#else + Execute( this, PCBNEW_EXE, QuoteFullPath( board ) ); +#endif } @@ -250,25 +267,57 @@ void KICAD_MANAGER_FRAME::OnRunCvpcb( wxCommandEvent& event ) wxFileName fn( m_ProjectFileName ); fn.SetExt( NetlistFileExtension ); + +#if USE_KIFACE + KIWAY_PLAYER* frame = Kiway.Player( FRAME_CVPCB, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_CVPCB, true ); + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + } + frame->Raise(); +#else Execute( this, CVPCB_EXE, QuoteFullPath( fn ) ); +#endif } + void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event ) { wxFileName fn( m_ProjectFileName ); fn.SetExt( SchematicFileExtension ); - Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) ); +#if USE_KIFACE + KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_SCH, true ); + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + } + frame->Raise(); +#else + Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) ); +#endif } void KICAD_MANAGER_FRAME::OnRunGerbview( wxCommandEvent& event ) { wxFileName fn( m_ProjectFileName ); + wxString path = wxT( "\"" ); + path += fn.GetPath( wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME ) + wxT( "\"" ); +#if USE_KIFACE && 0 + + // I cannot make sense of the fn. + +#else Execute( this, GERBVIEW_EXE, path ); +#endif } @@ -338,10 +387,11 @@ void KICAD_MANAGER_FRAME::SaveSettings( wxConfigBase* aCfg ) */ void KICAD_MANAGER_FRAME::PrintPrjInfo() { - wxString msg; - msg.Printf( _( "Working dir: %s\nProject: %s\n" ), - GetChars( wxGetCwd() ), - GetChars( m_ProjectFileName.GetFullPath() ) ); + wxString msg = wxString::Format( _( + "Working dir: %s\nProject: %s\n" ), + GetChars( wxGetCwd() ), + GetChars( m_ProjectFileName.GetFullPath() ) + ); PrintMsg( msg ); } diff --git a/pagelayout_editor/CMakeLists.txt b/pagelayout_editor/CMakeLists.txt index 308bd94949..cd6e41acdd 100644 --- a/pagelayout_editor/CMakeLists.txt +++ b/pagelayout_editor/CMakeLists.txt @@ -62,7 +62,7 @@ if( USE_KIWAY_DLLS ) ${PL_EDITOR_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=PL_EDITOR_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_wks\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PL_EDITOR;PGM_DATA_FILE_EXT=\"kicad_wks\";BUILD_KIWAY_DLL" ) target_link_libraries( pl_editor #singletop # replaces common, giving us restrictive control and link warnings. diff --git a/pagelayout_editor/pl_editor.cpp b/pagelayout_editor/pl_editor.cpp index b96b07d4aa..f15d34e8ab 100644 --- a/pagelayout_editor/pl_editor.cpp +++ b/pagelayout_editor/pl_editor.cpp @@ -54,7 +54,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -62,7 +62,7 @@ static struct IFACE : public KIFACE_I { switch( aClassId ) { - case PL_EDITOR_FRAME_TYPE: + case FRAME_PL_EDITOR: { PL_EDITOR_FRAME* frame = new PL_EDITOR_FRAME( aKiway, aParent ); @@ -126,9 +126,9 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - start_common(); + start_common( aCtlBits ); // Must be called before creating the main frame in order to // display the real hotkeys in menus or tool tips diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index d5defe8d16..dd1162b9f3 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -54,7 +54,7 @@ #define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" ) PL_EDITOR_FRAME::PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) : - EDA_DRAW_FRAME( aKiway, aParent, PL_EDITOR_FRAME_TYPE, wxT( "PlEditorFrame" ), + EDA_DRAW_FRAME( aKiway, aParent, FRAME_PL_EDITOR, wxT( "PlEditorFrame" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PL_EDITOR_FRAME_NAME ) { m_FrameName = PL_EDITOR_FRAME_NAME; diff --git a/pcb_calculator/pcb_calculator.cpp b/pcb_calculator/pcb_calculator.cpp index cfec7e2135..31f27c7a61 100644 --- a/pcb_calculator/pcb_calculator.cpp +++ b/pcb_calculator/pcb_calculator.cpp @@ -55,7 +55,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -117,9 +117,9 @@ PGM_BASE& Pgm() } -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { - start_common(); + start_common( aCtlBits ); return true; } diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 976ee30a9a..3e7e89fafa 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -517,7 +517,7 @@ if( USE_KIWAY_DLLS ) ${PCBNEW_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp pcbnew.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PCB;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL" ) target_link_libraries( pcbnew #singletop # replaces common, giving us restrictive control and link warnings. @@ -619,7 +619,7 @@ else() # milestone A) kills this off: ${PCBNEW_RESOURCES} ) set_source_files_properties( ../common/single_top.cpp PROPERTIES - COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\"" + COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PCB;PGM_DATA_FILE_EXT=\"kicad_pcb\"" ) target_link_libraries( pcbnew 3d-viewer diff --git a/pcbnew/autorouter/auto_place_footprints.cpp b/pcbnew/autorouter/auto_place_footprints.cpp index 0351c43bd1..a49ccd1b2c 100644 --- a/pcbnew/autorouter/auto_place_footprints.cpp +++ b/pcbnew/autorouter/auto_place_footprints.cpp @@ -516,12 +516,7 @@ int genPlacementRoutingMatrix( BOARD* aBrd, EDA_MSG_PANEL* messagePanel ) if( DrawSegm->GetLayer() != EDGE_N ) break; - TmpSegm.SetStart( DrawSegm->GetStart() ); - TmpSegm.SetEnd( DrawSegm->GetEnd() ); - TmpSegm.SetShape( DrawSegm->GetShape() ); - TmpSegm.m_Param = DrawSegm->GetAngle(); - - TraceSegmentPcb( &TmpSegm, HOLE | CELL_is_EDGE, + TraceSegmentPcb( DrawSegm, HOLE | CELL_is_EDGE, RoutingMatrix.m_GridRouting, WRITE_CELL ); break; diff --git a/pcbnew/autorouter/autorout.h b/pcbnew/autorouter/autorout.h index 98f5ac0b3a..b284b63ab8 100644 --- a/pcbnew/autorouter/autorout.h +++ b/pcbnew/autorouter/autorout.h @@ -38,6 +38,7 @@ class BOARD; +class DRAWSEGMENT; #define TOP 0 @@ -195,6 +196,7 @@ void PlacePad( D_PAD* pt_pad, int type, int marge, int op_logic ); /* Draws a segment of track on the board. */ void TraceSegmentPcb( TRACK* pt_segm, int type, int marge, int op_logic ); +void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int type, int marge, int op_logic ); /* Uses the color value of all cells included in the board * coord of the rectangle ux0, uy0 (top right corner) diff --git a/pcbnew/autorouter/graphpcb.cpp b/pcbnew/autorouter/graphpcb.cpp index 28dff7ff32..54b94a01f7 100644 --- a/pcbnew/autorouter/graphpcb.cpp +++ b/pcbnew/autorouter/graphpcb.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -256,29 +257,52 @@ void TraceFilledCircle( int cx, int cy, int radius, } } - -void TraceSegmentPcb( TRACK* pt_segm, int color, int marge, int op_logic ) +void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int color, int marge, int op_logic ) { - int half_width; - int ux0, uy0, ux1, uy1; - - half_width = ( pt_segm->GetWidth() / 2 ) + marge; + int half_width = ( pt_segm->GetWidth() / 2 ) + marge; // Calculate the bounding rectangle of the segment (if H, V or Via) - ux0 = pt_segm->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x; - uy0 = pt_segm->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y; - ux1 = pt_segm->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x; - uy1 = pt_segm->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y; + int ux0 = pt_segm->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy0 = pt_segm->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y; + int ux1 = pt_segm->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy1 = pt_segm->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y; - // Test if VIA (filled circle was drawn) - if( pt_segm->Type() == PCB_VIA_T ) + LAYER_NUM layer = pt_segm->GetLayer(); + + if( color == VIA_IMPOSSIBLE ) + layer = UNDEFINED_LAYER; + + switch( pt_segm->GetShape() ) + { + // The segment is here a straight line or a circle or an arc.: + case S_CIRCLE: + TraceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); + break; + + case S_ARC: + TraceArc( ux0, uy0, ux1, uy1, pt_segm->GetAngle(), half_width, layer, color, op_logic ); + break; + + // The segment is here a line segment. + default: + DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); + break; + } +} + +void TraceSegmentPcb( TRACK* aTrack, int color, int marge, int op_logic ) +{ + int half_width = ( aTrack->GetWidth() / 2 ) + marge; + + // Test if VIA (filled circle need to be drawn) + if( aTrack->Type() == PCB_VIA_T ) { LAYER_MSK layer_mask = NO_LAYERS; - if( pt_segm->IsOnLayer( g_Route_Layer_BOTTOM ) ) + if( aTrack->IsOnLayer( g_Route_Layer_BOTTOM ) ) layer_mask = GetLayerMask( g_Route_Layer_BOTTOM ); - if( pt_segm->IsOnLayer( g_Route_Layer_TOP ) ) + if( aTrack->IsOnLayer( g_Route_Layer_TOP ) ) { if( layer_mask == 0 ) layer_mask = GetLayerMask( g_Route_Layer_TOP ); @@ -290,39 +314,25 @@ void TraceSegmentPcb( TRACK* pt_segm, int color, int marge, int op_logic ) layer_mask = FULL_LAYERS; if( layer_mask ) - TraceFilledCircle( pt_segm->GetStart().x, pt_segm->GetStart().y, + TraceFilledCircle( aTrack->GetStart().x, aTrack->GetStart().y, half_width, layer_mask, color, op_logic ); - return; } - - LAYER_NUM layer = pt_segm->GetLayer(); - - if( color == VIA_IMPOSSIBLE ) - layer = UNDEFINED_LAYER; - - // The segment is here a straight line or a circle or an arc.: - if( pt_segm->GetShape() == S_CIRCLE ) + else { - TraceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); - return; - } + // Calculate the bounding rectangle of the segment + int ux0 = aTrack->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy0 = aTrack->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y; + int ux1 = aTrack->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x; + int uy1 = aTrack->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y; - if( pt_segm->GetShape() == S_ARC ) - { - TraceArc( ux0, uy0, ux1, uy1, pt_segm->m_Param, half_width, layer, color, op_logic ); - return; - } + // Ordinary track + LAYER_NUM layer = aTrack->GetLayer(); + + if( color == VIA_IMPOSSIBLE ) + layer = UNDEFINED_LAYER; - // The segment is here a line segment. - if( ( ux0 != ux1 ) && ( uy0 != uy1 ) ) // Segment tilts. - { DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); - return; } - - // The segment is horizontal or vertical. - // F4EXB 051018-01 - DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic ); } diff --git a/pcbnew/autorouter/routing_matrix.cpp b/pcbnew/autorouter/routing_matrix.cpp index b5d02e926a..8449c90bc1 100644 --- a/pcbnew/autorouter/routing_matrix.cpp +++ b/pcbnew/autorouter/routing_matrix.cpp @@ -225,7 +225,6 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) // Place outlines of modules on matrix routing, if they are on a copper layer // or on the edge layer - TRACK tmpSegm( NULL ); // A dummy track used to create segments. for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { @@ -236,21 +235,13 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) case PCB_MODULE_EDGE_T: { EDGE_MODULE* edge = (EDGE_MODULE*) item; + EDGE_MODULE tmpEdge( *edge ); - tmpSegm.SetLayer( edge->GetLayer() ); + if( tmpEdge.GetLayer() == EDGE_N ) + tmpEdge.SetLayer( UNDEFINED_LAYER ); - if( tmpSegm.GetLayer() == EDGE_N ) - tmpSegm.SetLayer( UNDEFINED_LAYER ); - - tmpSegm.SetStart( edge->GetStart() ); - tmpSegm.SetEnd( edge->GetEnd() ); - tmpSegm.SetShape( edge->GetShape() ); - tmpSegm.SetWidth( edge->GetWidth() ); - tmpSegm.m_Param = edge->GetAngle(); - tmpSegm.SetNetCode( -1 ); - - TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL ); - TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); + TraceSegmentPcb( &tmpEdge, HOLE, marge, WRITE_CELL ); + TraceSegmentPcb( &tmpEdge, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); } break; @@ -271,7 +262,7 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) int type_cell = HOLE; DrawSegm = (DRAWSEGMENT*) item; - tmpSegm.SetLayer( DrawSegm->GetLayer() ); + DRAWSEGMENT tmpSegm( DrawSegm ); if( DrawSegm->GetLayer() == EDGE_N ) { @@ -279,13 +270,6 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) type_cell |= CELL_is_EDGE; } - tmpSegm.SetStart( DrawSegm->GetStart() ); - tmpSegm.SetEnd( DrawSegm->GetEnd() ); - tmpSegm.SetShape( DrawSegm->GetShape() ); - tmpSegm.SetWidth( DrawSegm->GetWidth() ); - tmpSegm.m_Param = DrawSegm->GetAngle(); - tmpSegm.SetNetCode( -1 ); - TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL ); } break; diff --git a/pcbnew/autorouter/solve.cpp b/pcbnew/autorouter/solve.cpp index 86e937073a..8ddf52f040 100644 --- a/pcbnew/autorouter/solve.cpp +++ b/pcbnew/autorouter/solve.cpp @@ -1159,14 +1159,11 @@ static int Retrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC, static void OrCell_Trace( BOARD* pcb, int col, int row, int side, int orient, int current_net_code ) { - int dx0, dy0, dx1, dy1; - TRACK* newTrack; - if( orient == HOLE ) // placement of a via { - newTrack = new SEGVIA( pcb ); + VIA *newVia = new VIA( pcb ); - g_CurrentTrackList.PushBack( newTrack ); + g_CurrentTrackList.PushBack( newVia ); g_CurrentTrackSegment->SetState( TRACK_AR, true ); g_CurrentTrackSegment->SetLayer( 0x0F ); @@ -1178,13 +1175,15 @@ static void OrCell_Trace( BOARD* pcb, int col, int row, g_CurrentTrackSegment->SetEnd( g_CurrentTrackSegment->GetStart() ); g_CurrentTrackSegment->SetWidth( pcb->GetCurrentViaSize() ); - g_CurrentTrackSegment->SetShape( pcb->GetDesignSettings().m_CurrentViaType ); + newVia->SetViaType( pcb->GetDesignSettings().m_CurrentViaType ); g_CurrentTrackSegment->SetNetCode( current_net_code ); } else // placement of a standard segment { - newTrack = new TRACK( pcb ); + TRACK *newTrack = new TRACK( pcb ); + int dx0, dy0, dx1, dy1; + g_CurrentTrackList.PushBack( newTrack ); @@ -1301,12 +1300,14 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) g_CurrentTrackList.PushBack( newTrack ); } - g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, FLG_START ); + g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, + ENDPOINT_START ); if( g_FirstTrackSegment->start ) g_FirstTrackSegment->SetState( BEGIN_ONPAD, true ); - g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, FLG_END ); + g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, + ENDPOINT_END ); if( g_CurrentTrackSegment->end ) g_CurrentTrackSegment->SetState( END_ONPAD, true ); diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 3abbba0aff..22b847ad30 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -130,7 +130,7 @@ BEGIN_EVENT_TABLE( PCB_BASE_FRAME, EDA_DRAW_FRAME ) END_EVENT_TABLE() -PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType, +PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString & aFrameName ) : EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ), diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 22878bfcfc..db51056d02 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -233,31 +233,38 @@ void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) int atmp = track->GetWidth(); track->SetWidth( image->GetWidth() ); image->SetWidth( atmp ); - atmp = track->GetShape(); - track->SetShape( image->GetShape() ); - image->SetShape( atmp ); - atmp = track->GetDrillValue(); + if( Type() == PCB_VIA_T ) + { + VIA *via = static_cast( this ); + VIA *viaimage = static_cast( aImage ); - if( track->IsDrillDefault() ) - atmp = -1; + VIATYPE_T viatmp = via->GetViaType(); + via->SetViaType( viaimage->GetViaType() ); + viaimage->SetViaType( viatmp ); - int itmp = image->GetDrillValue(); + int drilltmp = via->GetDrillValue(); - if( image->IsDrillDefault() ) - itmp = -1; + if( via->IsDrillDefault() ) + drilltmp = -1; - EXCHG(itmp, atmp ); + int itmp = viaimage->GetDrillValue(); - if( atmp > 0 ) - track->SetDrill( atmp ); - else - track->SetDrillDefault(); + if( viaimage->IsDrillDefault() ) + itmp = -1; - if( itmp > 0 ) - image->SetDrill( itmp ); - else - image->SetDrillDefault(); + EXCHG(itmp, drilltmp ); + + if( drilltmp > 0 ) + via->SetDrill( drilltmp ); + else + via->SetDrillDefault(); + + if( itmp > 0 ) + viaimage->SetDrill( itmp ); + else + viaimage->SetDrillDefault(); + } } break; diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 20860474eb..a7b4e35987 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -242,7 +242,7 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, LAYER_MSK aLayerMask, TRACK_ segment = m_Track; candidate = NULL; NbSegm = 0; - while( ( segment = ::GetTrace( segment, NULL, aPosition, aLayerMask ) ) != NULL ) + while( ( segment = ::GetTrack( segment, NULL, aPosition, aLayerMask ) ) != NULL ) { if( segment->GetState( BUSY ) ) // already found and selected: skip it { @@ -1172,7 +1172,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData, #if 0 // both these are on same list, so we must scan it twice in order // to get VIA priority, using new #else code below. - // But we are not using separate lists for TRACKs and SEGVIAs, because + // But we are not using separate lists for TRACKs and VIA, because // items are ordered (sorted) in the linked // list by netcode AND by physical distance: // when created, if a track or via is connected to an existing track or @@ -1561,29 +1561,17 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) } -TRACK* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) +VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) const { - TRACK* track; - - for( track = m_Track; track; track = track->Next() ) + for( VIA *via = GetFirstVia( m_Track); via; via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - if( track->GetStart() != aPosition ) - continue; - - if( track->GetState( BUSY | IS_DELETED ) ) - continue; - - if( aLayer == UNDEFINED_LAYER ) - break; - - if( track->IsOnLayer( aLayer ) ) - break; + if( (via->GetStart() == aPosition) && + (via->GetState( BUSY | IS_DELETED ) == 0) && + ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) ) + return via; } - return track; + return NULL; } @@ -1603,22 +1591,13 @@ D_PAD* BOARD::GetPad( const wxPoint& aPosition, LAYER_MSK aLayerMask ) } -D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint ) +D_PAD* BOARD::GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint ) { D_PAD* pad = NULL; - wxPoint aPosition; + const wxPoint &aPosition = aTrace->GetEndPoint( aEndPoint ); LAYER_MSK aLayerMask = GetLayerMask( aTrace->GetLayer() ); - if( aEndPoint == FLG_START ) - { - aPosition = aTrace->GetStart(); - } - else - { - aPosition = aTrace->GetEnd(); - } - for( MODULE* module = m_Modules; module; module = module->Next() ) { pad = module->GetPad( aPosition, aLayerMask ); @@ -1777,9 +1756,10 @@ void BOARD::GetSortedPadListByXthenYCoord( std::vector& aVector, int aNe } -TRACK* BOARD::GetTrace( TRACK* aTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) +TRACK* BOARD::GetTrack( TRACK* aTrace, const wxPoint& aPosition, + LAYER_MSK aLayerMask ) const { - for( TRACK* track = aTrace; track; track = track->Next() ) + for( TRACK* track = aTrace; track; track = track->Next() ) { LAYER_NUM layer = track->GetLayer(); @@ -1846,16 +1826,16 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount, if( aTrace->Type() == PCB_VIA_T ) { TRACK* Segm1, * Segm2 = NULL, * Segm3 = NULL; - Segm1 = ::GetTrace( m_Track, NULL, aTrace->GetStart(), layerMask ); + Segm1 = ::GetTrack( m_Track, NULL, aTrace->GetStart(), layerMask ); if( Segm1 ) { - Segm2 = ::GetTrace( Segm1->Next(), NULL, aTrace->GetStart(), layerMask ); + Segm2 = ::GetTrack( Segm1->Next(), NULL, aTrace->GetStart(), layerMask ); } if( Segm2 ) { - Segm3 = ::GetTrace( Segm2->Next(), NULL, aTrace->GetStart(), layerMask ); + Segm3 = ::GetTrack( Segm2->Next(), NULL, aTrace->GetStart(), layerMask ); } if( Segm3 ) // More than 2 segments are connected to this via. the track" is only this via @@ -1903,7 +1883,7 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount, layerMask = via->GetLayerMask(); - TRACK* track = ::GetTrace( m_Track, NULL, via->GetStart(), layerMask ); + TRACK* track = ::GetTrack( m_Track, NULL, via->GetStart(), layerMask ); // GetTrace does not consider tracks flagged BUSY. // So if no connected track found, this via is on the current track @@ -1925,7 +1905,7 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount, */ LAYER_NUM layer = track->GetLayer(); - while( ( track = ::GetTrace( track->Next(), NULL, via->GetStart(), layerMask ) ) != NULL ) + while( ( track = ::GetTrack( track->Next(), NULL, via->GetStart(), layerMask ) ) != NULL ) { if( layer != track->GetLayer() ) { @@ -2127,10 +2107,10 @@ BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, LAYER_MSK a } /* No pad has been located so check for a segment of the trace. */ - TRACK* segment = ::GetTrace( m_Track, NULL, aPosition, aLayerMask ); + TRACK* segment = ::GetTrack( m_Track, NULL, aPosition, aLayerMask ); if( segment == NULL ) - segment = GetTrace( m_Track, aPosition, aLayerMask ); + segment = GetTrack( m_Track, aPosition, aLayerMask ); return segment; } @@ -2199,7 +2179,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS aSegment->end = newTrack; aSegment->SetState( END_ONPAD, false ); - D_PAD * pad = GetPad( newTrack, FLG_START ); + D_PAD * pad = GetPad( newTrack, ENDPOINT_START ); if ( pad ) { diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 6131859bb3..308f69a13d 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -284,7 +284,7 @@ public: DLIST m_Drawings; // linked list of lines & texts DLIST m_Modules; // linked list of MODULEs - DLIST m_Track; // linked list of TRACKs and SEGVIAs + DLIST m_Track; // linked list of TRACKs and VIAs DLIST m_Zone; // linked list of SEGZONEs /// Ratsnest list for the BOARD @@ -1368,9 +1368,9 @@ public: *

* @param aPosition The wxPoint to HitTest() against. * @param aLayer The layer to search. Use -1 for a don't care. - * @return TRACK* A point a to the SEGVIA object if found, else NULL. + * @return VIA* A point a to the VIA object if found, else NULL. */ - TRACK* GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ); + VIA* GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ) const; /** * Function GetPad @@ -1390,7 +1390,7 @@ public: * @param aEndPoint The end point of \a aTrace the hit test against. * @return A pointer to a D_PAD object if found or NULL if not found. */ - D_PAD* GetPad( TRACK* aTrace, int aEndPoint ); + D_PAD* GetPad( TRACK* aTrace, ENDPOINT_T aEndPoint ); /** * Function GetPadFast @@ -1436,7 +1436,7 @@ public: void GetSortedPadListByXthenYCoord( std::vector& aVector, int aNetCode = -1 ); /** - * Function GetTrace + * Function GetTrack * find the segment of \a aTrace at \a aPosition on \a aLayer if \a Layer is visible. * Traces that are flagged as deleted or busy are ignored. * @@ -1446,7 +1446,7 @@ public: * layer mask. * @return A TRACK object pointer if found otherwise NULL. */ - TRACK* GetTrace( TRACK* aTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); + TRACK* GetTrack( TRACK* aTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) const; /** * Function MarkTrace diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 56862aa7db..2821409406 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -69,9 +69,6 @@ public: /// skip the linked list stuff, and parent const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs ); - DRAWSEGMENT* Next() const { return (DRAWSEGMENT*) Pnext; } - DRAWSEGMENT* Back() const { return (DRAWSEGMENT*) Pback; } - void SetWidth( int aWidth ) { m_Width = aWidth; } int GetWidth() const { return m_Width; } diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 8c6559ad74..18790d9b9b 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -51,9 +51,6 @@ public: ~EDGE_MODULE(); - EDGE_MODULE* Next() const { return (EDGE_MODULE*) Pnext; } - EDGE_MODULE* Back() const { return (EDGE_MODULE*) Pback; } - /// skip the linked list stuff, and parent const EDGE_MODULE& operator = ( const EDGE_MODULE& rhs ); diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h index da42a07fb0..0a7186b6b1 100644 --- a/pcbnew/class_mire.h +++ b/pcbnew/class_mire.h @@ -56,9 +56,6 @@ public: ~PCB_TARGET(); - PCB_TARGET* Next() const { return (PCB_TARGET*) Pnext; } - PCB_TARGET* Back() const { return (PCB_TARGET*) Pnext; } - void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } // override const wxPoint& GetPosition() const { return m_Pos; } // override diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 237a24499d..ce4dc00441 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -422,9 +422,12 @@ EDA_RECT MODULE::GetFootprintRect() const area.SetEnd( m_Pos ); area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area - for( EDGE_MODULE* edge = (EDGE_MODULE*) m_Drawings.GetFirst(); edge; edge = edge->Next() ) - if( edge->Type() == PCB_MODULE_EDGE_T ) + for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() ) + { + const EDGE_MODULE *edge = dynamic_cast( item ); + if( edge ) area.Merge( edge->GetBoundingBox() ); + } for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) area.Merge( pad->GetBoundingBox() ); diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 3127d73fb1..189abfe6be 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -77,8 +77,8 @@ public: ~MODULE(); - MODULE* Next() const { return (MODULE*) Pnext; } - MODULE* Back() const { return (MODULE*) Pback; } + MODULE* Next() const { return static_cast( Pnext ); } + MODULE* Back() const { return static_cast( Pback ); } void Copy( MODULE* Module ); // Copy structure diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 64e6e9f8b8..88e77df440 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -234,7 +234,7 @@ private: /** - * Class NETINFO + * Class NETINFO_LIST * is a container class for NETINFO_ITEM elements, which are the nets. That makes * this class a container for the nets. */ diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index f61705385f..447cf8a503 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -82,7 +82,6 @@ void NETINFO_ITEM::Draw( EDA_DRAW_PANEL* panel, void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { int count; - EDA_ITEM* Struct; wxString txt; MODULE* module; D_PAD* pad; @@ -113,20 +112,19 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), txt, DARKGREEN ) ); count = 0; - Struct = m_parent->GetBoard()->m_Track; - for( ; Struct != NULL; Struct = Struct->Next() ) + for( const TRACK *track = m_parent->GetBoard()->m_Track; track != NULL; track = track->Next() ) { - if( Struct->Type() == PCB_VIA_T ) + if( track->Type() == PCB_VIA_T ) { - if( ( (SEGVIA*) Struct )->GetNetCode() == GetNet() ) + if( track->GetNetCode() == GetNet() ) count++; } - if( Struct->Type() == PCB_TRACE_T ) + if( track->Type() == PCB_TRACE_T ) { - if( ( (TRACK*) Struct )->GetNetCode() == GetNet() ) - lengthnet += ( (TRACK*) Struct )->GetLength(); + if( track->GetNetCode() == GetNet() ) + lengthnet += track->GetLength(); } } diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index da3bd875d1..5f73ca0a98 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -1,8 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 11b49568c1..3cbdcbe82a 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -106,7 +106,7 @@ public: void Copy( D_PAD* source ); - D_PAD* Next() const { return (D_PAD*) Pnext; } + D_PAD* Next() const { return static_cast( Pnext ); } MODULE* GetParent() const { return (MODULE*) m_Parent; } diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index dfa489041a..78fcaf457c 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -499,10 +499,10 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) wxPoint tpos0 = shape_pos; // Position of the centre of text wxPoint tpos = tpos0; wxSize AreaSize; // size of text area, normalized to AreaSize.y < AreaSize.x - int shortname_len = GetShortNetname().Len(); + int shortname_len = 0; - if( !aDrawInfo.m_Display_netname ) - shortname_len = 0; + if( aDrawInfo.m_Display_netname ) + shortname_len = GetShortNetname().Len(); if( GetShape() == PAD_CIRCLE ) angle = 0; diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index 5917759cd0..e63fa058eb 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -100,10 +100,6 @@ public: void Flip( const wxPoint& aCentre ); - TEXTE_MODULE* Next() const { return (TEXTE_MODULE*) Pnext; } - - TEXTE_MODULE* Back() const { return (TEXTE_MODULE*) Pback; } - /// @deprecated it seems (but the type is used to 'protect' //reference and value from deletion, and for identification) void SetType( TEXT_TYPE aType ) { m_Type = aType; } diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 8346dabeb5..4ce09ff177 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -70,7 +70,7 @@ static bool ShowClearance( const TRACK* aTrack ) * return true if the dist between p1 and p2 < max_dist * Currently in test (currently ratsnest algos work only if p1 == p2) */ -inline bool IsNear( wxPoint& p1, wxPoint& p2, int max_dist ) +inline bool IsNear( const wxPoint& p1, const wxPoint& p2, int max_dist ) { #if 0 // Do not change it: does not work int dist; @@ -88,15 +88,10 @@ inline bool IsNear( wxPoint& p1, wxPoint& p2, int max_dist ) } -TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, const wxPoint& aPosition, - LAYER_MSK aLayerMask ) +TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace, + const wxPoint& aPosition, LAYER_MSK aLayerMask ) { - TRACK* PtSegm; - - if( aStartTrace == NULL ) - return NULL; - - for( PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() ) + for( TRACK *PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() ) { if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 ) { @@ -125,9 +120,7 @@ TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) : BOARD_CONNECTED_ITEM( aParent, idtype ) { m_Width = Millimeter2iu( 0.2 ); - m_Shape = S_SEGMENT; start = end = NULL; - SetDrillDefault(); m_Param = 0; } @@ -179,34 +172,41 @@ wxString SEGZONE::GetSelectMenuText() const } -SEGVIA::SEGVIA( BOARD_ITEM* aParent ) : +VIA::VIA( BOARD_ITEM* aParent ) : TRACK( aParent, PCB_VIA_T ) { - SetShape( VIA_THROUGH ); - m_Width = Millimeter2iu( 0.5 ); + SetViaType( VIA_THROUGH ); + m_BottomLayer = LAYER_N_BACK; + SetDrillDefault(); } -EDA_ITEM* SEGVIA::Clone() const +EDA_ITEM* VIA::Clone() const { - return new SEGVIA( *this ); + return new VIA( *this ); } -wxString SEGVIA::GetSelectMenuText() const +wxString VIA::GetSelectMenuText() const { wxString text; wxString format; BOARD* board = GetBoard(); - int shape = GetShape(); - - if( shape == VIA_BLIND_BURIED ) + switch( GetViaType() ) + { + case VIA_BLIND_BURIED: format = _( "Blind/Buried Via %s, net[%s] (%d) on layers %s/%s" ); - else if( shape == VIA_MICROVIA ) + break; + case VIA_MICROVIA: format = _( "Micro Via %s, Net [%s] (%d) on layers %s/%s" ); + break; // else say nothing about normal (through) vias - else format = _( "Via %s net [%s] (%d) on layers %s/%s" ); + default: + format = _( "Via %s net [%s] (%d) on layers %s/%s" ); + break; + } + if( board ) { @@ -224,7 +224,7 @@ wxString SEGVIA::GetSelectMenuText() const } else { - wxFAIL_MSG( wxT( "SEGVIA::GetSelectMenuText: BOARD is NULL" ) ); + wxFAIL_MSG( wxT( "VIA::GetSelectMenuText: BOARD is NULL" ) ); text.Printf( format.GetData(), GetChars( ShowWidth() ), wxT( "???" ), 0, wxT( "??" ), wxT( "??" ) ); @@ -242,18 +242,15 @@ int TRACK::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const } -int TRACK::GetDrillValue() const +int VIA::GetDrillValue() const { - if( Type() != PCB_VIA_T ) - return 0; - if( m_Drill > 0 ) // Use the specific value. return m_Drill; // Use the default value from the Netclass NETCLASS* netclass = GetNetClass(); - if( m_Shape == VIA_MICROVIA ) + if( GetViaType() == VIA_MICROVIA ) return netclass->GetuViaDrill(); return netclass->GetViaDrill(); @@ -368,9 +365,14 @@ void TRACK::Flip( const wxPoint& aCentre ) { m_Start.y = aCentre.y - (m_Start.y - aCentre.y); m_End.y = aCentre.y - (m_End.y - aCentre.y); + SetLayer( FlipLayer( GetLayer() ) ); +} - if( Type() != PCB_VIA_T ) - SetLayer( FlipLayer( GetLayer() ) ); + +void VIA::Flip( const wxPoint& aCentre ) +{ + m_Start.y = aCentre.y - (m_Start.y - aCentre.y); + m_End.y = aCentre.y - (m_End.y - aCentre.y); } @@ -391,7 +393,7 @@ SEARCH_RESULT TRACK::Visit( INSPECTOR* inspector, const void* testData, } -bool SEGVIA::IsOnLayer( LAYER_NUM layer_number ) const +bool VIA::IsOnLayer( LAYER_NUM layer_number ) const { LAYER_NUM bottom_layer, top_layer; @@ -403,66 +405,60 @@ bool SEGVIA::IsOnLayer( LAYER_NUM layer_number ) const return false; } +LAYER_MSK VIA::GetLayerMask() const +{ + if( GetViaType() == VIA_THROUGH ) + return ALL_CU_LAYERS; + + // VIA_BLIND_BURIED or VIA_MICRVIA: + + LAYER_NUM bottom_layer, top_layer; + + // LayerPair() knows how layers are stored + LayerPair( &top_layer, &bottom_layer ); + + LAYER_MSK layermask = NO_LAYERS; + + while( bottom_layer <= top_layer ) + { + layermask |= ::GetLayerMask( bottom_layer ); + ++bottom_layer; + } + + return layermask; +} LAYER_MSK TRACK::GetLayerMask() const { - if( Type() == PCB_VIA_T ) - { - int via_type = GetShape(); - - if( via_type == VIA_THROUGH ) - return ALL_CU_LAYERS; - - // VIA_BLIND_BURIED or VIA_MICRVIA: - - LAYER_NUM bottom_layer, top_layer; - - // LayerPair() knows how layers are stored - ( (SEGVIA*) this )->LayerPair( &top_layer, &bottom_layer ); - - LAYER_MSK layermask = NO_LAYERS; - - while( bottom_layer <= top_layer ) - { - layermask |= ::GetLayerMask( bottom_layer ); - ++bottom_layer; - } - - return layermask; - } - else - { - return ::GetLayerMask( m_Layer ); - } + return ::GetLayerMask( m_Layer ); } -void SEGVIA::SetLayerPair( LAYER_NUM top_layer, LAYER_NUM bottom_layer ) +void VIA::SetLayerPair( LAYER_NUM aTopLayer, LAYER_NUM aBottomLayer ) { - if( GetShape() == VIA_THROUGH ) + if( GetViaType() == VIA_THROUGH ) { - top_layer = LAYER_N_FRONT; - bottom_layer = LAYER_N_BACK; + aTopLayer = LAYER_N_FRONT; + aBottomLayer = LAYER_N_BACK; } - if( bottom_layer > top_layer ) - EXCHG( bottom_layer, top_layer ); + if( aBottomLayer > aTopLayer ) + EXCHG( aBottomLayer, aTopLayer ); - // XXX EVIL usage of LAYER - m_Layer = (top_layer & 15) + ( (bottom_layer & 15) << 4 ); + m_Layer = aTopLayer; + m_BottomLayer = aBottomLayer; } -void SEGVIA::LayerPair( LAYER_NUM* top_layer, LAYER_NUM* bottom_layer ) const +void VIA::LayerPair( LAYER_NUM* top_layer, LAYER_NUM* bottom_layer ) const { LAYER_NUM b_layer = LAYER_N_BACK; LAYER_NUM t_layer = LAYER_N_FRONT; - if( GetShape() != VIA_THROUGH ) + if( GetViaType() != VIA_THROUGH ) { - // XXX EVIL usage of LAYER - b_layer = (m_Layer >> 4) & 15; - t_layer = m_Layer & 15; + b_layer = m_BottomLayer; + t_layer = m_Layer; if( b_layer > t_layer ) EXCHG( b_layer, t_layer ); @@ -557,116 +553,13 @@ TRACK* TRACK::GetEndNetCode( int NetCode ) return NULL; } - -void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, - const wxPoint& aOffset ) +void TRACK::DrawShortNetname( EDA_DRAW_PANEL* panel, + wxDC* aDC, GR_DRAWMODE aDrawMode, EDA_COLOR_T aBgColor ) { - int l_trace; - int radius; - LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; - - if( Type() == PCB_ZONE_T && DisplayOpt.DisplayZonesMode != 0 ) - return; - - BOARD * brd = GetBoard( ); - EDA_COLOR_T color = brd->GetLayerColor(m_Layer); - - if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) - return; - -#ifdef USE_WX_OVERLAY - // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay - if( (m_Flags && IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) - return; -#endif - - if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) - { - if( !IsOnLayer( curr_layer ) ) - ColorTurnToDarkDarkGray( &color ); - } - - if( aDrawMode & GR_HIGHLIGHT ) - ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); - - ColorApplyHighlightFlag( &color ); - - SetAlpha( &color, 150 ); - - GRSetDrawMode( aDC, aDrawMode ); - - - l_trace = m_Width >> 1; - - if( m_Shape == S_CIRCLE ) - { - radius = KiROUND( GetLineLength( m_Start, m_End ) ); - - if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius, color ); - } - else - { - - if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) // Line mode if too small - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius, color ); - } - else if( ( !DisplayOpt.DisplayPcbTrackFill) || GetState( FORCE_SKETCH ) ) - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius - l_trace, color ); - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius + l_trace, color ); - } - else - { - GRCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, radius, m_Width, color ); - } - } - - return; - } - - if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) - { - GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); - return; - } - - if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) - { - GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); - } - else - { - GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, - m_Start.y + aOffset.y, - m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); - } - - if( panel->GetScreen()->m_IsPrinting ) - return; - - // Show clearance for tracks, not for zone segments - if( ShowClearance( this ) ) - { - GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, - m_Width + (GetClearance() * 2), color ); - } - - /* Display the short netname for tracks, not for zone segments. - * we must filter tracks, to avoid a lot of texts. + /* we must filter tracks, to avoid a lot of texts. * - only tracks with a length > 10 * thickness are eligible * and, of course, if we are not printing the board */ - if( Type() == PCB_ZONE_T ) - return; - if( DisplayOpt.DisplayNetNamesMode == 0 || DisplayOpt.DisplayNetNamesMode == 1 ) return; @@ -703,7 +596,7 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, // Calculate angle: if the track segment is vertical, angle = 90 degrees // If horizontal 0 degrees, otherwise compute it - double angle; // angle is in 0.1 degree + double angle; // angle is in 0.1 degree if( dy == 0 ) // Horizontal segment { @@ -723,6 +616,7 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, } } + LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; if( ( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE ) && ( !(!IsOnLayer( curr_layer )&& DisplayOpt.ContrastModeDisplay) ) ) { @@ -732,15 +626,136 @@ void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, tsize = (tsize * 7) / 10; // small reduction to give a better look EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL; DrawGraphicHaloText( clipbox, aDC, tpos, - color, BLACK, WHITE, net->GetShortNetname(), angle, - wxSize( tsize, tsize ), - GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, - tsize / 7, - false, false ); + aBgColor, BLACK, WHITE, net->GetShortNetname(), angle, + wxSize( tsize, tsize ), + GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, + tsize / 7, + false, false ); } } } +void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, + const wxPoint& aOffset ) +{ + BOARD * brd = GetBoard( ); + EDA_COLOR_T color = brd->GetLayerColor(m_Layer); + + if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) + return; + +#ifdef USE_WX_OVERLAY + // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay + if( (m_Flags && IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) + return; +#endif + + if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) + { + LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; + + if( !IsOnLayer( curr_layer ) ) + ColorTurnToDarkDarkGray( &color ); + } + + if( aDrawMode & GR_HIGHLIGHT ) + ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); + + ColorApplyHighlightFlag( &color ); + + SetAlpha( &color, 150 ); + + GRSetDrawMode( aDC, aDrawMode ); + + int l_trace = m_Width / 2; + + if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) + { + GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); + return; + } + + if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) + { + GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); + } + else + { + GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, + m_Start.y + aOffset.y, + m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); + } + + if( panel->GetScreen()->m_IsPrinting ) + return; + + // Show clearance for tracks, not for zone segments + if( ShowClearance( this ) ) + { + GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, + m_Width + (GetClearance() * 2), color ); + } + + DrawShortNetname( panel, aDC, aDrawMode, color ); +} + +void SEGZONE::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, + const wxPoint& aOffset ) +{ + if( DisplayOpt.DisplayZonesMode != 0 ) + return; + + BOARD * brd = GetBoard( ); + EDA_COLOR_T color = brd->GetLayerColor(m_Layer); + + if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) + return; + +#ifdef USE_WX_OVERLAY + // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay + if( (m_Flags && IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) + return; +#endif + + if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) + { + LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; + + if( !IsOnLayer( curr_layer ) ) + ColorTurnToDarkDarkGray( &color ); + } + + if( aDrawMode & GR_HIGHLIGHT ) + ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); + + ColorApplyHighlightFlag( &color ); + + SetAlpha( &color, 150 ); + + GRSetDrawMode( aDC, aDrawMode ); + + int l_trace = m_Width / 2; + + if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) + { + GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); + return; + } + + if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) + { + GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); + } + else + { + GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, + m_Start.y + aOffset.y, + m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); + } + + // No clearance or netnames for zones +} + void TRACK::ViewGetLayers( int aLayers[], int& aCount ) const { @@ -764,7 +779,7 @@ unsigned int TRACK::ViewGetLOD( int aLayer ) const } -void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, +void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset ) { int radius; @@ -780,9 +795,9 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, GRSetDrawMode( aDC, aDrawMode ); BOARD * brd = GetBoard( ); - EDA_COLOR_T color = brd->GetVisibleElementColor(VIAS_VISIBLE + m_Shape); + EDA_COLOR_T color = brd->GetVisibleElementColor(VIAS_VISIBLE + GetViaType()); - if( brd->IsElementVisible( PCB_VISIBLE(VIAS_VISIBLE + m_Shape) ) == false + if( brd->IsElementVisible( PCB_VISIBLE(VIAS_VISIBLE + GetViaType()) ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG ) return; @@ -879,7 +894,7 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, // for Micro Vias, draw a partial cross : X on component layer, or + on copper layer // (so we can see 2 superimposed microvias ): - if( GetShape() == VIA_MICROVIA ) + if( GetViaType() == VIA_MICROVIA ) { int ax, ay, bx, by; @@ -917,12 +932,12 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, // for Buried Vias, draw a partial line : orient depending on layer pair // (so we can see superimposed buried vias ): - if( GetShape() == VIA_BLIND_BURIED ) + if( GetViaType() == VIA_BLIND_BURIED ) { int ax = 0, ay = radius, bx = 0, by = drill_radius; LAYER_NUM layer_top, layer_bottom; - ( (SEGVIA*) this )->LayerPair( &layer_top, &layer_bottom ); + ( (VIA*) this )->LayerPair( &layer_top, &layer_bottom ); // lines for the top layer RotatePoint( &ax, &ay, layer_top * 3600.0 / brd->GetCopperLayerCount( ) ); @@ -978,7 +993,7 @@ void SEGVIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, } -void SEGVIA::ViewGetLayers( int aLayers[], int& aCount ) const +void VIA::ViewGetLayers( int aLayers[], int& aCount ) const { // Just show it on common via & via holes layers aLayers[0] = ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ); @@ -1035,56 +1050,12 @@ void TRACK::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) } } - -void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +void TRACK::GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; - BOARD* board = GetBoard(); - switch( Type() ) - { - case PCB_VIA_T: - switch( GetShape() ) - { - default: - case 0: - msg = wxT( "???" ); // Not used yet, does not exist currently - break; - - case 1: - msg = _( "Micro Via" ); // from external layer (TOP or BOTTOM) from - // the near neighbor inner layer only - break; - - case 2: - msg = _( "Blind/Buried Via" ); // from inner or external to inner - // or external layer (no restriction) - break; - - case 3: - msg = _( "Through Via" ); // Usual via (from TOP to BOTTOM layer only ) - break; - } - - break; - - case PCB_TRACE_T: - msg = _( "Track" ); - break; - - case PCB_ZONE_T: - msg = _( "Zone" ); - break; - - default: - msg = wxT( "???" ); - break; - } - - aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) ); - - // Display Net Name (in Pcbnew) - if( board ) + // Display Net Name + if( GetBoard() ) { NETINFO_ITEM* net = GetNet(); @@ -1095,7 +1066,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) ); - /* Display net code : (useful in test or debug) */ + // Display net code : (useful in test or debug) msg.Printf( wxT( "%d.%d" ), GetNetCode(), GetSubNet() ); aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); } @@ -1127,7 +1098,7 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) #endif // defined(DEBUG) - /* Display the State member */ + // Display the State member msg = wxT( ". . " ); if( GetState( TRACK_LOCKED ) ) @@ -1137,179 +1108,211 @@ void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) msg[2] = 'A'; aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) ); +} - /* Display layer or layer pair) */ - if( Type() == PCB_VIA_T ) - { - SEGVIA* Via = (SEGVIA*) this; - LAYER_NUM top_layer, bottom_layer; +void TRACK::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +{ + wxString msg; + BOARD* board = GetBoard(); - Via->LayerPair( &top_layer, &bottom_layer ); - if( board ) - msg = board->GetLayerName( top_layer ) + wxT( "/" ) - + board->GetLayerName( bottom_layer ); - else - msg.Printf(wxT("%d/%d"), top_layer, bottom_layer ); - } + aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Track" ), DARKCYAN ) ); + + GetMsgPanelInfoBase_Common( aList ); + + // Display layer + if( board ) + msg = board->GetLayerName( m_Layer ); else - { - if( board ) - msg = board->GetLayerName( m_Layer ); - else - msg.Printf(wxT("%d"), m_Layer ); - } + msg.Printf(wxT("%d"), m_Layer ); aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) ); // Display width msg = ::CoordinateToString( (unsigned) m_Width ); - if( Type() == PCB_VIA_T ) // Display Diam and Drill values - { - // Display diameter value: - aList.push_back( MSG_PANEL_ITEM( _( "Diam" ), msg, DARKCYAN ) ); - - // Display drill value - int drill_value = GetDrillValue(); - - msg = ::CoordinateToString( drill_value ); - - wxString title = _( "Drill" ); - title += wxT( " " ); - - if( m_Drill >= 0 ) - title += _( "(Specific)" ); - else - title += _( "(Default)" ); - - aList.push_back( MSG_PANEL_ITEM( title, msg, RED ) ); - } - else - { - aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) ); - } + aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) ); // Display segment length - if( Type() != PCB_VIA_T ) // Display Diam and Drill values + msg = ::LengthDoubleToString( GetLength() ); + aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) ); +} + +void SEGZONE::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +{ + wxString msg; + BOARD* board = GetBoard(); + + aList.push_back( MSG_PANEL_ITEM( _( "Type" ), _( "Zone " ), DARKCYAN ) ); + + GetMsgPanelInfoBase_Common( aList ); + + // Display layer + if( board ) + msg = board->GetLayerName( m_Layer ); + else + msg.Printf(wxT("%d"), m_Layer ); + + aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), msg, BROWN ) ); + + // Display width + msg = ::CoordinateToString( (unsigned) m_Width ); + + aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) ); + + // Display segment length + msg = ::LengthDoubleToString( GetLength() ); + aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) ); +} + +void VIA::GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ) +{ + wxString msg; + BOARD* board = GetBoard(); + + switch( GetViaType() ) { - msg = ::LengthDoubleToString( GetLength() ); - aList.push_back( MSG_PANEL_ITEM( _( "Segment Length" ), msg, DARKCYAN ) ); + default: + case VIA_NOT_DEFINED: + msg = wxT( "???" ); // Not used yet, does not exist currently + break; + + case VIA_MICROVIA: + msg = _( "Micro Via" ); // from external layer (TOP or BOTTOM) from + // the near neighbor inner layer only + break; + + case VIA_BLIND_BURIED: + msg = _( "Blind/Buried Via" ); // from inner or external to inner + // or external layer (no restriction) + break; + + case VIA_THROUGH: + msg = _( "Through Via" ); // Usual via (from TOP to BOTTOM layer only ) + break; } + + aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) ); + + GetMsgPanelInfoBase_Common( aList ); + + + // Display layer pair + LAYER_NUM top_layer, bottom_layer; + + LayerPair( &top_layer, &bottom_layer ); + if( board ) + msg = board->GetLayerName( top_layer ) + wxT( "/" ) + + board->GetLayerName( bottom_layer ); + else + msg.Printf(wxT("%d/%d"), top_layer, bottom_layer ); + + aList.push_back( MSG_PANEL_ITEM( _( "Layers" ), msg, BROWN ) ); + + // Display width + msg = ::CoordinateToString( (unsigned) m_Width ); + + // Display diameter value: + aList.push_back( MSG_PANEL_ITEM( _( "Diam" ), msg, DARKCYAN ) ); + + // Display drill value + int drill_value = GetDrillValue(); + + msg = ::CoordinateToString( drill_value ); + + wxString title = _( "Drill" ); + title += wxT( " " ); + + if( m_Drill >= 0 ) + title += _( "(Specific)" ); + else + title += _( "(Default)" ); + + aList.push_back( MSG_PANEL_ITEM( title, msg, RED ) ); } bool TRACK::HitTest( const wxPoint& aPosition ) { - int max_dist = m_Width >> 1; + return TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ); +} - if( Type() == PCB_VIA_T ) - { - // rel_pos is aPosition relative to m_Start (or the center of the via) - wxPoint rel_pos = aPosition - m_Start; - double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y; - return dist <= (double) max_dist * max_dist; - } +bool VIA::HitTest( const wxPoint& aPosition ) +{ + int max_dist = m_Width / 2; - return TestSegmentHit( aPosition, m_Start, m_End, max_dist ); + // rel_pos is aPosition relative to m_Start (or the center of the via) + wxPoint rel_pos = aPosition - m_Start; + double dist = (double) rel_pos.x * rel_pos.x + (double) rel_pos.y * rel_pos.y; + return dist <= (double) max_dist * max_dist; } bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +{ + EDA_RECT arect = aRect; + arect.Inflate( aAccuracy ); + + if( aContained ) + /* Tracks are a special case: + * they are considered inside the rect if one end is inside the rect */ + return arect.Contains( GetStart() ) || arect.Contains( GetEnd() ); + else + return arect.Intersects( GetStart(), GetEnd() ); +} + +bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const { EDA_RECT box; EDA_RECT arect = aRect; arect.Inflate( aAccuracy ); - if( Type() == PCB_VIA_T ) - { - box.SetOrigin( GetStart() ); - box.Inflate( GetWidth() >> 1 ); + box.SetOrigin( GetStart() ); + box.Inflate( GetWidth() / 2 ); - if(aContained) - return arect.Contains( box ); - else - return arect.Intersects( box ); - } + if( aContained ) + return arect.Contains( box ); else - { - if( aContained ) - // Tracks are a specila case: - // they are considered inside the rect if one end - // is inside the rect - return arect.Contains( GetStart() ) || arect.Contains( GetEnd() ); - else - return arect.Intersects( GetStart(), GetEnd() ); - } + return arect.Intersects( box ); } - -TRACK* TRACK::GetVia( const wxPoint& aPosition, LAYER_NUM aLayer) +VIA* TRACK::GetVia( const wxPoint& aPosition, LAYER_NUM aLayer) { - TRACK* track; - - for( track = this; track; track = track->Next() ) + for( VIA *via = GetFirstVia( this ); via; via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - if( !track->HitTest( aPosition ) ) - continue; - - if( track->GetState( BUSY | IS_DELETED ) ) - continue; - - if( aLayer == UNDEFINED_LAYER ) - break; - - if( track->IsOnLayer( aLayer ) ) - break; - } - - return track; -} - - -TRACK* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) -{ - TRACK* trace; - - for( trace = this; trace != NULL; trace = trace->Next() ) - { - if( trace->Type() == PCB_VIA_T ) - { - if( aPosition == trace->m_Start ) - { - if( trace->GetState( BUSY | IS_DELETED ) == 0 ) - { - if( aLayerMask & trace->GetLayerMask() ) - return trace; - } - } - } - - if( trace == aEndTrace ) - break; + if( via->HitTest( aPosition ) && + !via->GetState( BUSY | IS_DELETED ) && + ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) ) + return via; } return NULL; } -TRACK* TRACK::GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ) +VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) +{ + for( VIA *via = GetFirstVia( this, aEndTrace ); via; via = GetFirstVia( via->Next() ) ) + { + if( via->HitTest( aPosition ) && + !via->GetState( BUSY | IS_DELETED ) && + (aLayerMask & via->GetLayerMask()) ) + return via; + } + + return NULL; +} + + +TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint ) { const int NEIGHTBOUR_COUNT_MAX = 50; TRACK* previousSegment; TRACK* nextSegment; int Reflayer; - wxPoint position; int ii; int max_dist; - - if( aEndPoint == FLG_START ) - position = m_Start; - else - position = m_End; + const wxPoint &position = GetEndPoint( aEndPoint ); Reflayer = GetLayerMask(); @@ -1466,7 +1469,7 @@ int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace ) } Track->SetState( BUSY, true ); - segm = ::GetTrace( this, TrackListEnd, Track->m_Start, layerMask ); + segm = ::GetTrack( this, TrackListEnd, Track->m_Start, layerMask ); Track->SetState( BUSY, false ); if( via ) @@ -1513,7 +1516,7 @@ int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace ) } Track->SetState( BUSY, true ); - segm = ::GetTrace( this, TrackListEnd, Track->m_End, layerMask ); + segm = ::GetTrack( this, TrackListEnd, Track->m_End, layerMask ); Track->SetState( BUSY, false ); if( via ) diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 56ac970102..9afc346788 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -31,6 +31,7 @@ #define CLASS_TRACK_H +#include #include #include #include @@ -38,23 +39,27 @@ class TRACK; +class VIA; class D_PAD; class MSG_PANEL_ITEM; -// Via attributes (m_Shape parameter) -#define VIA_THROUGH 3 /* Always a through hole via */ -#define VIA_BLIND_BURIED 2 /* this via can be on internal layers */ -#define VIA_MICROVIA 1 /* this via which connect from an external layer - * to the near neighbor internal layer */ -#define VIA_NOT_DEFINED 0 /* not yet used */ +// Via types +enum VIATYPE_T +{ + VIA_THROUGH = 3, /* Always a through hole via */ + VIA_BLIND_BURIED = 2, /* this via can be on internal layers */ + VIA_MICROVIA = 1, /* this via which connect from an external layer + * to the near neighbor internal layer */ + VIA_NOT_DEFINED = 0 /* not yet used */ +}; #define UNDEFINED_DRILL_DIAMETER -1 //< Undefined via drill diameter. #define MIN_VIA_DRAW_SIZE 4 /// Minimum size in pixel for full drawing /** - * Function GetTrace + * Function GetTrack * is a helper function to locate a trace segment having an end point at \a aPosition * on \a aLayerMask starting at \a aStartTrace and end at \a aEndTrace. *

@@ -69,9 +74,8 @@ class MSG_PANEL_ITEM; * layer mask. * @return A TRACK object pointer if found otherwise NULL. */ -extern TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, const wxPoint& aPosition, - LAYER_MSK aLayerMask ); - +extern TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace, + const wxPoint& aPosition, LAYER_MSK aLayerMask ); class TRACK : public BOARD_CONNECTED_ITEM { @@ -85,9 +89,6 @@ protected: 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.. - - int m_Drill; // for vias: via drill (- 1 for default value) public: BOARD_CONNECTED_ITEM* start; // pointers to a connected item (pad or track) @@ -99,8 +100,8 @@ public: // Do not create a copy constructor. The one generated by the compiler is adequate. - TRACK* Next() const { return (TRACK*) Pnext; } - TRACK* Back() const { return (TRACK*) Pback; } + TRACK* Next() const { return static_cast( Pnext ); } + TRACK* Back() const { return static_cast( Pback ); } virtual void Move( const wxPoint& aMoveVector ) { @@ -124,8 +125,15 @@ public: void SetStart( const wxPoint& aStart ) { m_Start = aStart; } const wxPoint& GetStart() const { return m_Start; } - int GetShape() const { return m_Shape; } - void SetShape( int aShape ) { m_Shape = aShape; } + + /// Return the selected endpoint (start or end) + const wxPoint& GetEndPoint( ENDPOINT_T aEndPoint ) const + { + if( aEndPoint == ENDPOINT_START ) + return m_Start; + else + return m_End; + } // Virtual function const EDA_RECT GetBoundingBox() const; @@ -180,47 +188,13 @@ public: int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor ) const; - /** - * Function SetDrill - * sets the drill value for vias. - * @param aDrill is the new drill diameter - */ - void SetDrill( int aDrill ) { m_Drill = aDrill; } - - /** - * Function GetDrill - * returns the local drill setting for this VIA. If you want the calculated value, - * use GetDrillValue() instead. - */ - int GetDrill() const { return m_Drill; } - - /** - * Function GetDrillValue - * "calculates" the drill value for vias (m-Drill if > 0, or default - * drill value for the board. - * @return real drill_value - */ - int GetDrillValue() const; - - /** - * Function SetDrillDefault - * sets the drill value for vias to the default value #UNDEFINED_DRILL_DIAMETER. - */ - void SetDrillDefault() { m_Drill = UNDEFINED_DRILL_DIAMETER; } - - /** - * Function IsDrillDefault - * @return true if the drill value is default value (-1) - */ - bool IsDrillDefault() { return m_Drill <= 0; } - /** * Function GetLayerMask * returns a "layer mask", which is a bitmap of all layers on which the - * TRACK segment or SEGVIA physically resides. + * TRACK segment or VIA physically resides. * @return int - a layer mask, see pcbstruct.h's LAYER_BACK, etc. */ - LAYER_MSK GetLayerMask() const; + virtual LAYER_MSK GetLayerMask() const; /** * Function IsPointOnEnds @@ -239,13 +213,6 @@ public: void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ); - /** - * Function GetMsgPanelInfoBase - * Display info about the track segment only, and does not calculate the full track length - * @param aList A list of #MSG_PANEL_ITEM objects to add status information. - */ - void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); - /** * Function ShowWidth * returns the width of the track in displayable user units. @@ -261,32 +228,32 @@ public: /** @copydoc BOARD_ITEM::HitTest(const EDA_RECT& aRect, * bool aContained = true, int aAccuracy ) const */ - bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; + virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; /** * Function GetVia - * finds the first SEGVIA object at \a aPosition on \a aLayer starting at the trace. + * finds the first VIA object at \a aPosition on \a aLayer starting at the trace. * * @param aPosition The wxPoint to HitTest() against. * @param aLayer The layer to match, pass -1 for a don't care. - * @return A pointer to a SEGVIA object if found, else NULL. + * @return A pointer to a VIA object if found, else NULL. */ - TRACK* GetVia( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ); + VIA* GetVia( const wxPoint& aPosition, LAYER_NUM aLayer = UNDEFINED_LAYER ); /** * Function GetVia - * finds the first SEGVIA object at \a aPosition on \a aLayer starting at the trace + * finds the first VIA object at \a aPosition on \a aLayer starting at the trace * and ending at \a aEndTrace. * * @param aEndTrace Pointer to the last TRACK object to end search. * @param aPosition The wxPoint to HitTest() against. * @param aLayerMask The layers to match, pass -1 for a don't care. - * @return A pointer to a SEGVIA object if found, else NULL. + * @return A pointer to a VIA object if found, else NULL. */ - TRACK* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); + VIA* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); /** - * Function GetTrace + * Function GetTrack * return the trace segment connected to the segment at \a aEndPoint from \a * aStartTrace to \a aEndTrace. * @@ -296,7 +263,7 @@ public: * @param aEndPoint The start or end point of the segment to test against. * @return A TRACK object pointer if found otherwise NULL. */ - TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ); + TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint ); /** * Function GetEndSegments @@ -349,6 +316,24 @@ public: static wxString ShowState( int stateBits ); #endif + +protected: + /** + * Function GetMsgPanelInfoBase + * Display info about the track segment only, and does not calculate the full track length + * @param aList A list of #MSG_PANEL_ITEM objects to add status information. + */ + virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); + + + /** + * Helper function for the common panel info */ + void GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList ); + + /** + * Helper for drawing the short netname in tracks */ + void DrawShortNetname( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, + EDA_COLOR_T aBgColor ); }; @@ -365,20 +350,26 @@ public: } - SEGZONE* Next() const { return (SEGZONE*) Pnext; } + SEGZONE* Next() const { return static_cast( Pnext ); } wxString GetSelectMenuText() const; + void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, + GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset ); + BITMAP_DEF GetMenuImage() const { return add_zone_xpm; } EDA_ITEM* Clone() const; + +protected: + virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); }; -class SEGVIA : public TRACK +class VIA : public TRACK { public: - SEGVIA( BOARD_ITEM* aParent ); + VIA( BOARD_ITEM* aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. @@ -387,17 +378,16 @@ public: bool IsOnLayer( LAYER_NUM aLayer ) const; + virtual LAYER_MSK GetLayerMask() const; + /** * Function SetLayerPair - * set the .m_Layer member param: - * For a via m_Layer contains the 2 layers : - * top layer and bottom layer used by the via. - * The via connect all layers from top layer to bottom layer - * 4 bits for the first layer and 4 next bits for the second layer + * For a via m_Layer contains the top layer, the other layer is in + * m_BottomLayer * @param top_layer = first layer connected by the via * @param bottom_layer = last layer connected by the via */ - void SetLayerPair( LAYER_NUM top_layer, LAYER_NUM bottom_layer ); + void SetLayerPair( LAYER_NUM aTopLayer, LAYER_NUM aBottomLayer ); /** * Function LayerPair @@ -411,6 +401,10 @@ public: const wxPoint& GetPosition() const { return m_Start; } // was overload void SetPosition( const wxPoint& aPoint ) { m_Start = aPoint; m_End = aPoint; } // was overload + virtual bool HitTest( const wxPoint& aPosition ); + + virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; + wxString GetClass() const { return wxT( "VIA" ); @@ -425,10 +419,73 @@ public: /// @copydoc VIEW_ITEM::ViewGetLayers() virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + virtual void Flip( const wxPoint& aCentre ); + #if defined (DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override #endif + + VIATYPE_T GetViaType() const { return m_ViaType; } + void SetViaType( VIATYPE_T aViaType ) { m_ViaType = aViaType; } + + /** + * Function SetDrill + * sets the drill value for vias. + * @param aDrill is the new drill diameter + */ + void SetDrill( int aDrill ) { m_Drill = aDrill; } + + /** + * Function GetDrill + * returns the local drill setting for this VIA. If you want the calculated value, + * use GetDrillValue() instead. + */ + int GetDrill() const { return m_Drill; } + + /** + * Function GetDrillValue + * "calculates" the drill value for vias (m-Drill if > 0, or default + * drill value for the board. + * @return real drill_value + */ + int GetDrillValue() const; + + /** + * Function SetDrillDefault + * sets the drill value for vias to the default value #UNDEFINED_DRILL_DIAMETER. + */ + void SetDrillDefault() { m_Drill = UNDEFINED_DRILL_DIAMETER; } + + /** + * Function IsDrillDefault + * @return true if the drill value is default value (-1) + */ + bool IsDrillDefault() const { return m_Drill <= 0; } + + +protected: + virtual void GetMsgPanelInfoBase( std::vector< MSG_PANEL_ITEM >& aList ); + +private: + /// The bottom layer of the via (the top layer is in m_Layer) + LAYER_NUM m_BottomLayer; + + VIATYPE_T m_ViaType; // Type of via + + int m_Drill; // for vias: via drill (- 1 for default value) }; +/// Scan a track list for the first VIA o NULL if not found (or NULL passed) +inline VIA *GetFirstVia( TRACK *aTrk, const TRACK *aStopPoint = NULL ) +{ + while( aTrk && (aTrk != aStopPoint) && (aTrk->Type() != PCB_VIA_T) ) + aTrk = aTrk->Next(); + + // It could stop because of the stop point, not on a via + if( aTrk && (aTrk->Type() == PCB_VIA_T) ) + return static_cast( aTrk ); + else + return NULL; +} #endif /* CLASS_TRACK_H */ diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 03f68cffe1..cea17c626b 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -87,7 +87,12 @@ private: * i.e. when they are colinear, same width, and obviously same layer */ TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, - TRACK* aCandidate, int aEndType ); + TRACK* aCandidate, ENDPOINT_T aEndType ); + + const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK *aTrack, + ENDPOINT_T aEndPoint ); + + bool testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint ); }; /* Install the cleanup dialog frame to know what should be cleaned @@ -102,7 +107,7 @@ void PCB_EDIT_FRAME::Clean_Pcb() wxBusyCursor( dummy ); TRACKS_CLEANER cleaner( GetBoard() ); - cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments, + cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm ); m_canvas->Refresh( true ); } @@ -112,7 +117,7 @@ void PCB_EDIT_FRAME::Clean_Pcb() * Delete * - Redundant points on tracks (merge aligned segments) * - vias on pad - * - null lenght segments + * - null length segments * Create segments when track ends are incorrectly connected: * i.e. when a track end covers a pad or a via but is not exactly on the pad or the via center */ @@ -135,8 +140,6 @@ bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame, if( modified ) { // Clear undo and redo lists to avoid inconsistencies between lists - // XXX This is very involved... maybe a member in PCB_EDIT_FRAME - // would be better? aFrame->GetScreen()->ClearUndoRedoList(); aFrame->SetCurItem( NULL ); aFrame->Compile_Ratsnest( NULL, true ); @@ -159,7 +162,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() BuildTracksCandidatesList( m_Brd->m_Track, NULL); // clear flags and variables used in cleanup - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() ) { track->start = NULL; track->end = NULL; @@ -169,7 +172,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() // Build connections info tracks to pads SearchTracksConnectedToPads(); - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() ) { // Mark track if connected to pads for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ ) @@ -195,65 +198,54 @@ bool TRACKS_CLEANER::clean_vias() { bool modified = false; - for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) + for( VIA* via = GetFirstVia( m_Brd->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) { - // Correct via m_End defects (if any) - if( track->Type() == PCB_VIA_T ) + // Correct via m_End defects (if any), should never happen + if( via->GetStart() != via->GetEnd() ) { - if( track->GetStart() != track->GetEnd() ) - track->SetEnd( track->GetStart() ); + wxFAIL_MSG( "Via with mismatching ends" ); + via->SetEnd( via->GetStart() ); } - if( track->GetShape() != VIA_THROUGH ) - continue; - - // Search and delete others vias at same location - TRACK* alt_track = track->Next(); - - TRACK* next_track; - for( ; alt_track != NULL; alt_track = next_track ) + /* Important: these cleanups only do thru hole vias, they don't + * (yet) handle high density interconnects */ + if( via->GetViaType() != VIA_THROUGH ) { - next_track = alt_track->Next(); - - if( alt_track->GetShape() != VIA_THROUGH ) - continue; - - if( alt_track->GetStart() != track->GetStart() ) - continue; - - // delete via - m_Brd->GetRatsnest()->Remove( alt_track ); - alt_track->ViewRelease(); - alt_track->UnLink(); - delete alt_track; - modified = true; - } - } - - // Delete Via on pads at same location - TRACK* next_track; - for( TRACK* track = m_Brd->m_Track; track != NULL; track = next_track ) - { - next_track = track->Next(); - - if( track->GetShape() != VIA_THROUGH ) - continue; - - // Examine the list of connected pads: - // if one pad through is found, the via can be removed - for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ ) - { - D_PAD * pad = track->m_PadsConnected[ii]; - - if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) + // Search and delete others vias at same location + VIA* next_via; + for( VIA* alt_via = GetFirstVia( via->Next() ); alt_via != NULL; + alt_via = next_via ) { - // redundant: via delete it - m_Brd->GetRatsnest()->Remove( track ); - track->ViewRelease(); - track->UnLink(); - delete track; - modified = true; - break; + next_via = GetFirstVia( alt_via->Next() ); + + if( (alt_via->GetViaType() == VIA_THROUGH) && + (alt_via->GetStart() == via->GetStart()) ) + { + // delete via + m_Brd->GetRatsnest()->Remove( alt_via ); + alt_via->ViewRelease(); + alt_via->DeleteStructure(); + modified = true; + } + } + + /* To delete through Via on THT pads at same location + * Examine the list of connected pads: + * if one through pad is found, the via can be removed */ + for( unsigned ii = 0; ii < via->m_PadsConnected.size(); ++ii ) + { + const D_PAD *pad = via->m_PadsConnected[ii]; + + if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) + { + // redundant: delete the via + m_Brd->GetRatsnest()->Remove( via ); + via->ViewRelease(); + via->DeleteStructure(); + modified = true; + break; + } } } } @@ -261,6 +253,64 @@ bool TRACKS_CLEANER::clean_vias() return modified; } +/// Utility for checking if a track/via ends on a zone +const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK *aTrack, + ENDPOINT_T aEndPoint ) +{ + // Vias are special cased, since they get a layer range, not a single one + LAYER_NUM top_layer, bottom_layer; + const VIA *via = dynamic_cast( aTrack ); + + if( via ) + via->LayerPair( &top_layer, &bottom_layer ); + else + { + top_layer = aTrack->GetLayer(); + bottom_layer = top_layer; + } + return m_Brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ), + top_layer, bottom_layer, aTrack->GetNetCode() ); +} + +/** Utility: does the endpoint unconnected processed for one endpoint of one track + * Returns true if the track must be deleted, false if not necessarily */ +bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint ) +{ + bool flag_erase = false; + + TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint ); + if( (other == NULL) && + (zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) ) + flag_erase = true; // Start endpoint is neither on pad, zone or other track + else // segment, via or zone connected to this end + { + // Fill connectivity informations + if( aEndPoint == ENDPOINT_START ) + aTrack->start = other; + else + aTrack->end = other; + + /* If a via is connected to this end, test if this via has a second item connected. + * If not, remove the current segment (the via would then become + * unconnected and remove on the following pass) */ + VIA* via = dynamic_cast( other ); + if( via ) + { + // search for another segment following the via + aTrack->SetState( BUSY, true ); + + other = via->GetTrack( m_Brd->m_Track, NULL, aEndPoint ); + + // There is a via on the start but it goes nowhere + if( (other == NULL) && + (zoneForTrackEndpoint( via, aEndPoint ) == NULL) ) + flag_erase = true; + + aTrack->SetState( BUSY, false ); + } + } + return flag_erase; +} /* * Delete dangling tracks @@ -273,149 +323,31 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() return false; bool modified = false; - bool item_erased = true; - while( item_erased ) // Iterate when at least one track is deleted + bool item_erased; + do // Iterate when at least one track is deleted { item_erased = false; TRACK* next_track; - for( TRACK * track = m_Brd->m_Track; track ; track = next_track ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = next_track ) { next_track = track->Next(); - int flag_erase = 0; //Not connected indicator - int type_end = 0; + bool flag_erase = false; // Start without a good reason to erase it - if( track->GetState( START_ON_PAD ) ) - type_end |= START_ON_PAD; + /* if a track endpoint is not connected to a pad, test if + * the endpoint is connected to another track or to a zone. + * For via test, an enhancement could be to test if + * connected to 2 items on different layers. Currently + * a via must be connected to 2 items, that can be on the + * same layer */ - if( track->GetState( END_ON_PAD ) ) - type_end |= END_ON_PAD; + // Check if there is nothing attached on the start + if( !(track->GetState( START_ON_PAD )) ) + flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START ); - // if the track start point is not connected to a pad, - // test if this track start point is connected to another track - // For via test, an enhancement could be to test if connected - // to 2 items on different layers. - // Currently a via must be connected to 2 items, that can be on the same layer - LAYER_NUM top_layer, bottom_layer; - ZONE_CONTAINER* zone; - - if( (type_end & START_ON_PAD ) == 0 ) - { - TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_START ); - - if( other == NULL ) // Test a connection to zones - { - if( track->Type() != PCB_VIA_T ) - { - zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), - track->GetLayer(), - track->GetLayer(), - track->GetNetCode() ); - } - else - { - ((SEGVIA*)track)->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), - top_layer, bottom_layer, - track->GetNetCode() ); - } - } - - if( (other == NULL) && (zone == NULL) ) - { - flag_erase |= 1; - } - else // segment, via or zone connected to this end - { - track->start = other; - // If a via is connected to this end, - // test if this via has a second item connected. - // If no, remove it with the current segment - - if( other && other->Type() == PCB_VIA_T ) - { - // search for another segment following the via - track->SetState( BUSY, true ); - - SEGVIA* via = (SEGVIA*) other; - other = via->GetTrace( m_Brd->m_Track, NULL, FLG_START ); - - if( other == NULL ) - { - via->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( via->GetStart(), - bottom_layer, - top_layer, - via->GetNetCode() ); - } - - if( (other == NULL) && (zone == NULL) ) - flag_erase |= 2; - - track->SetState( BUSY, false ); - } - } - } - - // if track end point is not connected to a pad, - // test if this track end point is connected to an other track - if( (type_end & END_ON_PAD ) == 0 ) - { - TRACK* other = track->GetTrace( m_Brd->m_Track, NULL, FLG_END ); - - if( other == NULL ) // Test a connection to zones - { - if( track->Type() != PCB_VIA_T ) - { - zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), - track->GetLayer(), - track->GetLayer(), - track->GetNetCode() ); - } - else - { - ((SEGVIA*)track)->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), - top_layer, bottom_layer, - track->GetNetCode() ); - } - } - - if ( (other == NULL) && (zone == NULL) ) - { - flag_erase |= 0x10; - } - else // segment, via or zone connected to this end - { - track->end = other; - - // If a via is connected to this end, test if this via has a second item connected - // if no, remove it with the current segment - - if( other && other->Type() == PCB_VIA_T ) - { - // search for another segment following the via - - track->SetState( BUSY, true ); - - SEGVIA* via = (SEGVIA*) other; - other = via->GetTrace( m_Brd->m_Track, NULL, FLG_END ); - - if( other == NULL ) - { - via->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( via->GetEnd(), - bottom_layer, top_layer, - via->GetNetCode() ); - } - - if( (other == NULL) && (zone == NULL) ) - flag_erase |= 0x20; - - track->SetState( BUSY, false ); - } - } - } + // Check if there is nothing attached on the end + if( !(track->GetState( END_ON_PAD )) ) + flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END ); if( flag_erase ) { @@ -423,13 +355,14 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() m_Brd->GetRatsnest()->Remove( track ); track->ViewRelease(); track->DeleteStructure(); - // iterate, because a track connected to the deleted track - // is now perhaps now not connected and should be deleted + + /* keep iterating, because a track connected to the deleted track + * now perhaps is not connected and should be deleted */ item_erased = true; modified = true; } } - } + } while( item_erased ); return modified; } @@ -511,7 +444,7 @@ bool TRACKS_CLEANER::clean_segments() // search for a possible point connected to the START point of the current segment for( segStart = segment->Next(); ; ) { - segStart = segment->GetTrace( segStart, NULL, FLG_START ); + segStart = segment->GetTrack( segStart, NULL, ENDPOINT_START ); if( segStart ) { @@ -525,7 +458,7 @@ bool TRACKS_CLEANER::clean_segments() // We must have only one segment connected segStart->SetState( BUSY, true ); - other = segment->GetTrace( m_Brd->m_Track, NULL, FLG_START ); + other = segment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); segStart->SetState( BUSY, false ); if( other == NULL ) @@ -538,7 +471,7 @@ bool TRACKS_CLEANER::clean_segments() if( flag ) // We have the starting point of the segment is connected to an other segment { - segDelete = mergeCollinearSegmentIfPossible( segment, segStart, FLG_START ); + segDelete = mergeCollinearSegmentIfPossible( segment, segStart, ENDPOINT_START ); if( segDelete ) { @@ -553,7 +486,7 @@ bool TRACKS_CLEANER::clean_segments() // search for a possible point connected to the END point of the current segment: for( segEnd = segment->Next(); ; ) { - segEnd = segment->GetTrace( segEnd, NULL, FLG_END ); + segEnd = segment->GetTrack( segEnd, NULL, ENDPOINT_END ); if( segEnd ) { @@ -565,7 +498,7 @@ bool TRACKS_CLEANER::clean_segments() // We must have only one segment connected segEnd->SetState( BUSY, true ); - other = segment->GetTrace( m_Brd->m_Track, NULL, FLG_END ); + other = segment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); segEnd->SetState( BUSY, false ); if( other == NULL ) @@ -581,7 +514,7 @@ bool TRACKS_CLEANER::clean_segments() if( flag & 2 ) // We have the ending point of the segment is connected to an other segment { - segDelete = mergeCollinearSegmentIfPossible( segment, segEnd, FLG_END ); + segDelete = mergeCollinearSegmentIfPossible( segment, segEnd, ENDPOINT_END ); if( segDelete ) { @@ -614,7 +547,7 @@ bool TRACKS_CLEANER::clean_segments() * else return NULL */ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, - int aEndType ) + ENDPOINT_T aEndType ) { if( aTrackRef->GetWidth() != aCandidate->GetWidth() ) return NULL; @@ -674,7 +607,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* * (this function) is called when there is only 2 connected segments, *and if this point is not on a pad, it can be removed and the 2 segments will be merged */ - if( aEndType == FLG_START ) + if( aEndType == ENDPOINT_START ) { // We do not have a pad, which is a always terminal point for a track if( aTrackRef->GetState( START_ON_PAD) ) @@ -755,7 +688,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); + other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START ); if( other ) net_code_s = other->GetNetCode(); @@ -773,7 +706,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); + other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END ); if( other ) net_code_e = other->GetNetCode(); diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp index 4aee57a556..2470684c6d 100644 --- a/pcbnew/collectors.cpp +++ b/pcbnew/collectors.cpp @@ -149,7 +149,7 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testDa MODULE* module = NULL; D_PAD* pad = NULL; bool pad_through = false; - SEGVIA* via = NULL; + VIA* via = NULL; MARKER_PCB* marker = NULL; #if 0 // debugging @@ -252,7 +252,7 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testDa break; case PCB_VIA_T: // vias are on many layers, so layer test is specific - via = (SEGVIA*) item; + via = (VIA*) item; break; case PCB_TRACE_T: diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 6aba44cb2b..05f12dc766 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include #include @@ -130,6 +132,55 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) } +std::string FormatProbeItem( BOARD_ITEM* aItem ) +{ + MODULE* module; + + switch( aItem->Type() ) + { + case PCB_MODULE_T: + module = (MODULE*) aItem; + return StrPrintf( "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); + + case PCB_PAD_T: + { + module = (MODULE*) aItem->GetParent(); + wxString pad = ((D_PAD*)aItem)->GetPadName(); + + return StrPrintf( "$PART: \"%s\" $PAD: \"%s\"", + TO_UTF8( module->GetReference() ), + TO_UTF8( pad ) ); + } + + case PCB_MODULE_TEXT_T: + { + module = (MODULE*) aItem->GetParent(); + + TEXTE_MODULE* text_mod = (TEXTE_MODULE*) aItem; + + const char* text_key; + + if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) + text_key = "$REF:"; + else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) + text_key = "$VAL:"; + else + break; + + return StrPrintf( "$PART: \"%s\" %s \"%s\"", + TO_UTF8( module->GetReference() ), + text_key, + TO_UTF8( text_mod->GetText() ) ); + } + + default: + break; + } + + return ""; +} + + /** * Send a remote command to Eeschema via a socket, * @param objectToSync = item to be located on schematic (module, pin or text) @@ -139,57 +190,44 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) * $PART: "reference" $REF: "reference" put cursor on the component ref * $PART: "reference" $VAL: "value" put cursor on the component value */ -void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) +void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* aSyncItem ) { - char cmd[1024]; - const char* text_key; - MODULE* module = NULL; - D_PAD* pad; - TEXTE_MODULE* text_mod; - wxString msg; - - if( objectToSync == NULL ) +#if 1 + wxASSERT( aSyncItem ); // can't we fix the caller? +#else + if( !aSyncItem ) return; +#endif - switch( objectToSync->Type() ) + std::string packet = FormatProbeItem( aSyncItem ); + + if( packet.size() ) { - case PCB_MODULE_T: - module = (MODULE*) objectToSync; - sprintf( cmd, "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); - break; - - case PCB_PAD_T: - module = (MODULE*) objectToSync->GetParent(); - pad = (D_PAD*) objectToSync; - msg = pad->GetPadName(); - sprintf( cmd, "$PART: \"%s\" $PAD: \"%s\"", - TO_UTF8( module->GetReference() ), - TO_UTF8( msg ) ); - break; - - case PCB_MODULE_TEXT_T: - module = (MODULE*) objectToSync->GetParent(); - text_mod = (TEXTE_MODULE*) objectToSync; - - if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) - text_key = "$REF:"; - else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) - text_key = "$VAL:"; + if( Kiface().IsSingle() ) + SendCommand( MSG_TO_SCH, packet.c_str() ); else - break; - - sprintf( cmd, "$PART: \"%s\" %s \"%s\"", - TO_UTF8( module->GetReference() ), - text_key, - TO_UTF8( text_mod->GetText() ) ); - break; - - default: - break; - } - - if( module ) - { - SendCommand( MSG_TO_SCH, cmd ); + { + // Typically ExpressMail is going to be s-expression packets, but since + // we have existing interpreter of the cross probe packet on the other + // side in place, we use that here. + Kiway().ExpressMail( FRAME_SCH, MAIL_CROSS_PROBE, packet, this ); + } } } + + +void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) +{ + const std::string& payload = mail.GetPayload(); + + switch( mail.Command() ) + { + case MAIL_CROSS_PROBE: + ExecuteRemoteCommand( payload.c_str() ); + break; + + // many many others. + + } +} + diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp index dc03481fca..6daa73471e 100644 --- a/pcbnew/dialogs/dialog_gendrill.cpp +++ b/pcbnew/dialogs/dialog_gendrill.cpp @@ -140,15 +140,27 @@ void DIALOG_GENDRILL::InitDisplayParams() for( TRACK* track = m_parent->GetBoard()->m_Track; track != NULL; track = track->Next() ) { - if( track->Type() != PCB_VIA_T ) - continue; + const VIA *via = dynamic_cast( track ); + if( via ) + { + switch( via->GetViaType() ) + { + case VIA_THROUGH: + m_throughViasCount++; + break; - if( track->GetShape() == VIA_THROUGH ) - m_throughViasCount++; - else if( track->GetShape() == VIA_MICROVIA ) - m_microViasCount++; - else if( track->GetShape() == VIA_BLIND_BURIED ) - m_blindOrBuriedViasCount++; + case VIA_MICROVIA: + m_microViasCount++; + break; + + case VIA_BLIND_BURIED: + m_blindOrBuriedViasCount++; + break; + + default: + break; + } + } } m_MicroViaDrillValue->Enable( m_microViasCount ); diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index 21c306b66f..fe5faeba66 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -97,11 +97,17 @@ private: PCB_BASE_FRAME* m_parent; D_PAD* m_currentPad; // pad currently being edited D_PAD* m_dummyPad; // a working copy used to show changes - BOARD* m_board; - D_PAD& m_padMaster; + D_PAD* m_padMaster; // The pad used to create new pads in board or + // footprint editor + BOARD* m_board; // the main board: this is the board handled by + // the PCB editor, if running or the dummy + // board used by the footprint editor + // (could happen when the Footprint editor will be run + // alone, outside the board editor bool m_isFlipped; // true if the parent footprint (therefore pads) is flipped (mirrored) // in this case, some Y coordinates values must be negated bool m_canUpdate; + bool m_canEditNetName; // true only if the called is the board editor private: void initValues(); @@ -139,25 +145,31 @@ private: void PadPropertiesAccept( wxCommandEvent& event ); }; +void PCB_BASE_FRAME::InstallPadOptionsFrame( D_PAD* aPad ) +{ + DIALOG_PAD_PROPERTIES dlg( this, aPad ); + + dlg.ShowModal(); +} + DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aPad ) : - DIALOG_PAD_PROPERTIES_BASE( aParent ), - // use aParent's parent, which is the original BOARD, not the dummy module editor BOARD, - // since FOOTPRINT_EDIT_FRAME::GetDesignSettings() is tricked out to use the PCB_EDIT_FRAME's - // BOARD, not its own BOARD. - m_padMaster( aParent->GetDesignSettings().m_Pad_Master ) + DIALOG_PAD_PROPERTIES_BASE( aParent ) { m_canUpdate = false; m_parent = aParent; m_currentPad = aPad; // aPad can be NULL, if the dialog is called // from the module editor to set default pad characteristics + m_board = m_parent->GetBoard(); + + m_padMaster = &m_parent->GetDesignSettings().m_Pad_Master; m_dummyPad = new D_PAD( (MODULE*) NULL ); if( aPad ) m_dummyPad->Copy( aPad ); - else - m_dummyPad->Copy( &m_padMaster ); + else // We are editing a "master" pad, i.e. a pad used to create new pads + m_dummyPad->Copy( m_padMaster ); initValues(); @@ -238,19 +250,16 @@ void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event ) } -void PCB_BASE_FRAME::InstallPadOptionsFrame( D_PAD* aPad ) -{ - DIALOG_PAD_PROPERTIES dlg( this, aPad ); - - dlg.ShowModal(); -} - - void DIALOG_PAD_PROPERTIES::initValues() { wxString msg; double angle; + // Disable pad net name wxTextCtrl if the caller is the footprint editor + // because nets are living only in the board managed by the board editor + m_canEditNetName = m_parent->IsType( FRAME_PCB ); + + // Setup layers names from board // Should be made first, before calling m_rbCopperLayersSel->SetSelection() m_rbCopperLayersSel->SetString( 0, m_board->GetLayerName( LAYER_N_FRONT ) ); @@ -471,7 +480,7 @@ void DIALOG_PAD_PROPERTIES::initValues() bool enable = m_dummyPad->GetAttribute() != PAD_HOLE_NOT_PLATED; m_PadNumCtrl->Enable( enable ); - m_PadNetNameCtrl->Enable( enable ); + m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL ); m_LengthPadToDieCtrl->Enable( enable ); if( m_dummyPad->GetDrillShape() != PAD_DRILL_OBLONG ) @@ -593,7 +602,7 @@ void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event ) void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) { - unsigned ii = m_PadType->GetSelection(); + unsigned ii = m_PadType->GetSelection(); if( ii >= NBTYPES ) // catches < 0 also ii = 0; @@ -614,7 +623,7 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) // (disable for NPTH pads (mechanical pads) bool enable = ii != 3; m_PadNumCtrl->Enable( enable ); - m_PadNetNameCtrl->Enable( enable ); + m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL ); m_LengthPadToDieCtrl->Enable( enable ); } @@ -752,7 +761,9 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) bool rastnestIsChanged = false; int isign = m_isFlipped ? -1 : 1; - transferDataToPad( &m_padMaster ); + transferDataToPad( m_padMaster ); + // m_padMaster is a pattern: ensure there is no net for this pad: + m_padMaster->SetNetCode( NETINFO_LIST::UNCONNECTED ); if( m_currentPad ) // Set current Pad parameters { @@ -768,12 +779,12 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) m_currentPad->ClearFlags( DO_NOT_DRAW ); // Update values - m_currentPad->SetShape( m_padMaster.GetShape() ); - m_currentPad->SetAttribute( m_padMaster.GetAttribute() ); + m_currentPad->SetShape( m_padMaster->GetShape() ); + m_currentPad->SetAttribute( m_padMaster->GetAttribute() ); - if( m_currentPad->GetPosition() != m_padMaster.GetPosition() ) + if( m_currentPad->GetPosition() != m_padMaster->GetPosition() ) { - m_currentPad->SetPosition( m_padMaster.GetPosition() ); + m_currentPad->SetPosition( m_padMaster->GetPosition() ); rastnestIsChanged = true; } @@ -785,54 +796,62 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) m_currentPad->SetPos0( pt ); - m_currentPad->SetOrientation( m_padMaster.GetOrientation() * isign + module->GetOrientation() ); + m_currentPad->SetOrientation( m_padMaster->GetOrientation() * isign + module->GetOrientation() ); - m_currentPad->SetSize( m_padMaster.GetSize() ); + m_currentPad->SetSize( m_padMaster->GetSize() ); - size = m_padMaster.GetDelta(); + size = m_padMaster->GetDelta(); size.y *= isign; m_currentPad->SetDelta( size ); - m_currentPad->SetDrillSize( m_padMaster.GetDrillSize() ); - m_currentPad->SetDrillShape( m_padMaster.GetDrillShape() ); + m_currentPad->SetDrillSize( m_padMaster->GetDrillSize() ); + m_currentPad->SetDrillShape( m_padMaster->GetDrillShape() ); - wxPoint offset = m_padMaster.GetOffset(); + wxPoint offset = m_padMaster->GetOffset(); offset.y *= isign; m_currentPad->SetOffset( offset ); - m_currentPad->SetPadToDieLength( m_padMaster.GetPadToDieLength() ); + m_currentPad->SetPadToDieLength( m_padMaster->GetPadToDieLength() ); - if( m_currentPad->GetLayerMask() != m_padMaster.GetLayerMask() ) + if( m_currentPad->GetLayerMask() != m_padMaster->GetLayerMask() ) { rastnestIsChanged = true; - m_currentPad->SetLayerMask( m_padMaster.GetLayerMask() ); + m_currentPad->SetLayerMask( m_padMaster->GetLayerMask() ); } if( m_isFlipped ) m_currentPad->SetLayerMask( FlipLayerMask( m_currentPad->GetLayerMask() ) ); - m_currentPad->SetPadName( m_padMaster.GetPadName() ); + m_currentPad->SetPadName( m_padMaster->GetPadName() ); - if( m_currentPad->GetNetname() != m_PadNetNameCtrl->GetValue() ) + wxString padNetname; + + // For PAD_HOLE_NOT_PLATED, ensure there is no net name selected + if( m_padMaster->GetAttribute() != PAD_HOLE_NOT_PLATED ) + padNetname = m_PadNetNameCtrl->GetValue(); + + if( m_currentPad->GetNetname() != padNetname ) { - if( !m_PadNetNameCtrl->GetValue().IsEmpty() && m_padMaster.GetNetCode() == 0 ) + const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname ); + + if( !padNetname.IsEmpty() && netinfo == NULL ) { DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); } else { rastnestIsChanged = true; - m_currentPad->SetNetCode( m_padMaster.GetNetCode() ); + m_currentPad->SetNetCode( netinfo->GetNet() ); } } - m_currentPad->SetLocalClearance( m_padMaster.GetLocalClearance() ); - m_currentPad->SetLocalSolderMaskMargin( m_padMaster.GetLocalSolderMaskMargin() ); - m_currentPad->SetLocalSolderPasteMargin( m_padMaster.GetLocalSolderPasteMargin() ); - m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster.GetLocalSolderPasteMarginRatio() ); - m_currentPad->SetZoneConnection( m_padMaster.GetZoneConnection() ); - m_currentPad->SetThermalWidth( m_padMaster.GetThermalWidth() ); - m_currentPad->SetThermalGap( m_padMaster.GetThermalGap() ); + m_currentPad->SetLocalClearance( m_padMaster->GetLocalClearance() ); + m_currentPad->SetLocalSolderMaskMargin( m_padMaster->GetLocalSolderMaskMargin() ); + m_currentPad->SetLocalSolderPasteMargin( m_padMaster->GetLocalSolderPasteMargin() ); + m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster->GetLocalSolderPasteMarginRatio() ); + m_currentPad->SetZoneConnection( m_padMaster->GetZoneConnection() ); + m_currentPad->SetThermalWidth( m_padMaster->GetThermalWidth() ); + m_currentPad->SetThermalGap( m_padMaster->GetThermalGap() ); module->CalculateBoundingBox(); m_parent->SetMsgPanel( m_currentPad ); @@ -984,6 +1003,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) // Check if user has set an existing net name const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() ); + if( netinfo != NULL ) aPad->SetNetCode( netinfo->GetNet() ); else diff --git a/pcbnew/dialogs/dialog_set_grid.cpp b/pcbnew/dialogs/dialog_set_grid.cpp index d60e152805..689b803699 100644 --- a/pcbnew/dialogs/dialog_set_grid.cpp +++ b/pcbnew/dialogs/dialog_set_grid.cpp @@ -211,7 +211,7 @@ bool PCB_BASE_FRAME::InvokeDialogGrid() if( ret == wxID_OK ) { - if( GetGridOrigin() != grid_origin && IsType( PCB_FRAME_TYPE ) ) + if( GetGridOrigin() != grid_origin && IsType( FRAME_PCB ) ) OnModify(); // because grid origin is saved in board, show as modified SetGridOrigin( grid_origin ); diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index dc875e47fc..b32ddb65b4 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -609,7 +609,7 @@ void DRC::testKeepoutAreas() if( ! area->GetDoNotAllowVias() ) continue; - if( ! ((SEGVIA*)segm)->IsOnLayer( area->GetLayer() ) ) + if( ! ((VIA*)segm)->IsOnLayer( area->GetLayer() ) ) continue; if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 ) @@ -658,7 +658,7 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( ! area->GetDoNotAllowVias() ) continue; - if( ! ((SEGVIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) ) + if( ! ((VIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) ) continue; if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 ) diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index 0550f6cfa2..04394d2d08 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -169,21 +169,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // Phase 0 : Test vias if( aRefSeg->Type() == PCB_VIA_T ) { + const VIA *refvia = static_cast( aRefSeg ); // test if the via size is smaller than minimum - if( aRefSeg->GetShape() == VIA_MICROVIA ) + if( refvia->GetViaType() == VIA_MICROVIA ) { - if( aRefSeg->GetWidth() < netclass->GetuViaMinDiameter() ) + if( refvia->GetWidth() < netclass->GetuViaMinDiameter() ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_TOO_SMALL_MICROVIA, m_currentMarker ); return false; } } else { - if( aRefSeg->GetWidth() < netclass->GetViaMinDiameter() ) + if( refvia->GetWidth() < netclass->GetViaMinDiameter() ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_TOO_SMALL_VIA, m_currentMarker ); return false; } @@ -192,9 +193,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // test if via's hole is bigger than its diameter // This test is necessary since the via hole size and width can be modified // and a default via hole can be bigger than some vias sizes - if( aRefSeg->GetDrillValue() > aRefSeg->GetWidth() ) + if( refvia->GetDrillValue() > refvia->GetWidth() ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_VIA_HOLE_BIGGER, m_currentMarker ); return false; } @@ -202,12 +203,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // For microvias: test if they are blind vias and only between 2 layers // because they are used for very small drill size and are drill by laser // and **only one layer** can be drilled - if( aRefSeg->GetShape() == VIA_MICROVIA ) + if( refvia->GetViaType() == VIA_MICROVIA ) { LAYER_NUM layer1, layer2; bool err = true; - ( (SEGVIA*) aRefSeg )->LayerPair( &layer1, &layer2 ); + refvia->LayerPair( &layer1, &layer2 ); if( layer1 > layer2 ) EXCHG( layer1, layer2 ); @@ -222,7 +223,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( err ) { - m_currentMarker = fillMarker( aRefSeg, NULL, + m_currentMarker = fillMarker( refvia, NULL, DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker ); return false; } diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp index a069acaaa4..3e4124164b 100644 --- a/pcbnew/drc_marker_functions.cpp +++ b/pcbnew/drc_marker_functions.cpp @@ -44,7 +44,8 @@ #include -MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ) +MARKER_PCB* DRC::fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, + MARKER_PCB* fillMe ) { wxString textA = aTrack->GetSelectMenuText(); wxString textB; @@ -62,7 +63,7 @@ MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, M } else if( aItem->Type() == PCB_VIA_T ) { - posB = position = ((SEGVIA*)aItem)->GetPosition(); + posB = position = ((VIA*)aItem)->GetPosition(); } else if( aItem->Type() == PCB_TRACE_T ) { diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h index f2daee5b95..927e94936a 100644 --- a/pcbnew/drc_stuff.h +++ b/pcbnew/drc_stuff.h @@ -212,14 +212,14 @@ private: * DRC problem, or unconnected pad problem. * * @param aTrack The reference track. - * @param aItem Another item on the BOARD, such as a SEGVIA, SEGZONE, + * @param aItem Another item on the BOARD, such as a VIA, SEGZONE, * or TRACK. * @param aErrorCode A categorizing identifier for the particular type * of error that is being reported. * @param fillMe A MARKER_PCB* which is to be filled in, or NULL if one is to * first be allocated, then filled. */ - MARKER_PCB* fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ); + MARKER_PCB* fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER_PCB* fillMe ); MARKER_PCB* fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PCB* fillMe ); diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index f8e31fddec..a78007761b 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -2410,9 +2410,9 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) if( IsCopperLayer( layer_front_most ) && IsCopperLayer( layer_back_most ) ) { - int kidiam; - int drillz = kicad( v.drill ); - SEGVIA* via = new SEGVIA( m_board ); + int kidiam; + int drillz = kicad( v.drill ); + VIA* via = new VIA( m_board ); m_board->m_Track.Insert( via, NULL ); via->SetLayerPair( layer_front_most, layer_back_most ); @@ -2439,11 +2439,11 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) m_min_via_hole = drillz; if( layer_front_most == LAYER_N_FRONT && layer_back_most == LAYER_N_BACK ) - via->SetShape( VIA_THROUGH ); + via->SetViaType( VIA_THROUGH ); else if( layer_front_most == LAYER_N_FRONT || layer_back_most == LAYER_N_BACK ) - via->SetShape( VIA_MICROVIA ); + via->SetViaType( VIA_MICROVIA ); else - via->SetShape( VIA_BLIND_BURIED ); + via->SetViaType( VIA_BLIND_BURIED ); via->SetTimeStamp( timeStamp( it->second ) ); @@ -2453,8 +2453,6 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) via->SetEnd( pos ); via->SetNetCode( netCode ); - - via->SetShape( S_CIRCLE ); // @todo should be in SEGVIA constructor } m_xpath->pop(); } diff --git a/pcbnew/edgemod.cpp b/pcbnew/edgemod.cpp index 7239dc37a8..77019494f2 100644 --- a/pcbnew/edgemod.cpp +++ b/pcbnew/edgemod.cpp @@ -169,12 +169,11 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge ) { aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems(); - for( ; aEdge != NULL; aEdge = aEdge->Next() ) + for( BOARD_ITEM *item = module->GraphicalItems(); item; item = item->Next() ) { - if( aEdge->Type() != PCB_MODULE_EDGE_T ) - continue; - - aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); + aEdge = dynamic_cast( item ); + if( aEdge ) + aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); } } else @@ -216,14 +215,12 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge ) if( aEdge == NULL ) { - aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems(); - - for( ; aEdge != NULL; aEdge = aEdge->Next() ) + for( BOARD_ITEM *item = module->GraphicalItems() ; item != NULL; + item = item->Next() ) { - if( aEdge->Type() != PCB_MODULE_EDGE_T ) - continue; + aEdge = dynamic_cast( item ); - if( aEdge->GetLayer() != new_layer ) + if( aEdge && (aEdge->GetLayer() != new_layer) ) { if( ! modified ) // save only once SaveCopyInUndoList( module, UR_MODEDIT ); diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 3aad9dc78f..71e6a53c53 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -197,7 +197,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) if( !editor ) { - editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); editor->Show( true ); editor->Zoom_Automatique( false ); @@ -223,7 +225,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) if( !viewer ) { - viewer = (FOOTPRINT_VIEWER_FRAME*) Kiface().CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() ); viewer->Show( true ); viewer->Zoom_Automatique( false ); @@ -393,14 +397,23 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) } else { - int v_type = GetDesignSettings().m_CurrentViaType; - if( id == ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA || - id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA ) - GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED; - else if( id == ID_POPUP_PCB_PLACE_MICROVIA ) - GetDesignSettings().m_CurrentViaType = VIA_MICROVIA; - else - GetDesignSettings().m_CurrentViaType = VIA_THROUGH; + BOARD_DESIGN_SETTINGS &settings = GetDesignSettings(); + VIATYPE_T v_type = settings.m_CurrentViaType; + switch( id ) + { + case ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA: + case ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA: + settings.m_CurrentViaType = VIA_BLIND_BURIED; + break; + + case ID_POPUP_PCB_PLACE_MICROVIA: + settings.m_CurrentViaType = VIA_MICROVIA; + break; + + default: + settings.m_CurrentViaType = VIA_THROUGH; + break; + } // place via and switch layer. if( id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA || @@ -425,7 +438,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) else Other_Layer_Route( (TRACK*) GetCurItem(), &dc ); - GetDesignSettings().m_CurrentViaType = v_type; + settings.m_CurrentViaType = v_type; if( DisplayOpt.ContrastModeDisplay ) m_canvas->Refresh(); @@ -842,7 +855,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) if( !editor ) { - editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); } editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() ); diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index 4c2d5e8327..c371ee0978 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -47,8 +47,10 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, if( aTrackItem->Type() == PCB_VIA_T ) { - if( !aTrackItem->IsDrillDefault() ) - initial_drill = aTrackItem->GetDrillValue(); + const VIA *via = static_cast( aTrackItem ); + + if( !via->IsDrillDefault() ) + initial_drill = via->GetDrillValue(); if( net ) { @@ -60,7 +62,7 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, new_drill = GetBoard()->GetCurrentViaDrill(); } - if( aTrackItem->GetShape() == VIA_MICROVIA ) + if( via->GetViaType() == VIA_MICROVIA ) { if( net ) new_width = net->GetMicroViaSize(); @@ -107,10 +109,11 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, if( aTrackItem->Type() == PCB_VIA_T ) { // Set new drill value. Note: currently microvias have only a default drill value + VIA *via = static_cast( aTrackItem ); if( new_drill > 0 ) - aTrackItem->SetDrill( new_drill ); + via->SetDrill( new_drill ); else - aTrackItem->SetDrillDefault(); + via->SetDrillDefault(); } } } diff --git a/pcbnew/editmod.cpp b/pcbnew/editmod.cpp index 7eed255d4c..49325bc1eb 100644 --- a/pcbnew/editmod.cpp +++ b/pcbnew/editmod.cpp @@ -78,7 +78,9 @@ void PCB_EDIT_FRAME::InstallModuleOptionsFrame( MODULE* Module, wxDC* DC ) if( !editor ) { - editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() ); } editor->Load_Module_From_BOARD( Module ); diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index 528d96988a..ef7ed1642f 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -95,9 +95,9 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // create the via - SEGVIA* via = new SEGVIA( GetBoard() ); + VIA* via = new VIA( GetBoard() ); via->SetFlags( IS_NEW ); - via->SetShape( GetDesignSettings().m_CurrentViaType ); + via->SetViaType( GetDesignSettings().m_CurrentViaType ); via->SetWidth( GetBoard()->GetCurrentViaSize()); via->SetNetCode( GetBoard()->GetHighLightNetCode() ); via->SetEnd( g_CurrentTrackSegment->GetEnd() ); @@ -118,7 +118,7 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) last_layer = GetScreen()->m_Route_Layer_BOTTOM; // Adjust the actual via layer pair - switch ( via->GetShape() ) + switch ( via->GetViaType() ) { case VIA_BLIND_BURIED: via->SetLayerPair( first_layer, last_layer ); diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 41cc2d7e30..220668148c 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -62,9 +62,9 @@ static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC ) { PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent(); BOARD* pcb = frame->GetBoard(); - TRACK* track = (TRACK*) frame->GetCurItem(); + TRACK* track = dynamic_cast( frame->GetCurItem() ); - if( track && ( track->Type()==PCB_VIA_T || track->Type()==PCB_TRACE_T ) ) + if( track ) { // Erase the current drawing ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false ); @@ -266,7 +266,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) newTrack->SetState( BEGIN_ONPAD | END_ONPAD, false ); - D_PAD* pad = GetBoard()->GetPad( previousTrack, FLG_END ); + D_PAD* pad = GetBoard()->GetPad( previousTrack, ENDPOINT_END ); if( pad ) { @@ -1057,7 +1057,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST& aTrackList ) while( track != NULL ) { TRACK* next_track = track->Next(); - LockPoint = pcb->GetPad( track, FLG_END ); + LockPoint = pcb->GetPad( track, ENDPOINT_END ); if( LockPoint ) { diff --git a/pcbnew/edtxtmod.cpp b/pcbnew/edtxtmod.cpp index d180cd00cd..78c1f40d30 100644 --- a/pcbnew/edtxtmod.cpp +++ b/pcbnew/edtxtmod.cpp @@ -108,7 +108,7 @@ void PCB_BASE_FRAME::RotateTextModule( TEXTE_MODULE* Text, wxDC* DC ) if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command { - if( IsType( PCB_FRAME_TYPE ) ) + if( IsType( FRAME_PCB ) ) SaveCopyInUndoList( module, UR_CHANGED ); } @@ -236,7 +236,7 @@ void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC ) double tmp = Text->GetOrientation(); Text->SetOrientation( TextInitialOrientation ); - if( IsType( PCB_FRAME_TYPE ) ) + if( IsType( FRAME_PCB ) ) SaveCopyInUndoList( Module, UR_CHANGED ); else SaveCopyInUndoList( Module, UR_MODEDIT ); diff --git a/pcbnew/exporters/export_d356.cpp b/pcbnew/exporters/export_d356.cpp index 865986acc9..f75dfbdeba 100644 --- a/pcbnew/exporters/export_d356.cpp +++ b/pcbnew/exporters/export_d356.cpp @@ -198,23 +198,23 @@ static void build_via_testpoints( BOARD *aPcb, { if( track->Type() == PCB_VIA_T ) { - SEGVIA *via = (SEGVIA*) track; - NETINFO_ITEM *net = track->GetNet(); + VIA *via = (VIA*) track; + NETINFO_ITEM *net = track->GetNet(); D356_RECORD rk; - rk.smd = false; + rk.smd = false; rk.hole = true; - if( net ) - rk.netname = net->GetNetname(); - else - rk.netname = wxEmptyString; + if( net ) + rk.netname = net->GetNetname(); + else + rk.netname = wxEmptyString; rk.refdes = wxT("VIA"); rk.pin = wxT(""); rk.midpoint = true; // Vias are always midpoints rk.drill = via->GetDrillValue(); rk.mechanical = false; LAYER_NUM top_layer, bottom_layer; - via->LayerPair( &top_layer, &bottom_layer ); + via->LayerPair( &top_layer, &bottom_layer ); rk.access = via_access_code( aPcb, top_layer, bottom_layer ); rk.x_location = via->GetPosition().x - origin.x; rk.y_location = origin.y - via->GetPosition().y; diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index 8ef7e19214..c1895cbc7b 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -222,8 +222,8 @@ static int PadListSortByShape( const void* aRefptr, const void* aObjptr ) // Sort vias for uniqueness static int ViaSort( const void* aRefptr, const void* aObjptr ) { - TRACK* padref = *(TRACK**) aRefptr; - TRACK* padcmp = *(TRACK**) aObjptr; + VIA* padref = *(VIA**) aRefptr; + VIA* padcmp = *(VIA**) aObjptr; if( padref->GetWidth() != padcmp->GetWidth() ) return padref->GetWidth() - padcmp->GetWidth(); @@ -253,8 +253,8 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) { std::vector pads; std::vector padstacks; - std::vector vias; - std::vector viastacks; + std::vector vias; + std::vector viastacks; padstacks.resize( 1 ); // We count pads from 1 // The master layermask (i.e. the enabled layers) for padstack generation @@ -271,21 +271,19 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) } // The same for vias - for( TRACK* track = aPcb->m_Track; track != NULL; track = track->Next() ) + for( VIA* via = GetFirstVia( aPcb->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) { - if( track->Type() == PCB_VIA_T ) - { - vias.push_back( track ); - } + vias.push_back( via ); } - qsort( &vias[0], vias.size(), sizeof(TRACK*), ViaSort ); + qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort ); // Emit vias pads TRACK* old_via = 0; for( unsigned i = 0; i < vias.size(); i++ ) { - TRACK* via = vias[i]; + VIA* via = vias[i]; if( old_via && 0 == ViaSort( &old_via, &via ) ) continue; @@ -433,7 +431,7 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) // Via padstacks for( unsigned i = 0; i < viastacks.size(); i++ ) { - TRACK* via = viastacks[i]; + VIA* via = viastacks[i]; LAYER_MSK mask = via->GetLayerMask() & master_layermask; fprintf( aFile, "PADSTACK VIA%d.%d.%X %g\n", via->GetWidth(), via->GetDrillValue(), mask, @@ -832,11 +830,12 @@ static void CreateRoutesSection( FILE* aFile, BOARD* aPcb ) } if( track->Type() == PCB_VIA_T ) { + const VIA *via = static_cast(track); fprintf( aFile, "VIA VIA%d.%d.%X %g %g ALL %g via%d\n", - track->GetWidth(), track->GetDrillValue(), - track->GetLayerMask() & master_layermask, - MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ), - track->GetDrillValue() / SCALE_FACTOR, vianum++ ); + via->GetWidth(), via->GetDrillValue(), + via->GetLayerMask() & master_layermask, + MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ), + via->GetDrillValue() / SCALE_FACTOR, vianum++ ); } } diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index ae1b37c194..2522e813e2 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -600,38 +600,36 @@ static void export_vrml_pcbtext( MODEL_VRML& aModel, TEXTE_PCB* text ) if( text->IsMirrored() ) NEGATE( size.x ); + EDA_COLOR_T color = BLACK; // not actually used, but needed by DrawGraphicText + if( text->IsMultilineAllowed() ) { - wxPoint pos = text->GetTextPosition(); wxArrayString* list = wxStringSplit( text->GetText(), '\n' ); - wxPoint offset; + std::vector positions; + positions.reserve( list->Count() ); + text->GetPositionsOfLinesOfMultilineText( positions, list->Count() ); - offset.y = text->GetInterline(); - - RotatePoint( &offset, text->GetOrientation() ); - - for( unsigned i = 0; iCount(); i++ ) + for( unsigned ii = 0; ii < list->Count(); ii++ ) { - wxString txt = list->Item( i ); - DrawGraphicText( NULL, NULL, pos, BLACK, - txt, text->GetOrientation(), size, - text->GetHorizJustify(), text->GetVertJustify(), - text->GetThickness(), text->IsItalic(), - true, - vrml_text_callback ); - pos += offset; + wxString txt = list->Item( ii ); + DrawGraphicText( NULL, NULL, positions[ii], color, + txt, text->GetOrientation(), size, + text->GetHorizJustify(), text->GetVertJustify(), + text->GetThickness(), text->IsItalic(), + true, + vrml_text_callback ); } delete (list); } else { - DrawGraphicText( NULL, NULL, text->GetTextPosition(), BLACK, - text->GetText(), text->GetOrientation(), size, - text->GetHorizJustify(), text->GetVertJustify(), - text->GetThickness(), text->IsItalic(), - true, - vrml_text_callback ); + DrawGraphicText( NULL, NULL, text->GetTextPosition(), color, + text->GetText(), text->GetOrientation(), size, + text->GetHorizJustify(), text->GetVertJustify(), + text->GetThickness(), text->IsItalic(), + true, + vrml_text_callback ); } } @@ -803,7 +801,7 @@ static void export_round_padstack( MODEL_VRML& aModel, BOARD* pcb, } -static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, SEGVIA* via ) +static void export_vrml_via( MODEL_VRML& aModel, BOARD* pcb, const VIA* via ) { double x, y, r, hole; LAYER_NUM top_layer, bottom_layer; @@ -829,7 +827,7 @@ static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb ) { if( track->Type() == PCB_VIA_T ) { - export_vrml_via( aModel, pcb, (SEGVIA*) track ); + export_vrml_via( aModel, pcb, (const VIA*) track ); } else if( track->GetLayer() == FIRST_COPPER_LAYER || track->GetLayer() == LAST_COPPER_LAYER ) diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index 8a3413db1f..679df5bed1 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -453,12 +453,9 @@ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, // build hole list for vias if( ! aGenerateNPTH_list ) // vias are always plated ! { - for( TRACK* track = m_pcb->m_Track; track; track = track->Next() ) + for( VIA* via = GetFirstVia( m_pcb->m_Track ); via; + via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - SEGVIA* via = (SEGVIA*) track; hole_value = via->GetDrillValue(); if( hole_value == 0 ) diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index a5d5a5a325..b09623f074 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -121,7 +121,7 @@ static wxAcceleratorEntry accels[] = FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, FOOTPRINT_EDIT_FRAME* aParent, wxSemaphore* semaphore, long style ) : - PCB_BASE_FRAME( aKiway, aParent, FOOTPRINT_WIZARD_FRAME_TYPE, + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_FOOTPRINT_WIZARD, _( "Footprint Wizard" ), wxDefaultPosition, wxDefaultSize, style, FOOTPRINT_WIZARD_FRAME_NAME ) { diff --git a/pcbnew/github/CMakeLists.txt b/pcbnew/github/CMakeLists.txt index 34bf3c9cef..48596231ae 100644 --- a/pcbnew/github/CMakeLists.txt +++ b/pcbnew/github/CMakeLists.txt @@ -54,9 +54,7 @@ set( GITHUB_PLUGIN_SRCS github_plugin.cpp ) -add_library( github_plugin - github_plugin.cpp - ) +add_library( github_plugin STATIC ${GITHUB_PLUGIN_SRCS} ) # No, you don't get github without boost and openssl. Boost_LIBRARIES now moved up # into CMakeLists.txt for pcbnew and cvpcb: diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 07b80aef42..d74f077774 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1342,7 +1342,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const { LAYER_NUM layer1, layer2; - SEGVIA* via = (SEGVIA*) aTrack; + const VIA* via = static_cast(aTrack); BOARD* board = (BOARD*) via->GetParent(); wxCHECK_RET( board != 0, wxT( "Via " ) + via->GetSelectMenuText() + @@ -1352,7 +1352,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const via->LayerPair( &layer1, &layer2 ); - switch( aTrack->GetShape() ) + switch( via->GetViaType() ) { case VIA_THROUGH: // Default shape not saved. break; @@ -1366,15 +1366,15 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const break; default: - THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), aTrack->GetShape() ) ); + THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), via->GetViaType() ) ); } m_out->Print( 0, " (at %s) (size %s)", FMT_IU( aTrack->GetStart() ).c_str(), FMT_IU( aTrack->GetWidth() ).c_str() ); - if( aTrack->GetDrill() != UNDEFINED_DRILL_DIAMETER ) - m_out->Print( 0, " (drill %s)", FMT_IU( aTrack->GetDrill() ).c_str() ); + if( via->GetDrill() != UNDEFINED_DRILL_DIAMETER ) + m_out->Print( 0, " (drill %s)", FMT_IU( via->GetDrill() ).c_str() ); m_out->Print( 0, " (layers %s %s)", m_out->Quotew( m_board->GetLayerName( layer1 ) ).c_str(), diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index d0a6460563..d94852db4c 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -1998,7 +1998,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) assert( TESTLINE( "Po" ) ); - int shape = intParse( line + SZ( "Po" ), &data ); + VIATYPE_T viatype = static_cast( intParse( line + SZ( "Po" ), &data )); BIU start_x = biuParse( data, &data ); BIU start_y = biuParse( data, &data ); BIU end_x = biuParse( data, &data ); @@ -2059,7 +2059,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) break; case PCB_VIA_T: - newTrack = new SEGVIA( m_board ); + newTrack = new VIA( m_board ); m_board->m_Track.Append( newTrack ); break; @@ -2075,19 +2075,20 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType ) newTrack->SetEnd( wxPoint( end_x, end_y ) ); newTrack->SetWidth( width ); - newTrack->SetShape( shape ); - - if( drill < 0 ) - newTrack->SetDrillDefault(); - else - newTrack->SetDrill( drill ); - newTrack->SetLayer( layer ); if( makeType == PCB_VIA_T ) // Ensure layers are OK when possible: { - if( newTrack->GetShape() == VIA_THROUGH ) - ( (SEGVIA*) newTrack )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); + VIA *via = static_cast( newTrack ); + via->SetViaType( viatype ); + + if( drill < 0 ) + via->SetDrillDefault(); + else + via->SetDrill( drill ); + + if( via->GetViaType() == VIA_THROUGH ) + via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); } newTrack->SetNetCode( net_code ); @@ -3612,17 +3613,24 @@ void LEGACY_PLUGIN::savePCB_LINE( const DRAWSEGMENT* me ) const void LEGACY_PLUGIN::saveTRACK( const TRACK* me ) const { int type = 0; + VIATYPE_T viatype = VIA_NOT_DEFINED; + int drill = UNDEFINED_DRILL_DIAMETER; if( me->Type() == PCB_VIA_T ) + { + const VIA *via = static_cast(me); type = 1; + viatype = via->GetViaType(); + drill = via->GetDrill(); + } fprintf(m_fp, "Po %d %s %s %s %s\n", - me->GetShape(), + viatype, fmtBIUPoint( me->GetStart() ).c_str(), fmtBIUPoint( me->GetEnd() ).c_str(), fmtBIU( me->GetWidth() ).c_str(), - me->GetDrill() == UNDEFINED_DRILL_DIAMETER ? - "-1" : fmtBIU( me->GetDrill() ).c_str() ); + drill == UNDEFINED_DRILL_DIAMETER ? + "-1" : fmtBIU( drill ).c_str() ); fprintf(m_fp, "De %d %d %d %lX %X\n", me->GetLayer(), type, me->GetNetCode(), diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 2db1223087..6c324b4d65 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -87,23 +87,28 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) aModule = newModule; - GetBoard()->Add( aModule ); + GetBoard()->Add( newModule ); - aModule->ClearFlags(); + newModule->ClearFlags(); - GetBoard()->BuildListOfNets(); + // Clear references to net info, because the footprint editor + // does know any thing about nets handled by the current edited board. + // Morever the main board can change or the net info relative to this main board + // can change while editing this footprint in the footprint editor + for( D_PAD* pad = newModule->Pads(); pad; pad = pad->Next() ) + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); SetCrossHairPosition( wxPoint( 0, 0 ) ); - PlaceModule( aModule, NULL ); + PlaceModule( newModule, NULL ); // Put it on FRONT layer, // because this is the default in ModEdit, and in libs - if( aModule->GetLayer() != LAYER_N_FRONT ) - aModule->Flip( aModule->GetPosition() ); + if( newModule->GetLayer() != LAYER_N_FRONT ) + newModule->Flip( newModule->GetPosition() ); // Put it in orientation 0, // because this is the default orientation in ModEdit, and in libs - Rotate_Module( NULL, aModule, 0, false ); + Rotate_Module( NULL, newModule, 0, false ); GetScreen()->ClrModify(); Zoom_Automatique( false ); diff --git a/pcbnew/magnetic_tracks_functions.cpp b/pcbnew/magnetic_tracks_functions.cpp index 5c84d0d6d8..1c901cf760 100644 --- a/pcbnew/magnetic_tracks_functions.cpp +++ b/pcbnew/magnetic_tracks_functions.cpp @@ -193,7 +193,7 @@ bool Magnetize( PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize, { LAYER_MSK layer_mask = GetLayerMask( layer ); - TRACK* track = m_Pcb->GetTrace( m_Pcb->m_Track, pos, layer_mask ); + TRACK* track = m_Pcb->GetTrack( m_Pcb->m_Track, pos, layer_mask ); if( !track || track->Type() != PCB_TRACE_T ) { diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index fd61c9cba4..11aa831c27 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -39,9 +39,6 @@ #include #include -/** - * Pcbnew mainframe menubar - */ void PCB_EDIT_FRAME::ReCreateMenuBar() { wxString text; @@ -49,7 +46,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() wxFileHistory& fhist = Kiface().GetFileHistory(); - if( ! menuBar ) + if( !menuBar ) menuBar = new wxMenuBar(); // Delete all existing menus so they can be rebuilt. @@ -64,17 +61,18 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() // Create File Menu wxMenu* filesMenu = new wxMenu; - // New - AddMenuItem( filesMenu, ID_NEW_BOARD, - _( "&New" ), - _( "Clear current board and initialize a new one" ), - KiBitmap( new_pcb_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( filesMenu, ID_NEW_BOARD, + _( "&New" ), + _( "Clear current board and initialize a new one" ), + KiBitmap( new_pcb_xpm ) ); - // Open - text = AddHotkeyName( _( "&Open" ), g_Board_Editor_Hokeys_Descr, HK_LOAD_BOARD ); - AddMenuItem( filesMenu, ID_LOAD_FILE, text, - _( "Delete current board and load new board" ), - KiBitmap( open_brd_file_xpm ) ); + text = AddHotkeyName( _( "&Open" ), g_Board_Editor_Hokeys_Descr, HK_LOAD_BOARD ); + AddMenuItem( filesMenu, ID_LOAD_FILE, text, + _( "Delete current board and load new board" ), + KiBitmap( open_brd_file_xpm ) ); + } // Load Recent submenu static wxMenu* openRecentMenu; @@ -89,44 +87,46 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() fhist.UseMenu( openRecentMenu ); fhist.AddFilesToMenu(); - AddMenuItem( filesMenu, openRecentMenu, - -1, _( "Open &Recent" ), - _( "Open a recent opened board" ), - KiBitmap( open_project_xpm ) ); + if( Kiface().IsSingle() ) // not when under a project mgr + { + AddMenuItem( filesMenu, openRecentMenu, + -1, _( "Open &Recent" ), + _( "Open a recent opened board" ), + KiBitmap( open_project_xpm ) ); + } - // Pcbnew Board AddMenuItem( filesMenu, ID_APPEND_FILE, _( "&Append Board" ), _( "Append another Pcbnew board to the current loaded board" ), KiBitmap( import_xpm ) ); filesMenu->AppendSeparator(); - // Save text = AddHotkeyName( _( "&Save" ), g_Board_Editor_Hokeys_Descr, HK_SAVE_BOARD ); AddMenuItem( filesMenu, ID_SAVE_BOARD, text, _( "Save current board" ), KiBitmap( save_xpm ) ); - // Save As - text = AddHotkeyName( _( "Sa&ve As..." ), g_Board_Editor_Hokeys_Descr, HK_SAVE_BOARD_AS ); - AddMenuItem( filesMenu, ID_SAVE_BOARD_AS, text, - _( "Save the current board as..." ), - KiBitmap( save_as_xpm ) ); - filesMenu->AppendSeparator(); + if( Kiface().IsSingle() ) // not when under a project mgr + { + text = AddHotkeyName( _( "Sa&ve As..." ), g_Board_Editor_Hokeys_Descr, HK_SAVE_BOARD_AS ); + AddMenuItem( filesMenu, ID_SAVE_BOARD_AS, text, + _( "Save the current board as..." ), + KiBitmap( save_as_xpm ) ); + filesMenu->AppendSeparator(); + } - // Revert AddMenuItem( filesMenu, ID_MENU_READ_BOARD_BACKUP_FILE, _( "Revert to Last" ), _( "Clear board and get previous backup version of board" ), KiBitmap( help_xpm ) ); - // Rescue - AddMenuItem( filesMenu, ID_MENU_RECOVER_BOARD_AUTOSAVE, _( "Rescue" ), - _( "Clear board and get last rescue file automatically saved by Pcbnew" ), - KiBitmap( help_xpm ) ); + AddMenuItem( filesMenu, ID_MENU_RECOVER_BOARD_AUTOSAVE, + _( "Rescue" ), + _( "Clear board and get last rescue file automatically saved by Pcbnew" ), + KiBitmap( help_xpm ) ); filesMenu->AppendSeparator(); - /* Fabrication Outputs submenu */ + //----- Fabrication Outputs submenu ----------------------------------------- wxMenu* fabricationOutputsMenu = new wxMenu; AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_POS_MODULES_FILE, _( "&Modules Position (.pos) File" ), @@ -138,40 +138,34 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Generate excellon2 drill file" ), KiBitmap( post_drill_xpm ) ); - // Module Report AddMenuItem( fabricationOutputsMenu, ID_GEN_EXPORT_FILE_MODULE_REPORT, _( "&Module (.rpt) Report" ), _( "Create a report of all modules on the current board" ), KiBitmap( tools_xpm ) ); AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_D356_FILE, - _( "IPC-D-356 Netlist File" ), - _( "Generate IPC-D-356 netlist file" ), - KiBitmap( netlist_xpm ) ); + _( "IPC-D-356 Netlist File" ), + _( "Generate IPC-D-356 netlist file" ), + KiBitmap( netlist_xpm ) ); - // Component File AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_CMP_FILE, _( "&Component (.cmp) File" ), _( "(Re)create components file (*.cmp) for CvPcb" ), KiBitmap( create_cmp_file_xpm ) ); - // BOM File AddMenuItem( fabricationOutputsMenu, ID_PCB_GEN_BOM_FILE_FROM_BOARD, _( "&BOM File" ), _( "Create a bill of materials from schematic" ), KiBitmap( bom_xpm ) ); - // Fabrications Outputs submenu append AddMenuItem( filesMenu, fabricationOutputsMenu, -1, _( "&Fabrication Outputs" ), _( "Generate files for fabrication" ), KiBitmap( fabrication_xpm ) ); - - /** Import submenu **/ + //----- Import submenu ------------------------------------------------------ wxMenu* submenuImport = new wxMenu(); - // Specctra Session AddMenuItem( submenuImport, ID_GEN_IMPORT_SPECCTRA_SESSION, _( "&Specctra Session" ), _( "Import a routed \"Specctra Session\" (*.ses) file" ), @@ -187,27 +181,23 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Import files" ), KiBitmap( import_xpm ) ); - /** Export submenu **/ + //----- Export submenu ------------------------------------------------------ wxMenu* submenuexport = new wxMenu(); - // Specctra DSN AddMenuItem( submenuexport, ID_GEN_EXPORT_SPECCTRA, _( "&Specctra DSN" ), _( "Export the current board to a \"Specctra DSN\" file" ), KiBitmap( export_dsn_xpm ) ); - // GenCAD AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_GENCADFORMAT, _( "&GenCAD" ), _( "Export GenCAD format" ), KiBitmap( export_xpm ) ); - // VRML AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_VRML, _( "&VRML" ), _( "Export a VRML board representation" ), KiBitmap( three_d_xpm ) ); - // IDF3 AddMenuItem( submenuexport, ID_GEN_EXPORT_FILE_IDF3, _( "I&DFv3 Export" ), _( "IDFv3 board and component export" ), KiBitmap( export_idf_xpm ) ); @@ -218,24 +208,20 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() filesMenu->AppendSeparator(); - // Page settings AddMenuItem( filesMenu, ID_SHEET_SET, _( "Page s&ettings" ), _( "Page settings for paper size and texts" ), KiBitmap( sheetset_xpm ) ); - // Print AddMenuItem( filesMenu, wxID_PRINT, _( "&Print" ), _( "Print board" ), KiBitmap( print_button_xpm ) ); - // Create SVG file AddMenuItem( filesMenu, ID_GEN_PLOT_SVG, _( "Export SV&G" ), _( "Export a board file in Scalable Vector Graphics format" ), KiBitmap( plot_svg_xpm ) ); - // Plot AddMenuItem( filesMenu, ID_GEN_PLOT, _( "P&lot" ), _( "Plot board in HPGL, PostScript or Gerber RS-274X format)" ), @@ -243,15 +229,14 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() filesMenu->AppendSeparator(); + //----- archive submenu ----------------------------------------------------- wxMenu* submenuarchive = new wxMenu(); - // Archive New Footprints AddMenuItem( submenuarchive, ID_MENU_ARCHIVE_NEW_MODULES, _( "&Archive New Footprints" ), _( "Archive new footprints only in a library (keep other footprints in this lib)" ), KiBitmap( library_update_xpm ) ); - // Create FootPrint Archive AddMenuItem( submenuarchive, ID_MENU_ARCHIVE_ALL_MODULES, _( "&Create Footprint Archive" ), _( "Archive all footprints in a library (old library will be deleted)" ), @@ -263,60 +248,51 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Archive or add footprints in a library file" ), KiBitmap( library_xpm ) ); - // Quit filesMenu->AppendSeparator(); AddMenuItem( filesMenu, wxID_EXIT, _( "&Quit" ), _( "Quit Pcbnew" ), KiBitmap( exit_xpm ) ); - /** Create Edit menu **/ + //----- Edit menu ----------------------------------------------------------- wxMenu* editMenu = new wxMenu; - // Undo text = AddHotkeyName( _( "&Undo" ), g_Pcbnew_Editor_Hokeys_Descr, HK_UNDO ); AddMenuItem( editMenu, wxID_UNDO, text, HELP_UNDO, KiBitmap( undo_xpm ) ); - // Redo text = AddHotkeyName( _( "&Redo" ), g_Pcbnew_Editor_Hokeys_Descr, HK_REDO ); AddMenuItem( editMenu, wxID_REDO, text, HELP_REDO, KiBitmap( redo_xpm ) ); - // Delete AddMenuItem( editMenu, ID_PCB_DELETE_ITEM_BUTT, _( "&Delete" ), _( "Delete items" ), KiBitmap( delete_xpm ) ); editMenu->AppendSeparator(); - // Find text = AddHotkeyName( _( "&Find" ), g_Pcbnew_Editor_Hokeys_Descr, HK_FIND_ITEM ); AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND , KiBitmap( find_xpm ) ); editMenu->AppendSeparator(); - // Global Deletions AddMenuItem( editMenu, ID_PCB_GLOBAL_DELETE, _( "&Global Deletions" ), _( "Delete tracks, modules, texts... on board" ), KiBitmap( general_deletions_xpm ) ); - // Cleanup Tracks and Vias AddMenuItem( editMenu, ID_MENU_PCB_CLEAN, _( "&Cleanup Tracks and Vias" ), _( "Clean stubs, vias, delete break points, or connect dangling tracks to pads and vias" ), KiBitmap( delete_xpm ) ); - // Swap Layers AddMenuItem( editMenu, ID_MENU_PCB_SWAP_LAYERS, _( "&Swap Layers" ), _( "Swap tracks on copper layers or drawings on other layers" ), KiBitmap( swap_layer_xpm ) ); - // Reset module reference sizes AddMenuItem( editMenu, ID_MENU_PCB_RESET_TEXTMODULE_FIELDS_SIZES, _( "&Reset Module Field Sizes" ), _( "Reset text size and width of all module fields to current defaults" ), KiBitmap( reset_text_xpm ) ); - /** Create View menu **/ + //----- View menu ----------------------------------------------------------- wxMenu* viewMenu = new wxMenu; /* Important Note for ZOOM IN and ZOOM OUT commands from menubar: @@ -330,43 +306,34 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() * in other words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators * for Zoom in and Zoom out sub menus */ - // Zoom In text = AddHotkeyName( _( "Zoom &In" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_IN, IS_ACCELERATOR ); AddMenuItem( viewMenu, ID_ZOOM_IN, text, HELP_ZOOM_IN, KiBitmap( zoom_in_xpm ) ); - // Zoom Out text = AddHotkeyName( _( "Zoom &Out" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_OUT, IS_ACCELERATOR ); AddMenuItem( viewMenu, ID_ZOOM_OUT, text, HELP_ZOOM_OUT, KiBitmap( zoom_out_xpm ) ); - // Fit on Screen text = AddHotkeyName( _( "&Fit on Screen" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_AUTO ); - AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT, KiBitmap( zoom_fit_in_page_xpm ) ); viewMenu->AppendSeparator(); - // Redraw text = AddHotkeyName( _( "&Redraw" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ZOOM_REDRAW ); - AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) ); viewMenu->AppendSeparator(); - // 3D Display AddMenuItem( viewMenu, ID_MENU_PCB_SHOW_3D_FRAME, _( "&3D Display" ),_( "Show board in 3D viewer" ), KiBitmap( three_d_xpm ) ); - // List Nets AddMenuItem( viewMenu, ID_MENU_LIST_NETS, _( "&List Nets" ), _( "View a list of nets with names and id's" ), KiBitmap( tools_xpm ) ); - // Switching GAL-based canvas on/off viewMenu->AppendSeparator(); text = AddHotkeyName( _( "&Switch canvas to default" ), g_Pcbnew_Editor_Hokeys_Descr, @@ -390,44 +357,36 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() text, _( "Switch the canvas implementation to Cairo" ), KiBitmap( tools_xpm ) ); - /** Create Place Menu **/ + //----- Place Menu ---------------------------------------------------------- wxMenu* placeMenu = new wxMenu; - // Module text = AddHotkeyName( _( "&Module" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ADD_MODULE ); AddMenuItem( placeMenu, ID_PCB_MODULE_BUTT, text, _( "Add modules" ), KiBitmap( module_xpm ) ); - // Track text = AddHotkeyName( _( "&Track" ), g_Pcbnew_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK ); AddMenuItem( placeMenu, ID_TRACK_BUTT, text, _( "Add tracks and vias" ), KiBitmap( add_tracks_xpm ) ); - // Zone AddMenuItem( placeMenu, ID_PCB_ZONES_BUTT, _( "&Zone" ), _( "Add filled zones" ), KiBitmap( add_zone_xpm ) ); - // Keepout areas AddMenuItem( placeMenu, ID_PCB_KEEPOUT_AREA_BUTT, _( "&Keepout Area" ), _( "Add keepout areas" ), KiBitmap( add_keepout_area_xpm ) ); - // Text AddMenuItem( placeMenu, ID_PCB_ADD_TEXT_BUTT, _( "Te&xt" ), _( "Add text on copper layers or graphic text" ), KiBitmap( add_text_xpm ) ); - // Graphic Arc AddMenuItem( placeMenu, ID_PCB_ARC_BUTT, _( "&Arc" ), _( "Add graphic arc" ),KiBitmap( add_arc_xpm ) ); - // Graphic Circle AddMenuItem( placeMenu, ID_PCB_CIRCLE_BUTT, _( "&Circle" ), _( "Add graphic circle" ), KiBitmap( add_circle_xpm ) ); - // Line or Polygon AddMenuItem( placeMenu, ID_PCB_ADD_LINE_BUTT, _( "&Line or Polygon" ), _( "Add graphic line or polygon" ), @@ -435,34 +394,29 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() placeMenu->AppendSeparator(); - // Dimension AddMenuItem( placeMenu, ID_PCB_DIMENSION_BUTT, _( "&Dimension" ), _( "Add dimension" ), KiBitmap( add_dimension_xpm ) ); - // Layer alignment target AddMenuItem( placeMenu, ID_PCB_MIRE_BUTT, _( "La&yer alignment target" ), _( "Add layer alignment target" ), KiBitmap( add_mires_xpm ) ); placeMenu->AppendSeparator(); - // Drill & Place Offset AddMenuItem( placeMenu, ID_PCB_PLACE_OFFSET_COORD_BUTT, _( "Drill and Place O&ffset" ), _( "Place the origin point for drill and place files" ), KiBitmap( pcb_offset_xpm ) ); - // Grid Origin AddMenuItem( placeMenu, ID_PCB_PLACE_GRID_COORD_BUTT, _( "&Grid Origin" ), _( "Set the origin point for the grid" ), KiBitmap( grid_select_axis_xpm ) ); - /* Create Preferences and configuration menu */ + //----- Preferences and configuration menu------------------------------------ wxMenu* configmenu = new wxMenu; - // Library AddMenuItem( configmenu, ID_PCB_LIB_TABLE_EDIT, _( "Li&brary Tables" ), _( "Setup footprint libraries" ), KiBitmap( library_table_xpm ) ); @@ -480,7 +434,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() HELP_SHOW_HIDE_MICROWAVE_TOOLS, KiBitmap( mw_toolbar_xpm ) ); - // General #ifdef __WXMAC__ configmenu->Append(wxID_PREFERENCES); @@ -490,52 +443,44 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() KiBitmap( preference_xpm ) ); #endif - // Display AddMenuItem( configmenu, ID_PCB_DISPLAY_OPTIONS_SETUP, _( "&Display" ), _( "Select how items (pads, tracks texts ... ) are displayed" ), KiBitmap( display_options_xpm ) ); - // Create sizes and dimensions submenu + //--- dimensions submenu ------------------------------------------------------ wxMenu* dimensionsMenu = new wxMenu; - // Grid AddMenuItem( dimensionsMenu, ID_PCB_USER_GRID_SETUP, _( "G&rid" ),_( "Adjust user grid dimensions" ), KiBitmap( grid_xpm ) ); - // Text and Drawings AddMenuItem( dimensionsMenu, ID_PCB_DRAWINGS_WIDTHS_SETUP, _( "Te&xts and Drawings" ), _( "Adjust dimensions for texts and drawings" ), KiBitmap( options_text_xpm ) ); - // Pads AddMenuItem( dimensionsMenu, ID_PCB_PAD_SETUP, _( "&Pads" ), _( "Adjust default pad characteristics" ), KiBitmap( pad_dimensions_xpm ) ); - // Pads Mask Clearance AddMenuItem( dimensionsMenu, ID_PCB_MASK_CLEARANCE, _( "Pads &Mask Clearance" ), _( "Adjust the global clearance between pads and the solder resist mask" ), KiBitmap( pads_mask_layers_xpm ) ); - // Save dimension preferences dimensionsMenu->AppendSeparator(); AddMenuItem( dimensionsMenu, ID_CONFIG_SAVE, _( "&Save" ), _( "Save dimension preferences" ), KiBitmap( save_xpm ) ); - // Language submenu Pgm().AddMenuLanguageList( configmenu ); // Hotkey submenu AddHotkeyConfigMenu( configmenu ); - - // Macros submenu + //--- Macros submenu -------------------------------------------------------- wxMenu* macrosMenu = new wxMenu; AddMenuItem( macrosMenu, ID_PREFRENCES_MACROS_SAVE, @@ -548,7 +493,6 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Read macros from file" ), KiBitmap( read_setup_xpm ) ); - // Append macros menu to config menu AddMenuItem( configmenu, macrosMenu, -1, _( "Ma&cros" ), _( "Macros save/read operations" ), @@ -556,75 +500,58 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() configmenu->AppendSeparator(); - // Save Preferences AddMenuItem( configmenu, ID_CONFIG_SAVE, _( "&Save Preferences" ), _( "Save application preferences" ), KiBitmap( save_setup_xpm ) ); - // Read Preferences AddMenuItem( configmenu, ID_CONFIG_READ, _( "&Read Preferences" ), _( "Read application preferences" ), KiBitmap( read_setup_xpm ) ); - /** - * Tools menu - */ + //----- Tools menu ---------------------------------------------------------- wxMenu* toolsMenu = new wxMenu; - /* Netlist */ AddMenuItem( toolsMenu, ID_GET_NETLIST, _( "&Netlist" ), _( "Read the netlist and update board connectivity" ), KiBitmap( netlist_xpm ) ); - /* Layer pair */ AddMenuItem( toolsMenu, ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR, _( "&Layer Pair" ), _( "Change the active layer pair" ), KiBitmap( select_layer_pair_xpm ) ); - /* DRC */ AddMenuItem( toolsMenu, ID_DRC_CONTROL, _( "&DRC" ), _( "Perform design rules check" ), KiBitmap( erc_xpm ) ); - /* FreeRoute */ AddMenuItem( toolsMenu, ID_TOOLBARH_PCB_FREEROUTE_ACCESS, _( "&FreeRoute" ), _( "Fast access to the Web Based FreeROUTE advanced router" ), KiBitmap( web_support_xpm ) ); -#ifdef KICAD_SCRIPTING_WXPYTHON - /* Scripting */ +#if defined(KICAD_SCRIPTING_WXPYTHON) AddMenuItem( toolsMenu, ID_TOOLBARH_PCB_SCRIPTING_CONSOLE, _( "&Scripting Console" ), _( "Show/Hide the Scripting console" ), KiBitmap( book_xpm ) ); #endif - /* Design Rules menu - */ wxMenu* designRulesMenu = new wxMenu; - // Design Rules AddMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, _( "Design Rules" ), _( "Open the design rules editor" ), KiBitmap( hammer_xpm ) ); - // Layers Setup AddMenuItem( designRulesMenu, ID_PCB_LAYERS_SETUP, _( "&Layers Setup" ), _( "Enable and set layer properties" ), KiBitmap( copper_layers_setup_xpm ) ); - /** - * Help menu - */ wxMenu* helpMenu = new wxMenu; AddHelpVersionInfoMenuEntry( helpMenu ); - // Contents AddMenuItem( helpMenu, wxID_HELP, _( "&Contents" ), _( "Open the Pcbnew handbook" ), @@ -635,16 +562,13 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Open the \"Getting Started in KiCad\" guide for beginners" ), KiBitmap( help_xpm ) ); - // About helpMenu->AppendSeparator(); AddMenuItem( helpMenu, wxID_ABOUT, _( "&About Pcbnew" ), _( "About Pcbnew printed circuit board designer" ), KiBitmap( info_xpm ) ); - /** - * Append all menus to the menuBar - */ + // Append all menus to the menuBar menuBar->Append( filesMenu, _( "&File" ) ); menuBar->Append( editMenu, _( "&Edit" ) ); menuBar->Append( viewMenu, _( "&View" ) ); diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 2729504ab1..c9198d4a41 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -271,7 +271,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) FOOTPRINT_VIEWER_FRAME* viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( top_project ); if( !viewer ) { - viewer = (FOOTPRINT_VIEWER_FRAME*) Kiface().CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway() ); + KIFACE_I& kf = Kiface(); + + viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() ); viewer->Show( true ); viewer->Zoom_Automatique( false ); } diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index fa28eca5b4..cb7a0425fc 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -46,7 +46,6 @@ #include #include -#include #include #include #include @@ -153,7 +152,7 @@ END_EVENT_TABLE() #define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" ) FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, PCB_EDIT_FRAME* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, MODULE_EDITOR_FRAME_TYPE, wxEmptyString, + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString, wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() ) { diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index b79a2c4d3c..30bb30063e 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -119,7 +119,7 @@ static wxAcceleratorEntry accels[] = FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, wxSemaphore* aSemaphore ) : - PCB_BASE_FRAME( aKiway, aParent, MODULE_VIEWER_FRAME_TYPE, _( "Footprint Library Browser" ), + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_VIEWER, _( "Footprint Library Browser" ), wxDefaultPosition, wxDefaultSize, !aSemaphore ? KICAD_DEFAULT_DRAWFRAME_STYLE : diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index 6525d7abd7..6631ce31dc 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -709,7 +709,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC s_StartSegmentPresent = s_EndSegmentPresent = true; if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) ) - TrackToStartPoint = track->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); + TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START ); // Test if more than one segment is connected to this point if( TrackToStartPoint ) @@ -717,14 +717,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToStartPoint->SetState( BUSY, true ); if( ( TrackToStartPoint->Type() == PCB_VIA_T ) - || track->GetTrace( GetBoard()->m_Track, NULL, FLG_START ) ) + || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START ) ) error = true; TrackToStartPoint->SetState( BUSY, false ); } if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) ) - TrackToEndPoint = track->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); + TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END ); // Test if more than one segment is connected to this point if( TrackToEndPoint ) @@ -732,7 +732,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToEndPoint->SetState( BUSY, true ); if( (TrackToEndPoint->Type() == PCB_VIA_T) - || track->GetTrace( GetBoard()->m_Track, NULL, FLG_END ) ) + || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END ) ) error = true; TrackToEndPoint->SetState( BUSY, false ); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp index 4985958fc9..c1e7c416b2 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_pad.cpp @@ -329,7 +329,7 @@ void PCB_PAD::AddToBoard() if( IsCopperLayer( m_KiCadLayer ) ) { - SEGVIA* via = new SEGVIA( m_board ); + VIA* via = new VIA( m_board ); m_board->m_Track.Append( via ); via->SetTimeStamp( 0 ); @@ -338,8 +338,8 @@ void PCB_PAD::AddToBoard() via->SetEnd( wxPoint( m_positionX, m_positionY ) ); via->SetWidth( height ); - via->SetShape( VIA_THROUGH ); - ( (SEGVIA*) via )->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); + via->SetViaType( VIA_THROUGH ); + via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); via->SetDrill( m_hole ); via->SetLayer( m_KiCadLayer ); diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 4475494d7e..0465f450aa 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -202,15 +202,15 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) { case PCB_ZONE_T: case PCB_TRACE_T: - draw( (TRACK*) aItem, aLayer ); + draw( (const TRACK*) aItem, aLayer ); break; case PCB_VIA_T: - draw( (SEGVIA*) aItem, aLayer ); + draw( (const VIA*) aItem, aLayer ); break; case PCB_PAD_T: - draw( (D_PAD*) aItem, aLayer ); + draw( (const D_PAD*) aItem, aLayer ); break; case PCB_LINE_T: @@ -318,7 +318,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) } -void PCB_PAINTER::draw( const SEGVIA* aVia, int aLayer ) +void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) { VECTOR2D center( aVia->GetStart() ); double radius; diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index cdcedb1db7..d9ef81b4e1 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -37,7 +37,7 @@ class DISPLAY_OPTIONS; class BOARD_ITEM; class BOARD; -class SEGVIA; +class VIA; class TRACK; class D_PAD; class DRAWSEGMENT; @@ -206,7 +206,7 @@ protected: // Drawing functions for various types of PCB-specific items void draw( const TRACK* aTrack, int aLayer ); - void draw( const SEGVIA* aVia, int aLayer ); + void draw( const VIA* aVia, int aLayer ); void draw( const D_PAD* aPad, int aLayer ); void draw( const DRAWSEGMENT* aSegment ); void draw( const TEXTE_PCB* aText, int aLayer ); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index db66648d21..bfa1ea337d 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -432,7 +432,7 @@ BOARD* PCB_PARSER::parseBOARD() throw( IO_ERROR, PARSE_ERROR ) break; case T_via: - m_board->Add( parseSEGVIA(), ADD_APPEND ); + m_board->Add( parseVIA(), ADD_APPEND ); break; case T_zone: @@ -2313,15 +2313,15 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR ) } -SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ) +VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR ) { wxCHECK_MSG( CurTok() == T_via, NULL, - wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as SEGVIA." ) ); + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as VIA." ) ); wxPoint pt; T token; - std::auto_ptr< SEGVIA > via( new SEGVIA( m_board ) ); + std::auto_ptr< VIA > via( new VIA( m_board ) ); for( token = NextTok(); token != T_RIGHT; token = NextTok() ) { @@ -2331,11 +2331,11 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ) switch( token ) { case T_blind: - via->SetShape( VIA_BLIND_BURIED ); + via->SetViaType( VIA_BLIND_BURIED ); break; case T_micro: - via->SetShape( VIA_MICROVIA ); + via->SetViaType( VIA_MICROVIA ); break; case T_at: diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h index 0dfb0bbdc5..eeb4faf9d6 100644 --- a/pcbnew/pcb_parser.h +++ b/pcbnew/pcb_parser.h @@ -49,7 +49,7 @@ class TEXTE_PCB; class TRACK; class MODULE; class PCB_TARGET; -class SEGVIA; +class VIA; class S3D_MASTER; class ZONE_CONTAINER; @@ -101,7 +101,7 @@ class PCB_PARSER : public PCB_LEXER EDGE_MODULE* parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR ); D_PAD* parseD_PAD( MODULE* aParent = NULL ) throw( IO_ERROR, PARSE_ERROR ); TRACK* parseTRACK() throw( IO_ERROR, PARSE_ERROR ); - SEGVIA* parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ); + VIA* parseVIA() throw( IO_ERROR, PARSE_ERROR ); ZONE_CONTAINER* parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ); PCB_TARGET* parsePCB_TARGET() throw( IO_ERROR, PARSE_ERROR ); BOARD* parseBOARD() throw( IO_ERROR, PARSE_ERROR ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 302a9574c8..c32655ebc8 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -298,7 +298,7 @@ END_EVENT_TABLE() #define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" ) PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, PCB_FRAME_TYPE, wxT( "Pcbnew" ), wxDefaultPosition, + PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME ) { m_FrameName = PCB_EDIT_FRAME_NAME; @@ -446,7 +446,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); -#ifdef KICAD_SCRIPTING_WXPYTHON +#if defined(KICAD_SCRIPTING_WXPYTHON) // Add the scripting panel EDA_PANEINFO pythonAuiInfo; pythonAuiInfo.ScriptingToolbarPane(); @@ -800,7 +800,7 @@ void PCB_EDIT_FRAME::SetGridColor(EDA_COLOR_T aColor) } -bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void ) +bool PCB_EDIT_FRAME::IsMicroViaAcceptable() { int copperlayercnt = GetBoard()->GetCopperLayerCount( ); LAYER_NUM currLayer = GetActiveLayer(); @@ -1077,7 +1077,7 @@ void PCB_EDIT_FRAME::UpdateTitle() SetTitle( title ); } -#ifdef KICAD_SCRIPTING_WXPYTHON +#if defined(KICAD_SCRIPTING_WXPYTHON) void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent ) { if ( m_pythonPanelHidden ) diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index c9a4129e1b..3c47fb7f3d 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -101,7 +101,7 @@ static struct IFACE : public KIFACE_I KIFACE_I( aName, aType ) {} - bool OnKifaceStart( PGM_BASE* aProgram ); + bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); void OnKifaceEnd(); @@ -110,25 +110,27 @@ static struct IFACE : public KIFACE_I switch( aClassId ) { - case PCB_FRAME_TYPE: + case FRAME_PCB: { PCB_EDIT_FRAME* frame = new PCB_EDIT_FRAME( aKiway, aParent ); frame->Zoom_Automatique( true ); -#ifdef KICAD_SCRIPTING +#if defined(KICAD_SCRIPTING) // give the scripting helpers access to our frame ScriptingSetPcbEditFrame( frame ); #endif - // @todo temporarily here - CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER ); - + if( Kiface().IsSingle() ) + { + // only run this under single_top, not under a project manager. + CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER ); + } return frame; } break; - case MODULE_EDITOR_FRAME_TYPE: + case FRAME_PCB_MODULE_EDITOR: { // yuck: PCB_EDIT_FRAME* editor = dynamic_cast( aParent ); @@ -141,12 +143,11 @@ static struct IFACE : public KIFACE_I /* Read a default config file in case no project given on command line. frame->LoadProjectFile( wxEmptyString, true ); */ - return frame; } break; - case MODULE_VIEWER_FRAME_TYPE: + case FRAME_PCB_MODULE_VIEWER: { // yuck: PCB_BASE_FRAME* editor = dynamic_cast( aParent ); @@ -159,7 +160,6 @@ static struct IFACE : public KIFACE_I /* Read a default config file in case no project given on command line. frame->LoadProjectFile( wxEmptyString, true ); */ - return frame; } break; @@ -411,13 +411,13 @@ static bool scriptingSetup() FP_LIB_TABLE GFootprintTable; -bool IFACE::OnKifaceStart( PGM_BASE* aProgram ) +bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { // This is process level, not project level, initialization of the DSO. // Do nothing in here pertinent to a project! - start_common(); + start_common( aCtlBits ); // Must be called before creating the main frame in order to // display the real hotkeys in menus or tool tips diff --git a/pcbnew/pcbnew.h b/pcbnew/pcbnew.h index 25df567ebb..d2c6427ea6 100644 --- a/pcbnew/pcbnew.h +++ b/pcbnew/pcbnew.h @@ -25,9 +25,11 @@ #define MATCH_LAYER (1 << 2) ///< if module not on current layer, do not select #define VISIBLE_ONLY (1 << 3) ///< if module not on a visible layer, do not select - -#define FLG_START 0 // Flag used in locate routines -#define FLG_END 1 // Flag used in locate routines +/// Flag used in locate routines (from which endpoint work) +enum ENDPOINT_T { + ENDPOINT_START = 0, + ENDPOINT_END = 1 +}; #define DIM_ANCRE_MODULE 3 // Anchor size (footprint center) diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 34d708195b..f299787716 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -357,10 +357,10 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, // plot them on solder mask for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { - if( track->Type() != PCB_VIA_T ) - continue; + const VIA* Via = dynamic_cast( track ); - SEGVIA* Via = (SEGVIA*) track; + if( !Via ) + continue; // vias are not plotted if not on selected layer, but if layer // is SOLDERMASK_LAYER_BACK or SOLDERMASK_LAYER_FRONT,vias are drawn, @@ -396,7 +396,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter, if( diameter <= 0 ) continue; - EDA_COLOR_T color = aBoard->GetVisibleElementColor(VIAS_VISIBLE + Via->GetShape()); + EDA_COLOR_T color = aBoard->GetVisibleElementColor(VIAS_VISIBLE + Via->GetViaType()); // Set plot color (change WHITE to LIGHTGRAY because // the white items are not seen on a white paper or screen aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY); @@ -534,10 +534,10 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, int via_margin = via_clearance + inflate; for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) { - if( track->Type() != PCB_VIA_T ) - continue; + const VIA* via = dynamic_cast( track ); - SEGVIA* via = (SEGVIA*) track; + if( !via ) + continue; // vias are plotted only if they are on the corresponding // external copper layer @@ -553,11 +553,11 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, continue; via->TransformShapeWithClearanceToPolygon( bufferPolys, via_margin, - circleToSegmentsCount, - correction ); + circleToSegmentsCount, + correction ); via->TransformShapeWithClearanceToPolygon( initialPolys, via_clearance, - circleToSegmentsCount, - correction ); + circleToSegmentsCount, + correction ); } } diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 32f9209938..00dbeede81 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -148,10 +148,11 @@ bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule ) PlotTextModule( &aModule->Value(), GetValueColor() ); } - for( textModule = (TEXTE_MODULE*) aModule->GraphicalItems().GetFirst(); - textModule != NULL; textModule = textModule->Next() ) + for( BOARD_ITEM *item = aModule->GraphicalItems().GetFirst(); + item != NULL; item = item->Next() ) { - if( textModule->Type() != PCB_MODULE_TEXT_T ) + textModule = dynamic_cast( item ); + if( !textModule ) continue; if( !GetPlotOtherText() ) @@ -350,13 +351,11 @@ void BRDITEMS_PLOTTER::Plot_Edges_Modules() { for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { - for( EDGE_MODULE* edge = (EDGE_MODULE*) module->GraphicalItems().GetFirst(); - edge; edge = edge->Next() ) + for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() ) { - if( edge->Type() != PCB_MODULE_EDGE_T ) - continue; + EDGE_MODULE *edge = dynamic_cast( item ); - if( ( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0 ) + if( !edge || (( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0) ) continue; Plot_1_EdgeModule( edge ); @@ -685,11 +684,12 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() for( TRACK *pts = m_board->m_Track; pts != NULL; pts = pts->Next() ) { - if( pts->Type() != PCB_VIA_T ) - continue; + const VIA *via = dynamic_cast( pts ); - plotOneDrillMark( PAD_DRILL_CIRCLE, pts->GetStart(), wxSize( pts->GetDrillValue(), 0 ), - wxSize( pts->GetWidth(), 0 ), 0, small_drill ); + if( via ) + plotOneDrillMark( PAD_DRILL_CIRCLE, via->GetStart(), + wxSize( via->GetDrillValue(), 0 ), + wxSize( via->GetWidth(), 0 ), 0, small_drill ); } for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() ) diff --git a/pcbnew/print_board_functions.cpp b/pcbnew/print_board_functions.cpp index f663521417..2683e268b5 100644 --- a/pcbnew/print_board_functions.cpp +++ b/pcbnew/print_board_functions.cpp @@ -249,12 +249,14 @@ void PCB_EDIT_FRAME::PrintPage( wxDC* aDC, if( track->Type() == PCB_VIA_T ) // VIA encountered. { - int radius = track->GetWidth() >> 1; - EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + track->GetShape() ); + int radius = track->GetWidth() / 2; + const VIA *via = static_cast( track ); + + EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + via->GetViaType() ); GRSetDrawMode( aDC, drawmode ); GRFilledCircle( m_canvas->GetClipBox(), aDC, - track->GetStart().x, - track->GetStart().y, + via->GetStart().x, + via->GetStart().y, radius, 0, color, color ); } @@ -313,11 +315,12 @@ void PCB_EDIT_FRAME::PrintPage( wxDC* aDC, if( track->Type() == PCB_VIA_T ) // VIA encountered. { int diameter; + const VIA *via = static_cast( track ); if( drillShapeOpt == PRINT_PARAMETERS::SMALL_DRILL_SHAPE ) - diameter = std::min( SMALL_DRILL, track->GetDrillValue() ); + diameter = std::min( SMALL_DRILL, via->GetDrillValue() ); else - diameter = track->GetDrillValue(); + diameter = via->GetDrillValue(); GRFilledCircle( m_canvas->GetClipBox(), aDC, track->GetStart().x, track->GetStart().y, diff --git a/pcbnew/printout_controler.cpp b/pcbnew/printout_controler.cpp index 092304298c..c553cd83ed 100644 --- a/pcbnew/printout_controler.cpp +++ b/pcbnew/printout_controler.cpp @@ -263,7 +263,7 @@ void BOARD_PRINTOUT_CONTROLLER::DrawPage() // In module editor, the module is located at 0,0 but for printing // it is moved to pageSizeIU.x/2, pageSizeIU.y/2. // So the equivalent board must be moved to the center of the page: - if( m_Parent->IsType( MODULE_EDITOR_FRAME_TYPE ) ) + if( m_Parent->IsType( FRAME_PCB_MODULE_EDITOR ) ) { boardBoundingBox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) ); } diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index 028c632568..a9703a5450 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -234,9 +234,10 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest() { NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code ); - if( net == NULL ) //Should not occur + if( !net ) // Should not occur { - wxMessageBox( wxT( "Build_Board_Ratsnest() error: net not found" ) ); + UTF8 msg = StrPrintf( "%s: error, net %d not found", __func__, current_net_code ); + wxMessageBox( msg ); // BTW, it does happen. return; } diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index f74a412479..4b4c063485 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -393,7 +393,7 @@ void RN_NET::AddItem( const D_PAD* aPad ) } -void RN_NET::AddItem( const SEGVIA* aVia ) +void RN_NET::AddItem( const VIA* aVia ) { m_vias[aVia] = m_links.AddNode( aVia->GetPosition().x, aVia->GetPosition().y ); @@ -482,7 +482,7 @@ void RN_NET::RemoveItem( const D_PAD* aPad ) } -void RN_NET::RemoveItem( const SEGVIA* aVia ) +void RN_NET::RemoveItem( const VIA* aVia ) { try { @@ -686,7 +686,7 @@ std::list RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con case PCB_VIA_T: { - const SEGVIA* via = static_cast( aItem ); + const VIA* via = static_cast( aItem ); nodes.push_back( m_vias.at( via ) ); } break; @@ -877,7 +877,7 @@ void RN_DATA::Add( const BOARD_ITEM* aItem ) break; case PCB_VIA_T: - m_nets[net].AddItem( static_cast( aItem ) ); + m_nets[net].AddItem( static_cast( aItem ) ); break; case PCB_ZONE_AREA_T: @@ -928,7 +928,7 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem ) break; case PCB_VIA_T: - m_nets[net].RemoveItem( static_cast( aItem ) ); + m_nets[net].RemoveItem( static_cast( aItem ) ); break; case PCB_ZONE_AREA_T: @@ -973,7 +973,7 @@ void RN_DATA::ProcessBoard() if( netCode > 0 ) { if( track->Type() == PCB_VIA_T ) - m_nets[netCode].AddItem( static_cast( track ) ); + m_nets[netCode].AddItem( static_cast( track ) ); else if( track->Type() == PCB_TRACE_T ) m_nets[netCode].AddItem( track ); } diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index afc9c0935f..348c31902e 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -44,7 +44,7 @@ class BOARD_ITEM; class BOARD_CONNECTED_ITEM; class MODULE; class D_PAD; -class SEGVIA; +class VIA; class TRACK; class ZONE_CONTAINER; class CPolyPt; @@ -332,7 +332,7 @@ public: * taken into account during ratsnest computations. * @param aVia is a via for which node is added. */ - void AddItem( const SEGVIA* aVia ); + void AddItem( const VIA* aVia ); /** * Function AddItem() @@ -364,7 +364,7 @@ public: * taken into account during ratsnest computations anymore. * @param aVia is a via for which nodes and edges are removed. */ - void RemoveItem( const SEGVIA* aVia ); + void RemoveItem( const VIA* aVia ); /** * Function RemoveItem() @@ -522,7 +522,7 @@ protected: boost::unordered_map m_pads; ///> Map that associates nodes in the ratsnest model to respective vias. - boost::unordered_map m_vias; + boost::unordered_map m_vias; ///> Map that associates edges in the ratsnest model to respective tracks. boost::unordered_map m_tracks; diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 399173c41f..72d4cb7960 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -189,7 +189,7 @@ PNS_ITEM* PNS_ROUTER::syncTrack( TRACK* aTrack ) } -PNS_ITEM* PNS_ROUTER::syncVia( SEGVIA* aVia ) +PNS_ITEM* PNS_ROUTER::syncVia( VIA* aVia ) { PNS_VIA* v = new PNS_VIA( aVia->GetPosition(), @@ -268,7 +268,7 @@ void PNS_ROUTER::SyncWorld() if( type == PCB_TRACE_T ) item = syncTrack( t ); else if( type == PCB_VIA_T ) - item = syncVia( static_cast( t ) ); + item = syncVia( static_cast( t ) ); if( item ) m_world->Add( item ); @@ -622,7 +622,7 @@ void PNS_ROUTER::commitRouting( PNS_NODE* aNode ) case PNS_ITEM::VIA: { - SEGVIA* via_board = new SEGVIA( m_board ); + VIA* via_board = new VIA( m_board ); PNS_VIA* via = static_cast( item ); via_board->SetPosition( wxPoint( via->GetPos().x, via->GetPos().y ) ); via_board->SetWidth( via->GetDiameter() ); diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 430f950a37..e5fabbeec2 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -37,7 +37,7 @@ class BOARD; class BOARD_ITEM; class D_PAD; class TRACK; -class SEGVIA; +class VIA; class PNS_NODE; class PNS_LINE_PLACER; class PNS_ITEM; @@ -169,7 +169,7 @@ private: PNS_ITEM* syncPad( D_PAD* aPad ); PNS_ITEM* syncTrack( TRACK* aTrack ); - PNS_ITEM* syncVia( SEGVIA* aVia ); + PNS_ITEM* syncVia( VIA* aVia ); void commitPad( PNS_SOLID* aPad ); void commitSegment( PNS_SEGMENT* aTrack ); diff --git a/pcbnew/scripting/board_item.i b/pcbnew/scripting/board_item.i index 37e3ed1f83..1671c10da2 100644 --- a/pcbnew/scripting/board_item.i +++ b/pcbnew/scripting/board_item.i @@ -36,28 +36,27 @@ } %extend BOARD_ITEM -{ - TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } - DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } - MODULE* Cast_to_MODULE() { return dynamic_cast(self); } - TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast(self); } - DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } - MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } - BOARD* Cast_to_BOARD() { return dynamic_cast(self); } - EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } - D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } - TRACK* Cast_to_TRACK() { return dynamic_cast(self); } +{ + TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast(self); } + DIMENSION* Cast_to_DIMENSION() { return dynamic_cast(self); } + MODULE* Cast_to_MODULE() { return dynamic_cast(self); } + TEXTE_MODULE* Cast_to_TEXTE_MODULE() { return dynamic_cast(self); } + DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast(self); } + MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast(self); } + BOARD* Cast_to_BOARD() { return dynamic_cast(self); } + EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast(self); } + D_PAD* Cast_to_D_PAD() { return dynamic_cast(self); } + TRACK* Cast_to_TRACK() { return dynamic_cast(self); } SEGZONE* Cast_to_SEGZONE() { return dynamic_cast(self); } - SEGVIA* Cast_to_SEGVIA() { return dynamic_cast(self); } - + VIA* Cast_to_VIA() { return dynamic_cast(self); } %pythoncode { def Cast(self): - + ct = self.GetClass() - + if ct=="PTEXT": return self.Cast_to_TEXTE_PCB() elif ct=="BOARD": @@ -77,7 +76,7 @@ elif ct=="ZONE": return self.Cast_to_SEGZONE() elif ct=="VIA": - return self.Cast_to_SEGVIA() + return self.Cast_to_VIA() elif ct=="TRACK": return self.Cast_to_TRACK() else: diff --git a/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py b/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py new file mode 100644 index 0000000000..d1046bdafb --- /dev/null +++ b/pcbnew/scripting/plugins/FootprintWizardDrawingAids.py @@ -0,0 +1,134 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +import pcbnew + +class FootprintWizardDrawingAids: + """ + Collection of handy functions to simplify drawing shapes from within + footprint wizards + + A "drawing context" is provided which can be used to set and retain + settings such as line width and layer + """ + def __init__(self, module): + self.module = module + #drawing context defaults + self.dc = { + 'layer': pcbnew.SILKSCREEN_N_FRONT, + 'width': pcbnew.FromMM(0.2) + } + + def SetWidth(self, width): + self.dc['width'] = width + + def SetLayer(self, layer): + self.dc['layer'] = layer + + def Line(self, x1, y1, x2, y2): + + outline = pcbnew.EDGE_MODULE(self.module) + outline.SetWidth(self.dc['width']) + outline.SetLayer(self.dc['layer']) + outline.SetShape(pcbnew.S_SEGMENT) + start = pcbnew.wxPoint(x1, y1) + end = pcbnew.wxPoint(x2, y2) + outline.SetStartEnd(start, end) + self.module.Add(outline) + + # extends from (x1,y1) right + def HLine(self, x, y, l): + """ + Draw a horizontal line from (x,y), rightwards + """ + self.Line(x, y, x + l, y) + + def VLine(self, x, y, l): + """ + Draw a vertical line from (x1,y1), downwards + """ + self.Line(x, y, x, y + l) + + def Polyline(self, pts): + + if len(pts) < 2: + return + + for i in range(0, len(pts) - 1): + self.Line(pts[i][0], pts[i][1], pts[i+1][0], pts[i+1][1]) + + def Reference(self, x, y, size): + """ + Draw the module's reference as the given point. + + The actual setting of the reference is not done in this drawing + aid - that is up to the wizard + """ + + text_size = pcbnew.wxSize(size, size) + + self.module.Reference().SetPos0(pcbnew.wxPoint(x, y)) + self.module.Reference().SetTextPosition(self.module.Reference().GetPos0()) + self.module.Reference().SetSize(text_size) + + def Value(self, x, y, size): + """ + As for references, draw the module's value + """ + text_size = pcbnew.wxSize(size, size) + + self.module.Value().SetPos0(pcbnew.wxPoint(x, y)) + self.module.Value().SetTextPosition(self.module.Value().GetPos0()) + self.module.Value().SetSize(text_size) + + def Box(self, x, y, w, h): + """ + Draw a rectangular box, centred at (x,y), with given width and + height + """ + self.VLine(x - w/2, y - h/2, h) # left + self.VLine(x + w/2, y - h/2, h) # right + self.HLine(x - w/2, y + h/2, w) # bottom + self.HLine(x - w/2, y - h/2, w) # top + + def NotchedBox(self, x, y, w, h, notchW, notchH): + """ + Draw a box with a notch in the top edge + """ + #limit to half the overall width + notchW = min(x + w/2, notchW) + + # draw notch + self.Polyline([ #three sides of box + (x - w/2, y - h/2), + (x - w/2, y + h/2), + (x + w/2, y + h/2), + (x + w/2, y - h/2), + #the notch + (notchW/2, y - h/2), + (notchW/2, y - h/2 + notchH), + (-notchW/2, y - h/2 + notchH), + (-notchW/2, y - h/2), + (x - w/2, y - h/2) + ]) + + def BoxWithDiagonalAtCorner(self, x, y, w, h, diagSetback): + + self.Box(x, y, w, h) + + #diagonal corner + self.Line(x - w/2 + diagSetback, x - h/2, x - w/2, + x - h/2 + diagSetback) diff --git a/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py new file mode 100644 index 0000000000..de93cfda03 --- /dev/null +++ b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py @@ -0,0 +1,250 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +import pcbnew +import FootprintWizardDrawingAids + +class FootprintWizardParameterManager: + """ + Functions for helpfully managing parameters to a KiCAD Footprint + Wizard. + + Abstracts away from whatever structure is used by pcbnew's footprint + wizard class + """ + + def __init__(self): + self.parameters = {} + self.GenerateParameterList() + + def GenerateParameterList(self): + """ + Construct parameters here, or leave out to have no parameters + """ + pass + + def CheckParameters(self): + """ + Implement this to make checks on parameter values, filling + parameter_errors (or using the checker routines) + + Subclasses can implment their own and override the parent + defaults and add new ones + """ + pass + + uMM = 1 + uMils = 2 + uNatural = 3 + uBool = 4 + + def AddParam(self, section, param, unit, default, hint = ''): + """ + Add a parameter with some properties. + + TODO: Hints are not supported, as there is as yet nowhere to + put them in the KiCAD interface + """ + + val = None + if unit == self.uMM: + val = pcbnew.FromMM(default) + elif unit == self.uMils: + val = pcbnew.FromMils(default) + elif unit == self.uNatural: + val = default + elif unit == self.uBool: + val = "True" if default else "False" #ugly stringing + else: + print "Warning: Unknown unit type: %s" % unit + return + + if unit in [self.uNatural, self.uBool]: + param = "*%s" % param #star prefix for natural + + if section not in self.parameters: + self.parameters[section] = {} + + self.parameters[section][param] = val + + def _PrintParameterTable(self): + """ + Pretty-print the parameters we have + """ + for name, section in self.parameters.iteritems(): + print " %s:" % name + + for key, value in section.iteritems(): + unit = "" + if (type(value) is int or type(value) is float) and not "*" in key: + unit = "mm" + + if "*" in key: + key = key[1:] + else: + value = pcbnew.ToMM(value) + + print " %s: %s%s" % (key, value, unit) + + def _ParametersHaveErrors(self): + """ + Return true if we discovered errors suring parameter processing + """ + + for name, section in self.parameter_errors.iteritems(): + for k, v in section.iteritems(): + if v: + return True + + return False + + def _PrintParameterErrors(self): + """ + Pretty-print parameters with errors + """ + + for name, section in self.parameter_errors.iteritems(): + printed_section = False + + for key, value in section.iteritems(): + if value: + if not printed_section: + print " %s:" % name + + print " %s: %s (have %s)" % (key, value, + self.parameters[name][key]) + + def ProcessParameters(self): + """ + Make sure the parameters we have meet whatever expectations the + footprint wizard has of them + """ + + self.ClearErrors() + self.CheckParameters(); + + if self._ParametersHaveErrors(): + print "Cannot build footprint: Parameters have errors:" + self._PrintParameterErrors() + return False + + print "Building new %s footprint with the following parameters:" % self.name + + self._PrintParameterTable() + return True + + ################################################################# + # PARAMETER CHECKERS + ################################################################# + + def CheckParamPositiveInt(self, section, param, min_value = 1, + max_value = None, is_multiple_of = 1): + """ + Make sure a parameter can be made into an int, and enforce + limits if required + """ + + try: + self.parameters[section][param] = int(self.parameters[section][param]) + except ValueError: + self.parameter_errors[section][param] = "Must be a valid integer" + return + + if min_value is not None and (self.parameters[section][param] < min_value): + self.parameter_errors[section][param] = "Must be greater than or equal to %d" % (min_value) + return + + if max_value is not None and (self.parameters[section][param] > min_value): + self.parameter_errors[section][param] = "Must be less than or equal to %d" % (max_value) + return + + if is_multiple_of > 1 and (self.parameters[section][param] % is_multiple_of) > 0: + self.parameter_errors[section][param] = "Must be a multiple of %d" % is_multiple_of + return + + return + + def CheckParamBool(self, section, param): + """ + Make sure a parameter looks like a boolean, convert to native + boolean type if so + """ + if str(self.parameters[section][param]).lower() in ["true", "t", "y", "yes", "on", "1", "1.0"]: + self.parameters[section][param] = True; + return + elif str(self.parameters[section][param]).lower() in ["false", "f", "n", "no", "off", "0", "0.0"]: + self.parameters[section][param] = False; + return + + self.parameter_errors[section][param] = "Must be boolean (true/false)" + return + + +class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin, + FootprintWizardParameterManager): + """ + A class to simplify many aspects of footprint creation, leaving only + the foot-print specific routines to the wizards themselves + + Generally, you need to implement: + GetReference() + GetValue() + GenerateParameterList() + CheckParameters() + BuildThisFootprint() + GetName() + GetDescription() + """ + def __init__(self): + pcbnew.FootprintWizardPlugin.__init__(self) + FootprintWizardParameterManager.__init__(self) + + self.name = self.GetName() + self.decription = self.GetDescription() + self.image = self.GetImage() + + def GetReference(self): + raise NotImplementedError + + def GetValuePrefix(self): + return "U" # footprints needing wizards of often ICs + + def GetImage(self): + return "" + + def BuildThisFootprint(self): + raise NotImplementedError + + def BuildFootprint(self): + """ + Actually make the footprint. We defer all but the setup to + the implmenting class + """ + + if not self.ProcessParameters(): + return + + self.module = pcbnew.MODULE(None) # create a new module + + self.draw = FootprintWizardDrawingAids.FootprintWizardDrawingAids(self.module) + + self.module.SetReference(self.GetReference()) + self.module.SetValue("%s**" % self.GetValuePrefix()) + + fpid = pcbnew.FPID(self.module.GetReference()) #the name in library + self.module.SetFPID( fpid ) + + self.BuildThisFootprint() # implementer's build function diff --git a/pcbnew/scripting/plugins/PadArray.py b/pcbnew/scripting/plugins/PadArray.py new file mode 100644 index 0000000000..99fa70e0dc --- /dev/null +++ b/pcbnew/scripting/plugins/PadArray.py @@ -0,0 +1,148 @@ + +import pcbnew + +class PadMaker: + """ + Useful construction functions for common types of pads + """ + + def __init__(self, module): + self.module = module + + def THPad(self, w, l, drill, shape = pcbnew.PAD_OVAL): + pad = pcbnew.D_PAD(self.module) + + pad.SetSize(pcbnew.wxSize(l, w)) + + pad.SetShape(shape) + + pad.SetAttribute(pcbnew.PAD_STANDARD) + pad.SetLayerMask(pcbnew.PAD_STANDARD_DEFAULT_LAYERS) + pad.SetDrillSize(pcbnew.wxSize(drill, drill)) + + return pad + + def SMDPad(self, w, l, shape = pcbnew.PAD_RECT): + pad = pcbnew.D_PAD(self.module) + pad.SetSize(pcbnew.wxSize(l, w)) + + pad.SetShape(shape) + + pad.SetAttribute(pcbnew.PAD_SMD) + pad.SetLayerMask(pcbnew.PAD_SMD_DEFAULT_LAYERS) + + return pad + + def SMTRoundPad(self, size): + pad = self.SMDPad(size, size, shape = pcbnew.PAD_CIRCLE) + return pad + +class PadArray: + + def __init__(self): + self.firstPad = 1; + + def SetFirstPadInArray(self, fpNum): + self.firstPad = fpNum + + # HACK! pad should one day have its own clone method + def ClonePad(self): + + pad = pcbnew.D_PAD(self.pad.GetParent()) + + pad.SetSize(self.pad.GetSize()) + pad.SetShape(self.pad.GetShape()) + pad.SetAttribute(self.pad.GetAttribute()) + pad.SetLayerMask(self.pad.GetLayerMask()) + pad.SetDrillSize(self.pad.GetDrillSize()) + + return pad + + def AddPad(self, pad): + self.pad.GetParent().Add(pad) + +class PadGridArray(PadArray): + + def __init__(self, pad, nx, ny, px, py, pin1Pos): + # this pad is more of a "context", we will use it as a source of + # pad data, but not actually add it + self.pad = pad + self.nx = int(nx) + self.ny = int(ny) + self.px = px + self.py = py + self.pin1Pos = pin1Pos + + # handy utility function 1 - A, 2 - B, 26 - AA, etc + # aIndex = 0 for 0 - A + def AlphaNameFromNumber(self, n, aIndex = 1): + + div, mod = divmod(n - aIndex, 26) + alpha = chr(65 + mod) + + if div > 0: + return self.AlphaNameFromNumber(div) + alpha; + + return alpha; + + # right to left, top to bottom + def NamingFunction(self, x, y): + return self.firstPad + (self.nx * y + x) + + #relocate the pad and add it as many times as we need + def AddPadsToModule(self): + + for x in range(0, self.nx): + for y in range(self.ny): + posX = self.pin1Pos.x + (self.px * x) + posY = self.pin1Pos.y + (self.py * y) + + pos = pcbnew.wxPoint(posX, posY) + + # THIS DOESN'T WORK yet! + #pad = self.pad.Clone() + pad = self.ClonePad() + + pad.SetPos0(pos) + pad.SetPosition(pos) + + pad.SetPadName(str(self.NamingFunction(x,y))) + + self.AddPad(pad) + +class PadLineArray(PadGridArray): + + def __init__(self, pad, n, pitch, isVertical, pin1Pos): + + if isVertical: + PadGridArray.__init__(self, pad, 1, n, 0, pitch, pin1Pos) + else: + PadGridArray.__init__(self, pad, n, 1, pitch, 0, pin1Pos) + +class RectPadArray(PadArray): + + def __init__(self, nx, ny, pitch, xpitch, ypitch, pin1Pos): + + #left row + pin1Pos = pcbnew.wxPoint(-h_pitch / 2, -row_len / 2) + array = PadLineArray(h_pad, pads_per_row, pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(1) + array.AddPadsToModule() + + #bottom row + pin1Pos = pcbnew.wxPoint(-row_len / 2, v_pitch / 2) + array = PA.PadLineArray(v_pad, pads_per_row, pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(pads_per_row + 1) + array.AddPadsToModule() + + #right row + pin1Pos = pcbnew.wxPoint(h_pitch / 2, row_len / 2) + array = PadLineArray(h_pad, pads_per_row, -pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(2*pads_per_row + 1) + array.AddPadsToModule() + + #top row + pin1Pos = pcbnew.wxPoint(row_len / 2, -v_pitch / 2) + array = PadLineArray(v_pad, pads_per_row, -pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(3*pads_per_row + 1) + array.AddPadsToModule() diff --git a/pcbnew/scripting/plugins/bga_wizard.py b/pcbnew/scripting/plugins/bga_wizard.py new file mode 100644 index 0000000000..7fd6258f3e --- /dev/null +++ b/pcbnew/scripting/plugins/bga_wizard.py @@ -0,0 +1,98 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +from __future__ import division +import pcbnew + +import HelpfulFootprintWizardPlugin as HFPW +import PadArray as PA + + +class BGAPadGridArray(PA.PadGridArray): + + def NamingFunction(self, x, y): + return "%s%d" % (self.AlphaNameFromNumber(y + 1), x + 1) + + +class BGAWizard(HFPW.HelpfulFootprintWizardPlugin): + + def GetName(self): + return "BGA" + + def GetDescription(self): + return "Ball Grid Array Footprint Wizard" + + def GenerateParameterList(self): + + self.AddParam("Pads", "pad pitch", self.uMM, 1) + self.AddParam("Pads", "pad size", self.uMM, 0.5) + self.AddParam("Pads", "row count", self.uNatural, 5) + self.AddParam("Pads", "column count", self.uNatural, 5) + self.AddParam("Pads", "outline x margin", self.uMM, 1) + self.AddParam("Pads", "outline y margin", self.uMM, 1) + + def CheckParameters(self): + + self.CheckParamPositiveInt("Pads", "*row count") + self.CheckParamPositiveInt("Pads", "*column count") + + + def GetReference(self): + + pins = self.parameters["Pads"]["*row count"] * self.parameters["Pads"]["*column count"] + + return "BGA %d" % pins + + + def GetValuePrefix(self): + return "U" + + + def BuildThisFootprint(self): + + pads = self.parameters["Pads"] + + rows = pads["*row count"] + cols = pads["*column count"] + pad_size = pads["pad size"] + + pad_size = pcbnew.wxSize(pad_size, pad_size) + + pad_pitch = pads["pad pitch"] + + # add in the pads + pad = PA.PadMaker(self.module).SMTRoundPad(pads["pad size"]) + + pin1Pos = pcbnew.wxPoint(-((rows - 1) * pad_pitch) / 2, + -((cols - 1) * pad_pitch) / 2) + + array = BGAPadGridArray(pad, rows, cols, pad_pitch, pad_pitch, pin1Pos) + array.AddPadsToModule() + + #box + ssX = -pin1Pos.x + pads["outline x margin"] + ssY = -pin1Pos.y + pads["outline y margin"] + + self.draw.BoxWithDiagonalAtCorner(0, 0, ssX*2, ssY*2, pads["outline x margin"]) + + #reference and value + textSize = pcbnew.FromMM(0.8) + + self.draw.Value(0, - ssY - textSize, textSize) + self.draw.Reference(0, ssY + textSize, textSize) + + +BGAWizard().register() diff --git a/pcbnew/scripting/plugins/qfp_wizard.py b/pcbnew/scripting/plugins/qfp_wizard.py index 2df89e113b..0034c1fadb 100644 --- a/pcbnew/scripting/plugins/qfp_wizard.py +++ b/pcbnew/scripting/plugins/qfp_wizard.py @@ -1,235 +1,89 @@ +from __future__ import division import pcbnew -def abs(x): - if x < 0: - return -x +import HelpfulFootprintWizardPlugin +import PadArray as PA - return x +class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin): -class QFPWizard(pcbnew.FootprintWizardPlugin): - def __init__(self): - pcbnew.FootprintWizardPlugin.__init__(self) - self.name = "QFP" - self.description = "QFP Footprint Wizard" - self.parameters = { - "Pads": { - "*n": 100, - "pitch": pcbnew.FromMM(0.5), - "width": pcbnew.FromMM(0.25), - "length": pcbnew.FromMM(1.5), - "horizontal pitch": pcbnew.FromMM(15), - "vertical pitch": pcbnew.FromMM(15), - "*oval": "True" - }, - "Package": { - "width": pcbnew.FromMM(14), - "height": pcbnew.FromMM(14) - } - } + def GetName(self): + return "QFP" - self.ClearErrors() + def GetDescription(self): + return "QFP Footprint Wizard" - def smd_rect_pad(self, module, size, pos, name): - pad = pcbnew.D_PAD(module) + def GenerateParameterList(self): + self.AddParam("Pads", "n", self.uNatural, 100) + self.AddParam("Pads", "pad pitch", self.uMM, 0.5) + self.AddParam("Pads", "pad width", self.uMM, 0.25) + self.AddParam("Pads", "pad length", self.uMM, 1.5) + self.AddParam("Pads", "vertical pitch", self.uMM, 15) + self.AddParam("Pads", "horizontal pitch", self.uMM, 15) + self.AddParam("Pads", "oval", self.uBool, True) - pad.SetSize(size) - - if self.parameters['Pads'].get('*oval', "true").lower() == "true": - pad.SetShape(pcbnew.PAD_OVAL) - else: - pad.SetShape(pcbnew.PAD_RECT) - - pad.SetAttribute(pcbnew.PAD_SMD) - pad.SetLayerMask(pcbnew.PAD_SMD_DEFAULT_LAYERS) - pad.SetPos0(pos) - pad.SetPosition(pos) - pad.SetPadName(name) - - return pad + self.AddParam("Pads", "package width", self.uMM, 14) + self.AddParam("Pads", "package height", self.uMM, 14) def CheckParameters(self): - errors = "" - pads = self.parameters - num_pads = pads["Pads"]["*n"] - if (num_pads < 1): - self.parameter_errors["Pads"]["*n"] = "Must be positive" - errors +="Pads/n has wrong value, " - pads["Pads"]["*n"] = int(num_pads) # Reset to int instead of float + self.CheckParamPositiveInt("Pads", "*n", is_multiple_of = 4) - return errors + def GetReference(self): + return "QFP %d" % self.parameters["Pads"]["*n"] - def BuildFootprint(self): - if self.has_errors(): - print "Cannot build footprint: Parameters have errors:" - print self.parameter_errors - return + def BuildThisFootprint(self): - print "Building new QFP footprint with the following parameters:" - self.print_parameter_table() + pads = self.parameters["Pads"] - self.module = pcbnew.MODULE(None) # create a new module + pad_pitch = pads["pad pitch"] + pad_length = self.parameters["Pads"]["pad length"] + pad_width = self.parameters["Pads"]["pad width"] - pads = self.parameters - num_pads = int(pads["Pads"]["*n"]) - pad_width = pads["Pads"]["width"] - pad_length = pads["Pads"]["length"] - pad_pitch = pads["Pads"]["pitch"] - pad_horizontal_pitch = pads["Pads"]["horizontal pitch"] - pad_vertical_pitch = pads["Pads"]["vertical pitch"] + v_pitch = pads["vertical pitch"] + h_pitch = pads["horizontal pitch"] - package_width = pads["Package"]["width"] - package_height = pads["Package"]["height"] + pads_per_row = pads["*n"] // 4 - side_length = pad_pitch * ((num_pads / 4) - 1) + row_len = (pads_per_row - 1) * pad_pitch - offsetX = pad_pitch * ((num_pads / 4) - 1) / 2 - text_size = pcbnew.wxSize(pcbnew.FromMM(0.8), pcbnew.FromMM(0.8)) + h_pad = PA.PadMaker(self.module).SMDPad(pad_width, pad_length, shape = pcbnew.PAD_OVAL) + v_pad = PA.PadMaker(self.module).SMDPad(pad_length, pad_width, shape = pcbnew.PAD_OVAL) - self.module.SetReference("QFP %d" % int(num_pads)) - self.module.Reference().SetPos0(pcbnew.wxPoint(0, pcbnew.FromMM(-0.8))) - self.module.Reference().SetTextPosition(self.module.Reference().GetPos0()) - self.module.Reference().SetSize(text_size) + #left row + pin1Pos = pcbnew.wxPoint(-h_pitch / 2, -row_len / 2) + array = PA.PadLineArray(h_pad, pads_per_row, pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(1) + array.AddPadsToModule() - self.module.SetValue("U**") - self.module.Value().SetPos0(pcbnew.wxPoint(0, pcbnew.FromMM(+0.8))) - self.module.Value().SetTextPosition(self.module.Value().GetPos0()) - self.module.Value().SetSize(text_size) + #bottom row + pin1Pos = pcbnew.wxPoint(-row_len / 2, v_pitch / 2) + array = PA.PadLineArray(v_pad, pads_per_row, pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(pads_per_row + 1) + array.AddPadsToModule() - fpid = pcbnew.FPID(self.module.GetReference()) #the name in library - self.module.SetFPID( fpid ) + #right row + pin1Pos = pcbnew.wxPoint(h_pitch / 2, row_len / 2) + array = PA.PadLineArray(h_pad, pads_per_row, -pad_pitch, True, pin1Pos) + array.SetFirstPadInArray(2*pads_per_row + 1) + array.AddPadsToModule() - pad_size_left_right = pcbnew.wxSize(pad_length, pad_width) - pad_size_bottom_top = pcbnew.wxSize(pad_width, pad_length) + #top row + pin1Pos = pcbnew.wxPoint(row_len / 2, -v_pitch / 2) + array = PA.PadLineArray(v_pad, pads_per_row, -pad_pitch, False, pin1Pos) + array.SetFirstPadInArray(3*pads_per_row + 1) + array.AddPadsToModule() - for cur_pad in range(0, num_pads): - side = int(cur_pad / (num_pads / 4)) # 0 -> left, 1 -> bottom, 2 -> right, 3 -> top + limX = pads["package width"] / 2 + limY = pads["package height"] / 2 + inner = (row_len / 2) + pad_pitch - if side == 0 or side == 2: - pad_size = pad_size_left_right - - pad_pos_x = -(pad_horizontal_pitch / 2) - pad_pos_y = (cur_pad % (num_pads / 4)) * pad_pitch - (side_length / 2) - - if side == 2: - pad_pos_x = -pad_pos_x - pad_pos_y = -pad_pos_y - - else: - pad_size = pad_size_bottom_top - - pad_pos_x = (cur_pad % (num_pads / 4)) * pad_pitch - (side_length / 2) - pad_pos_y = -(pad_vertical_pitch / 2) - - if side == 1: - pad_pos_y = -pad_pos_y - else: - pad_pos_x = -pad_pos_x - - pad_pos = pcbnew.wxPoint(pad_pos_x, pad_pos_y) - - pad = self.smd_rect_pad(self.module, pad_size, pad_pos, str(cur_pad + 1)) - - self.module.Add(pad) - - half_package_width = package_width / 2 - half_package_height = package_height / 2 - - package_pad_height_offset = abs(package_height - side_length) / 2 - pad_pitch - package_pad_width_offset = abs(package_width - side_length) / 2 - pad_pitch - - # Bottom Left Edge, vertical line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(-half_package_width, half_package_height - package_pad_height_offset) - end = pcbnew.wxPoint(-half_package_width, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Bottom Left Edge, horizontal line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(-half_package_width, half_package_height) - end = pcbnew.wxPoint(-half_package_width + package_pad_width_offset, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Bottom Right Edge, vertical line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, half_package_height - package_pad_height_offset) - end = pcbnew.wxPoint(half_package_width, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Bottom Right Edge, horizontal line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, half_package_height) - end = pcbnew.wxPoint(half_package_width - package_pad_width_offset, half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Top Right Edge, vertical line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, -half_package_height + package_pad_height_offset) - end = pcbnew.wxPoint(half_package_width, -half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Top Right Edge, horizontal line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(half_package_width, -half_package_height) - end = pcbnew.wxPoint(half_package_width - package_pad_width_offset, -half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - # Top Left Edge, straight line - outline = pcbnew.EDGE_MODULE(self.module) - outline.SetWidth(pcbnew.FromMM(0.2)) - outline.SetLayer(pcbnew.SILKSCREEN_N_FRONT) - outline.SetShape(pcbnew.S_SEGMENT) - start = pcbnew.wxPoint(-half_package_width, -half_package_height + package_pad_height_offset) - end = pcbnew.wxPoint(-half_package_width + package_pad_width_offset, -half_package_height) - outline.SetStartEnd(start, end) - self.module.Add(outline) - - def print_parameter_table(self): - for name, section in self.parameters.iteritems(): - print " %s:" % name - - for key, value in section.iteritems(): - unit = "" - if (type(value) is int or type(value) is float) and not "*" in key: - unit = "mm" - - if "*" in key: - key = key[1:] - else: - value = pcbnew.ToMM(value) - - print " %s: %s%s" % (key, value, unit) - - def has_errors(self): - for name, section in self.parameter_errors.iteritems(): - for k, v in section.iteritems(): - if v: - return True - - return False + #top left - diagonal + self.draw.Line(-limX, -inner, -inner, -limY) + # top right + self.draw.Polyline([(inner, -limY), (limX, -limY), (limX, -inner)]) + # bottom left + self.draw.Polyline([(-inner, limY), (-limX, limY), (-limX, inner)]) + # bottom right + self.draw.Polyline([(inner, limY), (limX, limY), (limX, inner)]) QFPWizard().register() diff --git a/pcbnew/scripting/plugins/sdip_wizard.py b/pcbnew/scripting/plugins/sdip_wizard.py new file mode 100644 index 0000000000..c2a37653cb --- /dev/null +++ b/pcbnew/scripting/plugins/sdip_wizard.py @@ -0,0 +1,200 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +from __future__ import division +import pcbnew + +import HelpfulFootprintWizardPlugin as HFPW +import PadArray as PA + + +class RowedGridArray(PA.PadGridArray): + + def NamingFunction(self, x, y): + if (x % 2) == 0: # even row, count up + return (x * self.ny) + y + 1; + else: # odd row, count down + return (self.ny * (x + 1)) - y; + +class RowedFootprint(HFPW.HelpfulFootprintWizardPlugin): + + def GenerateParameterList(self): + + # defaults for a DIP package + self.AddParam("Pads", "n", self.uNatural, 24) + self.AddParam("Pads", "silk screen inside", self.uBool, False) + self.AddParam("Pads", "row count", self.uNatural, 2) + + def CheckParameters(self): + self.CheckParamPositiveInt("Pads", "*row count") + self.CheckParamPositiveInt("Pads", "*n", is_multiple_of = self.parameters["Pads"]["*row count"]) + self.CheckParamBool("Pads", "*silk screen inside") #can do this internally to parameter manager? + + def BuildThisFootprint(self): + + pads = self.parameters["Pads"] + + num_pads = pads["*n"] + + pad_length = pads["pad length"] + pad_width = pads["pad width"] + row_pitch = pads["row spacing"] + pad_pitch = pads["pad pitch"] + num_rows = pads["*row count"] + + pads_per_row = num_pads // num_rows + + row_length = pad_pitch * (pads_per_row - 1) #fenceposts + + # add in the pads + pad = self.GetPad() + + pin1Pos = pcbnew.wxPoint(-((num_rows - 1) * row_pitch) / 2, -row_length / 2) + + array = RowedGridArray(pad, num_rows, pads_per_row, row_pitch, pad_pitch, pin1Pos) + array.AddPadsToModule() + + # draw the Silk Screen + + pad_length = pads["pad length"] + pad_width = pads["pad width"] + + ssXOffset = -pad_length / 2 - pads["outline x margin"] + ssYOffset = -pad_width / 2 - pads["outline y margin"] + + + if pads["*silk screen inside"]: + ssXOffset *= -1 + + ssX = -pin1Pos.x - ssXOffset + ssY = -pin1Pos.y - ssYOffset + + + self.DrawBox(ssX, ssY) + + #reference and value + textSize = pcbnew.FromMM(0.8) + + self.draw.Value(0, - ssY - textSize, textSize) + self.draw.Reference(0, ssY + textSize, textSize) + + +class SDIPWizard(RowedFootprint): + + def GetName(self): + return "S/DIP" + + def GetDescription(self): + return "Single/Dual Inline Package Footprint Wizard" + + def GenerateParameterList(self): + RowedFootprint.GenerateParameterList(self) + + self.AddParam("Pads", "pad pitch", self.uMils, 100) + self.AddParam("Pads", "pad width", self.uMils, 60) + self.AddParam("Pads", "pad length", self.uMils, 150) + self.AddParam("Pads", "row spacing", self.uMils, 300) + self.AddParam("Pads", "drill size", self.uMM, 1) + self.AddParam("Pads", "outline x margin", self.uMM, 0.5) + self.AddParam("Pads", "outline y margin", self.uMM, 1) + + def GetReference(self): + + rows = self.parameters["Pads"]["*row count"] + + if rows == 1: + name = "SIP" + elif rows == 2: + name = "DIP" + else: # triple and up aren't really a thing, but call it something! + name = "xIP" + + return "%s %d" % (name, self.parameters["Pads"]["*n"]) + + def GetPad(self): + pad_length = self.parameters["Pads"]["pad length"] + pad_width = self.parameters["Pads"]["pad width"] + drill = self.parameters["Pads"]["drill size"] + return PA.PadMaker(self.module).THPad(pad_width, pad_length, drill, shape = pcbnew.PAD_OVAL) + + def DrawBox(self, ssX, ssY): + + if self.parameters["Pads"]["*row count"] == 2: + + # ---------- + # |8 7 6 5 | + # > | + # |1 2 3 4 | + # ---------- + + # draw the notch + notchWidth = pcbnew.FromMM(3) + notchHeight = pcbnew.FromMM(1) + + self.draw.NotchedBox(0, 0, ssX*2, ssY*2, notchWidth, notchHeight) + else: + # ----------------- + # |1|2 3 4 5 6 7 8| + # ----------------- + self.draw.Box(ssX*2, ssY*2) + + #line between pin1 and pin2 + pad_pitch = self.parameters["Pads"]["pad pitch"]; + self.draw.HLine(-ssX, pin1Pos.y + pad_pitch/2, ssX * 2) + + return ssX, ssY + +SDIPWizard().register() + + +class SOICWizard(RowedFootprint): + + def GetName(self): + return "SOIC" + + def GetDescription(self): + return "SOIC, MSOP, SSOP, TSSOP, etc, footprint wizard" + + def GetReference(self): + return "%s %d" % ("SOIC", self.parameters["Pads"]["*n"]) + + def GenerateParameterList(self): + RowedFootprint.GenerateParameterList(self) + + #and override some of them + self.AddParam("Pads", "pad pitch", self.uMM, 1.27) + self.AddParam("Pads", "pad width", self.uMM, 0.6) + self.AddParam("Pads", "pad length", self.uMM, 2.2) + self.AddParam("Pads", "row spacing", self.uMM, 5.2) + + self.AddParam("Pads", "outline x margin", self.uMM, 0.5) + self.AddParam("Pads", "outline y margin", self.uMM, 0.5) + + def GetPad(self): + pad_length = self.parameters["Pads"]["pad length"] + pad_width = self.parameters["Pads"]["pad width"] + return PA.PadMaker(self.module).SMDPad(pad_width, pad_length, shape = pcbnew.PAD_RECT) + + def DrawBox(self, ssX, ssY): + + # ---------- + # |8 7 6 5 | + # |1 2 3 4 | + # \--------- + + self.draw.BoxWithDiagonalAtCorner(0, 0, ssX*2, ssY*2, pcbnew.FromMM(1)) + +SOICWizard().register() diff --git a/pcbnew/specctra.h b/pcbnew/specctra.h index 35572563fa..d2a5104d95 100644 --- a/pcbnew/specctra.h +++ b/pcbnew/specctra.h @@ -40,7 +40,7 @@ class TYPE_COLLECTOR; // outside the DSN namespace class BOARD; class TRACK; -class SEGVIA; +class VIA; class NETCLASS; class MODULE; @@ -3790,12 +3790,12 @@ class SPECCTRA_DB : public SPECCTRA_LEXER /** * Function makeVia - * makes any kind of PADSTACK using the given KiCad SEGVIA. - * @param aVia The SEGVIA to build the padstack from. + * makes any kind of PADSTACK using the given KiCad VIA. + * @param aVia The VIA to build the padstack from. * @return PADSTACK* - The padstack, which is on the heap only, user must save * or delete it. */ - PADSTACK* makeVia( const SEGVIA* aVia ); + PADSTACK* makeVia( const ::VIA* aVia ); /** * Function deleteNETs @@ -3827,10 +3827,10 @@ class SPECCTRA_DB : public SPECCTRA_LEXER /** * Function makeVIA - * instantiates a KiCad SEGVIA on the heap and initializes it with internal + * instantiates a KiCad VIA on the heap and initializes it with internal * values consistent with the given PADSTACK, POINT, and netcode. */ - SEGVIA* makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ); + ::VIA* makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ); //--------------------------------------------------------- diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 40aa2eeb97..ef452ce66d 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -834,7 +834,7 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter, } -PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia ) +PADSTACK* SPECCTRA_DB::makeVia( const ::VIA* aVia ) { LAYER_NUM topLayerNum; LAYER_NUM botLayerNum; @@ -1985,7 +1985,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) for( int i = 0; iType() == PCB_VIA_T ); int netcode = via->GetNetCode(); diff --git a/pcbnew/specctra_import.cpp b/pcbnew/specctra_import.cpp index 417d433bb3..dbe998375c 100644 --- a/pcbnew/specctra_import.cpp +++ b/pcbnew/specctra_import.cpp @@ -214,9 +214,9 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro } -SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ) +::VIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode ) throw( IO_ERROR ) { - SEGVIA* via = 0; + ::VIA* via = 0; SHAPE* shape; int shapeCount = aPadstack->Length(); @@ -261,10 +261,10 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet CIRCLE* circle = (CIRCLE*) shape->shape; int viaDiam = scale( circle->diameter, routeResolution ); - via = new SEGVIA( sessionBoard ); + via = new ::VIA( sessionBoard ); via->SetPosition( mapPt( aPoint, routeResolution ) ); via->SetDrill( drillDiam ); - via->SetShape( VIA_THROUGH ); + via->SetViaType( VIA_THROUGH ); via->SetWidth( viaDiam ); via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); } @@ -279,10 +279,10 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet CIRCLE* circle = (CIRCLE*) shape->shape; int viaDiam = scale( circle->diameter, routeResolution ); - via = new SEGVIA( sessionBoard ); + via = new ::VIA( sessionBoard ); via->SetPosition( mapPt( aPoint, routeResolution ) ); via->SetDrill( drillDiam ); - via->SetShape( VIA_THROUGH ); + via->SetViaType( VIA_THROUGH ); via->SetWidth( viaDiam ); via->SetLayerPair( LAYER_N_FRONT, LAYER_N_BACK ); } @@ -321,15 +321,15 @@ SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNet viaDiam = scale( circle->diameter, routeResolution ); } - via = new SEGVIA( sessionBoard ); + via = new ::VIA( sessionBoard ); via->SetPosition( mapPt( aPoint, routeResolution ) ); via->SetDrill( drillDiam ); if( (topLayerNdx==0 && botLayerNdx==1) || (topLayerNdx==copperLayerCount-2 && botLayerNdx==copperLayerCount-1)) - via->SetShape( VIA_MICROVIA ); + via->SetViaType( VIA_MICROVIA ); else - via->SetShape( VIA_BLIND_BURIED ); + via->SetViaType( VIA_BLIND_BURIED ); via->SetWidth( viaDiam ); @@ -546,7 +546,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IO_ERROR ) for( unsigned v=0; vvertexes.size(); ++v ) { - SEGVIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode ); + ::VIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode ); aBoard->Add( via ); } } diff --git a/pcbnew/swap_layers.cpp b/pcbnew/swap_layers.cpp index 11180b107b..e3bf92bc59 100644 --- a/pcbnew/swap_layers.cpp +++ b/pcbnew/swap_layers.cpp @@ -360,9 +360,9 @@ void PCB_EDIT_FRAME::Swap_Layers( wxCommandEvent& event ) if( pt_segm->Type() == PCB_VIA_T ) { - SEGVIA* Via = (SEGVIA*) pt_segm; + VIA* Via = (VIA*) pt_segm; - if( Via->GetShape() == VIA_THROUGH ) + if( Via->GetViaType() == VIA_THROUGH ) continue; LAYER_NUM top_layer, bottom_layer; diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 6fdc83dd4e..2511cb687e 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -519,7 +519,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const { // For vias it is enough if only one of layers is visible LAYER_NUM top, bottom; - static_cast( aItem )->LayerPair( &top, &bottom ); + static_cast( aItem )->LayerPair( &top, &bottom ); return board->IsLayerVisible( top ) || board->IsLayerVisible( bottom ); } diff --git a/pcbnew/tr_modif.cpp b/pcbnew/tr_modif.cpp index 59c0f042fb..2e929fc9a1 100644 --- a/pcbnew/tr_modif.cpp +++ b/pcbnew/tr_modif.cpp @@ -168,7 +168,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, /* A segment must be connected to the starting point, otherwise * it is unnecessary to analyze the other point */ - pt_segm = GetTrace( bufStart, bufEnd, start, startmasklayer ); + pt_segm = GetTrack( bufStart, bufEnd, start, startmasklayer ); if( pt_segm == NULL ) // Not connected to the track starting point. { @@ -183,7 +183,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, */ for( pt_del = bufStart, nbconnect = 0; ; ) { - pt_segm = GetTrace( pt_del, bufEnd, end, endmasklayer ); + pt_segm = GetTrack( pt_del, bufEnd, end, endmasklayer ); if( pt_segm == NULL ) break; diff --git a/pcbnew/zones_polygons_test_connections.cpp b/pcbnew/zones_polygons_test_connections.cpp index ce9c948c46..b1d69d0455 100644 --- a/pcbnew/zones_polygons_test_connections.cpp +++ b/pcbnew/zones_polygons_test_connections.cpp @@ -175,12 +175,15 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) } else if( item->Type() == PCB_VIA_T ) { - pos1 = pos2 = ( (SEGVIA*) item )->GetStart(); + const VIA *via = static_cast( item ); + pos1 = via->GetStart(); + pos2 = pos1; } else if( item->Type() == PCB_TRACE_T ) { - pos1 = ( (TRACK*) item )->GetStart(); - pos2 = ( (TRACK*) item )->GetEnd(); + const TRACK *trk = static_cast( item ); + pos1 = trk->GetStart(); + pos2 = trk->GetEnd(); } else {