int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); if( !hoverSelection( selection ) ) return 0; wxPoint translation; double rotation = 0; PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); DIALOG_MOVE_EXACT dialog( editFrame, translation, rotation ); int ret = dialog.ShowModal(); if( ret == wxID_OK ) { if( !isUndoInhibited() ) { editFrame->OnModify(); // Record an action of move and rotate editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); } VECTOR2I rp = selection.GetCenter(); wxPoint rotPoint( rp.x, rp.y ); for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i ); item->Move( translation ); item->Rotate( rotPoint, rotation ); if( !m_dragging ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } updateRatsnest( m_dragging ); if( m_dragging ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); else getModel<BOARD>()->GetRatsnest()->Recalculate(); if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } return 0; }
int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); if( !makeSelection( selection ) || m_selectionTool->CheckLock() ) { setTransitions(); return 0; } wxPoint flipPoint = getModificationPoint( selection ); if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag { editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_FLIPPED, flipPoint ); } for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i ); item->Flip( flipPoint ); if( !m_dragging ) item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } updateRatsnest( m_dragging ); // Update dragging offset (distance between cursor and the first dragged item) m_offset = static_cast<BOARD_ITEM*>( selection.items.GetPickedItem( 0 ) )->GetPosition() - flipPoint; if( m_dragging ) selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); else getModel<BOARD>()->GetRatsnest()->Recalculate(); if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); setTransitions(); return 0; }
int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED ) return 0; wxPoint translation; double rotation = 0; PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); DIALOG_MOVE_EXACT dialog( editFrame, translation, rotation ); int ret = dialog.ShowModal(); if( ret == wxID_OK ) { VECTOR2I rp = selection.GetCenter(); wxPoint rotPoint( rp.x, rp.y ); for( unsigned int i = 0; i < selection.items.GetCount(); ++i ) { BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i ); m_commit->Modify( item ); item->Move( translation ); item->Rotate( rotPoint, rotation ); if( !m_dragging ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } m_commit->Push( _( "Move exact" ) ); if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true ); } return 0; }
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); if( !hoverSelection( selection, false ) ) return 0; // Properties are displayed when there is only one item selected if( selection.Size() == 1 ) { // Display properties dialog BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 ); std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); // It is necessary to determine if anything has changed PICKED_ITEMS_LIST* lastChange = undoList.empty() ? NULL : undoList.back(); // Display properties dialog editFrame->OnEditItemRequest( NULL, item ); PICKED_ITEMS_LIST* currentChange = undoList.empty() ? NULL : undoList.back(); if( lastChange != currentChange ) // Something has changed { processChanges( currentChange ); updateRatsnest( true ); getModel<BOARD>()->GetRatsnest()->Recalculate(); item->ViewUpdate(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } item->SetFlags( flags ); } return 0; }
void EDIT_TOOL::processChanges( const PICKED_ITEMS_LIST* aList ) { KIGFX::VIEW* view = getView(); RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest(); for( unsigned int i = 0; i < aList->GetCount(); ++i ) { UNDO_REDO_T operation = aList->GetPickedItemStatus( i ); BOARD_ITEM* updItem = static_cast<BOARD_ITEM*>( aList->GetPickedItem( i ) ); switch( operation ) { case UR_CHANGED: ratsnest->Update( updItem ); // fall through case UR_MODEDIT: updItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_DELETED: if( updItem->Type() == PCB_MODULE_T ) static_cast<MODULE*>( updItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); view->Remove( updItem ); //ratsnest->Remove( updItem ); // this is done in BOARD::Remove break; case UR_NEW: if( updItem->Type() == PCB_MODULE_T ) static_cast<MODULE*>( updItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); view->Add( updItem ); //ratsnest->Add( updItem ); // this is done in BOARD::Add break; default: assert( false ); // Not handled break; } } }
void MODULE::ViewUpdate( int aUpdateFlags ) { if( !m_view ) return; // Update the module itself VIEW_ITEM::ViewUpdate( aUpdateFlags ); // Update pads for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() ) pad->ViewUpdate( aUpdateFlags ); // Update module's drawing (mostly silkscreen) for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() ) drawing->ViewUpdate( aUpdateFlags ); // Update module's texts m_Reference->ViewUpdate( aUpdateFlags ); m_Value->ViewUpdate( aUpdateFlags ); }
void SELECTION_TOOL::clearSelection() { if( m_selection.Empty() ) return; KIGFX::VIEW_GROUP::const_iter it, it_end; // Restore the initial properties for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) { BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it ); item->ViewHide( false ); item->ClearSelected(); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ) ; } m_selection.clear(); m_frame->SetCurItem( NULL ); m_locked = true; // Inform other potentially interested tools m_toolMgr->ProcessEvent( ClearedEvent ); }
int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent ) { SELECTION selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection(); BOARD* board = getModel<BOARD>(); RN_DATA* ratsnest = board->GetRatsnest(); KIGFX::VIEW* view = getView(); if( selection.Size() < 2 ) return 0; PICKED_ITEMS_LIST changes; int netcode = -1; // Loop through all combinations for( int ia1 = 0; ia1 < selection.Size() - 1; ++ia1 ) { ZONE_CONTAINER* curr_area = dynamic_cast<ZONE_CONTAINER*>( selection.Item<EDA_ITEM>( ia1 ) ); if( !curr_area ) continue; netcode = curr_area->GetNetCode(); EDA_RECT b1 = curr_area->Outline()->GetBoundingBox(); bool mod_ia1 = false; for( int ia2 = selection.Size() - 1; ia2 > ia1; --ia2 ) { ZONE_CONTAINER* area2 = dynamic_cast<ZONE_CONTAINER*>( selection.Item<EDA_ITEM>( ia2 ) ); if( !area2 ) continue; if( area2->GetNetCode() != netcode ) continue; if( curr_area->GetPriority() != area2->GetPriority() ) continue; if( curr_area->GetIsKeepout() != area2->GetIsKeepout() ) continue; if( curr_area->GetLayer() != area2->GetLayer() ) continue; EDA_RECT b2 = area2->Outline()->GetBoundingBox(); if( b1.Intersects( b2 ) ) { EDA_ITEM* backup = curr_area->Clone(); bool ret = board->TestAreaIntersection( curr_area, area2 ); if( ret && board->CombineAreas( &changes, curr_area, area2 ) ) { mod_ia1 = true; selection.items.RemovePicker( ia2 ); ITEM_PICKER picker( curr_area, UR_CHANGED ); picker.SetLink( backup ); changes.PushItem( picker ); } else { delete backup; } } } if( mod_ia1 ) --ia1; // if modified, we need to check it again } m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_frame->SaveCopyInUndoList( changes, UR_UNSPECIFIED ); for( unsigned i = 0; i < changes.GetCount(); ++i ) { ITEM_PICKER picker = changes.GetItemWrapper( i ); BOARD_ITEM* item = static_cast<BOARD_ITEM*>( picker.GetItem() ); if( picker.GetStatus() == UR_DELETED ) { view->Remove( item ); ratsnest->Remove( item ); } else if( picker.GetStatus() == UR_CHANGED ) { item->ViewUpdate( KIGFX::VIEW_ITEM::ALL ); m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item ); } } return 0; }
int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); if( !hoverSelection( selection, false ) ) return 0; // Tracks & vias are treated in a special way: if( ( SELECTION_CONDITIONS::OnlyTypes( m_tracksViasType ) )( selection ) ) { DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection ); if( dlg.ShowModal() ) { RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest(); editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); dlg.Apply(); selection.ForAll<KIGFX::VIEW_ITEM>( boost::bind( &KIGFX::VIEW_ITEM::ViewUpdate, _1, KIGFX::VIEW_ITEM::ALL ) ); selection.ForAll<BOARD_ITEM>( boost::bind( &RN_DATA::Update, ratsnest, _1 ) ); ratsnest->Recalculate(); } } else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected { // Display properties dialog BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 ); // Store the head of the undo list to compare if anything has changed std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); // It is necessary to determine if anything has changed, so store the current undo save point PICKED_ITEMS_LIST* undoSavePoint = undoList.empty() ? NULL : undoList.back(); // Display properties dialog provided by the legacy canvas frame editFrame->OnEditItemRequest( NULL, item ); if( !undoList.empty() && undoList.back() != undoSavePoint ) // Undo buffer has changed { // Process changes stored after undoSavePoint processUndoBuffer( undoSavePoint ); // Update the modified item item->ViewUpdate(); RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest(); ratsnest->Recalculate(); // TODO OBSERVER! I miss you so much.. m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } item->SetFlags( flags ); } if( unselect ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); return 0; }
int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); if( !makeSelection( selection ) ) { setTransitions(); return 0; } // Properties are displayed when there is only one item selected if( selection.Size() == 1 ) { // Display properties dialog BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 ); // Check if user wants to edit pad or module properties if( item->Type() == PCB_MODULE_T ) { VECTOR2D cursor = getViewControls()->GetCursorPosition(); for( D_PAD* pad = static_cast<MODULE*>( item )->Pads(); pad; pad = pad->Next() ) { if( pad->ViewBBox().Contains( cursor ) ) { // Turns out that user wants to edit a pad properties item = pad; break; } } } std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); // It is necessary to determine if anything has changed PICKED_ITEMS_LIST* lastChange = undoList.empty() ? NULL : undoList.back(); // Display properties dialog editFrame->OnEditItemRequest( NULL, item ); PICKED_ITEMS_LIST* currentChange = undoList.empty() ? NULL : undoList.back(); if( lastChange != currentChange ) // Something has changed { processChanges( currentChange ); updateRatsnest( true ); getModel<BOARD>()->GetRatsnest()->Recalculate(); item->ViewUpdate(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } item->SetFlags( flags ); } setTransitions(); return 0; }
void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand, bool aRebuildRatsnet ) { BOARD_ITEM* item; bool not_found = false; bool reBuild_ratsnest = false; KIGFX::VIEW* view = GetGalCanvas()->GetView(); RN_DATA* ratsnest = GetBoard()->GetRatsnest(); // Undo in the reverse order of list creation: (this can allow stacked changes // like the same item can be changes and deleted in the same complex command bool build_item_list = true; // if true the list of existing items must be rebuilt for( int ii = aList->GetCount() - 1; ii >= 0 ; ii-- ) { item = (BOARD_ITEM*) aList->GetPickedItem( ii ); wxASSERT( item ); /* Test for existence of item on board. * It could be deleted, and no more on board: * - if a call to SaveCopyInUndoList was forgotten in Pcbnew * - in zones outlines, when a change in one zone merges this zone with an other * This test avoids a Pcbnew crash * Obviously, this test is not made for deleted items */ UNDO_REDO_T status = aList->GetPickedItemStatus( ii ); if( status != UR_DELETED ) { if( build_item_list ) // Build list of existing items, for integrity test TestForExistingItem( GetBoard(), NULL ); build_item_list = false; if( !TestForExistingItem( GetBoard(), item ) ) { // Remove this non existent item aList->RemovePicker( ii ); ii++; // the current item was removed, ii points now the next item // decrement it because it will be incremented later not_found = true; continue; } } item->ClearFlags(); // see if we must rebuild ratsnets and pointers lists switch( item->Type() ) { case PCB_MODULE_T: case PCB_ZONE_AREA_T: case PCB_TRACE_T: case PCB_VIA_T: reBuild_ratsnest = true; break; default: break; } switch( aList->GetPickedItemStatus( ii ) ) { case UR_CHANGED: /* Exchange old and new data for each item */ { BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii ); // Remove all pads/drawings/texts, as they become invalid // for the VIEW after SwapData() called for modules if( item->Type() == PCB_MODULE_T ) { MODULE* oldModule = static_cast<MODULE*>( item ); oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); } ratsnest->Remove( item ); item->SwapData( image ); // Update all pads/drawings/texts, as they become invalid // for the VIEW after SwapData() called for modules if( item->Type() == PCB_MODULE_T ) { MODULE* newModule = static_cast<MODULE*>( item ); newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); } ratsnest->Add( item ); item->ClearFlags( SELECTED ); item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); } break; case UR_NEW: /* new items are deleted */ aList->SetPickedItemStatus( UR_DELETED, ii ); GetBoard()->Remove( item ); if( item->Type() == PCB_MODULE_T ) { MODULE* module = static_cast<MODULE*>( item ); module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); } view->Remove( item ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; case UR_DELETED: /* deleted items are put in List, as new items */ aList->SetPickedItemStatus( UR_NEW, ii ); GetBoard()->Add( item ); if( item->Type() == PCB_MODULE_T ) { MODULE* module = static_cast<MODULE*>( item ); module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1) ); } view->Add( item ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); build_item_list = true; break; case UR_MOVED: item->Move( aRedoCommand ? aList->m_TransformPoint : -aList->m_TransformPoint ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); ratsnest->Update( item ); break; case UR_ROTATED: item->Rotate( aList->m_TransformPoint, aRedoCommand ? m_rotationAngle : -m_rotationAngle ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); ratsnest->Update( item ); break; case UR_ROTATED_CLOCKWISE: item->Rotate( aList->m_TransformPoint, aRedoCommand ? -m_rotationAngle : m_rotationAngle ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); ratsnest->Update( item ); break; case UR_FLIPPED: item->Flip( aList->m_TransformPoint ); item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS ); ratsnest->Update( item ); break; default: { wxString msg; msg.Printf( wxT( "PutDataInPreviousState() error (unknown code %X)" ), aList->GetPickedItemStatus( ii ) ); wxMessageBox( msg ); } break; } } if( not_found ) wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) ); // Rebuild pointers and ratsnest that can be changed. if( reBuild_ratsnest && aRebuildRatsnet ) { if( IsGalCanvasActive() ) ratsnest->Recalculate(); else Compile_Ratsnest( NULL, true ); } }
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(); }