/** * Function SetTrackSegmentWidth * Modify one track segment width or one via diameter and drill (using DRC control). * Basic routine used by other routines when editing tracks or vias * @param aTrackItem = the track segment or via to modify * @param aItemsListPicker = the list picker to use for an undo command (can be NULL) * @param aUseNetclassValue = true to use NetClass value, false to use BOARD::m_designSettings value * @return true if done, false if no not change (because DRC error) */ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, PICKED_ITEMS_LIST* aItemsListPicker, bool aUseNetclassValue ) { int initial_width, new_width; int initial_drill = -1,new_drill = -1; bool change_ok = false; NETINFO_ITEM* net = NULL; if( aUseNetclassValue ) net = aTrackItem->GetNet(); initial_width = aTrackItem->GetWidth(); if( net ) new_width = net->GetTrackWidth(); else new_width = GetDesignSettings().GetCurrentTrackWidth(); if( aTrackItem->Type() == PCB_VIA_T ) { const VIA *via = static_cast<const VIA *>( aTrackItem ); if( !via->IsDrillDefault() ) initial_drill = via->GetDrillValue(); if( net ) { new_width = net->GetViaSize(); } else { new_width = GetDesignSettings().GetCurrentViaSize(); new_drill = GetDesignSettings().GetCurrentViaDrill(); } if( via->GetViaType() == VIA_MICROVIA ) { if( net ) new_width = net->GetMicroViaSize(); else new_width = GetDesignSettings().GetCurrentMicroViaSize(); } } aTrackItem->SetWidth( new_width ); // make a DRC test because the new size is bigger than the old size if( initial_width < new_width ) { int diagdrc = OK_DRC; if( g_Drc_On ) diagdrc = m_drc->Drc( aTrackItem, GetBoard()->m_Track ); if( diagdrc == OK_DRC ) change_ok = true; } else if( initial_width > new_width ) { change_ok = true; } else if( (aTrackItem->Type() == PCB_VIA_T) && (initial_drill != new_drill) ) { // if new width == initial_width: do nothing, unless a via has its drill value changed change_ok = true; } if( change_ok ) { OnModify(); if( aItemsListPicker ) { aTrackItem->SetWidth( initial_width ); ITEM_PICKER picker( aTrackItem, UR_CHANGED ); picker.SetLink( aTrackItem->Clone() ); aItemsListPicker->PushItem( picker ); aTrackItem->SetWidth( new_width ); if( aTrackItem->Type() == PCB_VIA_T ) { // Set new drill value. Note: currently microvias have only a default drill value VIA *via = static_cast<VIA *>( aTrackItem ); if( new_drill > 0 ) via->SetDrill( new_drill ); else via->SetDrillDefault(); } } } else { aTrackItem->SetWidth( initial_width ); } return change_ok; }
bool DIALOG_TRACK_VIA_PROPERTIES::Apply( COMMIT& aCommit ) { if( !check() ) return false; bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED; bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED; for( auto item : m_items ) { aCommit.Modify( item ); switch( item->Type() ) { case PCB_TRACE_T: { assert( m_tracks ); TRACK* t = static_cast<TRACK*>( item ); if( m_trackStartX.Valid() || m_trackStartY.Valid() ) { wxPoint start = t->GetStart(); if( m_trackStartX.Valid() ) start.x = m_trackStartX.GetValue(); if( m_trackStartY.Valid() ) start.y = m_trackStartY.GetValue(); t->SetStart( start ); } if( m_trackEndX.Valid() || m_trackEndY.Valid() ) { wxPoint end = t->GetEnd(); if( m_trackEndX.Valid() ) end.x = m_trackEndX.GetValue(); if( m_trackEndY.Valid() ) end.y = m_trackEndY.GetValue(); t->SetEnd( end ); } if( m_trackNetclass->IsChecked() ) { t->SetWidth( t->GetNetClass()->GetTrackWidth() ); } else if( m_trackWidth.Valid() ) { t->SetWidth( m_trackWidth.GetValue() ); } LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection(); if( layer != UNDEFINED_LAYER ) t->SetLayer( (LAYER_ID) layer ); if( changeLock ) t->SetLocked( setLock ); break; } case PCB_VIA_T: { assert( m_vias ); VIA* v = static_cast<VIA*>( item ); if( m_viaX.Valid() || m_viaY.Valid() ) { wxPoint pos = v->GetPosition(); if( m_viaX.Valid() ) pos.x = m_viaX.GetValue(); if( m_viaY.Valid() ) pos.y = m_viaY.GetValue(); v->SetPosition( pos ); } if( m_viaNetclass->IsChecked() ) { switch( v->GetViaType() ) { default: wxFAIL_MSG("Unhandled via type"); // fall through case VIA_THROUGH: case VIA_BLIND_BURIED: v->SetWidth( v->GetNetClass()->GetViaDiameter() ); v->SetDrill( v->GetNetClass()->GetViaDrill() ); break; case VIA_MICROVIA: v->SetWidth( v->GetNetClass()->GetuViaDiameter() ); v->SetDrill( v->GetNetClass()->GetuViaDrill() ); break; } } else { if( m_viaDiameter.Valid() ) v->SetWidth( m_viaDiameter.GetValue() ); if( m_viaDrill.Valid() ) v->SetDrill( m_viaDrill.GetValue() ); } if( changeLock ) v->SetLocked( setLock ); break; } default: assert( false ); break; } } return true; }
bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) { unsigned itmp; if( aTrack == NULL ) { if( GetActiveLayer() != GetScreen()->m_Route_Layer_TOP ) SetActiveLayer( GetScreen()->m_Route_Layer_TOP ); else SetActiveLayer( GetScreen()->m_Route_Layer_BOTTOM ); UpdateStatusBar(); return true; } // Avoid more than one via on the current location: if( GetBoard()->GetViaByPosition( g_CurrentTrackSegment->GetEnd(), g_CurrentTrackSegment->GetLayer() ) ) return false; for( TRACK* segm = g_FirstTrackSegment; segm; segm = segm->Next() ) { if( segm->Type() == PCB_VIA_T && g_CurrentTrackSegment->GetEnd() == segm->GetStart() ) return false; } // Is the current segment Ok (no DRC error) ? if( g_Drc_On ) { if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) ) // DRC error, the change layer is not made return false; // Handle 2 segments. if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() ) { if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) ) return false; } } /* Save current state before placing a via. * If the via cannot be placed this current state will be reused */ itmp = g_CurrentTrackList.GetCount(); Begin_Route( g_CurrentTrackSegment, DC ); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // create the via VIA* via = new VIA( GetBoard() ); via->SetFlags( IS_NEW ); via->SetViaType( GetDesignSettings().m_CurrentViaType ); via->SetNetCode( GetBoard()->GetHighLightNetCode() ); via->SetPosition( g_CurrentTrackSegment->GetEnd() ); // for microvias, the size and hole will be changed later. via->SetWidth( GetDesignSettings().GetCurrentViaSize()); via->SetDrill( GetDesignSettings().GetCurrentViaDrill() ); // Usual via is from copper to component. // layer pair is B_Cu and F_Cu. via->SetLayerPair( B_Cu, F_Cu ); LAYER_ID first_layer = GetActiveLayer(); LAYER_ID last_layer; // prepare switch to new active layer: if( first_layer != GetScreen()->m_Route_Layer_TOP ) last_layer = GetScreen()->m_Route_Layer_TOP; else last_layer = GetScreen()->m_Route_Layer_BOTTOM; // Adjust the actual via layer pair switch( via->GetViaType() ) { case VIA_BLIND_BURIED: via->SetLayerPair( first_layer, last_layer ); break; case VIA_MICROVIA: // from external to the near neighbor inner layer { LAYER_ID last_inner_layer = ToLAYER_ID( ( GetBoard()->GetCopperLayerCount() - 2 ) ); if( first_layer == B_Cu ) last_layer = last_inner_layer; else if( first_layer == F_Cu ) last_layer = In1_Cu; else if( first_layer == last_inner_layer ) last_layer = B_Cu; else if( first_layer == In1_Cu ) last_layer = F_Cu; // else error: will be removed later via->SetLayerPair( first_layer, last_layer ); // Update diameter and hole size, which where set previously // for normal vias NETINFO_ITEM* net = via->GetNet(); via->SetWidth( net->GetMicroViaSize() ); via->SetDrill( net->GetMicroViaDrillSize() ); } break; default: break; } if( g_Drc_On && BAD_DRC == m_drc->Drc( via, GetBoard()->m_Track ) ) { // DRC fault: the Via cannot be placed here ... delete via; m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // delete the track(s) added in Begin_Route() while( g_CurrentTrackList.GetCount() > itmp ) { Delete_Segment( DC, g_CurrentTrackSegment ); } SetCurItem( g_CurrentTrackSegment, false ); // Refresh DRC diag, erased by previous calls if( m_drc->GetCurrentMarker() ) SetMsgPanel( m_drc->GetCurrentMarker() ); return false; } SetActiveLayer( last_layer ); TRACK* lastNonVia = g_CurrentTrackSegment; /* A new via was created. It was Ok. */ g_CurrentTrackList.PushBack( via ); /* The via is now in linked list and we need a new track segment * after the via, starting at via location. * it will become the new current segment (from via to the mouse cursor) */ TRACK* track = (TRACK*)lastNonVia->Clone(); /* the above creates a new segment from the last entered segment, with the * current width, flags, netcode, etc... values. * layer, start and end point are not correct, * and will be modified next */ // set the layer to the new value track->SetLayer( GetActiveLayer() ); /* the start point is the via position and the end point is the cursor * which also is on the via (will change when moving mouse) */ track->SetEnd( via->GetStart() ); track->SetStart( via->GetStart() ); g_CurrentTrackList.PushBack( track ); if( g_TwoSegmentTrackBuild ) { // Create a second segment (we must have 2 track segments to adjust) g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() ); } m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); SetMsgPanel( via ); UpdateStatusBar(); return true; }
void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) { if( aImage == NULL ) { return; } EDA_ITEM * pnext = Next(); EDA_ITEM * pback = Back(); switch( Type() ) { case PCB_MODULE_T: { MODULE* tmp = (MODULE*) aImage->Clone(); ( (MODULE*) aImage )->Copy( (MODULE*) this ); ( (MODULE*) this )->Copy( tmp ); delete tmp; } break; case PCB_ZONE_AREA_T: { ZONE_CONTAINER* tmp = (ZONE_CONTAINER*) aImage->Clone(); ( (ZONE_CONTAINER*) aImage )->Copy( (ZONE_CONTAINER*) this ); ( (ZONE_CONTAINER*) this )->Copy( tmp ); delete tmp; } break; case PCB_LINE_T: std::swap( *((DRAWSEGMENT*)this), *((DRAWSEGMENT*)aImage) ); break; case PCB_TRACE_T: case PCB_VIA_T: { TRACK* track = (TRACK*) this; TRACK* image = (TRACK*) aImage; EXCHG(track->m_Layer, image->m_Layer ); // swap start, end, width and shape for track and image. wxPoint exchp = track->GetStart(); track->SetStart( image->GetStart() ); image->SetStart( exchp ); exchp = track->GetEnd(); track->SetEnd( image->GetEnd() ); image->SetEnd( exchp ); int atmp = track->GetWidth(); track->SetWidth( image->GetWidth() ); image->SetWidth( atmp ); if( Type() == PCB_VIA_T ) { VIA *via = static_cast<VIA*>( this ); VIA *viaimage = static_cast<VIA*>( aImage ); VIATYPE_T viatmp = via->GetViaType(); via->SetViaType( viaimage->GetViaType() ); viaimage->SetViaType( viatmp ); int drilltmp = via->GetDrillValue(); if( via->IsDrillDefault() ) drilltmp = -1; int itmp = viaimage->GetDrillValue(); if( viaimage->IsDrillDefault() ) itmp = -1; EXCHG(itmp, drilltmp ); if( drilltmp > 0 ) via->SetDrill( drilltmp ); else via->SetDrillDefault(); if( itmp > 0 ) viaimage->SetDrill( itmp ); else viaimage->SetDrillDefault(); } } break; case PCB_TEXT_T: std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) ); break; case PCB_TARGET_T: std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) ); break; case PCB_DIMENSION_T: std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) ); break; case PCB_ZONE_T: default: wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() ); break; } if( pnext != Next() || pback != Back() ) { Pnext = pnext; Pback = pback; #ifdef DEBUG wxLogMessage( wxT( "SwapData Error: %s Pnext or Pback pointers modified" ), GetClass().GetData() ); #endif } }
void PCB_PAD::AddToBoard() { PCB_PAD_SHAPE* padShape; int i; int width = 0; int height = 0; if( m_objType == wxT( 'V' ) ) // via { // choose one of the shapes for( i = 0; i < (int) m_shapes.GetCount(); i++ ) { padShape = m_shapes[i]; if( padShape->m_width > 0 && padShape->m_height > 0 ) { if( padShape->m_KiCadLayer == F_Cu || padShape->m_KiCadLayer == B_Cu ) { width = padShape->m_width; height = padShape->m_height; break; } } } if( width == 0 || height == 0 ) THROW_IO_ERROR( wxT( "pad or via with zero size" ) ); if( IsCopperLayer( m_KiCadLayer ) ) { VIA* via = new VIA( m_board ); m_board->m_Track.Append( via ); via->SetTimeStamp( 0 ); via->SetPosition( wxPoint( m_positionX, m_positionY ) ); via->SetEnd( wxPoint( m_positionX, m_positionY ) ); via->SetWidth( height ); via->SetViaType( VIA_THROUGH ); via->SetLayerPair( F_Cu, B_Cu ); via->SetDrill( m_hole ); via->SetLayer( m_KiCadLayer ); via->SetNetCode( m_netCode ); } } else // pad { MODULE* module = new MODULE( m_board ); m_board->Add( module, ADD_APPEND ); m_name.text = m_defaultPinDes; module->SetPosition( wxPoint( m_positionX, m_positionY ) ); AddToModule( module, 0, true ); } }
void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) { if( aImage == NULL ) return; // Remark: to create images of edited items to undo, we are using Clone method // which can duplication of items foe copy, but does not clone all members // mainly pointers in chain and time stamp, which is set to new, unique value. // So we have to use the current values of these parameters. EDA_ITEM * pnext = Next(); EDA_ITEM * pback = Back(); DHEAD* mylist = m_List; time_t timestamp = GetTimeStamp(); switch( Type() ) { case PCB_MODULE_T: { MODULE* tmp = (MODULE*) aImage->Clone(); ( (MODULE*) aImage )->Copy( (MODULE*) this ); ( (MODULE*) this )->Copy( tmp ); delete tmp; } break; case PCB_ZONE_AREA_T: { ZONE_CONTAINER* tmp = (ZONE_CONTAINER*) aImage->Clone(); ( (ZONE_CONTAINER*) aImage )->Copy( (ZONE_CONTAINER*) this ); ( (ZONE_CONTAINER*) this )->Copy( tmp ); delete tmp; } break; case PCB_LINE_T: std::swap( *((DRAWSEGMENT*)this), *((DRAWSEGMENT*)aImage) ); break; case PCB_TRACE_T: case PCB_VIA_T: { TRACK* track = (TRACK*) this; TRACK* image = (TRACK*) aImage; std::swap(track->m_Layer, image->m_Layer ); // swap start, end, width and shape for track and image. wxPoint exchp = track->GetStart(); track->SetStart( image->GetStart() ); image->SetStart( exchp ); exchp = track->GetEnd(); track->SetEnd( image->GetEnd() ); image->SetEnd( exchp ); int atmp = track->GetWidth(); track->SetWidth( image->GetWidth() ); image->SetWidth( atmp ); if( Type() == PCB_VIA_T ) { VIA *via = static_cast<VIA*>( this ); VIA *viaimage = static_cast<VIA*>( aImage ); VIATYPE_T viatmp = via->GetViaType(); via->SetViaType( viaimage->GetViaType() ); viaimage->SetViaType( viatmp ); int drilltmp = via->GetDrillValue(); if( via->IsDrillDefault() ) drilltmp = -1; int itmp = viaimage->GetDrillValue(); if( viaimage->IsDrillDefault() ) itmp = -1; std::swap(itmp, drilltmp ); if( drilltmp > 0 ) via->SetDrill( drilltmp ); else via->SetDrillDefault(); if( itmp > 0 ) viaimage->SetDrill( itmp ); else viaimage->SetDrillDefault(); } } break; case PCB_TEXT_T: std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) ); break; case PCB_TARGET_T: std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) ); break; case PCB_DIMENSION_T: std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) ); break; case PCB_ZONE_T: default: wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() ); break; } // Restore pointers and time stamp, to be sure they are not broken Pnext = pnext; Pback = pback; m_List = mylist; SetTimeStamp( timestamp ); }
bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() { auto connectivity = m_frame->GetBoard()->GetConnectivity(); int newNetCode = m_netSelector->GetSelectedNetcode(); std::vector<D_PAD*> changingPads; if ( !m_netSelector->IsIndeterminate() ) { std::set<D_PAD*> connectedPads; for( auto& item : m_items ) { const KICAD_T ourTypes[] = { PCB_TRACE_T, PCB_PAD_T, PCB_VIA_T, PCB_MODULE_T, EOT }; auto connectedItems = connectivity->GetConnectedItems( static_cast<BOARD_CONNECTED_ITEM*>( item ), ourTypes, true ); for ( auto citem : connectedItems ) { if( citem->Type() == PCB_PAD_T ) { connectedPads.insert( static_cast<D_PAD*>( citem ) ); } } } for( D_PAD* pad : connectedPads ) { if( pad->GetNetCode() != newNetCode ) changingPads.push_back( pad ); } } // Run validations: if( changingPads.size() ) { if( !confirmPadChange( changingPads ) ) return false; } if( m_vias ) { if( !m_viaDiameter.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) ) return false; if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate() && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate() && m_viaDiameter.GetValue() <= m_viaDrill.GetValue() ) { DisplayError( GetParent(), _( "Via drill size must be smaller than via diameter" ) ); m_ViaDrillCtrl->SelectAll(); m_ViaDrillCtrl->SetFocus(); return false; } if( m_ViaStartLayer->GetLayerSelection() != UNDEFINED_LAYER && m_ViaStartLayer->GetLayerSelection() == m_ViaEndLayer->GetLayerSelection() ) { DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) ); return false; } } if( m_tracks ) { if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) ) return false; } // If we survived that, then save the changes: bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED; bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED; for( auto item : m_items ) { m_commit.Modify( item ); switch( item->Type() ) { case PCB_TRACE_T: { wxASSERT( m_tracks ); TRACK* t = static_cast<TRACK*>( item ); if( !m_trackStartX.IsIndeterminate() ) t->SetStart( wxPoint( m_trackStartX.GetValue(), t->GetStart().y ) ); if( !m_trackStartY.IsIndeterminate() ) t->SetStart( wxPoint( t->GetStart().x, m_trackStartY.GetValue() ) ); if( !m_trackEndX.IsIndeterminate() ) t->SetEnd( wxPoint( m_trackEndX.GetValue(), t->GetEnd().y ) ); if( !m_trackEndY.IsIndeterminate() ) t->SetEnd( wxPoint( t->GetEnd().x, m_trackEndY.GetValue() ) ); if( m_trackNetclass->IsChecked() ) t->SetWidth( t->GetNetClass()->GetTrackWidth() ); else if( !m_trackWidth.IsIndeterminate() ) t->SetWidth( m_trackWidth.GetValue() ); LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection(); if( layer != UNDEFINED_LAYER ) t->SetLayer( (PCB_LAYER_ID) layer ); if( changeLock ) t->SetLocked( setLock ); if ( !m_netSelector->IsIndeterminate() ) t->SetNetCode( m_netSelector->GetSelectedNetcode() ); break; } case PCB_VIA_T: { wxASSERT( m_vias ); VIA* v = static_cast<VIA*>( item ); if( !m_viaX.IsIndeterminate() ) v->SetPosition( wxPoint( m_viaX.GetValue(), v->GetPosition().y ) ); if( !m_viaY.IsIndeterminate() ) v->SetPosition( wxPoint( v->GetPosition().x, m_viaY.GetValue() ) ); if( m_ViaTypeChoice->GetSelection() != 3) { switch( m_ViaTypeChoice->GetSelection() ) { default: case 0: v->SetViaType( VIA_THROUGH ); v->SanitizeLayers(); break; case 1: v->SetViaType( VIA_MICROVIA ); break; case 2: v->SetViaType( VIA_BLIND_BURIED ); break; } } auto startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() ); auto endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() ); if (startLayer != UNDEFINED_LAYER ) v->SetTopLayer( startLayer ); if (endLayer != UNDEFINED_LAYER ) v->SetBottomLayer( endLayer ); v->SanitizeLayers(); if( m_viaNetclass->IsChecked() ) { switch( v->GetViaType() ) { default: wxFAIL_MSG("Unhandled via type"); // fall through case VIA_THROUGH: case VIA_BLIND_BURIED: v->SetWidth( v->GetNetClass()->GetViaDiameter() ); v->SetDrill( v->GetNetClass()->GetViaDrill() ); break; case VIA_MICROVIA: v->SetWidth( v->GetNetClass()->GetuViaDiameter() ); v->SetDrill( v->GetNetClass()->GetuViaDrill() ); break; } } else { if( !m_viaDiameter.IsIndeterminate() ) v->SetWidth( m_viaDiameter.GetValue() ); if( !m_viaDrill.IsIndeterminate() ) v->SetDrill( m_viaDrill.GetValue() ); } if ( !m_netSelector->IsIndeterminate() ) v->SetNetCode( m_netSelector->GetSelectedNetcode() ); if( changeLock ) v->SetLocked( setLock ); break; } default: wxASSERT( false ); break; } } if ( !m_netSelector->IsIndeterminate() ) { // Commit::Push() will rebuild connectivitiy propagating nets from connected pads // outwards. We therefore have to update the connected pads in order for the net // change to "stick". for( D_PAD* pad : changingPads ) { m_commit.Modify( pad ); pad->SetNetCode( m_netSelector->GetSelectedNetcode() ); } } m_commit.Push( _( "Edit track/via properties" ) ); return true; }
bool DIALOG_TRACK_VIA_PROPERTIES::Apply() { if( !check() ) return false; for( int i = 0; i < m_items.Size(); ++i ) { BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i ); switch( item->Type() ) { case PCB_TRACE_T: { assert( m_tracks ); TRACK* t = static_cast<TRACK*>( item ); if( m_trackStartX.Valid() || m_trackStartY.Valid() ) { wxPoint start = t->GetStart(); if( m_trackStartX.Valid() ) start.x = m_trackStartX.GetValue(); if( m_trackStartY.Valid() ) start.y = m_trackStartY.GetValue(); t->SetStart( start ); } if( m_trackEndX.Valid() || m_trackEndY.Valid() ) { wxPoint end = t->GetEnd(); if( m_trackEndX.Valid() ) end.x = m_trackEndX.GetValue(); if( m_trackEndY.Valid() ) end.y = m_trackEndY.GetValue(); t->SetEnd( end ); } if( m_trackNetclass->IsChecked() ) { t->SetWidth( t->GetNetClass()->GetTrackWidth() ); } else if( m_trackWidth.Valid() ) { t->SetWidth( m_trackWidth.GetValue() ); } LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection(); if( layer != UNDEFINED_LAYER ) t->SetLayer( (LAYER_ID) layer ); break; } case PCB_VIA_T: { assert( m_vias ); VIA* v = static_cast<VIA*>( item ); if( m_viaX.Valid() || m_viaY.Valid() ) { wxPoint pos = v->GetPosition(); if( m_viaX.Valid() ) pos.x = m_viaX.GetValue(); if( m_viaY.Valid() ) pos.y = m_viaY.GetValue(); v->SetPosition( pos ); } if( m_viaNetclass->IsChecked() ) { v->SetWidth( v->GetNetClass()->GetViaDiameter() ); v->SetDrill( v->GetNetClass()->GetViaDrill() ); } else { if( m_viaDiameter.Valid() ) v->SetWidth( m_viaDiameter.GetValue() ); if( m_viaDrill.Valid() ) v->SetDrill( m_viaDrill.GetValue() ); } break; } default: assert( false ); break; } } return true; }
int PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, PICKED_ITEMS_LIST* aItemsListPicker, bool aUseNetclassValue ) { int return_code = TRACK_ACTION_NONE; int initial_width; int new_width; int initial_drill = -1; int new_drill = -1; NETINFO_ITEM* net = NULL; if( aUseNetclassValue ) net = aTrackItem->GetNet(); initial_width = aTrackItem->GetWidth(); if( net ) new_width = net->GetTrackWidth(); else new_width = GetDesignSettings().GetCurrentTrackWidth(); if( aTrackItem->Type() == PCB_VIA_T ) { const VIA *via = static_cast<const VIA *>( aTrackItem ); // Micro vias have a size only defined in their netclass // (no specific values defined by a table of specific value) // Ensure the netclass is accessible: if( via->GetViaType() == VIA_MICROVIA && net == NULL ) net = aTrackItem->GetNet(); // Get the draill value, regardless it is default or specific initial_drill = via->GetDrillValue(); if( net ) { new_width = net->GetViaSize(); new_drill = net->GetViaDrillSize(); } else { new_width = GetDesignSettings().GetCurrentViaSize(); new_drill = GetDesignSettings().GetCurrentViaDrill(); } if( via->GetViaType() == VIA_MICROVIA ) { if( net ) { new_width = net->GetMicroViaSize(); new_drill = net->GetMicroViaDrillSize(); } else { // Should not occur } } // Old versions set a drill value <= 0, when the default netclass it used // but it could be better to set the drill value to the actual value // to avoid issues for existing vias, if the default drill value is modified // in the netclass, and not in current vias. if( via->GetDrill() <= 0 ) // means default netclass drill value used { initial_drill = -1; // Force drill vias re-initialization } } aTrackItem->SetWidth( new_width ); // make a DRC test because the new size is bigger than the old size if( initial_width < new_width ) { int diagdrc = OK_DRC; return_code = TRACK_ACTION_SUCCESS; if( Settings().m_legacyDrcOn ) diagdrc = m_drc->DrcOnCreatingTrack( aTrackItem, GetBoard()->m_Track ); if( diagdrc != OK_DRC ) return_code = TRACK_ACTION_DRC_ERROR; } else if( initial_width > new_width ) { return_code = TRACK_ACTION_SUCCESS; } else if( (aTrackItem->Type() == PCB_VIA_T) ) { // if a via has its drill value changed, force change if( initial_drill != new_drill ) return_code = TRACK_ACTION_SUCCESS; } if( return_code == TRACK_ACTION_SUCCESS ) { OnModify(); if( aItemsListPicker ) { aTrackItem->SetWidth( initial_width ); ITEM_PICKER picker( aTrackItem, UR_CHANGED ); picker.SetLink( aTrackItem->Clone() ); aItemsListPicker->PushItem( picker ); aTrackItem->SetWidth( new_width ); if( aTrackItem->Type() == PCB_VIA_T ) { // Set new drill value. Note: currently microvias have only a default drill value VIA *via = static_cast<VIA *>( aTrackItem ); if( new_drill > 0 ) via->SetDrill( new_drill ); else via->SetDrillDefault(); } } } else { aTrackItem->SetWidth( initial_width ); } return return_code; }
bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, PICKED_ITEMS_LIST* aItemsListPicker, bool aUseNetclassValue ) { /* Modify one track segment width or one via diameter and drill (using DRC control). * Basic function used by other routines when editing tracks or vias * aTrackItem = the track segment or via to modify * aItemsListPicker = the list picker to use for an undo command (can be NULL) * aUseNetclassValue = true to use NetClass value, false to use BOARD::m_designSettings value * return true if done, false if no not change (due to DRC error) */ int initial_width, new_width; int initial_drill = -1,new_drill = -1; bool change_ok = false; NETINFO_ITEM* net = NULL; if( aUseNetclassValue ) net = aTrackItem->GetNet(); initial_width = aTrackItem->GetWidth(); if( net ) new_width = net->GetTrackWidth(); else new_width = GetDesignSettings().GetCurrentTrackWidth(); if( aTrackItem->Type() == PCB_VIA_T ) { const VIA *via = static_cast<const VIA *>( aTrackItem ); // Micro vias have a size only defined in their netclass // (no specific values defined by a table of specific value) // Ensure the netclass is accessible: if( via->GetViaType() == VIA_MICROVIA && net == NULL ) net = aTrackItem->GetNet(); // Get the draill value, regardless it is default or specific initial_drill = via->GetDrillValue(); if( net ) { new_width = net->GetViaSize(); new_drill = net->GetViaDrillSize(); } else { new_width = GetDesignSettings().GetCurrentViaSize(); new_drill = GetDesignSettings().GetCurrentViaDrill(); } if( via->GetViaType() == VIA_MICROVIA ) { if( net ) { new_width = net->GetMicroViaSize(); new_drill = net->GetMicroViaDrillSize(); } else { // Should not occur } } // Old versions set a drill value <= 0, when the default netclass it used // but it could be better to set the drill value to the actual value // to avoid issues for existing vias, if the default drill value is modified // in the netclass, and not in current vias. if( via->GetDrill() <= 0 ) // means default netclass drill value used { initial_drill = -1; // Force drill vias re-initialization } } aTrackItem->SetWidth( new_width ); // make a DRC test because the new size is bigger than the old size if( initial_width < new_width ) { int diagdrc = OK_DRC; if( g_Drc_On ) diagdrc = m_drc->Drc( aTrackItem, GetBoard()->m_Track ); if( diagdrc == OK_DRC ) change_ok = true; } else if( initial_width > new_width ) { change_ok = true; } else if( (aTrackItem->Type() == PCB_VIA_T) ) { // if a via has its drill value changed, force change if( initial_drill != new_drill ) change_ok = true; } if( change_ok ) { OnModify(); if( aItemsListPicker ) { aTrackItem->SetWidth( initial_width ); ITEM_PICKER picker( aTrackItem, UR_CHANGED ); picker.SetLink( aTrackItem->Clone() ); aItemsListPicker->PushItem( picker ); aTrackItem->SetWidth( new_width ); if( aTrackItem->Type() == PCB_VIA_T ) { // Set new drill value. Note: currently microvias have only a default drill value VIA *via = static_cast<VIA *>( aTrackItem ); if( new_drill > 0 ) via->SetDrill( new_drill ); else via->SetDrillDefault(); } } } else { aTrackItem->SetWidth( initial_width ); } return change_ok; }