diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index 01a6c8d2b1..0c85868990 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -1,5 +1,5 @@ /** - * @file wxBasePcbStruct.h + * @file wxBasePcbFrame.h * @brief Classes used in pcbnew, cvpcb and gerbview. */ @@ -239,13 +239,19 @@ public: MODULE* Create_1_Module( const wxString& aModuleName ); void Edit_Module( MODULE* module, wxDC* DC ); - void Rotate_Module( wxDC* DC, - MODULE* module, - int angle, - bool incremental ); - void Place_Module( MODULE* module, - wxDC* DC, - bool aDoNotRecreateRatsnest = false ); + void Rotate_Module( wxDC* DC, MODULE* module, int angle, bool incremental ); + + /** + * Function PlaceModule + * places \a aModule at the current cursor position and updates module coordinates + * with the new position. + * + * @param aModule A MODULE object point of the module to be placed. + * @param aDC A wxDC object point of the device context to draw \a aModule on + * or NULL if no display screen need updated. + * @param aDoNotRecreateRatsnest A bool true redraws the module rats nest. + */ + void PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreateRatsnest = false ); // module texts void RotateTextModule( TEXTE_MODULE* Text, wxDC* DC ); @@ -297,7 +303,7 @@ public: // loading footprints /** - * Function Get_Librairie_Module + * Function GetModuleLibrary * * Read active libraries or one library to find and load a given module * If found the module is linked to the tail of linked list of modules @@ -308,9 +314,9 @@ public: * @return a pointer to the new module, or NULL * */ - MODULE* Get_Librairie_Module( const wxString& aLibraryFullFilename, - const wxString& aModuleName, - bool aDisplayMessageError ); + MODULE* GetModuleLibrary( const wxString& aLibraryFullFilename, + const wxString& aModuleName, + bool aDisplayMessageError ); /** * Function Select_1_Module_From_List @@ -345,12 +351,12 @@ public: void Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus ); /** - * Function Test_1_Net_Ratsnest + * Function TestOneRatsNest * Compute the ratsnest relative to the net "net_code" * @param aDC - Device context to draw on. - * @param aNetcode = netcode used to compute the ratsnest. + * @param aNetCode = netcode used to compute the ratsnest. */ - int Test_1_Net_Ratsnest( wxDC* aDC, int aNetcode ); + int TestOneRatsNest( wxDC* aDC, int aNetCode ); /** * Function build_ratsnest_module @@ -362,7 +368,13 @@ public: */ void build_ratsnest_module( MODULE* aModule ); - void trace_ratsnest_module( wxDC* DC ); + /** + * Function TraceModuleRatsNest + * display the rats nest of a moving footprint, computed by + * build_ratsnest_module() + */ + void TraceModuleRatsNest( wxDC* aDC ); + void Build_Board_Ratsnest( wxDC* DC ); /** @@ -377,7 +389,14 @@ public: void trace_ratsnest_pad( wxDC* DC ); void build_ratsnest_pad( BOARD_ITEM* ref, const wxPoint& refpos, bool init ); - void Tst_Ratsnest( wxDC* DC, int ref_netcode ); + /** + * Fucntion TestRatsNest + * computes the active rats nest + * The general rats nest list must exist. + * Compute the ACTIVE rats nest in the general rats nest list + * if aNetCode == 0, test all nets, else test only aNetCode + */ + void TestRatsNest( wxDC* aDC, int aNetCode ); /** * Function TestConnections @@ -409,6 +428,7 @@ public: *

* This is a 2 pass computation. First we search a connection between a track segment * and a pad. If the connection is found, the segment netcode is set to the pad netcode. + *

