bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller ) { DIALOG_DXF_IMPORT dlg( aCaller ); bool success = ( dlg.ShowModal() == wxID_OK ); if( success ) { const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems(); PICKED_ITEMS_LIST picklist; BOARD* board = aCaller->GetBoard(); std::list<BOARD_ITEM*>::const_iterator it, itEnd; for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) { BOARD_ITEM* item = *it; board->Add( item ); ITEM_PICKER itemWrapper( item, UR_NEW ); picklist.PushItem( itemWrapper ); } aCaller->SaveCopyInUndoList( picklist, UR_NEW, wxPoint( 0, 0 ) ); aCaller->OnModify(); } return success; }
/** * Function DeleteItemsInList * delete schematic items in aItemsList * deleted items are put in undo list */ void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList ) { SCH_SCREEN* screen = (SCH_SCREEN*) panel->GetScreen(); SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) panel->GetParent(); PICKED_ITEMS_LIST itemsList; for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) { SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii ); ITEM_PICKER itemWrapper( item, UR_DELETED ); if( item->Type() == SCH_SHEET_PIN_T ) { /* this item is depending on a sheet, and is not in global list */ wxMessageBox( wxT( "DeleteItemsInList() err: unexpected SCH_SHEET_PIN_T" ) ); } else { screen->Remove( item ); /* Unlink the structure */ itemsList.PushItem( itemWrapper ); } } frame->SaveCopyInUndoList( itemsList, UR_DELETED ); }
/* * Function SaveCopyInUndoList * Create a copy of the current board item, and put it in the undo list. * * aCommandType = * UR_CHANGED * UR_NEW * UR_DELETED * UR_MOVED * UR_FLIPPED * UR_ROTATED */ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, const wxPoint& aTransformPoint ) { if( aItem == NULL ) // Nothing to save return; PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); commandToUndo->m_TransformPoint = aTransformPoint; ITEM_PICKER itemWrapper( aItem, aCommandType ); switch( aCommandType ) { case UR_CHANGED: // Create a copy of item if( itemWrapper.GetLink() == NULL ) // When not null, the copy is already done itemWrapper.SetLink( aItem->Clone() ); commandToUndo->PushItem( itemWrapper ); break; case UR_NEW: case UR_DELETED: #ifdef USE_WX_OVERLAY m_canvas->Refresh(); #endif case UR_MOVED: case UR_FLIPPED: case UR_ROTATED: case UR_ROTATED_CLOCKWISE: commandToUndo->PushItem( itemWrapper ); break; default: { wxString msg; msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType ); wxMessageBox( msg ); } break; } if( commandToUndo->GetCount() ) { /* Save the copy in undo list */ GetScreen()->PushCommandToUndoList( commandToUndo ); /* Clear redo list, because after new save there is no redo to do */ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); } else { delete commandToUndo; } }
void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, UNDO_REDO_T aCommandType, const wxPoint& aTransformPoint ) { /* Does not save a null item or a UR_WIRE_IMAGE command type. UR_WIRE_IMAGE commands * are handled by the overloaded version of SaveCopyInUndoList that takes a reference * to a PICKED_ITEMS_LIST. */ if( aItem == NULL || aCommandType == UR_WIRE_IMAGE ) return; PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); commandToUndo->m_TransformPoint = aTransformPoint; ITEM_PICKER itemWrapper( aItem, aCommandType ); if( aItem ) itemWrapper.SetFlags( aItem->GetFlags() ); switch( aCommandType ) { case UR_CHANGED: /* Create a copy of item */ itemWrapper.SetLink( DuplicateStruct( aItem, true ) ); commandToUndo->PushItem( itemWrapper ); break; case UR_NEW: case UR_DELETED: case UR_ROTATED: case UR_MOVED: commandToUndo->PushItem( itemWrapper ); break; default: wxFAIL_MSG( wxString::Format( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType ) ); break; } if( commandToUndo->GetCount() ) { /* Save the copy in undo list */ GetScreen()->PushCommandToUndoList( commandToUndo ); /* Clear redo list, because after new save there is no redo to do */ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); } else { delete commandToUndo; } }
void SCH_EDIT_FRAME::DeleteItemsInList( PICKED_ITEMS_LIST& aItemsList, bool aAppend ) { PICKED_ITEMS_LIST itemsList; for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) { SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii ); ITEM_PICKER itemWrapper( item, UR_DELETED ); if( item->GetFlags() & STRUCT_DELETED ) continue; DeleteItem( item, aAppend ); aAppend = true; } GetScreen()->ClearDrawingState(); }
/* * Function GlobalChange_PadSettings * Function to change pad caracteristics for the given footprint * or alls footprints which look like the given footprint * aPad is the pattern. The given footprint is the parent of this pad * aSameFootprints: if true, make changes on all identical footprints * aPadShapeFilter: if true, make changes only on pads having the same shape as aPad * aPadOrientFilter: if true, make changes only on pads having the same orientation as aPad * aPadLayerFilter: if true, make changes only on pads having the same layers as aPad * aRedraw: if true: redraws the footprint * aSaveForUndo: if true: create an entry in the Undo/Redo list * (usually: true in Schematic editor, false in Module editor) */ void PCB_BASE_FRAME::GlobalChange_PadSettings( D_PAD* aPad, bool aSameFootprints, bool aPadShapeFilter, bool aPadOrientFilter, bool aPadLayerFilter, bool aRedraw, bool aSaveForUndo ) { if( aPad == NULL ) aPad = &GetDesignSettings().m_Pad_Master; MODULE* module = aPad->GetParent(); if( module == NULL ) { DisplayError( this, wxT( "Global_Import_Pad_Settings() Error: NULL module" ) ); return; } // Search and copy the name of library reference. MODULE* Module_Ref = module; double pad_orient = aPad->GetOrientation() - Module_Ref->GetOrientation(); // Prepare an undo list: if( aSaveForUndo ) { PICKED_ITEMS_LIST itemsList; for( module = m_Pcb->m_Modules; module; module = module->Next() ) { if( !aSameFootprints && (module != Module_Ref) ) continue; if( module->GetFPID() != Module_Ref->GetFPID() ) continue; bool saveMe = false; for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { // Filters changes prohibited. if( aPadShapeFilter && ( pad->GetShape() != aPad->GetShape() ) ) continue; double currpad_orient = pad->GetOrientation() - module->GetOrientation(); if( aPadOrientFilter && ( currpad_orient != pad_orient ) ) continue; if( aPadLayerFilter && pad->GetLayerSet() != aPad->GetLayerSet() ) continue; saveMe = true; } if( saveMe ) { ITEM_PICKER itemWrapper( module, UR_CHANGED ); itemsList.PushItem( itemWrapper ); } } SaveCopyInUndoList( itemsList, UR_CHANGED ); } // Update the current module and same others modules if requested. for( module = m_Pcb->m_Modules; module; module = module->Next() ) { if( !aSameFootprints && (module != Module_Ref) ) continue; if( module->GetFPID() != Module_Ref->GetFPID() ) continue; // Erase module on screen if( aRedraw ) { module->SetFlags( DO_NOT_DRAW ); m_canvas->RefreshDrawingRect( module->GetBoundingBox() ); module->ClearFlags( DO_NOT_DRAW ); } for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { // Filters changes prohibited. if( aPadShapeFilter && ( pad->GetShape() != aPad->GetShape() ) ) continue; if( aPadOrientFilter && (pad->GetOrientation() - module->GetOrientation()) != pad_orient ) continue; if( aPadLayerFilter ) { if( pad->GetLayerSet() != aPad->GetLayerSet() ) continue; else m_Pcb->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK); } // Change characteristics: pad->SetAttribute( aPad->GetAttribute() ); pad->SetShape( aPad->GetShape() ); pad->SetLayerSet( aPad->GetLayerSet() ); pad->SetSize( aPad->GetSize() ); pad->SetDelta( aPad->GetDelta() ); pad->SetOffset( aPad->GetOffset() ); pad->SetDrillSize( aPad->GetDrillSize() ); pad->SetDrillShape( aPad->GetDrillShape() ); pad->SetOrientation( pad_orient + module->GetOrientation() ); // copy also local mask margins, because these parameters usually depend on // pad sizes and layers pad->SetLocalSolderMaskMargin( aPad->GetLocalSolderMaskMargin() ); pad->SetLocalSolderPasteMargin( aPad->GetLocalSolderPasteMargin() ); pad->SetLocalSolderPasteMarginRatio( aPad->GetLocalSolderPasteMarginRatio() ); if( pad->GetShape() != PAD_TRAPEZOID ) { pad->SetDelta( wxSize( 0, 0 ) ); } if( pad->GetShape() == PAD_CIRCLE ) { // Ensure pad size.y = pad size.x int size = pad->GetSize().x; pad->SetSize( wxSize( size, size ) ); } switch( pad->GetAttribute() ) { case PAD_SMD: case PAD_CONN: pad->SetDrillSize( wxSize( 0, 0 ) ); pad->SetOffset( wxPoint( 0, 0 ) ); break; default: break; } } module->CalculateBoundingBox(); if( aRedraw ) m_canvas->RefreshDrawingRect( module->GetBoundingBox() ); } OnModify(); }
void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, const wxPoint& aTransformPoint ) { if( aItem == NULL ) // Nothing to save return; // For texts belonging to modules, we need to save state of the parent module if( aItem->Type() == PCB_MODULE_TEXT_T ) { aItem = aItem->GetParent(); wxASSERT( aItem->Type() == PCB_MODULE_T ); aCommandType = UR_CHANGED; if( aItem == NULL ) return; } PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); commandToUndo->m_TransformPoint = aTransformPoint; ITEM_PICKER itemWrapper( aItem, aCommandType ); switch( aCommandType ) { case UR_CHANGED: // Create a copy of item if( itemWrapper.GetLink() == NULL ) // When not null, the copy is already done itemWrapper.SetLink( aItem->Clone() ); commandToUndo->PushItem( itemWrapper ); break; case UR_NEW: case UR_DELETED: #ifdef USE_WX_OVERLAY // Avoid to redraw when autoplacing if( aItem->Type() == PCB_MODULE_T ) if( ((MODULE*)aItem)->GetFlags() & MODULE_to_PLACE ) break; m_canvas->Refresh(); #endif case UR_MOVED: case UR_FLIPPED: case UR_ROTATED: case UR_ROTATED_CLOCKWISE: commandToUndo->PushItem( itemWrapper ); break; default: { wxString msg; msg.Printf( wxT( "SaveCopyInUndoList() error (unknown code %X)" ), aCommandType ); wxMessageBox( msg ); } break; } if( commandToUndo->GetCount() ) { /* Save the copy in undo list */ GetScreen()->PushCommandToUndoList( commandToUndo ); /* Clear redo list, because after new save there is no redo to do */ GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList ); } else { delete commandToUndo; } }
void PCB_BASE_FRAME::ResetModuleTextSizes( const wxString & aFilter, bool aRef, bool aValue, bool aOthers ) { MODULE* module; BOARD_ITEM* boardItem; ITEM_PICKER itemWrapper( NULL, UR_CHANGED ); PICKED_ITEMS_LIST undoItemList; unsigned int ii; // Prepare undo list for( module = GetBoard()->m_Modules; module; module = module->Next() ) { itemWrapper.SetItem( module ); if( ! aFilter.IsEmpty() ) { if( ! WildCompareString( aFilter, FROM_UTF8( module->GetFPID().Format().c_str() ), false ) ) continue; } if( aRef ) { TEXTE_MODULE *item = &module->Reference(); if( item->GetSize() != GetDesignSettings().m_ModuleTextSize || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth ) { undoItemList.PushItem( itemWrapper ); } } if( aValue ) { TEXTE_MODULE *item = &module->Value(); if( item->GetSize() != GetDesignSettings().m_ModuleTextSize || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth ) { undoItemList.PushItem( itemWrapper ); } } if( aOthers ) { // Go through all other module text fields for( boardItem = module->GraphicalItems(); boardItem; boardItem = boardItem->Next() ) { if( boardItem->Type() == PCB_MODULE_TEXT_T ) { TEXTE_MODULE *item = static_cast<TEXTE_MODULE*>( boardItem ); if( item->GetSize() != GetDesignSettings().m_ModuleTextSize || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth ) { undoItemList.PushItem( itemWrapper ); } } } } } // Exit if there's nothing to do if( !undoItemList.GetCount() ) return; SaveCopyInUndoList( undoItemList, UR_CHANGED ); // Apply changes to modules in the undo list for( ii = 0; ii < undoItemList.GetCount(); ii++ ) { module = (MODULE*) undoItemList.GetPickedItem( ii ); if( aRef ) { module->Reference().SetThickness( GetDesignSettings().m_ModuleTextWidth ); module->Reference().SetSize( GetDesignSettings().m_ModuleTextSize ); } if( aValue ) { module->Value().SetThickness( GetDesignSettings().m_ModuleTextWidth ); module->Value().SetSize( GetDesignSettings().m_ModuleTextSize ); } if( aOthers ) { for( boardItem = module->GraphicalItems(); boardItem; boardItem = boardItem->Next() ) { if( boardItem->Type() == PCB_MODULE_TEXT_T ) { TEXTE_MODULE *item = static_cast<TEXTE_MODULE*>( boardItem ); item->SetThickness( GetDesignSettings().m_ModuleTextWidth ); item->SetSize( GetDesignSettings().m_ModuleTextSize ); } } } } OnModify(); }
int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent ) { if( m_editModules && !m_board->m_Modules ) return 0; DIALOG_DXF_IMPORT dlg( m_frame ); int dlgResult = dlg.ShowModal(); const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems(); if( dlgResult != wxID_OK || list.empty() ) return 0; VECTOR2I cursorPos = m_controls->GetCursorPosition(); VECTOR2I delta = cursorPos - (*list.begin())->GetPosition(); // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); // Build the undo list & add items to the current view std::list<BOARD_ITEM*>::const_iterator it, itEnd; for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) { KICAD_T type = (*it)->Type(); assert( type == PCB_LINE_T || type == PCB_TEXT_T ); if( type == PCB_LINE_T || type == PCB_TEXT_T ) preview.Add( *it ); } BOARD_ITEM* firstItem = static_cast<BOARD_ITEM*>( *preview.Begin() ); m_view->Add( &preview ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { cursorPos = m_controls->GetCursorPosition(); if( evt->IsMotion() ) { delta = cursorPos - firstItem->GetPosition(); for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) static_cast<BOARD_ITEM*>( *it )->Move( wxPoint( delta.x, delta.y ) ); preview.ViewUpdate(); } else if( evt->Category() == TC_COMMAND ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) static_cast<BOARD_ITEM*>( *it )->Rotate( wxPoint( cursorPos.x, cursorPos.y ), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) { for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) static_cast<BOARD_ITEM*>( *it )->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsCancel() || evt->IsActivate() ) { preview.FreeItems(); break; } } else if( evt->IsClick( BUT_LEFT ) ) { // Place the drawing if( m_editModules ) { assert( m_board->m_Modules ); m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT ); m_board->m_Modules->SetLastEditTime(); for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) { BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it ); BOARD_ITEM* converted = NULL; // Modules use different types for the same things, // so we need to convert imported items to appropriate classes. switch( item->Type() ) { case PCB_TEXT_T: converted = new TEXTE_MODULE( m_board->m_Modules ); // Copy coordinates, layer, etc. *static_cast<TEXTE_PCB*>( converted ) = *static_cast<TEXTE_PCB*>( item ); static_cast<TEXTE_MODULE*>( converted )->SetLocalCoord(); break; case PCB_LINE_T: converted = new EDGE_MODULE( m_board->m_Modules ); // Copy coordinates, layer, etc. *static_cast<DRAWSEGMENT*>( converted ) = *static_cast<DRAWSEGMENT*>( item ); static_cast<EDGE_MODULE*>( converted )->SetLocalCoord(); break; default: assert( false ); break; } delete item; if( converted ) { m_board->m_Modules->Add( converted ); m_view->Add( converted ); } } } else // !m_editModules case { PICKED_ITEMS_LIST picklist; for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) { BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it ); m_board->Add( item ); ITEM_PICKER itemWrapper( item, UR_NEW ); picklist.PushItem( itemWrapper ); m_view->Add( item ); } m_frame->SaveCopyInUndoList( picklist, UR_NEW ); } m_frame->OnModify(); break; } } preview.Clear(); m_controls->ShowCursor( false ); m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); m_view->Remove( &preview ); return 0; }
void BOARD_COMMIT::Push( const wxString& aMessage ) { // Objects potentially interested in changes: PICKED_ITEMS_LIST undoList; KIGFX::VIEW* view = m_toolMgr->GetView(); BOARD* board = (BOARD*) m_toolMgr->GetModel(); PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) m_toolMgr->GetEditFrame(); RN_DATA* ratsnest = board->GetRatsnest(); std::set<EDA_ITEM*> savedModules; if( Empty() ) return; for( COMMIT_LINE& ent : m_changes ) { int changeType = ent.m_type & CHT_TYPE; int changeFlags = ent.m_type & CHT_FLAGS; BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item ); // Module items need to be saved in the undo buffer before modification if( m_editModules ) { // Be sure that we are storing a module if( ent.m_item->Type() != PCB_MODULE_T ) ent.m_item = ent.m_item->GetParent(); // We have not saved the module yet, so let's create an entry if( savedModules.count( ent.m_item ) == 0 ) { if( !ent.m_copy ) { assert( changeType != CHT_MODIFY ); // too late to make a copy.. ent.m_copy = ent.m_item->Clone(); } assert( ent.m_item->Type() == PCB_MODULE_T ); assert( ent.m_copy->Type() == PCB_MODULE_T ); ITEM_PICKER itemWrapper( ent.m_item, UR_CHANGED ); itemWrapper.SetLink( ent.m_copy ); undoList.PushItem( itemWrapper ); frame->SaveCopyInUndoList( undoList, UR_CHANGED ); savedModules.insert( ent.m_item ); static_cast<MODULE*>( ent.m_item )->SetLastEditTime(); } } switch( changeType ) { case CHT_ADD: { if( !m_editModules ) { undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) ); if( !( changeFlags & CHT_DONE ) ) board->Add( boardItem ); //ratsnest->Add( boardItem ); // TODO currently done by BOARD::Add() if( boardItem->Type() == PCB_MODULE_T ) { MODULE* mod = static_cast<MODULE*>( boardItem ); mod->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); } } else { // modules inside modules are not supported yet assert( boardItem->Type() != PCB_MODULE_T ); if( !( changeFlags & CHT_DONE ) ) board->m_Modules->Add( boardItem ); } view->Add( boardItem ); break; } case CHT_REMOVE: { if( !m_editModules ) { undoList.PushItem( ITEM_PICKER( boardItem, UR_DELETED ) ); } switch( boardItem->Type() ) { // Module items case PCB_PAD_T: case PCB_MODULE_EDGE_T: case PCB_MODULE_TEXT_T: { // Do not allow footprint text removal when not editing a module if( !m_editModules ) break; bool remove = true; if( boardItem->Type() == PCB_MODULE_TEXT_T ) { TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( boardItem ); switch( text->GetType() ) { case TEXTE_MODULE::TEXT_is_REFERENCE: //DisplayError( frame, _( "Cannot delete component reference." ) ); remove = false; break; case TEXTE_MODULE::TEXT_is_VALUE: //DisplayError( frame, _( "Cannot delete component value." ) ); remove = false; break; case TEXTE_MODULE::TEXT_is_DIVERS: // suppress warnings break; default: assert( false ); break; } } if( remove ) { view->Remove( boardItem ); if( !( changeFlags & CHT_DONE ) ) { MODULE* module = static_cast<MODULE*>( boardItem->GetParent() ); assert( module && module->Type() == PCB_MODULE_T ); module->Delete( boardItem ); } board->m_Status_Pcb = 0; // it is done in the legacy view (ratsnest perhaps?) } break; } // Board items case PCB_LINE_T: // a segment not on copper layers case PCB_TEXT_T: // a text on a layer case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T: // a via (like track segment on a copper layer) case PCB_DIMENSION_T: // a dimension (graphic item) case PCB_TARGET_T: // a target (graphic item) case PCB_MARKER_T: // a marker used to show something case PCB_ZONE_T: // SEG_ZONE items are now deprecated case PCB_ZONE_AREA_T: view->Remove( boardItem ); if( !( changeFlags & CHT_DONE ) ) board->Remove( boardItem ); //ratsnest->Remove( boardItem ); // currently done by BOARD::Remove() break; case PCB_MODULE_T: { // There are no modules inside a module yet assert( !m_editModules ); MODULE* module = static_cast<MODULE*>( boardItem ); module->ClearFlags(); module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); view->Remove( module ); if( !( changeFlags & CHT_DONE ) ) board->Remove( module ); // Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore board->m_Status_Pcb = 0; } break; default: // other types do not need to (or should not) be handled assert( false ); break; } break; } case CHT_MODIFY: { if( !m_editModules ) { ITEM_PICKER itemWrapper( boardItem, UR_CHANGED ); assert( ent.m_copy ); itemWrapper.SetLink( ent.m_copy ); undoList.PushItem( itemWrapper ); } boardItem->ViewUpdate( KIGFX::VIEW_ITEM::ALL ); ratsnest->Update( boardItem ); break; } default: assert( false ); break; } } if( !m_editModules ) frame->SaveCopyInUndoList( undoList, UR_UNSPECIFIED ); frame->OnModify(); ratsnest->Recalculate(); clear(); }
/* * Function DoPushPadProperties * Function to change pad properties for the given footprint or all identical footprints * aPad is the pattern. The given footprint is the parent of this pad * aSameFootprints: if true, make changes on all identical footprints * aPadShapeFilter: if true, make changes only on pads having the same shape as aPad * aPadOrientFilter: if true, make changes only on pads having the same orientation as aPad * aPadLayerFilter: if true, make changes only on pads having the same layers as aPad * aSaveForUndo: if true: create an entry in the Undo/Redo list * (usually: true in Schematic editor, false in Module editor) */ void PCB_BASE_FRAME::DoPushPadProperties( D_PAD* aPad, bool aSameFootprints, bool aPadShapeFilter, bool aPadOrientFilter, bool aPadLayerFilter, bool aSaveForUndo ) { MODULE* Module_Ref = aPad->GetParent(); double pad_orient = aPad->GetOrientation() - Module_Ref->GetOrientation(); // Prepare an undo list: if( aSaveForUndo ) { PICKED_ITEMS_LIST itemsList; if( aSameFootprints ) { for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() ) { if( module->GetFPID() == Module_Ref->GetFPID() ) { ITEM_PICKER itemWrapper( module, UR_CHANGED ); itemsList.PushItem( itemWrapper ); } } } else { ITEM_PICKER itemWrapper( Module_Ref, UR_CHANGED ); itemsList.PushItem( itemWrapper ); } SaveCopyInUndoList( itemsList, UR_CHANGED ); } // Update the current module and same others modules if requested. for( MODULE* module = m_Pcb->m_Modules; module; module = module->Next() ) { if( !aSameFootprints && (module != Module_Ref) ) continue; if( module->GetFPID() != Module_Ref->GetFPID() ) continue; // Erase module on screen module->SetFlags( DO_NOT_DRAW ); m_canvas->RefreshDrawingRect( module->GetBoundingBox() ); module->ClearFlags( DO_NOT_DRAW ); for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() ) { if( aPadShapeFilter && ( pad->GetShape() != aPad->GetShape() ) ) continue; double currpad_orient = pad->GetOrientation() - module->GetOrientation(); if( aPadOrientFilter && ( currpad_orient != pad_orient ) ) continue; if( aPadLayerFilter && ( pad->GetLayerSet() != aPad->GetLayerSet() ) ) continue; // Do not copy pad to itself, it can create issues with custom pad primitives. if( pad == aPad ) continue; pad->ImportSettingsFromMaster( *aPad ); } module->CalculateBoundingBox(); m_canvas->RefreshDrawingRect( module->GetBoundingBox() ); } OnModify(); }