void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector ) { SCH_ITEM* newitem; if( aItemsList.GetCount() == 0 ) return; for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) { newitem = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) ); aItemsList.SetPickedItem( newitem, ii ); aItemsList.SetPickedItemStatus( UR_NEW, ii ); { switch( newitem->Type() ) { case SCH_JUNCTION_T: case SCH_LINE_T: case SCH_BUS_BUS_ENTRY_T: case SCH_BUS_WIRE_ENTRY_T: case SCH_TEXT_T: case SCH_LABEL_T: case SCH_GLOBAL_LABEL_T: case SCH_HIERARCHICAL_LABEL_T: case SCH_SHEET_PIN_T: case SCH_MARKER_T: case SCH_NO_CONNECT_T: default: break; case SCH_SHEET_T: { SCH_SHEET* sheet = (SCH_SHEET*) newitem; sheet->SetTimeStamp( GetNewTimeStamp() ); break; } case SCH_COMPONENT_T: ( (SCH_COMPONENT*) newitem )->SetTimeStamp( GetNewTimeStamp() ); ( (SCH_COMPONENT*) newitem )->ClearAnnotation( NULL ); break; } SetSchItemParent( newitem, screen ); screen->Append( newitem ); } } MoveItemsInList( aItemsList, aMoveVector ); }
void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC ) { SCH_ITEM* Struct; if( m_blockItems.GetCount() == 0 ) { DisplayError( this, wxT( "No struct to paste" ) ); return; } PICKED_ITEMS_LIST picklist; for( unsigned ii = 0; ii < m_blockItems.GetCount(); ii++ ) { Struct = DuplicateStruct( (SCH_ITEM*) m_blockItems.m_ItemsSelection.GetPickedItem( ii ) ); // Creates data, and push it as new data in undo item list buffer ITEM_PICKER picker( Struct, UR_NEW ); picklist.PushItem( picker ); // Clear annotation and init new time stamp for the new components: if( Struct->Type() == SCH_COMPONENT_T ) { ( (SCH_COMPONENT*) Struct )->SetTimeStamp( GetNewTimeStamp() ); ( (SCH_COMPONENT*) Struct )->ClearAnnotation( NULL ); } SetSchItemParent( Struct, GetScreen() ); Struct->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); GetScreen()->Append( Struct ); } SaveCopyInUndoList( picklist, UR_NEW ); MoveItemsInList( picklist, GetScreen()->m_BlockLocate.m_MoveVector ); // Clear flags for all items. GetScreen()->ClearDrawingState(); OnModify(); return; }
void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC ) { unsigned i; SCH_ITEM* item; SCH_SHEET_LIST hierarchy; // This is the entire schematic hierarcy. if( m_blockItems.GetCount() == 0 ) { DisplayError( this, _( "No item to paste." ) ); return; } wxFileName destFn = m_CurrentSheet->Last()->GetFileName(); if( destFn.IsRelative() ) destFn.MakeAbsolute( Prj().GetProjectPath() ); // Make sure any sheets in the block to be pasted will not cause recursion in // the destination sheet. for( i = 0; i < m_blockItems.GetCount(); i++ ) { item = (SCH_ITEM*) m_blockItems.GetItem( i ); if( item->Type() == SCH_SHEET_T ) { SCH_SHEET* sheet = (SCH_SHEET*)item; wxFileName srcFn = sheet->GetFileName(); if( srcFn.IsRelative() ) srcFn.MakeAbsolute( Prj().GetProjectPath() ); SCH_SHEET_LIST sheetHierarchy( sheet ); if( hierarchy.TestForRecursion( sheetHierarchy, destFn.GetFullPath( wxPATH_UNIX ) ) ) { wxString msg; msg.Printf( _( "The sheet changes cannot be made because the destination " "sheet already has the sheet <%s> or one of it's subsheets " "as a parent somewhere in the schematic hierarchy." ), GetChars( sheet->GetFileName() ) ); DisplayError( this, msg ); return; } // Duplicate sheet names and sheet time stamps are not valid. Use a time stamp // based sheet name and update the time stamp for each sheet in the block. unsigned long timeStamp = (unsigned long)GetNewTimeStamp(); sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), timeStamp ) ); sheet->SetTimeStamp( (time_t)timeStamp ); } } PICKED_ITEMS_LIST picklist; for( i = 0; i < m_blockItems.GetCount(); i++ ) { item = DuplicateStruct( (SCH_ITEM*) m_blockItems.GetItem( i ) ); // Creates data, and push it as new data in undo item list buffer ITEM_PICKER picker( item, UR_NEW ); picklist.PushItem( picker ); // Clear annotation and init new time stamp for the new components and sheets: if( item->Type() == SCH_COMPONENT_T ) { ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() ); ( (SCH_COMPONENT*) item )->ClearAnnotation( NULL ); } else if( item->Type() == SCH_SHEET_T ) { ( (SCH_SHEET*) item )->SetTimeStamp( GetNewTimeStamp() ); } SetSchItemParent( item, GetScreen() ); item->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); GetScreen()->Append( item ); } SaveCopyInUndoList( picklist, UR_NEW ); MoveItemsInList( picklist, GetScreen()->m_BlockLocate.GetMoveVector() ); // Clear flags for all items. GetScreen()->ClearDrawingState(); OnModify(); return; }
bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC ) { bool nextcmd = false; bool zoom_command = false; BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; if( block->GetCount() ) { BLOCK_STATE_T state = block->GetState(); BLOCK_COMMAND_T command = block->GetCommand(); m_canvas->CallEndMouseCapture( aDC ); block->SetState( state ); block->SetCommand( command ); m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand ); SetCrossHairPosition( block->GetEnd() ); if( block->GetCommand() != BLOCK_ABORT ) m_canvas->MoveCursorToCrossHair(); } if( m_canvas->IsMouseCaptured() ) { switch( block->GetCommand() ) { case BLOCK_IDLE: DisplayError( this, wxT( "Error in HandleBlockPLace()" ) ); break; case BLOCK_ROTATE: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { // Compute the rotation center and put it on grid: wxPoint rotationPoint = block->Centre(); rotationPoint = GetNearestGridPosition( rotationPoint ); SetCrossHairPosition( rotationPoint ); SaveCopyInUndoList( block->GetItems(), UR_ROTATED, rotationPoint ); RotateListOfItems( block->GetItems(), rotationPoint ); OnModify(); } block->ClearItemsList(); GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; case BLOCK_DRAG: case BLOCK_DRAG_ITEM: // Drag from a drag command GetScreen()->BreakSegmentsOnJunctions(); // fall through case BLOCK_MOVE: case BLOCK_COPY: if( block->GetCommand() == BLOCK_DRAG_ITEM && GetScreen()->GetCurItem() != NULL ) { // This is a drag command, not a mouse block command // Only this item is put in list ITEM_PICKER picker; picker.SetItem( GetScreen()->GetCurItem() ); block->PushItem( picker ); } else { // Collect all items in the locate block GetScreen()->UpdatePickList(); } // fall through case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/ if( block->GetCount() ) { nextcmd = true; GetScreen()->SelectBlockItems(); m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines ); m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); block->SetState( STATE_BLOCK_MOVE ); } else { m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); } break; case BLOCK_DELETE: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { DeleteItemsInList( m_canvas, block->GetItems() ); OnModify(); } block->ClearItemsList(); GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; case BLOCK_SAVE: // Save a copy of items in paste buffer GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { wxPoint move_vector = -GetScreen()->m_BlockLocate.GetLastCursorPosition(); copyBlockItems( block->GetItems() ); MoveItemsInList( m_blockItems.GetItems(), move_vector ); } block->ClearItemsList(); break; case BLOCK_PASTE: block->SetState( STATE_BLOCK_MOVE ); break; case BLOCK_ZOOM: zoom_command = true; break; case BLOCK_MIRROR_X: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { // Compute the mirror center and put it on grid. wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetNearestGridPosition( mirrorPoint ); SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_X, mirrorPoint ); MirrorX( block->GetItems(), mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; case BLOCK_MIRROR_Y: GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false ); if( block->GetCount() ) { // Compute the mirror center and put it on grid. wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetNearestGridPosition( mirrorPoint ); SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->GetItems(), UR_MIRRORED_Y, mirrorPoint ); MirrorY( block->GetItems(), mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, aDC ); m_canvas->Refresh(); break; default: break; } } if( block->GetCommand() == BLOCK_ABORT ) { GetScreen()->ClearDrawingState(); m_canvas->Refresh(); } if( ! nextcmd ) { block->SetState( STATE_NO_BLOCK ); block->SetCommand( BLOCK_IDLE ); GetScreen()->SetCurItem( NULL ); m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); } if( zoom_command ) Window_Zoom( GetScreen()->m_BlockLocate ); return nextcmd; }
void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC ) { BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; if( !m_canvas->IsMouseCaptured() ) { DisplayError( this, wxT( "HandleBlockPLace() : m_mouseCaptureCallback = NULL" ) ); } if( block->GetCount() == 0 ) { wxString msg; msg.Printf( wxT( "HandleBlockPLace() error : no items to place (cmd %d, state %d)" ), block->GetCommand(), block->GetState() ); DisplayError( this, msg ); } block->SetState( STATE_BLOCK_STOP ); switch( block->GetCommand() ) { case BLOCK_DRAG: // Drag from mouse case BLOCK_DRAG_ITEM: // Drag from a component selection and drag command case BLOCK_MOVE: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); SaveCopyInUndoList( block->GetItems(), UR_MOVED, block->GetMoveVector() ); MoveItemsInList( block->GetItems(), block->GetMoveVector() ); block->ClearItemsList(); break; case BLOCK_COPY: /* Copy */ case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); DuplicateItemsInList( GetScreen(), block->GetItems(), block->GetMoveVector() ); SaveCopyInUndoList( block->GetItems(), ( block->GetCommand() == BLOCK_PRESELECT_MOVE ) ? UR_CHANGED : UR_NEW ); block->ClearItemsList(); break; case BLOCK_PASTE: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); PasteListOfItems( DC ); block->ClearItemsList(); break; default: // others are handled by HandleBlockEnd() break; } OnModify(); // clear dome flags and pointers GetScreen()->ClearDrawingState(); GetScreen()->ClearBlockCommand(); GetScreen()->SetCurItem( NULL ); GetScreen()->TestDanglingEnds( m_canvas, DC ); if( block->GetCount() ) { DisplayError( this, wxT( "HandleBlockPLace() error: some items left in buffer" ) ); block->ClearItemsList(); } m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); m_canvas->Refresh(); }
void SCH_EDIT_FRAME::HandleBlockEndByPopUp( int Command, wxDC* DC ) { bool blockCmdFinished = true; /* set to false for block command which * have a next step * and true if the block command is finished here */ BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; // can convert only a block move command to an other command if( block->m_Command != BLOCK_MOVE ) return; // Useless if the new command is block move because we are already in block move. if( Command == BLOCK_MOVE ) return; block->m_Command = (CmdBlockType) Command; block->SetMessageBlock( this ); switch( block->m_Command ) { case BLOCK_COPY: /* move to copy */ block->m_State = STATE_BLOCK_MOVE; blockCmdFinished = false; break; case BLOCK_DRAG: /* move to Drag */ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // Clear list of items to move, and rebuild it with items to drag: block->ClearItemsList(); GetScreen()->BreakSegmentsOnJunctions(); GetScreen()->UpdatePickList(); if( block->GetCount() ) { blockCmdFinished = false; GetScreen()->SelectBlockItems(); if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); block->m_State = STATE_BLOCK_MOVE; } break; case BLOCK_DELETE: /* move to Delete */ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { DeleteItemsInList( m_canvas, block->m_ItemsSelection ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; case BLOCK_SAVE: /* Save list in paste buffer*/ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { wxPoint move_vector = -GetScreen()->m_BlockLocate.m_BlockLastCursorPosition; copyBlockItems( block->m_ItemsSelection ); MoveItemsInList( m_blockItems.m_ItemsSelection, move_vector ); } break; case BLOCK_ZOOM: /* Window Zoom */ m_canvas->CallEndMouseCapture( DC ); m_canvas->SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() ); Window_Zoom( GetScreen()->m_BlockLocate ); break; case BLOCK_ROTATE: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { /* Compute the rotation center and put it on grid */ wxPoint rotationPoint = block->Centre(); rotationPoint = GetScreen()->GetNearestGridPosition( rotationPoint ); GetScreen()->SetCrossHairPosition( rotationPoint ); SaveCopyInUndoList( block->m_ItemsSelection, UR_ROTATED, rotationPoint ); RotateListOfItems( block->m_ItemsSelection, rotationPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; case BLOCK_MIRROR_X: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { /* Compute the mirror center and put it on grid */ wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetScreen()->GetNearestGridPosition( mirrorPoint ); GetScreen()->SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->m_ItemsSelection, UR_MIRRORED_X, mirrorPoint ); MirrorX( block->m_ItemsSelection, mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; case BLOCK_MIRROR_Y: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); if( block->GetCount() ) { /* Compute the mirror center and put it on grid */ wxPoint mirrorPoint = block->Centre(); mirrorPoint = GetScreen()->GetNearestGridPosition( mirrorPoint ); GetScreen()->SetCrossHairPosition( mirrorPoint ); SaveCopyInUndoList( block->m_ItemsSelection, UR_MIRRORED_Y, mirrorPoint ); MirrorY( block->m_ItemsSelection, mirrorPoint ); OnModify(); } GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; default: break; } if( blockCmdFinished ) { block->Clear(); GetScreen()->SetCurItem( NULL ); m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); } }
bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* DC ) { bool nextcmd = false; bool zoom_command = false; BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; if( block->GetCount() ) { BlockState state = block->m_State; CmdBlockType command = block->m_Command; m_canvas->CallEndMouseCapture( DC ); block->m_State = state; block->m_Command = command; m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand ); GetScreen()->SetCrossHairPosition( block->GetEnd() ); if( block->m_Command != BLOCK_ABORT ) m_canvas->MoveCursorToCrossHair(); } if( m_canvas->IsMouseCaptured() ) { switch( block->m_Command ) { case BLOCK_IDLE: DisplayError( this, wxT( "Error in HandleBlockPLace()" ) ); break; case BLOCK_DRAG: /* Drag */ GetScreen()->BreakSegmentsOnJunctions(); // fall through case BLOCK_ROTATE: case BLOCK_MIRROR_X: case BLOCK_MIRROR_Y: case BLOCK_MOVE: /* Move */ case BLOCK_COPY: /* Copy */ GetScreen()->UpdatePickList(); // fall through case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/ if( block->GetCount() ) { nextcmd = true; GetScreen()->SelectBlockItems(); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines ); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); block->m_State = STATE_BLOCK_MOVE; } else { m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); } break; case BLOCK_DELETE: /* Delete */ GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, DC, wxDefaultPosition, false ); if( block->GetCount() ) { DeleteItemsInList( m_canvas, block->m_ItemsSelection ); OnModify(); } block->ClearItemsList(); GetScreen()->TestDanglingEnds( m_canvas, DC ); m_canvas->Refresh(); break; case BLOCK_SAVE: /* Save */ GetScreen()->UpdatePickList(); DrawAndSizingBlockOutlines( m_canvas, DC, wxDefaultPosition, false ); if( block->GetCount() ) { wxPoint move_vector = -GetScreen()->m_BlockLocate.m_BlockLastCursorPosition; copyBlockItems( block->m_ItemsSelection ); MoveItemsInList( m_blockItems.m_ItemsSelection, move_vector ); } block->ClearItemsList(); break; case BLOCK_PASTE: block->m_State = STATE_BLOCK_MOVE; break; case BLOCK_FLIP: /* Pcbnew only! */ break; case BLOCK_ZOOM: /* Window Zoom */ zoom_command = true; break; case BLOCK_SELECT_ITEMS_ONLY: /* Not used */ case BLOCK_ABORT: /* not executed here */ break; } } if( block->m_Command == BLOCK_ABORT ) { GetScreen()->ClearDrawingState(); m_canvas->Refresh(); } if( ! nextcmd ) { block->ClearFlags(); block->m_State = STATE_NO_BLOCK; block->m_Command = BLOCK_IDLE; GetScreen()->SetCurItem( NULL ); m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); } if( zoom_command ) Window_Zoom( GetScreen()->m_BlockLocate ); return nextcmd; }
void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC ) { BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; if( !m_canvas->IsMouseCaptured() ) { DisplayError( this, wxT( "HandleBlockPLace() : m_mouseCaptureCallback = NULL" ) ); } if( block->GetCount() == 0 ) { wxString msg; msg.Printf( wxT( "HandleBlockPLace() error : no items to place (cmd %d, state %d)" ), block->m_Command, block->m_State ); DisplayError( this, msg ); } block->m_State = STATE_BLOCK_STOP; switch( block->m_Command ) { case BLOCK_IDLE: break; case BLOCK_ROTATE: case BLOCK_MIRROR_X: case BLOCK_MIRROR_Y: case BLOCK_DRAG: /* Drag */ case BLOCK_MOVE: /* Move */ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); SaveCopyInUndoList( block->m_ItemsSelection, UR_MOVED, block->m_MoveVector ); MoveItemsInList( block->m_ItemsSelection, block->m_MoveVector ); block->ClearItemsList(); break; case BLOCK_COPY: /* Copy */ case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/ if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); DuplicateItemsInList( GetScreen(), block->m_ItemsSelection, block->m_MoveVector ); SaveCopyInUndoList( block->m_ItemsSelection, ( block->m_Command == BLOCK_PRESELECT_MOVE ) ? UR_CHANGED : UR_NEW ); block->ClearItemsList(); break; case BLOCK_PASTE: if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); PasteListOfItems( DC ); block->ClearItemsList(); break; case BLOCK_ZOOM: // Handled by HandleBlockEnd() case BLOCK_DELETE: case BLOCK_SAVE: case BLOCK_FLIP: case BLOCK_ABORT: case BLOCK_SELECT_ITEMS_ONLY: break; } OnModify(); // clear struct.m_Flags. GetScreen()->ClearDrawingState(); GetScreen()->ClearBlockCommand(); GetScreen()->SetCurItem( NULL ); GetScreen()->TestDanglingEnds( m_canvas, DC ); if( block->GetCount() ) { DisplayError( this, wxT( "HandleBlockPLace() error: some items left in buffer" ) ); block->ClearItemsList(); } m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false ); m_canvas->Refresh(); }