*/ void RecalculateAllTracksNetcode(); diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 8f535306fa..217bb51c6c 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -327,6 +327,14 @@ public: */ bool OnHotkeyDeleteItem( wxDC* aDC ); + /** + * Function OnHotkeyPlaceItem + * Place the item (footprint, track, text .. ) found under the mouse cursor + * An item can be placed only if there is this item currently edited + * Only a footprint, a pad or a track can be placed + * @param aDC = current device context + * @return true if an item was placedd + */ bool OnHotkeyPlaceItem( wxDC* aDC ); bool OnHotkeyEditItem( int aIdCommand ); @@ -343,6 +351,8 @@ public: /** * Function OnHotkeyRotateItem * Rotate the item (text or footprint) found under the mouse cursor + * @note This command can be used with an item currently in edit. + * Only some items can be rotated (footprints and texts). * @param aIdCommand = the hotkey command id * @return true if an item was moved */ @@ -766,6 +776,15 @@ public: */ bool Delete_Module( MODULE* aModule, wxDC* aDC, bool aAskBeforeDeleting ); + /** + * Function Change_Side_Module + * Flip a footprint (switch layer from component or component to copper) + * The mirroring is made from X axis + * if a footprint is not on copper or component layer it is not flipped + * (it could be on an adhesive layer, not supported at this time) + * @param Module the footprint to flip + * @param DC Current Device Context. if NULL, no redraw + */ void Change_Side_Module( MODULE* Module, wxDC* DC ); void InstallExchangeModuleFrame( MODULE* ExchangeModuleModule ); diff --git a/pcbnew/automove.cpp b/pcbnew/automove.cpp index fb1a0b6295..f231a4bec7 100644 --- a/pcbnew/automove.cpp +++ b/pcbnew/automove.cpp @@ -271,7 +271,7 @@ void PCB_EDIT_FRAME::AutoMoveModulesOnPcb( bool PlaceModulesHorsPcb ) Ymax_size = MAX( Ymax_size, Module->m_BoundaryBox.GetHeight() ); - Place_Module( Module, NULL, true ); + PlaceModule( Module, NULL, true ); current.x += Module->m_BoundaryBox.GetWidth() + pas_grille; } diff --git a/pcbnew/autoplac.cpp b/pcbnew/autoplac.cpp index e01dbfdb42..d23ffe81ef 100644 --- a/pcbnew/autoplac.cpp +++ b/pcbnew/autoplac.cpp @@ -49,7 +49,7 @@ float MinCout; static int TstModuleOnBoard( BOARD* Pcb, MODULE* Module, bool TstOtherSide ); -static void TracePenaliteRectangle( BOARD* Pcb, +static void CreateKeepOutRectangle( BOARD* Pcb, int ux0, int uy0, int ux1, @@ -115,11 +115,11 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) Board.m_GridRouting = (int) GetScreen()->GetGridSize().x; - // Ensure Board.m_GridRouting has a reasonnable value: + // Ensure Board.m_GridRouting has a reasonable value: if( Board.m_GridRouting < 10 ) Board.m_GridRouting = 10; // Min value = 1/1000 inch - /* Compute module parmeters used in auto place */ + /* Compute module parameters used in auto place */ Module = GetBoard()->m_Modules; NbTotalModules = 0; @@ -143,6 +143,7 @@ void PCB_EDIT_FRAME::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) case PLACE_1_MODULE: if( ThisModule == Module ) Module->m_ModuleStatus |= MODULE_to_PLACE; + break; case PLACE_OUT_OF_BOARD: @@ -294,7 +295,7 @@ end_of_tst: /* Place module. */ CurrPosition = GetScreen()->GetCrossHairPosition(); GetScreen()->SetCrossHairPosition( PosOK ); - Place_Module( Module, DC ); + PlaceModule( Module, DC ); GetScreen()->SetCrossHairPosition( CurrPosition ); Module->CalculateBoundingBox(); @@ -567,7 +568,7 @@ void PCB_EDIT_FRAME::GenModuleOnBoard( MODULE* Module ) /* Trace clearance. */ marge = ( Board.m_GridRouting * Module->m_PadNum ) / GAIN; Penalite = PENALITE; - TracePenaliteRectangle( GetBoard(), ox, oy, fx, fy, marge, Penalite, layerMask ); + CreateKeepOutRectangle( GetBoard(), ox, oy, fx, fy, marge, Penalite, layerMask ); } @@ -582,8 +583,7 @@ void PCB_EDIT_FRAME::GenModuleOnBoard( MODULE* Module ) int PCB_EDIT_FRAME::RecherchePlacementModule( MODULE* Module, wxDC* DC ) { int cx, cy; - int ox, oy, fx, fy; /* occupying part of the module focuses on the - * cursor */ + int ox, oy, fx, fy; /* occupying part of the module focuses on the cursor */ int error = 1; int DisplayChevelu = 0; wxPoint LastPosOK; @@ -604,6 +604,7 @@ int PCB_EDIT_FRAME::RecherchePlacementModule( MODULE* Module, wxDC* DC ) CurrPosition.x = GetBoard()->m_BoundaryBox.m_Pos.x - ox; CurrPosition.y = GetBoard()->m_BoundaryBox.m_Pos.y - oy; + /* Module placement on grid. */ CurrPosition.x -= CurrPosition.x % Board.m_GridRouting; CurrPosition.y -= CurrPosition.y % Board.m_GridRouting; @@ -885,7 +886,7 @@ int TstModuleOnBoard( BOARD* Pcb, MODULE* Module, bool TstOtherSide ) /* - * Display the module's ratsnet during displacement, and + * Display the module's ratsnest during displacement, and * assess the "cost" of the position. * The cost is the longest ratsnest distance with penalty for connections * approaching 45 degrees. @@ -909,16 +910,14 @@ float PCB_EDIT_FRAME::Compute_Ratsnest_PlaceModule( wxDC* DC ) for( unsigned ii = 0; ii < GetBoard()->m_LocalRatsnest.size(); ii++ ) { - RATSNEST_ITEM* pt_local_chevelu = &GetBoard()->m_LocalRatsnest[ii]; + RATSNEST_ITEM* pt_local_rats_nest = &GetBoard()->m_LocalRatsnest[ii]; - if( !( pt_local_chevelu->m_Status & LOCAL_RATSNEST_ITEM ) ) + if( !( pt_local_rats_nest->m_Status & LOCAL_RATSNEST_ITEM ) ) { - ox = pt_local_chevelu->m_PadStart->GetPosition().x - - g_Offset_Module.x; - oy = pt_local_chevelu->m_PadStart->GetPosition().y - - g_Offset_Module.y; - fx = pt_local_chevelu->m_PadEnd->GetPosition().x; - fy = pt_local_chevelu->m_PadEnd->GetPosition().y; + ox = pt_local_rats_nest->m_PadStart->GetPosition().x - g_Offset_Module.x; + oy = pt_local_rats_nest->m_PadStart->GetPosition().y - g_Offset_Module.y; + fx = pt_local_rats_nest->m_PadEnd->GetPosition().x; + fy = pt_local_rats_nest->m_PadEnd->GetPosition().y; if( AutoPlaceShowAll ) { @@ -953,7 +952,7 @@ float PCB_EDIT_FRAME::Compute_Ratsnest_PlaceModule( wxDC* DC ) /* Draw keep out area of a module. */ /***********************************/ -/* Buid the cost map. +/* Build the cost map. * Cells ( in Dist mao ) inside the rect x0,y0 a x1,y1 are * incremented by value Penalite * Cell outside this rectangle, but inside the rectangle @@ -961,7 +960,7 @@ float PCB_EDIT_FRAME::Compute_Ratsnest_PlaceModule( wxDC* DC ) * (Penalite ... 0). The decreasing value de pends on the distance to the first rectangle * Therefore the cost is high in rect x0,y0 a x1,y1, and decrease outside this rectangle */ -static void TracePenaliteRectangle( BOARD* Pcb, +static void CreateKeepOutRectangle( BOARD* Pcb, int ux0, int uy0, int ux1, @@ -973,7 +972,7 @@ static void TracePenaliteRectangle( BOARD* Pcb, int row, col; int row_min, row_max, col_min, col_max, pmarge; int trace = 0; - DIST_CELL data, LocalPenalite; + DIST_CELL data, LocalKeepOut; int lgain, cgain; if( aLayerMask & g_TabOneLayerMask[Route_Layer_BOTTOM] ) @@ -993,7 +992,9 @@ static void TracePenaliteRectangle( BOARD* Pcb, ux0 -= marge; ux1 += marge; uy0 -= marge; uy1 += marge; - pmarge = marge / Board.m_GridRouting; if( pmarge < 1 ) + pmarge = marge / Board.m_GridRouting; + + if( pmarge < 1 ) pmarge = 1; /* Calculate the coordinate limits of the rectangle. */ @@ -1033,7 +1034,7 @@ static void TracePenaliteRectangle( BOARD* Pcb, for( col = col_min; col <= col_max; col++ ) { cgain = 256; - LocalPenalite = Penalite; + LocalKeepOut = Penalite; if( col < pmarge ) cgain = ( 256 * col ) / pmarge; @@ -1043,18 +1044,18 @@ static void TracePenaliteRectangle( BOARD* Pcb, cgain = ( cgain * lgain ) / 256; if( cgain != 256 ) - LocalPenalite = ( LocalPenalite * cgain ) / 256; + LocalKeepOut = ( LocalKeepOut * cgain ) / 256; if( trace & 1 ) { - data = GetDist( row, col, BOTTOM ) + LocalPenalite; + data = GetDist( row, col, BOTTOM ) + LocalKeepOut; SetDist( row, col, BOTTOM, data ); } if( trace & 2 ) { data = GetDist( row, col, TOP ); - data = MAX( data, LocalPenalite ); + data = MAX( data, LocalKeepOut ); SetDist( row, col, TOP, data ); } } @@ -1072,6 +1073,7 @@ static bool Tri_PlaceModules( MODULE* ref, MODULE* compare ) return ff2 < ff1; } + static bool Tri_RatsModules( MODULE* ref, MODULE* compare ) { double ff1, ff2; @@ -1084,7 +1086,7 @@ static bool Tri_RatsModules( MODULE* ref, MODULE* compare ) /* Find the "best" module place * The criteria of choice are: - * - Maximum ratsnet with modules already placed + * - Maximum ratsnest with modules already placed * - Max size, and number of pads max */ static MODULE* PickModule( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) @@ -1115,7 +1117,7 @@ static MODULE* PickModule( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) Module->DisplayInfo( pcbframe ); pcbframe->build_ratsnest_module( Module ); - /* Calculate external ratsnet. */ + /* Calculate external ratsnest. */ for( unsigned ii = 0; ii < pcbframe->GetBoard()->m_LocalRatsnest.size(); ii++ ) { if( ( pcbframe->GetBoard()->m_LocalRatsnest[ii].m_Status & @@ -1164,7 +1166,7 @@ static MODULE* PickModule( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) * Start from an initial point, to fill zone * The zone must have no "copper island" * Algorithm: - * If the current cell has a neightbour flagged as "cell in the zone", it + * If the current cell has a neighbor flagged as "cell in the zone", it * become a cell in the zone * The first point in the zone is the starting point * 4 searches within the matrix are made: @@ -1172,10 +1174,10 @@ static MODULE* PickModule( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) * 2 - Right to left and top to bottom * 3 - bottom to top and Right to left * 4 - bottom to top and Left to right - * Given the current cell, for each search, we consider the 2 neightbour cells + * Given the current cell, for each search, we consider the 2 neighbor cells * the previous cell on the same line and the previous cell on the same column. * - * This funtion can request some iterations + * This function can request some iterations * Iterations are made until no cell is added to the zone. * @return: added cells count (i.e. which the attribute CELL_is_ZONE is set) */ @@ -1192,7 +1194,7 @@ int Propagation( PCB_EDIT_FRAME* frame ) frame->MsgPanel->SetMessage( 57, wxT( "Detect" ), msg, CYAN ); frame->MsgPanel->SetMessage( -1, wxEmptyString, wxT( "1" ), CYAN ); - // Alloc memory to handle 1 line or 1 colunmn on the routing matrix + // Alloc memory to handle 1 line or 1 column on the routing matrix nn = MAX( Nrows, Ncols ) * sizeof(*pt_cell_V); pt_cell_V = (long*) MyMalloc( nn ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 4089914c30..dfd4265b88 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1634,6 +1634,37 @@ D_PAD* BOARD::GetPad( LISTE_PAD* aPad, const wxPoint& aPosition, int aLayerMask } +TRACK* BOARD::GetTrace( TRACK* aTrace, const wxPoint& aPosition, int aLayerMask ) +{ + for( TRACK* track = aTrace; track; track = track->Next() ) + { + int layer = track->GetLayer(); + + if( track->GetState( BUSY | IS_DELETED ) ) + continue; + + if( GetBoardDesignSettings()->IsLayerVisible( layer ) == false ) + continue; + + if( track->Type() == TYPE_VIA ) /* VIA encountered. */ + { + if( track->HitTest( aPosition ) ) + return track; + } + else + { + if( (g_TabOneLayerMask[layer] & aLayerMask) == 0 ) + continue; /* Segments on different layers. */ + + if( track->HitTest( aPosition ) ) + return track; + } + } + + return NULL; +} + + #if defined(DEBUG) void BOARD::Show( int nestLevel, std::ostream& os ) diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index e0bc73778c..00cf33c0fe 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -1134,13 +1134,26 @@ public: * GetPadFast(). This list is a sorted pad list must be built before calling this * function. *

- * @note The normal pad list #m_Pads is sorted by increasing netcodes. + * @note The normal pad list is sorted by increasing netcodes. * @param aPad A D_PAD object pointer the first pad in the list to begin searching. * @param aPosition A wxPoint object containing the position to test. - * @param aLayerMast A layer or layers to mask the hit test. + * @param aLayerMask A layer or layers to mask the hit test. * @return A D_PAD object pointer to the connected pad. */ D_PAD* GetPad( LISTE_PAD* aPad, const wxPoint& aPosition, int aLayerMask ); + + /** + * Function GetTrace + * 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. + * + * @param aTrace A pointer to the TRACK object to search. + * @param aPosition A wxPoint object containing the position to test. + * @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore + * layer mask. + * @return A TRACK object pointer if found otherwise NULL. + */ + TRACK* GetTrace( TRACK* aTrace, const wxPoint& aPosition, int aLayerMask ); }; #endif // #ifndef CLASS_BOARD_H diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 6c25583673..5a33c63944 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -30,6 +30,60 @@ static bool ShowClearance( const TRACK* aTrack ) } +/* + * return true if the dist between p1 and p2 < max_dist + * Currently in test (currently rasnest algos work only if p1 == p2) + */ +inline bool IsNear( wxPoint& p1, wxPoint& p2, int max_dist ) +{ +#if 0 // Do not change it: does not work + int dist; + dist = abs( p1.x - p2.x ) + abs( p1.y - p2.y ); + dist *= 7; + dist /= 10; + + if ( dist < max_dist ) + return true; +#else + if ( p1 == p2 ) + return true; +#endif + return false; +} + + +TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, const wxPoint& aPosition, int aLayerMask ) +{ + TRACK* PtSegm; + + if( aStartTrace == NULL ) + return NULL; + + for( PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() ) + { + if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 ) + { + if( aPosition == PtSegm->m_Start ) + { + if( aLayerMask & PtSegm->ReturnMaskLayer() ) + return PtSegm; + } + + if( aPosition == PtSegm->m_End ) + { + if( aLayerMask & PtSegm->ReturnMaskLayer() ) + return PtSegm; + } + } + + if( PtSegm == aEndTrace ) + break; + } + + return NULL; +} + + TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) : BOARD_CONNECTED_ITEM( aParent, idtype ) { @@ -1165,6 +1219,265 @@ TRACK* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, int aLayerMask } +TRACK* TRACK::GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ) +{ + const int NEIGHTBOUR_COUNT_MAX = 50; + + TRACK* previousSegment; + TRACK* nextSegment; + int Reflayer; + wxPoint position; + int ii; + int max_dist; + + if( aEndPoint == START ) + position = m_Start; + else + position = m_End; + + Reflayer = ReturnMaskLayer(); + + previousSegment = nextSegment = this; + + for( ii = 0; ii < NEIGHTBOUR_COUNT_MAX; ii++ ) + { + if( (nextSegment == NULL) && (previousSegment == NULL) ) + break; + + if( nextSegment ) + { + if( nextSegment->GetState( BUSY | IS_DELETED ) ) + goto suite; + + if( nextSegment == this ) + goto suite; + + /* max_dist is the max distance between 2 track ends which + * ensure a copper continuity */ + max_dist = ( nextSegment->m_Width + this->m_Width ) / 2; + + if( IsNear( position, nextSegment->m_Start, max_dist ) ) + { + if( Reflayer & nextSegment->ReturnMaskLayer() ) + return nextSegment; + } + + if( IsNear( position, nextSegment->m_End, max_dist ) ) + { + if( Reflayer & nextSegment->ReturnMaskLayer() ) + return nextSegment; + } +suite: + if( nextSegment == aEndTrace ) + nextSegment = NULL; + else + nextSegment = nextSegment->Next(); + } + + if( previousSegment ) + { + if( previousSegment->GetState( BUSY | IS_DELETED ) ) + goto suite1; + + if( previousSegment == this ) + goto suite1; + + max_dist = ( previousSegment->m_Width + m_Width ) / 2; + + if( IsNear( position, previousSegment->m_Start, max_dist ) ) + { + if( Reflayer & previousSegment->ReturnMaskLayer() ) + return previousSegment; + } + + if( IsNear( position, previousSegment->m_End, max_dist ) ) + { + if( Reflayer & previousSegment->ReturnMaskLayer() ) + return previousSegment; + } +suite1: + if( previousSegment == aStartTrace ) + previousSegment = NULL; + else if( previousSegment->Type() != TYPE_PCB ) + previousSegment = previousSegment->Back(); + else + previousSegment = NULL; + } + } + + /* General search. */ + for( nextSegment = aStartTrace; nextSegment != NULL; nextSegment = nextSegment->Next() ) + { + if( nextSegment->GetState( IS_DELETED | BUSY ) ) + { + if( nextSegment == aEndTrace ) + break; + + continue; + } + + if( nextSegment == this ) + { + if( nextSegment == aEndTrace ) + break; + + continue; + } + + max_dist = ( nextSegment->m_Width + m_Width ) / 2; + + if( IsNear( position, nextSegment->m_Start, max_dist ) ) + { + if( Reflayer & nextSegment->ReturnMaskLayer() ) + return nextSegment; + } + + if( IsNear( position, nextSegment->m_End, max_dist ) ) + { + if( Reflayer & nextSegment->ReturnMaskLayer() ) + return nextSegment; + } + + if( nextSegment == aEndTrace ) + break; + } + + return NULL; +} + + +int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace ) +{ + TRACK* Track, * via, * segm, * TrackListEnd; + int NbEnds, layerMask, ii, ok = 0; + + if( aCount <= 1 ) + { + *aStartTrace = *aEndTrace = this; + return 1; + } + + /* Calculation of the limit analysis. */ + *aStartTrace = *aEndTrace = NULL; + TrackListEnd = Track = this; + ii = 0; + + for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() ) + { + TrackListEnd = Track; + Track->m_Param = 0; + } + + /* Calculate the extremes. */ + NbEnds = 0; + Track = this; + ii = 0; + + for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() ) + { + if( Track->Type() == TYPE_VIA ) + continue; + + layerMask = Track->ReturnMaskLayer(); + via = GetVia( TrackListEnd, Track->m_Start, layerMask ); + + if( via ) + { + layerMask |= via->ReturnMaskLayer(); + via->SetState( BUSY, ON ); + } + + Track->SetState( BUSY, ON ); + segm = ::GetTrace( this, TrackListEnd, Track->m_Start, layerMask ); + Track->SetState( BUSY, OFF ); + + if( via ) + via->SetState( BUSY, OFF ); + + if( segm == NULL ) + { + switch( NbEnds ) + { + case 0: + *aStartTrace = Track; NbEnds++; + break; + + case 1: + int BeginPad, EndPad; + *aEndTrace = Track; + + /* Swap ox, oy with fx, fy */ + BeginPad = Track->GetState( BEGIN_ONPAD ); + EndPad = Track->GetState( END_ONPAD ); + + Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); + + if( BeginPad ) + Track->SetState( END_ONPAD, ON ); + + if( EndPad ) + Track->SetState( BEGIN_ONPAD, ON ); + + EXCHG( Track->m_Start, Track->m_End ); + EXCHG( Track->start, Track->end ); + ok = 1; + return ok; + } + } + + layerMask = Track->ReturnMaskLayer(); + via = GetVia( TrackListEnd, Track->m_End, layerMask ); + + if( via ) + { + layerMask |= via->ReturnMaskLayer(); + via->SetState( BUSY, ON ); + } + + Track->SetState( BUSY, ON ); + segm = ::GetTrace( this, TrackListEnd, Track->m_End, layerMask ); + Track->SetState( BUSY, OFF ); + + if( via ) + via->SetState( BUSY, OFF ); + + if( segm == NULL ) + { + switch( NbEnds ) + { + case 0: + int BeginPad, EndPad; + *aStartTrace = Track; + NbEnds++; + + /* Swap ox, oy with fx, fy */ + BeginPad = Track->GetState( BEGIN_ONPAD ); + EndPad = Track->GetState( END_ONPAD ); + + Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); + + if( BeginPad ) + Track->SetState( END_ONPAD, ON ); + + if( EndPad ) + Track->SetState( BEGIN_ONPAD, ON ); + + EXCHG( Track->m_Start, Track->m_End ); + EXCHG( Track->start, Track->end ); + break; + + case 1: + *aEndTrace = Track; + ok = 1; + return ok; + } + } + } + + return ok; +} + + wxString TRACK::GetSelectMenuText() const { wxString text; diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 09218d3eab..366b66a5d1 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -17,7 +17,26 @@ * to the near neighbor internal layer */ #define VIA_NOT_DEFINED 0 /* not yet used */ -/***/ + +/** + * Function GetTrace + * 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. + *

+ * The segments of track that are flagged as deleted or busy are ignored. Layer + * visibility is also ignored. + *

+ * @param aStartTrace A pointer to the TRACK object to begin searching. + * @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value + * searches to the end of the list. + * @param aPosition A wxPoint object containing the position to test. + * @param aLayerMask A layer or layers to mask the hit test. Use -1 to ignore + * layer mask. + * @return A TRACK object pointer if found otherwise NULL. + */ +extern TRACK* GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, const wxPoint& aPosition, + int aLayerMask ); + class TRACK : public BOARD_CONNECTED_ITEM { @@ -300,6 +319,31 @@ public: */ TRACK* GetVia( TRACK* aEndTrace, const wxPoint& aPosition, int aLayerMask ); + /** + * Function GetTrace + * return the trace segment connected to the segment at \a aEndPoint from \a + * aStartTrace to \a aEndTrace. + * + * @param aStartTrace A pointer to the TRACK object to begin searching. + * @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value + * searches to the end of the list. + * @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 ); + + /** + * Function GetEndSegments + * get the segments connected to the end point of the track. + * return 1 if OK, 0 when a track is a closed loop + * and the beginning and the end of the track in *StartTrack and *EndTrack + * Modify *StartTrack en *EndTrack : + * (*StartTrack)->m_Start coordinate is the beginning of the track + * (*EndTrack)->m_End coordinate is the end of the track + * Segments connected must be consecutive in list + */ + int GetEndSegments( int NbSegm, TRACK** StartTrack, TRACK** EndTrack ); + /** * Function GetClass * returns the class name. diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 813fb5e76a..74d5b0cbb1 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -245,7 +245,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* frame, wxDC* DC ) if( (type_end & START_ON_PAD ) == 0 ) { - other = GetConnectedTrace( segment, frame->GetBoard()->m_Track, NULL, START ); + other = segment->GetTrace( frame->GetBoard()->m_Track, NULL, START ); if( other == NULL ) // Test a connection to zones { @@ -278,7 +278,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* frame, wxDC* DC ) segment->SetState( BUSY, ON ); SEGVIA* via = (SEGVIA*) other; - other = GetConnectedTrace( via, frame->GetBoard()->m_Track, NULL, START ); + other = via->GetTrace( frame->GetBoard()->m_Track, NULL, START ); if( other == NULL ) { @@ -299,7 +299,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* frame, wxDC* DC ) // if not connected to a pad, test if segment's END is connected to another track if( (type_end & END_ON_PAD ) == 0 ) { - other = GetConnectedTrace( segment, frame->GetBoard()->m_Track, NULL, END ); + other = segment->GetTrace( frame->GetBoard()->m_Track, NULL, END ); if( other == NULL ) // Test a connection to zones { @@ -333,7 +333,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* frame, wxDC* DC ) segment->SetState( BUSY, ON ); SEGVIA* via = (SEGVIA*) other; - other = GetConnectedTrace( via, frame->GetBoard()->m_Track, NULL, END ); + other = via->GetTrace( frame->GetBoard()->m_Track, NULL, END ); if( other == NULL ) { @@ -458,7 +458,7 @@ static void clean_segments( PCB_EDIT_FRAME* frame ) // search for a possible point that connects on the START point of the segment for( segStart = segment->Next(); ; ) { - segStart = GetConnectedTrace( segment, segStart, NULL, START ); + segStart = segment->GetTrace( segStart, NULL, START ); if( segStart ) { @@ -472,7 +472,7 @@ static void clean_segments( PCB_EDIT_FRAME* frame ) /* We must have only one segment connected */ segStart->SetState( BUSY, ON ); - other = GetConnectedTrace( segment, frame->GetBoard()->m_Track, NULL, START ); + other = segment->GetTrace( frame->GetBoard()->m_Track, NULL, START ); segStart->SetState( BUSY, OFF ); if( other == NULL ) @@ -497,7 +497,7 @@ static void clean_segments( PCB_EDIT_FRAME* frame ) /* search for a possible point that connects on the END point of the segment: */ for( segEnd = segment->Next(); ; ) { - segEnd = GetConnectedTrace( segment, segEnd, NULL, END ); + segEnd = segment->GetTrace( segEnd, NULL, END ); if( segEnd ) { @@ -509,7 +509,7 @@ static void clean_segments( PCB_EDIT_FRAME* frame ) /* We must have only one segment connected */ segEnd->SetState( BUSY, ON ); - other = GetConnectedTrace( segment, frame->GetBoard()->m_Track, NULL, END ); + other = segment->GetTrace( frame->GetBoard()->m_Track, NULL, END ); segEnd->SetState( BUSY, OFF ); if( other == NULL ) @@ -662,7 +662,8 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks( wxDC* aDC ) } else { - other = GetConnectedTrace( segment, GetBoard()->m_Track, NULL, START ); + other = segment->GetTrace( GetBoard()->m_Track, NULL, START ); + if( other ) net_code_s = other->GetNet(); } @@ -679,7 +680,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks( wxDC* aDC ) } else { - other = GetConnectedTrace( segment, GetBoard()->m_Track, NULL, END ); + other = segment->GetTrace( GetBoard()->m_Track, NULL, END ); if( other ) net_code_e = other->GetNet(); @@ -825,7 +826,7 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* frame, wxDC* DC ) // test if the track is not precisely starting on the found pad if( segment->m_Start != pad->m_Pos ) { - if( GetConnectedTrace( segment, frame->GetBoard()->m_Track, NULL, START ) == NULL ) + if( segment->GetTrace( frame->GetBoard()->m_Track, NULL, START ) == NULL ) { TRACK* newTrack = segment->Copy(); @@ -849,7 +850,7 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* frame, wxDC* DC ) // test if the track is not precisely ending on the found pad if( segment->m_End != pad->m_Pos ) { - if( GetConnectedTrace( segment, frame->GetBoard()->m_Track, NULL, END ) == NULL ) + if( segment->GetTrace( frame->GetBoard()->m_Track, NULL, END ) == NULL ) { TRACK* newTrack = segment->Copy(); diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index ee339e2e7e..ad1d3eb009 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -378,7 +378,7 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode ) Merge_SubNets_Connected_By_CopperAreas( m_Pcb, aNetCode ); /* Test the ratsnest for this net */ - int nb_net_noconnect = Test_1_Net_Ratsnest( aDC, aNetCode ); + int nb_net_noconnect = TestOneRatsNest( aDC, aNetCode ); /* Display results */ msg.Printf( wxT( "links %d nc %d net:nc %d" ), @@ -450,12 +450,12 @@ static void Build_Pads_Info_Connections_By_Tracks( TRACK* pt_start_conn, TRACK* if( Track->start == NULL ) // end track not already connected, search a connection { - Track->start = GetConnectedTrace( Track, Track, pt_end_conn, START ); + Track->start = Track->GetTrace( Track, pt_end_conn, START ); } if( Track->end == NULL ) // end track not already connected, search a connection { - Track->end = GetConnectedTrace( Track, Track, pt_end_conn, END ); + Track->end = Track->GetTrace( Track, pt_end_conn, END ); } if( Track == pt_end_conn ) @@ -578,12 +578,12 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() { if( pt_trace->start == NULL ) { - pt_trace->start = GetConnectedTrace( pt_trace, m_Pcb->m_Track, NULL, START ); + pt_trace->start = pt_trace->GetTrace( m_Pcb->m_Track, NULL, START ); } if( pt_trace->end == NULL ) { - pt_trace->end = GetConnectedTrace( pt_trace, m_Pcb->m_Track, NULL, END ); + pt_trace->end = pt_trace->GetTrace( m_Pcb->m_Track, NULL, END ); } } @@ -608,7 +608,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() // Lock for a connection to a track with a known netcode pt_next = m_Pcb->m_Track; - while( ( pt_next = GetConnectedTrace( via, pt_next, NULL, START ) ) != NULL ) + while( ( pt_next = via->GetTrace( pt_next, NULL, START ) ) != NULL ) { if( pt_next->GetNet() ) { diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index ca26d13dff..b3854a2775 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -529,7 +529,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) SetCurItem( NULL ); // CurItem might be deleted by this command, clear the pointer TestConnections( NULL ); - Tst_Ratsnest( NULL, 0 ); // Recalculate the active ratsnest, i.e. the unconnected links + TestRatsNest( NULL, 0 ); // Recalculate the active ratsnest, i.e. the unconnected links OnModify(); GetBoard()->DisplayInfo( this ); DrawPanel->Refresh(); diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index 204865baee..bd3ca7ae69 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -191,7 +191,7 @@ void PCB_EDIT_FRAME::DisplayNetStatus( wxDC* DC ) int layerMask = (1 << getActiveLayer()); wxPoint pos = GetScreen()->RefPos( true ); - pt_segm = GetTrace( GetBoard(), GetBoard()->m_Track, pos, layerMask ); + pt_segm = GetBoard()->GetTrace( GetBoard()->m_Track, pos, layerMask ); if( pt_segm == NULL ) GetBoard()->DisplayInfo( this ); diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp index 6086ae8c71..949b8def10 100644 --- a/pcbnew/hotkeys_board_editor.cpp +++ b/pcbnew/hotkeys_board_editor.cpp @@ -1,6 +1,6 @@ -/***************/ +/****************************/ /* hotkeys_board_editor.cpp */ -/***************/ +/****************************/ #include "fctsys.h" #include "pcbnew.h" @@ -32,7 +32,7 @@ void PCB_EDIT_FRAME::RecordMacros(wxDC* aDC, int aNumber) if( m_RecordingMacros < 0 ) { - m_RecordingMacros = aNumber; + m_RecordingMacros = aNumber; m_Macros[aNumber].m_StartPosition = GetScreen()->GetCrossHairPosition(false); m_Macros[aNumber].m_Record.clear(); @@ -75,7 +75,9 @@ void PCB_EDIT_FRAME::CallMacros(wxDC* aDC, const wxPoint& aPosition, int aNumber screen->SetMousePosition( tPosition ); GeneralControl( aDC, tPosition ); - for( std::list::iterator i = m_Macros[aNumber].m_Record.begin(); i != m_Macros[aNumber].m_Record.end(); i++ ) + for( std::list::iterator i = m_Macros[aNumber].m_Record.begin(); + i != m_Macros[aNumber].m_Record.end(); + i++ ) { wxPoint tmpPos = screen->GetNearestGridPosition( tPosition + i->m_Position ); @@ -126,23 +128,34 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit if( HK_Descr == NULL ) return; - if( (m_RecordingMacros != -1) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_1) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_1) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_2) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_2) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_3) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_3) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_4) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_4) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_5) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_5) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_6) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_6) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_7) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_7) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_8) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_8) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_9) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_9) && - (HK_Descr->m_Idcommand != HK_RECORD_MACROS_0) && (HK_Descr->m_Idcommand != HK_CALL_MACROS_0) ) + if( (m_RecordingMacros != -1) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_1) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_1) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_2) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_2) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_3) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_3) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_4) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_4) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_5) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_5) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_6) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_6) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_7) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_7) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_8) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_8) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_9) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_9) + && (HK_Descr->m_Idcommand != HK_RECORD_MACROS_0) + && (HK_Descr->m_Idcommand != HK_CALL_MACROS_0) ) { MACROS_RECORD macros_record; macros_record.m_HotkeyCode = aHotkeyCode; macros_record.m_Idcommand = HK_Descr->m_Idcommand; - macros_record.m_Position = screen->GetNearestGridPosition( aPosition ) - m_Macros[m_RecordingMacros].m_StartPosition; - m_Macros[m_RecordingMacros].m_Record.push_back(macros_record); + macros_record.m_Position = screen->GetNearestGridPosition( aPosition ) - + m_Macros[m_RecordingMacros].m_StartPosition; + m_Macros[m_RecordingMacros].m_Record.push_back( macros_record ); } // Create a wxCommandEvent that will be posted in some hot keys functions @@ -162,87 +175,88 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit break; case HK_RECORD_MACROS_0: - RecordMacros(aDC, 0); + RecordMacros( aDC, 0 ); break; case HK_RECORD_MACROS_1: - RecordMacros(aDC, 1); + RecordMacros( aDC, 1 ); break; case HK_RECORD_MACROS_2: - RecordMacros(aDC, 2); + RecordMacros( aDC, 2 ); break; case HK_RECORD_MACROS_3: - RecordMacros(aDC, 3); + RecordMacros( aDC, 3 ); break; case HK_RECORD_MACROS_4: - RecordMacros(aDC, 4); + RecordMacros( aDC, 4 ); break; case HK_RECORD_MACROS_5: - RecordMacros(aDC, 5); + RecordMacros( aDC, 5 ); break; case HK_RECORD_MACROS_6: - RecordMacros(aDC, 6); + RecordMacros( aDC, 6 ); break; case HK_RECORD_MACROS_7: - RecordMacros(aDC, 7); + RecordMacros( aDC, 7 ); break; case HK_RECORD_MACROS_8: - RecordMacros(aDC, 8); + RecordMacros( aDC, 8 ); break; case HK_RECORD_MACROS_9: - RecordMacros(aDC, 9); + RecordMacros( aDC, 9 ); break; case HK_CALL_MACROS_0: - CallMacros(aDC, screen->GetCrossHairPosition(false), 0); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 0 ); break; case HK_CALL_MACROS_1: - CallMacros(aDC, screen->GetCrossHairPosition(false), 1); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 1 ); break; case HK_CALL_MACROS_2: - CallMacros(aDC, screen->GetCrossHairPosition(false), 2); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 2 ); break; case HK_CALL_MACROS_3: - CallMacros(aDC, screen->GetCrossHairPosition(false), 3); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 3 ); break; case HK_CALL_MACROS_4: - CallMacros(aDC, screen->GetCrossHairPosition(false), 4); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 4 ); break; case HK_CALL_MACROS_5: - CallMacros(aDC, screen->GetCrossHairPosition(false), 5); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 5 ); break; case HK_CALL_MACROS_6: - CallMacros(aDC, screen->GetCrossHairPosition(false), 6); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 6 ); break; case HK_CALL_MACROS_7: - CallMacros(aDC, screen->GetCrossHairPosition(false), 7); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 7 ); break; case HK_CALL_MACROS_8: - CallMacros(aDC, screen->GetCrossHairPosition(false), 8); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 8 ); break; case HK_CALL_MACROS_9: - CallMacros(aDC, screen->GetCrossHairPosition(false), 9); + CallMacros( aDC, screen->GetCrossHairPosition( false ), 9 ); break; case HK_SWITCH_TRACK_WIDTH_TO_NEXT: - GetBoard()->m_TrackWidthSelector = ( GetBoard()->m_TrackWidthSelector + 1 ) % GetBoard()->m_TrackWidthList.size(); + GetBoard()->m_TrackWidthSelector = ( GetBoard()->m_TrackWidthSelector + 1 ) % + GetBoard()->m_TrackWidthList.size(); break; case HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS: @@ -259,6 +273,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); OnSelectGrid( cmd ); } + break; case HK_SWITCH_GRID_TO_FASTGRID2: @@ -268,56 +283,66 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); OnSelectGrid( cmd ); } + break; case HK_SWITCH_GRID_TO_NEXT: if( m_SelGridBox ) { - m_SelGridBox->SetSelection( ( m_SelGridBox->GetSelection() + 1 ) % m_SelGridBox->GetCount() ); + m_SelGridBox->SetSelection( ( m_SelGridBox->GetSelection() + 1 ) % + m_SelGridBox->GetCount() ); cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); OnSelectGrid( cmd ); } + break; case HK_SWITCH_GRID_TO_PREVIOUS: if( m_SelGridBox ) { cnt = m_SelGridBox->GetSelection(); + if ( cnt == 0 ) cnt = m_SelGridBox->GetCount() - 1; else cnt--; + m_SelGridBox->SetSelection( cnt ); cmd.SetEventType( wxEVT_COMMAND_COMBOBOX_SELECTED ); OnSelectGrid( cmd ); } + break; case HK_SWITCH_LAYER_TO_PREVIOUS: ll = getActiveLayer(); + if( (ll <= LAYER_N_BACK) || (ll > LAYER_N_FRONT) ) break; if( GetBoard()->GetCopperLayerCount() < 2 ) // Single layer ll = LAYER_N_BACK; else if( ll == LAYER_N_FRONT ) - ll = MAX( LAYER_N_BACK, - GetBoard()->GetCopperLayerCount() - 2 ); + ll = MAX( LAYER_N_BACK, GetBoard()->GetCopperLayerCount() - 2 ); else ll--; + SwitchLayer( aDC, ll ); break; case HK_SWITCH_LAYER_TO_NEXT: ll = getActiveLayer(); + if( (ll < LAYER_N_BACK) || (ll >= LAYER_N_FRONT) ) break; + if( GetBoard()->GetCopperLayerCount() < 2 ) // Single layer ll = LAYER_N_BACK; else if( ll >= GetBoard()->GetCopperLayerCount() - 2 ) ll = LAYER_N_FRONT; else ll++; + SwitchLayer( aDC, ll ); break; @@ -388,6 +413,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent ); wxPostEvent( this, event ); } + break; case HK_RESET_LOCAL_COORD: /*Reset the relative coord */ @@ -425,6 +451,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit Delete_Segment( aDC, (TRACK*) item ); SetCurItem( NULL ); } + OnModify(); } else if( GetCurItem()->IsTrack() ) @@ -437,6 +464,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit OnModify(); } } + break; case HK_END_TRACK: @@ -446,41 +474,50 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit DrawPanel->MoveCursorToCrossHair(); End_Route( (TRACK*) GetCurItem(), aDC ); } + break; case HK_GET_AND_MOVE_FOOTPRINT: if( !itemCurrentlyEdited ) evt_type = ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST; + break; case HK_FIND_ITEM: if( !itemCurrentlyEdited ) evt_type = ID_FIND_ITEMS; + break; case HK_LOAD_BOARD: if( !itemCurrentlyEdited ) evt_type = ID_LOAD_FILE ; + break; case HK_SAVE_BOARD: if( !itemCurrentlyEdited ) evt_type = ID_SAVE_BOARD; + break; case HK_ADD_MICROVIA: // Place a micro via if a track is in progress if( GetToolId() != ID_TRACK_BUTT ) return; + if( !itemCurrentlyEdited ) // no track in progress: nothing to do break; + if( GetCurItem()->Type() != TYPE_TRACK ) // Should not occur return; + if( !GetCurItem()->IsNew() ) return; // place micro via and switch layer if( IsMicroViaAcceptable() ) evt_type = ID_POPUP_PCB_PLACE_MICROVIA; + break; case HK_ADD_VIA: // Switch to alternate layer and Place a via if a track is in progress @@ -489,12 +526,16 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit Other_Layer_Route( NULL, aDC ); break; } + if( GetToolId() != ID_TRACK_BUTT ) return; + if( GetCurItem()->Type() != TYPE_TRACK ) return; + if( !GetCurItem()->IsNew() ) return; + evt_type = ID_POPUP_PCB_PLACE_VIA; break; @@ -530,6 +571,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit { TRACK* track = Begin_Route( NULL, aDC ); SetCurItem( track ); + if( track ) DrawPanel->m_AutoPAN_Request = true; } @@ -541,8 +583,10 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit // because a track info is displayed while moving the mouse cursor if( track ) // A new segment was created SetCurItem( track, false ); + DrawPanel->m_AutoPAN_Request = true; } + break; case HK_EDIT_ITEM: // Edit board item @@ -568,6 +612,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit module->SetLocked( !module->IsLocked() ); module->DisplayInfo( this ); } + break; case HK_DRAG_ITEM: // Start drag module or track segment @@ -603,7 +648,7 @@ void PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit * Depending on the current active tool:: * Tool track * if a track is in progress: Delete the last segment - * else delete the entire track + * else delete the entire track * Tool module (footprint): * Delete the module. * @param aDC = current device context @@ -619,11 +664,14 @@ bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC ) case ID_TRACK_BUTT: if( getActiveLayer() > LAYER_N_FRONT ) return false; + if( ItemFree ) { item = PcbGeneralLocateAndDisplay(); + if( item && !item->IsTrack( ) ) return false; + Delete_Track( aDC, (TRACK*) item ); } else if( item->IsTrack( ) ) @@ -659,10 +707,13 @@ bool PCB_EDIT_FRAME::OnHotkeyDeleteItem( wxDC* aDC ) if( ItemFree ) { item = PcbGeneralLocateAndDisplay(); + if( item == NULL ) return false; + if( (item->Type() == TYPE_MODULE) && !IsOK( this, _( "Delete module?" ) ) ) return false; + RemoveStruct( item, aDC ); } else @@ -697,16 +748,19 @@ bool PCB_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand ) case TYPE_VIA: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_TRACKSEG; + break; case TYPE_TEXTE: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_TEXTEPCB; + break; case TYPE_MODULE: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_MODULE; + break; case TYPE_PAD: @@ -716,31 +770,37 @@ bool PCB_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand ) // the parent. if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_MODULE; + break; case PCB_TARGET_T: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_MIRE; + break; case TYPE_DIMENSION: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_DIMENSION; + break; case TYPE_TEXTE_MODULE: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_TEXTMODULE; + break; case TYPE_DRAWSEGMENT: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_DRAWING; + break; case TYPE_ZONE_CONTAINER: if( aIdCommand == HK_EDIT_ITEM ) evt_type = ID_POPUP_PCB_EDIT_ZONE_PARAMS; + break; default: @@ -790,16 +850,20 @@ bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand ) case TYPE_VIA: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_TRACK_NODE; + if( aIdCommand == HK_DRAG_ITEM ) evt_type = ID_POPUP_PCB_DRAG_TRACK_SEGMENT; + if( aIdCommand == HK_DRAG_TRACK_KEEP_SLOPE ) evt_type = ID_POPUP_PCB_DRAG_TRACK_SEGMENT_KEEP_SLOPE; + break; case TYPE_MODULE: { if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_MODULE_REQUEST; + if( aIdCommand == HK_DRAG_ITEM ) evt_type = ID_POPUP_PCB_DRAG_MODULE_REQUEST; } @@ -821,28 +885,34 @@ bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand ) case TYPE_TEXTE: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST; + break; case PCB_TARGET_T: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_MIRE_REQUEST; + break; case TYPE_ZONE_CONTAINER: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_ZONE_OUTLINES; + if( aIdCommand == HK_DRAG_ITEM ) evt_type = ID_POPUP_PCB_DRAG_ZONE_OUTLINE_SEGMENT; + break; case TYPE_TEXTE_MODULE: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST; + break; case TYPE_DRAWSEGMENT: if( aIdCommand == HK_MOVE_ITEM ) evt_type = ID_POPUP_PCB_MOVE_DRAWING_REQUEST; + break; default: @@ -861,14 +931,7 @@ bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand ) return false; } -/** - * Function OnHotkeyPlaceItem - * Place the item (footprint, track, text .. ) found under the mouse cursor - * An item can be placed only if there is this item currently edited - * Only a footprint, a pad or a track can be placed - * @param aDC = current device context - * @return true if an item was placedd - */ + bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC ) { BOARD_ITEM* item = GetCurItem(); @@ -888,6 +951,7 @@ bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC ) case TYPE_VIA: if( item->m_Flags & IS_DRAGGED ) PlaceDraggedOrMovedTrackSegment( (TRACK*) item, aDC ); + break; case TYPE_TEXTE: @@ -903,7 +967,7 @@ bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC ) break; case TYPE_MODULE: - Place_Module( (MODULE*) item, aDC ); + PlaceModule( (MODULE*) item, aDC ); break; case PCB_TARGET_T: @@ -913,6 +977,7 @@ bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC ) case TYPE_DRAWSEGMENT: if( no_tool ) // when no tools: existing item moving. Place_DrawItem( (DRAWSEGMENT*) item, aDC ); + break; default: @@ -924,18 +989,11 @@ bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC ) return true; } + return false; } -/** - * Function OnHotkeyRotateItem - * Rotate the item (text or footprint) found under the mouse cursor - * Note: - * this command can be used with an item currently in edit - * Only some items can be rotated (footprints and texts) - * @param aIdCommand = the hotkey command id - * @return true if an item was moved - */ + bool PCB_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand ) { BOARD_ITEM* item = GetCurItem(); @@ -956,6 +1014,7 @@ bool PCB_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand ) { if( aIdCommand == HK_ROTATE_ITEM ) // Rotation evt_type = ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE; + if( aIdCommand == HK_FLIP_FOOTPRINT ) // move to other side evt_type = ID_POPUP_PCB_CHANGE_SIDE_MODULE; } @@ -964,11 +1023,13 @@ bool PCB_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand ) case TYPE_TEXTE: if( aIdCommand == HK_ROTATE_ITEM ) // Rotation evt_type = ID_POPUP_PCB_ROTATE_TEXTEPCB; + break; case TYPE_TEXTE_MODULE: if( aIdCommand == HK_ROTATE_ITEM ) // Rotation evt_type = ID_POPUP_PCB_ROTATE_TEXTMODULE; + break; default: diff --git a/pcbnew/librairi.cpp b/pcbnew/librairi.cpp index 39b7fdadd9..03b748cbfb 100644 --- a/pcbnew/librairi.cpp +++ b/pcbnew/librairi.cpp @@ -122,7 +122,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() /* Display info : */ module->DisplayInfo( this ); - Place_Module( module, NULL ); + PlaceModule( module, NULL ); GetBoard()->m_Status_Pcb = 0; GetBoard()->m_NetInfo->BuildListOfNets(); @@ -411,6 +411,7 @@ void PCB_BASE_FRAME::Archive_Modules( const wxString& LibName, bool NewModulesOn NewModulesOnly ? false : true, false ) == 0 ) break; + DisplayActivity( (int) ( ii * step ), wxEmptyString ); /* Check for request to stop backup (ESCAPE key actuated) */ @@ -458,7 +459,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName, wxTextEntryDialog dlg( this, _( "Name:" ), _( "Save module" ), Name_Cmp ); if( dlg.ShowModal() != wxID_OK ) - return false; // cancelled by user + return false; // canceled by user Name_Cmp = dlg.GetValue(); Name_Cmp.Trim( true ); @@ -557,7 +558,7 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibName, if( strnicmp( Line, "$EndLIBRARY", 8 ) == 0 ) continue; - // Search fo the beginning of module section: + // Search for the beginning of module section: if( skip_header ) { if( strnicmp( Line, "$MODULE", 7 ) == 0 ) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 6499b4a00a..7f3868459c 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -58,7 +58,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* Module ) GetBoard()->m_NetInfo->BuildListOfNets(); GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); - Place_Module( Module, NULL ); + PlaceModule( Module, NULL ); if( Module->GetLayer() != LAYER_N_FRONT ) Module->Flip( Module->m_Pos ); @@ -123,9 +123,9 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& library, wxDC* } } - module = Get_Librairie_Module( library, ModuleName, false ); + module = GetModuleLibrary( library, ModuleName, false ); - if( ( module == NULL ) && AllowWildSeach ) /* Search with wildcard */ + if( ( module == NULL ) && AllowWildSeach ) /* Search with wild card */ { AllowWildSeach = false; wxString wildname = wxChar( '*' ) + ModuleName + wxChar( '*' ); @@ -139,7 +139,7 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& library, wxDC* } else { - module = Get_Librairie_Module( library, ModuleName, true ); + module = GetModuleLibrary( library, ModuleName, true ); } } @@ -175,21 +175,9 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& library, wxDC* } -/** - * Function Get_Librairie_Module - * - * Read active libraries or one library to find and load a given module - * If found the module is linked to the tail of linked list of modules - * @param aLibraryFullFilename: the full filename of the library to read. If empty, - * all active libraries are read - * @param aModuleName = module name to load - * @param aDisplayMessageError = true to display an error message if any. - * @return a MODULE * pointer to the new module, or NULL - * - */ -MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilename, - const wxString& aModuleName, - bool aDisplayMessageError ) +MODULE* PCB_BASE_FRAME::GetModuleLibrary( const wxString& aLibraryFullFilename, + const wxString& aModuleName, + bool aDisplayMessageError ) { wxFileName fn; wxString Name; @@ -296,20 +284,6 @@ MODULE* PCB_BASE_FRAME::Get_Librairie_Module( const wxString& aLibraryFullFilena } -/** - * Function Select_1_Module_From_List - * Display a list of modules found in active libraries or a given library - * - * @param aWindow - The active window. - * @param aLibraryFullFilename = library to list (if aLibraryFullFilename == - * void, list all modules) - * @param aMask = Display filter (wildcard)( Mask = wxEmptyString if not used ) - * @param aKeyWord = keyword list, to display a filtered list of module having - * one (or more) of these keyworks in their keyword list - * ( aKeyWord = wxEmptyString if not used ) - * - * @return wxEmptyString if abort or fails, or the selected module name if Ok - */ wxString PCB_BASE_FRAME::Select_1_Module_From_List( EDA_DRAW_FRAME* aWindow, const wxString& aLibraryFullFilename, const wxString& aMask, @@ -406,6 +380,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Select_1_Module_From_BOARD( BOARD* aPcb ) wxArrayString listnames; Module = aPcb->m_Modules; + for( ; Module != NULL; Module = (MODULE*) Module->Next() ) listnames.Add( Module->m_Reference->m_Text ); diff --git a/pcbnew/locate.cpp b/pcbnew/locate.cpp index e6065902e5..8188a81f62 100644 --- a/pcbnew/locate.cpp +++ b/pcbnew/locate.cpp @@ -107,253 +107,3 @@ MODULE* Locate_Prefered_Module( BOARD* aPcb, const wxPoint& aPosition, int aActi return NULL; } - - -/* - * return true if the dist between p1 and p2 < max_dist - * Currently in test (currently rasnest algos work only if p1 == p2) -*/ -inline bool IsPointsAreNear(wxPoint & p1, wxPoint & p2, int max_dist) -{ -#if 0 // Do not change it: does not work -{ -int dist; - dist = abs(p1.x - p2.x) + abs (p1.y - p2.y); - dist *= 7; - dist /= 10; - if ( dist < max_dist ) return true; -} -#else - if ( p1 == p2 ) return true; -#endif - return false; -} - - -/** - * Search for the track (or via) segment which is connected to the track - * segment PtRefSegm - * if extr == START, the starting track segment PtRefSegm is used to locate - * a connected segment - * if extr == END, the ending track segment PtRefSegm is used - * The test connection consider only end track segments - * - * Search is made from pt_base to pt_lim (in the track linked list) - * if pt_lim == NULL, the search is made from pt_base to the end of list - * - * In order to have a fast computation time: - * a first search is made considering only the +/- 50 next door neighbor - * of PtRefSegm. - * if no track is found : the entire list is tested - * - * @param PtRefSegm = reference segment - * @param pt_base = lower limit for search - * @param pt_lim = upper limit for search (can be NULL) - * @param extr = START or END = end of ref track segment to use in tests - */ -TRACK* GetConnectedTrace( TRACK* PtRefSegm, TRACK* pt_base, TRACK* pt_lim, int extr ) -{ - const int NEIGHTBOUR_COUNT_MAX = 50; - - TRACK* PtSegmB, * PtSegmN; - int Reflayer; - wxPoint pos_ref; - int ii; - int max_dist; - - if( extr == START ) - pos_ref = PtRefSegm->m_Start; - else - pos_ref = PtRefSegm->m_End; - - Reflayer = PtRefSegm->ReturnMaskLayer(); - - PtSegmB = PtSegmN = PtRefSegm; - - for( ii = 0; ii < NEIGHTBOUR_COUNT_MAX; ii++ ) - { - if( (PtSegmN == NULL) && (PtSegmB == NULL) ) - break; - - if( PtSegmN ) - { - if( PtSegmN->GetState( BUSY | IS_DELETED ) ) - goto suite; - - if( PtSegmN == PtRefSegm ) - goto suite; - - /* max_dist is the max distance between 2 track ends which - * ensure a copper continuity */ - max_dist = (PtSegmN->m_Width + PtRefSegm->m_Width)/2; - - if( IsPointsAreNear(pos_ref, PtSegmN->m_Start, max_dist) ) - { - if( Reflayer & PtSegmN->ReturnMaskLayer() ) - return PtSegmN; - } - - if( IsPointsAreNear(pos_ref, PtSegmN->m_End, max_dist) ) - { - if( Reflayer & PtSegmN->ReturnMaskLayer() ) - return PtSegmN; - } -suite: - if( PtSegmN == pt_lim ) - PtSegmN = NULL; - else - PtSegmN = PtSegmN->Next(); - } - - if( PtSegmB ) - { - if( PtSegmB->GetState( BUSY | IS_DELETED ) ) - goto suite1; - - if( PtSegmB == PtRefSegm ) - goto suite1; - - max_dist = (PtSegmB->m_Width + PtRefSegm->m_Width)/2; - - if( IsPointsAreNear(pos_ref, PtSegmB->m_Start, max_dist) ) - { - if( Reflayer & PtSegmB->ReturnMaskLayer() ) - return PtSegmB; - } - - if( IsPointsAreNear(pos_ref, PtSegmB->m_End, max_dist) ) - { - if( Reflayer & PtSegmB->ReturnMaskLayer() ) - return PtSegmB; - } -suite1: - if( PtSegmB == pt_base ) - PtSegmB = NULL; - else if( PtSegmB->Type() != TYPE_PCB ) - PtSegmB = PtSegmB->Back(); - else - PtSegmB = NULL; - } - } - - /* General search. */ - for( PtSegmN = pt_base; PtSegmN != NULL; PtSegmN = PtSegmN->Next() ) - { - if( PtSegmN->GetState( IS_DELETED | BUSY ) ) - { - if( PtSegmN == pt_lim ) - break; - - continue; - } - - if( PtSegmN == PtRefSegm ) - { - if( PtSegmN == pt_lim ) - break; - - continue; - } - - max_dist = ( PtSegmN->m_Width + PtRefSegm->m_Width ) / 2; - - if( IsPointsAreNear( pos_ref, PtSegmN->m_Start, max_dist ) ) - { - if( Reflayer & PtSegmN->ReturnMaskLayer() ) - return PtSegmN; - } - - if( IsPointsAreNear( pos_ref, PtSegmN->m_End, max_dist ) ) - { - if( Reflayer & PtSegmN->ReturnMaskLayer() ) - return PtSegmN; - } - - if( PtSegmN == pt_lim ) - break; - } - - return NULL; -} - - -/* - * 1 - Locate segment of track leading from the mouse. - * 2 - Locate segment of track point by point - * ref_pos.x, ref_pos.y.r - * - * The search begins to address start_adresse - */ -TRACK* GetTrace( BOARD* aPcb, TRACK* start_adresse, const wxPoint& ref_pos, int LayerMask ) -{ - for( TRACK* track = start_adresse; track; track = track->Next() ) - { - int layer = track->GetLayer(); - - if( track->GetState( BUSY | IS_DELETED ) ) - { - // D( printf( "track %p is BUSY | IS_DELETED. BUSY=%d IS_DELETED=%d\n", - // track, track->GetState( BUSY ), - // track->GetState( IS_DELETED ) );) - continue; - } - - if( aPcb->GetBoardDesignSettings()->IsLayerVisible( layer ) == false ) - continue; - - if( track->Type() == TYPE_VIA ) /* VIA encountered. */ - { - if( track->HitTest( ref_pos ) ) - return track; - } - else - { - if( (g_TabOneLayerMask[layer] & LayerMask) == 0 ) - continue; /* Segments on different layers. */ - - if( track->HitTest( ref_pos ) ) - return track; - } - } - - return NULL; -} - - -/* Locate segment with one end that coincides with the point x, y - * Data on layers by masklayer - * Research is done to address start_adr has end_adr - * If end_adr = NULL, end search list - * The segments of track marks with the flag are not IS_DELETED or taken - * into account - */ -TRACK* GetTrace( TRACK* start_adr, TRACK* end_adr, const wxPoint& ref_pos, int MaskLayer ) -{ - TRACK* PtSegm; - - if( start_adr == NULL ) - return NULL; - - for( PtSegm = start_adr; PtSegm != NULL; PtSegm = PtSegm->Next() ) - { - if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 ) - { - if( ref_pos == PtSegm->m_Start ) - { - if( MaskLayer & PtSegm->ReturnMaskLayer() ) - return PtSegm; - } - - if( ref_pos == PtSegm->m_End ) - { - if( MaskLayer & PtSegm->ReturnMaskLayer() ) - return PtSegm; - } - } - - if( PtSegm == end_adr ) - break; - } - - return NULL; -} diff --git a/pcbnew/magnetic_tracks_functions.cpp b/pcbnew/magnetic_tracks_functions.cpp index 8f6c6b656c..3c02505559 100644 --- a/pcbnew/magnetic_tracks_functions.cpp +++ b/pcbnew/magnetic_tracks_functions.cpp @@ -193,7 +193,7 @@ bool Magnetize( BOARD* m_Pcb, PCB_EDIT_FRAME* frame, int aCurrentTool, wxSize gr { int layer_mask = g_TabOneLayerMask[layer]; - TRACK* track = GetTrace( m_Pcb, m_Pcb->m_Track, pos, layer_mask ); + TRACK* track = m_Pcb->GetTrace( m_Pcb->m_Track, pos, layer_mask ); if( !track || track->Type() != TYPE_TRACK ) { diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index fab89fb99e..403853ea81 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -330,7 +330,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { wxPoint cursor_pos = pcbframe->GetScreen()->GetCrossHairPosition(); pcbframe->GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); - pcbframe->Place_Module( newmodule, NULL ); + pcbframe->PlaceModule( newmodule, NULL ); pcbframe->GetScreen()->SetCrossHairPosition( cursor_pos ); newmodule->m_TimeStamp = GetTimeStamp(); pcbframe->SaveCopyInUndoList( newmodule, UR_NEW ); @@ -568,7 +568,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) { EDGE_MODULE* edge = NULL; if( GetScreen()->GetCurItem() - && ( GetScreen()->GetCurItem()->Type() == TYPE_EDGE_MODULE ) ) + && ( GetScreen()->GetCurItem()->Type() == TYPE_EDGE_MODULE ) ) { edge = (EDGE_MODULE*) GetScreen()->GetCurItem(); } diff --git a/pcbnew/modules.cpp b/pcbnew/modules.cpp index 369ef2a9ea..aa51add2c5 100644 --- a/pcbnew/modules.cpp +++ b/pcbnew/modules.cpp @@ -69,6 +69,7 @@ void PCB_EDIT_FRAME::StartMove_Module( MODULE* module, wxDC* DC ) delete s_ModuleInitialCopy; s_PickedList.ClearItemsList(); // Should be empty, but... + // Creates a copy of the current module, for abort and undo commands s_ModuleInitialCopy = new MODULE( GetBoard() ); s_ModuleInitialCopy->Copy( module ); @@ -256,14 +257,6 @@ void MoveFootprint( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, } -/** - * Function Delete Module - * Remove a footprint from m_Modules linked list and put it in undelete buffer - * The ratsnest and pad list are recalculated - * @param aModule = footprint to delete - * @param aDC = currentDevice Context. if NULL: do not redraw new ratsnest - * @param aAskBeforeDeleting : if true: ask for confirmation before deleting - */ bool PCB_EDIT_FRAME::Delete_Module( MODULE* aModule, wxDC* aDC, bool aAskBeforeDeleting ) { wxString msg; @@ -304,15 +297,6 @@ bool PCB_EDIT_FRAME::Delete_Module( MODULE* aModule, wxDC* aDC, bool aAskBeforeD } -/** - * Function Change_Side_Module - * Flip a footprint (switch layer from component or component to copper) - * The mirroring is made from X axis - * if a footprint is not on copper or component layer it is not flipped - * (it could be on an adhesive layer, not supported at this time) - * @param Module the footprint to flip - * @param DC Current Device Context. if NULL, no redraw - */ void PCB_EDIT_FRAME::Change_Side_Module( MODULE* Module, wxDC* DC ) { if( Module == NULL ) @@ -380,29 +364,24 @@ void PCB_EDIT_FRAME::Change_Side_Module( MODULE* Module, wxDC* DC ) } -/* Place module at cursor position. - * - * DC (if NULL: no display screen has the output. - * Update module coordinates with the new position. - */ -void PCB_BASE_FRAME::Place_Module( MODULE* module, wxDC* DC, bool aDoNotRecreateRatsnest ) +void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreateRatsnest ) { TRACK* pt_segm; wxPoint newpos; - if( module == 0 ) + if( aModule == 0 ) return; OnModify(); GetBoard()->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK); - if( module->IsNew() ) + if( aModule->IsNew() ) { - SaveCopyInUndoList( module, UR_NEW ); + SaveCopyInUndoList( aModule, UR_NEW ); } - else if( (module->m_Flags & IS_MOVED ) ) + else if( (aModule->m_Flags & IS_MOVED ) ) { - ITEM_PICKER picker( module, UR_CHANGED ); + ITEM_PICKER picker( aModule, UR_CHANGED ); picker.m_Link = s_ModuleInitialCopy; s_PickedList.PushItem( picker ); s_ModuleInitialCopy = NULL; // the picker is now owner of s_ModuleInitialCopy. @@ -417,18 +396,18 @@ void PCB_BASE_FRAME::Place_Module( MODULE* module, wxDC* DC, bool aDoNotRecreate s_PickedList.ClearItemsList(); } - if( g_Show_Module_Ratsnest && ( GetBoard()->m_Status_Pcb & LISTE_PAD_OK ) && DC ) - trace_ratsnest_module( DC ); + if( g_Show_Module_Ratsnest && ( GetBoard()->m_Status_Pcb & LISTE_PAD_OK ) && aDC ) + TraceModuleRatsNest( aDC ); newpos = GetScreen()->GetCrossHairPosition(); - module->SetPosition( newpos ); - module->m_Flags = 0; + aModule->SetPosition( newpos ); + aModule->m_Flags = 0; delete s_ModuleInitialCopy; s_ModuleInitialCopy = NULL; - if( DC ) - module->Draw( DrawPanel, DC, GR_OR ); + if( aDC ) + aModule->Draw( DrawPanel, aDC, GR_OR ); if( g_DragSegmentList.size() ) { @@ -438,8 +417,8 @@ void PCB_BASE_FRAME::Place_Module( MODULE* module, wxDC* DC, bool aDoNotRecreate pt_segm = g_DragSegmentList[ii].m_Segm; pt_segm->SetState( IN_EDIT, OFF ); - if( DC ) - pt_segm->Draw( DrawPanel, DC, GR_OR ); + if( aDC ) + pt_segm->Draw( DrawPanel, aDC, GR_OR ); } // Delete drag list @@ -450,12 +429,12 @@ void PCB_BASE_FRAME::Place_Module( MODULE* module, wxDC* DC, bool aDoNotRecreate DrawPanel->SetMouseCapture( NULL, NULL ); if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) && !aDoNotRecreateRatsnest ) - Compile_Ratsnest( DC, true ); + Compile_Ratsnest( aDC, true ); - if( DC ) + if( aDC ) DrawPanel->Refresh(); - module->DisplayInfo( this ); + aModule->DisplayInfo( this ); } @@ -559,6 +538,6 @@ void DrawModuleOutlines( EDA_DRAW_PANEL* panel, wxDC* DC, MODULE* module ) { PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) panel->GetParent(); frame->build_ratsnest_module( module ); - frame->trace_ratsnest_module( DC ); + frame->TraceModuleRatsNest( DC ); } } diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index 680b782b67..0238b1c31c 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -770,7 +770,7 @@ void SortTrackEndPoints( TRACK* track ) bool PCB_EDIT_FRAME::MergeCollinearTracks( TRACK* track, wxDC* DC, int end ) { - testtrack = (TRACK*) GetConnectedTrace( track, GetBoard()->m_Track, NULL, end ); + testtrack = track->GetTrace( GetBoard()->m_Track, NULL, end ); if( testtrack ) { @@ -844,7 +844,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC s_StartSegmentPresent = s_EndSegmentPresent = true; if( ( track->start == NULL ) || ( track->start->Type() == TYPE_TRACK ) ) - TrackToStartPoint = GetConnectedTrace( track, GetBoard()->m_Track, NULL, START ); + TrackToStartPoint = track->GetTrace( GetBoard()->m_Track, NULL, START ); // Test if more than one segment is connected to this point if( TrackToStartPoint ) @@ -852,14 +852,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToStartPoint->SetState( BUSY, ON ); if( ( TrackToStartPoint->Type() == TYPE_VIA ) - || GetConnectedTrace( track, GetBoard()->m_Track, NULL, START ) ) + || track->GetTrace( GetBoard()->m_Track, NULL, START ) ) error = true; TrackToStartPoint->SetState( BUSY, OFF ); } if( ( track->end == NULL ) || ( track->end->Type() == TYPE_TRACK ) ) - TrackToEndPoint = GetConnectedTrace( track, GetBoard()->m_Track, NULL, END ); + TrackToEndPoint = track->GetTrace( GetBoard()->m_Track, NULL, END ); // Test if more than one segment is connected to this point if( TrackToEndPoint ) @@ -867,7 +867,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToEndPoint->SetState( BUSY, ON ); if( (TrackToEndPoint->Type() == TYPE_VIA) - || GetConnectedTrace( track, GetBoard()->m_Track, NULL, END ) ) + || track->GetTrace( GetBoard()->m_Track, NULL, END ) ) error = true; TrackToEndPoint->SetState( BUSY, OFF ); @@ -1064,7 +1064,7 @@ BOARD_ITEM* LocateLockPoint( BOARD* Pcb, wxPoint pos, int LayerMask ) TRACK* ptsegm = GetTrace( Pcb->m_Track, NULL, pos, LayerMask ); if( ptsegm == NULL ) - ptsegm = GetTrace( Pcb, Pcb->m_Track, pos, LayerMask ); + ptsegm = Pcb->GetTrace( Pcb->m_Track, pos, LayerMask ); return ptsegm; } diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index deb5d44b74..52a7e69801 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -4,7 +4,7 @@ /* * Functions to read a netlist. They are: - * - Load new footprints and nitialize net info + * - Load new footprints and initialize net info * - Test for missing or extra footprints * - Recalculate full connectivity info * @@ -13,7 +13,7 @@ * between existing footprints an components in netlist) * This identification can be from 2 fields: * - The reference (U2, R5 ..): this is the normal mode - * - The Time Stamp (Signature Temporelle), useful after a full schematic + * - The Time Stamp (Signature Temporarily), useful after a full schematic * reannotation because references can be changed for the same schematic. * So when reading a netlist ReadPcbNetlist() can use references or time stamps * to identify footprints on board and the corresponding component in schematic. @@ -41,10 +41,12 @@ #include "dialog_netlist.h" + // constants used by ReadNetlistModuleDescr(): #define TESTONLY true #define READMODULE false + /* * Helper class, to store new footprints info found in netlist. * New footprints are footprints relative to new components found in netlist @@ -68,6 +70,7 @@ public: MODULE_INFO( const wxString& libname, ~MODULE_INFO() { }; }; + /* * Helper class, to read a netlist. */ @@ -86,7 +89,7 @@ private: // false to use netlist only to know component/footprint link public: - bool m_UseTimeStamp; // Set to true to identify footprits by time stamp + bool m_UseTimeStamp; // Set to true to identify footprints by time stamp // false to use schematic reference bool m_ChangeFootprints; // Set to true to change existing footprints to new ones // when netlist gives a different footprint name @@ -129,7 +132,7 @@ public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NUL * @return the component count, or -1 if netlist file cannot opened */ int BuildComponentsListFromNetlist( const wxString& aNetlistFilename, - wxArrayString& aBufName ); + wxArrayString& aBufName ); /** * function RemoveExtraFootprints @@ -185,6 +188,7 @@ private: bool readModuleComponentLinkfile( const wxString* aCmpIdent, wxString& aFootprintName ); }; + /** * Function OpenNetlistFile * used to open a netlist file @@ -195,6 +199,7 @@ static FILE* OpenNetlistFile( const wxString& aFullFileName ) return false; /* No filename: exit */ FILE* file = wxFopen( aFullFileName, wxT( "rt" ) ); + if( file == NULL ) { wxString msg; @@ -230,7 +235,8 @@ static bool SortByLibName( MODULE_INFO* ref, MODULE_INFO* cmp ) * when the netlist gives a different footprint. * false to keep existing footprints * @param aDeleteBadTracks - true to erase erroneous tracks after updating connectivity info. - * @param aDeleteExtraFootprints - true to remove unlocked footprints found on board but not in netlist. + * @param aDeleteExtraFootprints - true to remove unlocked footprints found on board but not + * in netlist. * @param aSelect_By_Timestamp - true to use schematic timestamps instead of schematic references * to identify footprints on board * (Must be used after a full reannotation in schematic). @@ -256,9 +262,11 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, wxString msg; msg.Printf( _( "Reading Netlist \"%s\"" ), GetChars( aNetlistFullFilename ) ); aMessageWindow->AppendText( msg + wxT( "\n" ) ); + if( ! aCmpFullFileName.IsEmpty() ) { - msg.Printf( _( "Using component/footprint link file \"%s\"" ), GetChars( aCmpFullFileName ) ); + msg.Printf( _( "Using component/footprint link file \"%s\"" ), + GetChars( aCmpFullFileName ) ); aMessageWindow->AppendText( msg + wxT( "\n" ) ); } } @@ -268,7 +276,7 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, OnModify(); - // Clear flags and pointeurs to avoid inconsistencies + // Clear flags and pointers to avoid inconsistencies GetBoard()->m_Status_Pcb = 0; SetCurItem( NULL ); @@ -301,6 +309,7 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, return true; } + /* function RemoveExtraFootprints * Remove (delete) not locked footprints found on board, but not in netlist */ @@ -309,20 +318,23 @@ void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) wxArrayString componentsInNetlist; // Build list of modules in the netlist - int modulesCount = - BuildComponentsListFromNetlist( aNetlistFileName, componentsInNetlist ); + int modulesCount = BuildComponentsListFromNetlist( aNetlistFileName, componentsInNetlist ); + if( modulesCount == 0 ) return; MODULE* nextModule; MODULE* module = m_pcbframe->GetBoard()->m_Modules; bool ask_user = true; + for( ; module != NULL; module = nextModule ) { int ii; nextModule = module->Next(); + if( module->m_ModuleStatus & MODULE_is_LOCKED ) continue; + for( ii = 0; ii < modulesCount; ii++ ) { if( module->m_Reference->m_Text.CmpNoCase( componentsInNetlist[ii] ) == 0 ) @@ -334,10 +346,12 @@ void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) if( ask_user ) { ask_user = false; + if( !IsOK( NULL, _( "Ok to delete not locked footprints not found in netlist?" ) ) ) break; } + module->DeleteStructure(); } } @@ -379,7 +393,10 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, /* First, read the netlist: Build the list of footprints to load (new * footprints) */ - FILE_LINE_READER netlineReader( aFile, m_netlistFullName ); // netlineReader dtor will close aFile + + // netlineReader dtor will close aFile + FILE_LINE_READER netlineReader( aFile, m_netlistFullName ); + while( netlineReader.ReadLine() ) { char* line = StrPurge( netlineReader.Line() ); @@ -389,11 +406,13 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, // Test for end of the current comment if( ( line = strchr( line, '}' ) ) == NULL ) continue; + is_comment = false; } if( *line == '{' ) /* Start Comment */ { is_comment = true; + if( ( line = strchr( line, '}' ) ) == NULL ) continue; } @@ -418,6 +437,7 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, /* Load new footprints */ bool success = loadNewModules(); + if( ! success ) wxMessageBox( _("Some footprints are not found in libraries") ); @@ -428,6 +448,7 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, m_currModule = NULL; state = 0; is_comment = false; + while( netlineReader.ReadLine() ) { char* line = StrPurge( netlineReader.Line() ); @@ -439,32 +460,40 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, continue; is_comment = false; } + if( *line == '{' ) // this is the beginning of a comment { is_comment = true; + if( ( line = strchr( line, '}' ) ) == NULL ) continue; } if( *line == '(' ) state++; + if( *line == ')' ) state--; if( state == 2 ) { m_currModule = ReadNetlistModuleDescr( line, READMODULE ); + if( m_currModule == NULL ) // the module could not be created (perhaps + { // footprint not found in library) continue; + } else /* clear pads netnames */ { D_PAD* pad = m_currModule->m_Pads; + for( ; pad != NULL; pad = pad->Next() ) { pad->SetNetname( wxEmptyString ); } } + continue; } @@ -546,15 +575,18 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) /* Test if module is already loaded. */ wxString * identMod = &textCmpReference; + if( m_UseTimeStamp ) identMod = &timeStampPath; MODULE* module = m_pcbframe->GetBoard()->m_Modules; MODULE* nextModule; bool found = false; + for( ; module != NULL; module = nextModule ) { nextModule = module->Next(); + if( m_UseTimeStamp ) /* identification by time stamp */ { if( timeStampPath.CmpNoCase( module->m_Path ) == 0 ) @@ -565,6 +597,7 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) if( textCmpReference.CmpNoCase( module->m_Reference->m_Text ) == 0 ) found = true; } + if( found ) // The footprint corresponding to the component is already on board { // This footprint is already on board @@ -573,22 +606,23 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) if( ! aTstOnly ) { cmpFootprintName = textFootprintName; // Use footprint name from netlist + if( m_useCmpFile ) // Try to get footprint name from .cmp file { m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName ); } - /* Module mismatch: current fotprint and footprint specified in + /* Module mismatch: current footprint and footprint specified in * net list are different. */ if( module->m_LibRef.CmpNoCase( cmpFootprintName ) != 0 ) { if( m_ChangeFootprints ) // footprint exchange allowed. { - MODULE* newModule = - m_pcbframe->Get_Librairie_Module( wxEmptyString, - cmpFootprintName, - true ); + MODULE* newModule = m_pcbframe->GetModuleLibrary( wxEmptyString, + cmpFootprintName, + true ); + if( newModule ) { // Change old module to the new module (and delete the old one) @@ -599,12 +633,10 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) else { wxString msg; - msg.Printf( - _( - "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ), - GetChars( textCmpReference ), - GetChars( module->m_LibRef ), - GetChars( cmpFootprintName ) ); + msg.Printf( _( "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ), + GetChars( textCmpReference ), + GetChars( module->m_LibRef ), + GetChars( cmpFootprintName ) ); if( m_messageWindow ) m_messageWindow->AppendText( msg ); @@ -619,6 +651,7 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) if( module == NULL ) // a new module must be loaded from libs { cmpFootprintName = textFootprintName; // Use footprint name from netlist + if( m_useCmpFile ) // Try to get footprint name from .cmp file { m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName ); @@ -635,11 +668,11 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) if( m_messageWindow ) { wxString msg; - msg.Printf( _( "Component [%s] not found" ), - GetChars( textCmpReference ) ); + msg.Printf( _( "Component [%s] not found" ), GetChars( textCmpReference ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) ); } } + return NULL; // The module could not be loaded. } @@ -673,13 +706,16 @@ bool NETLIST_READER::SetPadNetName( char* aText ) if( ( TextPinName = strtok( Line, " ()\t\n" ) ) == NULL ) error = true; + if( ( TextNetName = strtok( NULL, " ()\t\n" ) ) == NULL ) error = true; + if( error ) return 0; pad = m_currModule->m_Pads; found = false; + for( ; pad != NULL; pad = pad->Next() ) { if( strnicmp( TextPinName, pad->m_Padname, 4 ) == 0 ) @@ -699,8 +735,8 @@ bool NETLIST_READER::SetPadNetName( char* aText ) wxString msg; wxString pin_name = FROM_UTF8( TextPinName ); msg.Printf( _( "Module [%s]: Pad [%s] not found" ), - GetChars( m_currModule->m_Reference->m_Text ), - GetChars( pin_name ) ); + GetChars( m_currModule->m_Reference->m_Text ), + GetChars( pin_name ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) ); } } @@ -726,6 +762,7 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName( void ) wxArrayString listnames; Module = (MODULE*) GetBoard()->m_Modules; + for( ; Module != NULL; Module = (MODULE*) Module->Next() ) listnames.Add( Module->m_Reference->m_Text ); @@ -789,6 +826,7 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( list.Add( _( "Duplicates" ) ); MODULE* module = GetBoard()->m_Modules; + for( ; module != NULL; module = module->Next() ) { MODULE* altmodule = module->Next(); @@ -801,6 +839,7 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( list.Add( wxT("") ); else list.Add( module->m_Reference->m_Text ); + nberr++; break; } @@ -887,21 +926,26 @@ int NETLIST_READER::BuildComponentsListFromNetlist( const wxString& aNetlistFile while( netlineReader.ReadLine() ) { text = StrPurge( Line ); + if( is_comment ) { if( ( text = strchr( text, '}' ) ) == NULL ) continue; + is_comment = false; } + if( *text == '{' ) /* Comments. */ { is_comment = true; + if( ( text = strchr( text, '}' ) ) == NULL ) continue; } if( *text == '(' ) state++; + if( *text == ')' ) state--; @@ -976,12 +1020,15 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent, return false; } - FILE_LINE_READER netlineReader( cmpFile, m_cmplistFullName ); // netlineReader dtor will close cmpFile + // netlineReader dtor will close cmpFile + FILE_LINE_READER netlineReader( cmpFile, m_cmplistFullName ); wxString buffer; wxString value; + while( netlineReader.ReadLine() ) { buffer = FROM_UTF8( netlineReader.Line() ); + if( ! buffer.StartsWith( wxT("BeginCmp") ) ) continue; @@ -989,9 +1036,11 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent, refcurrcmp.Empty(); idmod.Empty(); timestamp.Empty(); + while( netlineReader.ReadLine() ) { buffer = FROM_UTF8( netlineReader.Line() ); + if( buffer.StartsWith( wxT("EndCmp") ) ) break; @@ -1000,6 +1049,7 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent, value = value.BeforeLast( ';'); value.Trim(true); value.Trim(false); + if( buffer.StartsWith( wxT("Reference") ) ) { refcurrcmp = value; @@ -1068,44 +1118,49 @@ bool NETLIST_READER::loadNewModules() } ref = cmp = m_newModulesList[0]; + for( unsigned ii = 0; ii < m_newModulesList.size(); ii++ ) { cmp = m_newModulesList[ii]; + if( (ii == 0) || ( ref->m_LibName != cmp->m_LibName) ) { /* New footprint : must be loaded from a library */ - Module = m_pcbframe->Get_Librairie_Module( wxEmptyString, - cmp->m_LibName, - false ); + Module = m_pcbframe->GetModuleLibrary( wxEmptyString, cmp->m_LibName, false ); ref = cmp; + if( Module == NULL ) { success = false; wxString msg; msg.Printf( _( "Component [%s]: footprint <%s> not found" ), - GetChars( cmp->m_CmpName ), - GetChars( cmp->m_LibName ) ); + GetChars( cmp->m_CmpName ), + GetChars( cmp->m_LibName ) ); + if( m_messageWindow ) { msg += wxT("\n"); m_messageWindow->AppendText( msg ); } else + { DisplayError( NULL, msg ); + } + continue; } + Module->SetPosition( ModuleBestPosition ); /* Update schematic links : reference "Time Stamp" and schematic - *hierarchical path */ + * hierarchical path */ Module->m_Reference->m_Text = cmp->m_CmpName; Module->m_TimeStamp = GetTimeStamp(); Module->m_Path = cmp->m_TimeStampPath; } else { - /* Footprint already loaded from a library, duplicate it (faster) - */ + // Footprint already loaded from a library, duplicate it (faster) if( Module == NULL ) continue; /* Module does not exist in library. */ diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp index c9136ac373..bca29d6cf8 100644 --- a/pcbnew/onleftclick.cpp +++ b/pcbnew/onleftclick.cpp @@ -68,7 +68,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) break; case TYPE_MODULE: - Place_Module( (MODULE*) DrawStruct, aDC ); + PlaceModule( (MODULE*) DrawStruct, aDC ); exit = true; break; @@ -190,8 +190,10 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) case ID_PCB_ADD_LINE_BUTT: { int shape = S_SEGMENT; + if( GetToolId() == ID_PCB_CIRCLE_BUTT ) shape = S_CIRCLE; + if( GetToolId() == ID_PCB_ARC_BUTT ) shape = S_ARC; @@ -200,6 +202,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) DisplayError( this, _( "Graphic not authorized on Copper layers" ) ); break; } + if( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) ) { DrawStruct = Begin_DrawSegment( NULL, shape, aDC ); @@ -207,8 +210,8 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) DrawPanel->m_AutoPAN_Request = true; } else if( DrawStruct - && (DrawStruct->Type() == TYPE_DRAWSEGMENT) - && DrawStruct->IsNew() ) + && (DrawStruct->Type() == TYPE_DRAWSEGMENT) + && DrawStruct->IsNew() ) { DrawStruct = Begin_DrawSegment( (DRAWSEGMENT*) DrawStruct, shape, aDC ); SetCurItem( DrawStruct ); @@ -228,20 +231,23 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) { DrawStruct = Begin_Route( NULL, aDC ); SetCurItem( DrawStruct ); + if( DrawStruct ) DrawPanel->m_AutoPAN_Request = true; } else if( DrawStruct && DrawStruct->IsNew() ) { TRACK* track = Begin_Route( (TRACK*) DrawStruct, aDC ); + // SetCurItem() must not write to the msg panel // because a track info is displayed while moving the mouse cursor if( track ) // A new segment was created SetCurItem( DrawStruct = track, false ); + DrawPanel->m_AutoPAN_Request = true; } - break; + break; case ID_PCB_ZONES_BUTT: @@ -254,23 +260,23 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) // there is no current item, try to find something under mouse DrawStruct = PcbGeneralLocateAndDisplay(); bool hit_on_corner = false; + if( DrawStruct && (DrawStruct->Type() == TYPE_ZONE_CONTAINER) ) { // We have a hit under mouse (a zone outline corner or segment) // test for a corner only because want to move corners only. ZONE_CONTAINER* edge_zone = (ZONE_CONTAINER*) DrawStruct; + if( edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) // corner located! hit_on_corner = true; } + if( hit_on_corner ) { DrawPanel->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); DrawPanel->m_AutoPAN_Request = true; - Start_Move_Zone_Corner( aDC, - zone_cont, - zone_cont->m_CornerSelection, - false ); + Start_Move_Zone_Corner( aDC, zone_cont, zone_cont->m_CornerSelection, false ); } else if( Begin_Zone( aDC ) ) { @@ -279,9 +285,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) GetScreen()->SetCurItem( DrawStruct ); } } - else if( DrawStruct - && (DrawStruct->Type() == TYPE_ZONE_CONTAINER) - && DrawStruct->IsNew() ) + else if( DrawStruct && (DrawStruct->Type() == TYPE_ZONE_CONTAINER) && DrawStruct->IsNew() ) { // Add a new corner to the current outline beeing created: DrawPanel->m_AutoPAN_Request = true; Begin_Zone( aDC ); @@ -326,7 +330,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) } else if( DrawStruct->Type() == TYPE_MODULE ) { - Place_Module( (MODULE*) DrawStruct, aDC ); + PlaceModule( (MODULE*) DrawStruct, aDC ); DrawPanel->m_AutoPAN_Request = false; } else @@ -342,15 +346,14 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) DisplayError( this, _( "Dimension not authorized on Copper layers" ) ); break; } + if( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) ) { DrawStruct = Begin_Dimension( NULL, aDC ); SetCurItem( DrawStruct ); DrawPanel->m_AutoPAN_Request = true; } - else if( DrawStruct - && (DrawStruct->Type() == TYPE_DIMENSION) - && DrawStruct->IsNew() ) + else if( DrawStruct && (DrawStruct->Type() == TYPE_DIMENSION) && DrawStruct->IsNew() ) { DrawStruct = Begin_Dimension( (DIMENSION*) DrawStruct, aDC ); SetCurItem( DrawStruct ); @@ -478,6 +481,7 @@ void PCB_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ) DrawPanel->m_AutoPAN_Request = false; SetCurItem( NULL ); } + break; case ID_PCB_ADD_LINE_BUTT: diff --git a/pcbnew/protos.h b/pcbnew/protos.h index 4bdb5e5ffc..a792470205 100644 --- a/pcbnew/protos.h +++ b/pcbnew/protos.h @@ -66,41 +66,10 @@ void DrawTraces( EDA_DRAW_PANEL* panel, /* LOCATE.CPP : */ /****************/ -/* Locates the center through the point x, y, on layer data - * by masquelayer. - * Search is done to address start_adr has end_adr (not included) - */ -TRACK* GetTrace( TRACK* start_adr, TRACK* end_adr, const wxPoint& ref_pos, int masquelayer ); - -/* Search for segment connected to the segment edge by - * Ptr_piste: - * If int = START, the point of beginning of the segment is used - * If int = END, the end point of the segment is used - * The search is done only on the ends of segments - * The search is limited to the area [... pt_base] pt_lim. - */ -TRACK* GetConnectedTrace( TRACK* aTrace, TRACK* pt_base, TRACK* pt_lim, int extr ); - -/* - * 1 - Locate segment of track leading from the mouse. - * 2 - Locate segment of track point by point. - * Ref_pX, ref_pY. - * - * If layer <0 the layer is not tested. - * - * The search begins to address start_adresse - */ -TRACK* GetTrace( BOARD* aPcb, TRACK* start_adresse, const wxPoint& ref_pos, int layer ); - /* Locate a footprint by its bounding rectangle. */ MODULE* Locate_Prefered_Module( BOARD* aPcb, const wxPoint& aPosition, int aActiveLayer, bool aVisibleOnly, bool aIgnoreLocked = false ); -/* Locate a trace segment at the current cursor position. - * The search begins to address start_adresse. - */ -TRACK* GetTrace( TRACK* start_adresse, int typeloc ); - DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int LayerSearch, int typeloc ); /*************/ diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index a87a02c800..69732a4772 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -148,7 +148,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus ) * it is faster than Build_Board_Ratsnest() * because many optimizations and computations are already made */ - Tst_Ratsnest( aDC, 0 ); + TestRatsNest( aDC, 0 ); // Redraw the active ratsnest ( if enabled ) if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) && aDC ) @@ -551,7 +551,7 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode ) /** - * Function used by Tst_Ratsnest + * Function used by TestRatsNest * Function like gen_rats_block_to_block(..) * Function testing the ratsnest between 2 blocks ( same net ) * The search is made between pads in block 1 and the others blocks @@ -615,7 +615,7 @@ static int tst_rats_block_to_block( NETINFO_ITEM* net, /** - * Function used by Tst_Ratsnest_general + * Function used by TestRatsNest_general * The general ratsnest list must exists * Activates the ratsnest between 2 pads ( assumes the same net ) * The function links 1 pad not already connected an other pad and activate @@ -673,12 +673,7 @@ static int tst_rats_pad_to_pad( int current_num_block, } -/* Compute the active ratsnest - * The general ratsnest list must exists - * Compute the ACTIVE ratsnest in the general ratsnest list - * if ref_netcode == 0, test all nets, else test only ref_netcode - */ -void PCB_BASE_FRAME::Tst_Ratsnest( wxDC* DC, int ref_netcode ) +void PCB_BASE_FRAME::TestRatsNest( wxDC* aDC, int aNetCode ) { RATSNEST_ITEM* rats; D_PAD* pad; @@ -688,19 +683,16 @@ void PCB_BASE_FRAME::Tst_Ratsnest( wxDC* DC, int ref_netcode ) return; if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) - Build_Board_Ratsnest( DC ); + Build_Board_Ratsnest( aDC ); for( int net_code = 1; net_code < (int) m_Pcb->m_NetInfo->GetCount(); net_code++ ) { net = m_Pcb->FindNet( net_code ); - if( net == NULL ) //Should not occur - { - DisplayError( this, wxT( "Tst_Ratsnest() error: net not found" ) ); - return; - } + wxCHECK_RET( net != NULL, + wxString::Format( wxT( "Net code %d not found!" ), net_code ) ); - if( ref_netcode && (net_code != ref_netcode) ) + if( aNetCode && (net_code != aNetCode) ) continue; int num_block = 0; @@ -741,38 +733,17 @@ void PCB_BASE_FRAME::Tst_Ratsnest( wxDC* DC, int ref_netcode ) } -/** - * Function Test_1_Net_Ratsnest - * Compute the ratsnest relative to the net "net_code" - * @param aDC - Device context to draw on. - * @param aNetcode = netcode used to compute the ratsnest. - */ -int PCB_BASE_FRAME::Test_1_Net_Ratsnest( wxDC* aDC, int aNetcode ) +int PCB_BASE_FRAME::TestOneRatsNest( wxDC* aDC, int aNetCode ) { DisplayRastnestInProgress = false; - DrawGeneralRatsnest( aDC, aNetcode ); - Tst_Ratsnest( aDC, aNetcode ); - DrawGeneralRatsnest( aDC, aNetcode ); + DrawGeneralRatsnest( aDC, aNetCode ); + TestRatsNest( aDC, aNetCode ); + DrawGeneralRatsnest( aDC, aNetCode ); return m_Pcb->GetRatsnestsCount(); } -/* - * Function build_ratsnest_module - * Build a ratsnest relative to one footprint. This is a simplified computation - * used only in move footprint. It is not optimal, but it is fast and sufficient - * to help a footprint placement - * It shows the connections from a pad to the nearest connected pad - * - * The ratsnest has 2 sections: - * - An "internal" ratsnest relative to pads of this footprint which are - * in the same net. - * this ratsnest section is computed once. - * - An "external" ratsnest connecting a pad of this footprint to an other - * pad (in an other footprint) - * The ratsnest section must be computed for each new position - */ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) { static unsigned pads_module_count; // node count (node = pad with a net @@ -989,11 +960,7 @@ CalculateExternalRatsnest: } -/* - * Display the ratsnest of a moving footprint, computed by - * build_ratsnest_module() - */ -void PCB_BASE_FRAME::trace_ratsnest_module( wxDC* DC ) +void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC ) { if( DC == NULL ) return; @@ -1022,7 +989,7 @@ void PCB_BASE_FRAME::trace_ratsnest_module( wxDC* DC ) } } - g_ColorsSettings.SetItemColor(RATSNEST_VISIBLE, tmpcolor); + g_ColorsSettings.SetItemColor( RATSNEST_VISIBLE, tmpcolor ); } diff --git a/pcbnew/tr_modif.cpp b/pcbnew/tr_modif.cpp index 72f162fe91..468453f772 100644 --- a/pcbnew/tr_modif.cpp +++ b/pcbnew/tr_modif.cpp @@ -10,8 +10,6 @@ #include "protos.h" static void ListSetState( EDA_ITEM* Start, int NbItem, int State, int onoff ); -extern int ReturnEndsTrack( TRACK* RefTrack, int NbSegm, - TRACK** StartTrack, TRACK** EndTrack ); int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, @@ -64,7 +62,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, #endif TRACK* bufStart = m_Pcb->m_Track->GetStartNetCode( netcode ); // Beginning of tracks of the net - TRACK* bufEnd = bufStart->GetEndNetCode( netcode ); // Enf of tracks of the net + TRACK* bufEnd = bufStart->GetEndNetCode( netcode ); // End of tracks of the net /* Flags for cleaning the net. */ for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() ) @@ -77,7 +75,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, break; } - if( ReturnEndsTrack( aNewTrack, aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 ) + if( aNewTrack->GetEndSegments( aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 ) return 0; if( ( StartTrack == NULL ) || ( EndTrack == NULL ) ) @@ -118,8 +116,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, endmasklayer |= pt_pad->m_layerMask; } - /* Mark as deleted a new track (which is not involved in the search for other connections) - */ + // Mark as deleted a new track (which is not involved in the search for other connections) ListSetState( aNewTrack, aNewTrackSegmentsCount, IS_DELETED, ON ); /* A segment must be connected to the starting point, otherwise @@ -249,8 +246,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC, } } - /* Clear BUSY flag here because the track did not get marked. - */ + // Clear BUSY flag here because the track did not get marked. ListSetState( pt_del, nb_segm, BUSY, OFF ); } diff --git a/pcbnew/track.cpp b/pcbnew/track.cpp index 045fa3b788..049e2cdae3 100644 --- a/pcbnew/track.cpp +++ b/pcbnew/track.cpp @@ -393,142 +393,3 @@ static void ChainMarkedSegments( BOARD* aPcb, } } } - - -/* Calculate the end points coordinates of a track (a list of connected - * segments) - * RefTrack is a segment of the track - * return 1 if OK, 0 when a track is a closed loop - * and the beginning and the end of the track in *StartTrack and *EndTrack - * Modify *StartTrack en *EndTrack : - * (*StartTrack)->m_Start coordinate is the beginning of the track - * (*EndTrack)->m_End coordinate is the end of the track - * Segments connected must be consecutive in list - */ -int ReturnEndsTrack( TRACK* RefTrack, int NbSegm, TRACK** StartTrack, TRACK** EndTrack ) -{ - TRACK* Track, * via, * segm, * TrackListEnd; - int NbEnds, layerMask, ii, ok = 0; - - if( NbSegm <= 1 ) - { - *StartTrack = *EndTrack = RefTrack; - return 1; - } - - /* Calculation of the limit analysis. */ - *StartTrack = *EndTrack = NULL; - TrackListEnd = Track = RefTrack; ii = 0; - - for( ; ( Track != NULL ) && ( ii < NbSegm ); ii++, Track = Track->Next() ) - { - TrackListEnd = Track; - Track->m_Param = 0; - } - - /* Calculate the extremes. */ - NbEnds = 0; Track = RefTrack; ii = 0; - - for( ; ( Track != NULL ) && ( ii < NbSegm ); ii++, Track = Track->Next() ) - { - if( Track->Type() == TYPE_VIA ) - continue; - - layerMask = Track->ReturnMaskLayer(); - via = RefTrack->GetVia( TrackListEnd, Track->m_Start, layerMask ); - - if( via ) - { - layerMask |= via->ReturnMaskLayer(); - via->SetState( BUSY, ON ); - } - - Track->SetState( BUSY, ON ); - segm = GetTrace( RefTrack, TrackListEnd, Track->m_Start, layerMask ); - Track->SetState( BUSY, OFF ); - - if( via ) - via->SetState( BUSY, OFF ); - - if( segm == NULL ) - { - switch( NbEnds ) - { - case 0: - *StartTrack = Track; NbEnds++; - break; - - case 1: - int BeginPad, EndPad; - *EndTrack = Track; - - /* Swap ox, oy with fx, fy */ - BeginPad = Track->GetState( BEGIN_ONPAD ); - EndPad = Track->GetState( END_ONPAD ); - - Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); - - if( BeginPad ) - Track->SetState( END_ONPAD, ON ); - - if( EndPad ) - Track->SetState( BEGIN_ONPAD, ON ); - - EXCHG( Track->m_Start, Track->m_End ); - EXCHG( Track->start, Track->end ); - ok = 1; - return ok; - } - } - - layerMask = Track->ReturnMaskLayer(); - via = RefTrack->GetVia( TrackListEnd, Track->m_End, layerMask ); - - if( via ) - { - layerMask |= via->ReturnMaskLayer(); - via->SetState( BUSY, ON ); - } - - Track->SetState( BUSY, ON ); - segm = GetTrace( RefTrack, TrackListEnd, Track->m_End, layerMask ); - Track->SetState( BUSY, OFF ); - - if( via ) - via->SetState( BUSY, OFF ); - - if( segm == NULL ) - { - switch( NbEnds ) - { - case 0: - int BeginPad, EndPad; - *StartTrack = Track; - NbEnds++; - - /* Swap ox, oy with fx, fy */ - BeginPad = Track->GetState( BEGIN_ONPAD ); - EndPad = Track->GetState( END_ONPAD ); - - Track->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); - - if( BeginPad ) - Track->SetState( END_ONPAD, ON ); - - if( EndPad ) - Track->SetState( BEGIN_ONPAD, ON ); - - EXCHG( Track->m_Start, Track->m_End ); - EXCHG( Track->start, Track->end ); - break; - - case 1: - *EndTrack = Track; - ok = 1; - return ok; - } - } - } - - return ok; -} diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index 9e9eb6b2f6..d960baa9b8 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -12,8 +12,7 @@ #include "dialog_exchange_modules_base.h" -int s_SelectionMode = 0; // Remember the last exchange option, when exit - // dialog. +int s_SelectionMode = 0; // Remember the last exchange option, when exit dialog. class DIALOG_EXCHANGE_MODULE : public DIALOG_EXCHANGE_MODULE_BASE @@ -420,9 +419,8 @@ bool DIALOG_EXCHANGE_MODULE::Change_1_Module( MODULE* Module, namecmp.Trim( true ); namecmp.Trim( false ); - NewModule = m_Parent->Get_Librairie_Module( wxEmptyString, - namecmp, - ShowError ); + NewModule = m_Parent->GetModuleLibrary( wxEmptyString, namecmp, ShowError ); + if( NewModule == NULL ) /* New module not found, redraw the old one. */ { m_WinMessages->AppendText( wxT( "No\n" ) ); @@ -431,6 +429,7 @@ bool DIALOG_EXCHANGE_MODULE::Change_1_Module( MODULE* Module, if( Module == m_CurrentModule ) m_CurrentModule = NewModule; + m_WinMessages->AppendText( wxT( "Ok\n" ) ); m_Parent->Exchange_Module( Module, NewModule, aUndoPickList ); @@ -477,7 +476,7 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, /* place module without ratsnest refresh: this will be made later * when all modules are on board */ - Place_Module( aNewModule, NULL, true ); + PlaceModule( aNewModule, NULL, true ); GetScreen()->SetCrossHairPosition( oldpos, false ); /* Flip footprint if needed */ diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp index 63dffb76d1..3527bac653 100644 --- a/pcbnew/zones_by_polygon_fill_functions.cpp +++ b/pcbnew/zones_by_polygon_fill_functions.cpp @@ -166,7 +166,7 @@ int PCB_EDIT_FRAME::Fill_All_Zones( bool verbose ) TestConnections( NULL ); // Recalculate the active ratsnest, i.e. the unconnected links - Tst_Ratsnest( NULL, 0 ); + TestRatsNest( NULL, 0 ); DrawPanel->Refresh( true ); return errorLevel;