/* Copy marked items, at new position = old position + offset */ void CopyMarkedItems( MODULE* module, wxPoint offset ) { if( module == NULL ) return; for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { if( !pad->IsSelected() ) continue; pad->ClearFlags( SELECTED ); D_PAD* NewPad = new D_PAD( *pad ); NewPad->SetParent( module ); NewPad->SetFlags( SELECTED ); module->Pads().PushFront( NewPad ); } BOARD_ITEM* newItem; for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { if( !item->IsSelected() ) continue; item->ClearFlags( SELECTED ); newItem = (BOARD_ITEM*)item->Clone(); newItem->SetParent( module ); newItem->SetFlags( SELECTED ); module->GraphicalItems().PushFront( newItem ); } MoveMarkedItems( module, offset ); }
/* Cancel move pad command. */ static void Abort_Move_Pad( EDA_DRAW_PANEL* Panel, wxDC* DC ) { D_PAD* pad = s_CurrentSelectedPad; Panel->SetMouseCapture( NULL, NULL ); if( pad == NULL ) return; pad->Draw( Panel, DC, GR_XOR ); pad->ClearFlags(); pad->SetPosition( Pad_OldPos ); pad->Draw( Panel, DC, GR_XOR ); // Pad move in progress: restore origin of dragged tracks, if any. for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) { TRACK* Track = g_DragSegmentList[ii].m_Track; Track->Draw( Panel, DC, GR_XOR ); Track->SetState( IN_EDIT, OFF ); g_DragSegmentList[ii].RestoreInitialValues(); Track->Draw( Panel, DC, GR_OR ); } EraseDragList(); s_CurrentSelectedPad = NULL; }
void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint ) { EDA_ITEM* item; MODULE* CopyItem; PICKED_ITEMS_LIST* lastcmd; CopyItem = new MODULE( *( (MODULE*) aItem ) ); CopyItem->SetParent( GetBoard() ); lastcmd = new PICKED_ITEMS_LIST(); ITEM_PICKER wrapper( CopyItem, UR_MODEDIT ); lastcmd->PushItem( wrapper ); GetScreen()->PushCommandToUndoList( lastcmd ); /* Clear current flags (which can be temporary set by a current edit command) */ for( item = CopyItem->GraphicalItems(); item != NULL; item = item->Next() ) item->ClearFlags(); for( D_PAD* pad = CopyItem->Pads(); pad; pad = pad->Next() ) pad->ClearFlags(); CopyItem->Reference().ClearFlags(); CopyItem->Value().ClearFlags(); /* Clear redo list, because after new save there is no redo to do */ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); }
/* Mark items inside rect. * Items are inside rect when an end point is inside rect */ int MarkItemsInBloc( MODULE* module, EDA_RECT& Rect ) { EDA_ITEM* item; int ItemsCount = 0; wxPoint pos; D_PAD* pad; if( module == NULL ) return 0; pad = module->Pads(); for( ; pad != NULL; pad = pad->Next() ) { pad->ClearFlags( SELECTED ); pos = pad->GetPosition(); if( Rect.Contains( pos ) ) { pad->SetFlags( SELECTED ); ItemsCount++; } } item = module->GraphicalItems(); for( ; item != NULL; item = item->Next() ) { item->ClearFlags( SELECTED ); switch( item->Type() ) { case PCB_MODULE_EDGE_T: if( ((EDGE_MODULE*)item )->HitTest( Rect ) ) { item->SetFlags( SELECTED ); ItemsCount++; } break; case PCB_MODULE_TEXT_T: pos = ( (TEXTE_MODULE*) item )->GetTextPosition(); if( Rect.Contains( pos ) ) { item->SetFlags( SELECTED ); ItemsCount++; } break; default: break; } } return ItemsCount; }
/* Copy marked items, at new position = old position + offset */ void CopyMarkedItems( MODULE* module, wxPoint offset, bool aIncrement ) { if( module == NULL ) return; // Reference and value cannot be copied, they are unique. // Ensure they are not selected module->Reference().ClearFlags(); module->Value().ClearFlags(); for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { if( !pad->IsSelected() ) continue; pad->ClearFlags( SELECTED ); D_PAD* NewPad = new D_PAD( *pad ); NewPad->SetParent( module ); NewPad->SetFlags( SELECTED ); module->Pads().PushFront( NewPad ); if( aIncrement ) NewPad->IncrementPadName( true, true ); } BOARD_ITEM* newItem; for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { if( !item->IsSelected() ) continue; item->ClearFlags( SELECTED ); newItem = (BOARD_ITEM*)item->Clone(); newItem->SetParent( module ); newItem->SetFlags( SELECTED ); module->GraphicalItems().PushFront( newItem ); } MoveMarkedItems( module, offset ); }
void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) { if( !padValuesOK() ) return; bool rastnestIsChanged = false; int isign = m_isFlipped ? -1 : 1; transferDataToPad( m_padMaster ); // m_padMaster is a pattern: ensure there is no net for this pad: m_padMaster->SetNetCode( NETINFO_LIST::UNCONNECTED ); if( m_currentPad ) // Set current Pad parameters { wxSize size; MODULE* module = m_currentPad->GetParent(); m_parent->SaveCopyInUndoList( module, UR_CHANGED ); module->SetLastEditTime(); // redraw the area where the pad was, without pad (delete pad on screen) m_currentPad->SetFlags( DO_NOT_DRAW ); m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() ); m_currentPad->ClearFlags( DO_NOT_DRAW ); // Update values m_currentPad->SetShape( m_padMaster->GetShape() ); m_currentPad->SetAttribute( m_padMaster->GetAttribute() ); if( m_currentPad->GetPosition() != m_padMaster->GetPosition() ) { m_currentPad->SetPosition( m_padMaster->GetPosition() ); rastnestIsChanged = true; } // compute the pos 0 value, i.e. pad position for module with orientation = 0 // i.e. relative to module origin (module position) wxPoint pt = m_currentPad->GetPosition() - module->GetPosition(); RotatePoint( &pt, -module->GetOrientation() ); m_currentPad->SetPos0( pt ); m_currentPad->SetOrientation( m_padMaster->GetOrientation() * isign + module->GetOrientation() ); m_currentPad->SetSize( m_padMaster->GetSize() ); size = m_padMaster->GetDelta(); size.y *= isign; m_currentPad->SetDelta( size ); m_currentPad->SetDrillSize( m_padMaster->GetDrillSize() ); m_currentPad->SetDrillShape( m_padMaster->GetDrillShape() ); wxPoint offset = m_padMaster->GetOffset(); offset.y *= isign; m_currentPad->SetOffset( offset ); m_currentPad->SetPadToDieLength( m_padMaster->GetPadToDieLength() ); if( m_currentPad->GetLayerSet() != m_padMaster->GetLayerSet() ) { rastnestIsChanged = true; m_currentPad->SetLayerSet( m_padMaster->GetLayerSet() ); } if( m_isFlipped ) m_currentPad->SetLayerSet( FlipLayerMask( m_currentPad->GetLayerSet() ) ); m_currentPad->SetPadName( m_padMaster->GetPadName() ); wxString padNetname; // For PAD_HOLE_NOT_PLATED, ensure there is no net name selected if( m_padMaster->GetAttribute() != PAD_HOLE_NOT_PLATED ) padNetname = m_PadNetNameCtrl->GetValue(); if( m_currentPad->GetNetname() != padNetname ) { const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname ); if( !padNetname.IsEmpty() && netinfo == NULL ) { DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); } else { rastnestIsChanged = true; m_currentPad->SetNetCode( netinfo->GetNet() ); } } m_currentPad->SetLocalClearance( m_padMaster->GetLocalClearance() ); m_currentPad->SetLocalSolderMaskMargin( m_padMaster->GetLocalSolderMaskMargin() ); m_currentPad->SetLocalSolderPasteMargin( m_padMaster->GetLocalSolderPasteMargin() ); m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster->GetLocalSolderPasteMarginRatio() ); m_currentPad->SetZoneConnection( m_padMaster->GetZoneConnection() ); m_currentPad->SetThermalWidth( m_padMaster->GetThermalWidth() ); m_currentPad->SetThermalGap( m_padMaster->GetThermalGap() ); module->CalculateBoundingBox(); m_parent->SetMsgPanel( m_currentPad ); // redraw the area where the pad was m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() ); m_parent->OnModify(); } EndModal( wxID_OK ); if( rastnestIsChanged ) // The net ratsnest must be recalculated m_board->m_Status_Pcb = 0; }
void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint ) { PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); commandToUndo->m_TransformPoint = aTransformPoint; // First, filter unnecessary stuff from the list (i.e. for multiple pads / labels modified), // take the first occurence of the module (we save copies of modules when one of its subitems // is changed). for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) { ITEM_PICKER curr_picker = aItemsList.GetItemWrapper(ii); BOARD_ITEM* item = (BOARD_ITEM*) aItemsList.GetPickedItem( ii ); // For items belonging to modules, we need to save state of the parent module if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_MODULE_EDGE_T || item->Type() == PCB_PAD_T ) { // Item to be stored in the undo buffer is the parent module item = item->GetParent(); wxASSERT( item && item->Type() == PCB_MODULE_T ); if( item == NULL ) continue; // Check if the parent module has already been saved in another entry bool found = false; for( unsigned j = 0; j < commandToUndo->GetCount(); j++ ) { if( commandToUndo->GetPickedItem( j ) == item && commandToUndo->GetPickedItemStatus( j ) == UR_CHANGED ) { found = true; break; } } if( !found ) { // Create a clean copy of the parent module MODULE* orig = static_cast<MODULE*>( item ); MODULE* clone = new MODULE( *orig ); clone->SetParent( GetBoard() ); // Clear current flags (which can be temporary set by a current edit command) for( EDA_ITEM* loc_item = clone->GraphicalItemsList(); loc_item; loc_item = loc_item->Next() ) loc_item->ClearFlags(); for( D_PAD* pad = clone->PadsList(); pad; pad = pad->Next() ) pad->ClearFlags(); clone->Reference().ClearFlags(); clone->Value().ClearFlags(); ITEM_PICKER picker( item, UR_CHANGED ); picker.SetLink( clone ); commandToUndo->PushItem( picker ); orig->SetLastEditTime(); } else { continue; } } else { // Normal case: all other BOARD_ITEMs, are simply copied to the new list commandToUndo->PushItem( curr_picker ); } } for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii ); UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii ); if( command == UR_UNSPECIFIED ) { command = aTypeCommand; commandToUndo->SetPickedItemStatus( command, ii ); } wxASSERT( item ); switch( command ) { case UR_CHANGED: case UR_DRILLORIGIN: case UR_GRIDORIGIN: /* If needed, create a copy of item, and put in undo list * in the picker, as link * If this link is not null, the copy is already done */ if( commandToUndo->GetPickedItemLink( ii ) == NULL ) { EDA_ITEM* cloned = item->Clone(); commandToUndo->SetPickedItemLink( cloned, ii ); } break; case UR_MOVED: case UR_ROTATED: case UR_ROTATED_CLOCKWISE: case UR_FLIPPED: case UR_NEW: case UR_DELETED: break; default: { wxLogDebug( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), command ); } break; } } if( commandToUndo->GetCount() ) { /* Save the copy in undo list */ GetScreen()->PushCommandToUndoList( commandToUndo ); /* Clear redo list, because after a new command one cannot redo a command */ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); } else { // Should not occur wxASSERT( false ); delete commandToUndo; } }