Library Editor: copy/cut/paste for graphical items
This commit is contained in:
parent
4fe06656a6
commit
256276cf1c
|
@ -147,6 +147,31 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
|||
block->SetState( STATE_BLOCK_MOVE );
|
||||
break;
|
||||
|
||||
case BLOCK_COPY: // Save a copy of items in the clipboard buffer
|
||||
case BLOCK_CUT:
|
||||
if( GetCurPart() )
|
||||
ItemCount = GetCurPart()->SelectItems( *block, m_unit, m_convert,
|
||||
m_editPinsPerPartOrConvert );
|
||||
|
||||
if( ItemCount )
|
||||
{
|
||||
copySelectedItems();
|
||||
auto cmd = block->GetCommand();
|
||||
|
||||
if( cmd == BLOCK_COPY )
|
||||
{
|
||||
GetCurPart()->ClearSelectedItems();
|
||||
block->ClearItemsList();
|
||||
}
|
||||
else if( cmd == BLOCK_CUT )
|
||||
{
|
||||
SaveCopyInUndoList( GetCurPart() );
|
||||
GetCurPart()->DeleteSelectedItems();
|
||||
OnModify();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BLOCK_DELETE: // Delete
|
||||
if( GetCurPart() )
|
||||
ItemCount = GetCurPart()->SelectItems( *block,
|
||||
|
@ -162,8 +187,10 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
|||
}
|
||||
break;
|
||||
|
||||
case BLOCK_COPY: // Save
|
||||
case BLOCK_PASTE:
|
||||
wxFAIL; // should not happen
|
||||
break;
|
||||
|
||||
case BLOCK_FLIP:
|
||||
break;
|
||||
|
||||
|
@ -208,7 +235,6 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
|
|||
|
||||
case BLOCK_DUPLICATE_AND_INCREMENT: // not used in Eeschema
|
||||
case BLOCK_MOVE_EXACT: // not used in Eeschema
|
||||
case BLOCK_CUT: // not used in libedit
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -280,6 +306,14 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
|
|||
|
||||
case BLOCK_PASTE: // Paste (recopy the last block saved)
|
||||
block->ClearItemsList();
|
||||
|
||||
if( GetCurPart() )
|
||||
SaveCopyInUndoList( GetCurPart() );
|
||||
|
||||
pt = block->GetMoveVector();
|
||||
pt.y = -pt.y;
|
||||
|
||||
pasteClipboard( pt );
|
||||
break;
|
||||
|
||||
case BLOCK_ROTATE: // Invert by popup menu, from block move
|
||||
|
@ -324,6 +358,73 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
|
|||
}
|
||||
|
||||
|
||||
void LIB_EDIT_FRAME::InitBlockPasteInfos()
|
||||
{
|
||||
BLOCK_SELECTOR& block = GetScreen()->m_BlockLocate;
|
||||
|
||||
// Copy the clipboard contents to the screen block selector
|
||||
// (only the copy, the new instances will be appended to the part once the items are placed)
|
||||
block.GetItems().CopyList( m_clipboard.GetItems() );
|
||||
|
||||
// Set the pate reference point
|
||||
block.SetLastCursorPosition( m_clipboard.GetLastCursorPosition() );
|
||||
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
|
||||
}
|
||||
|
||||
|
||||
void LIB_EDIT_FRAME::copySelectedItems()
|
||||
{
|
||||
LIB_PART* part = GetCurPart();
|
||||
|
||||
if( !part )
|
||||
return;
|
||||
|
||||
m_clipboard.ClearListAndDeleteItems(); // delete previous saved list, if exists
|
||||
m_clipboard.SetLastCursorPosition( GetScreen()->m_BlockLocate.GetEnd() ); // store the reference point
|
||||
|
||||
for( LIB_ITEM& item : part->GetDrawItems() )
|
||||
{
|
||||
// We *do not* copy fields because they are unique for the whole component
|
||||
// so skip them (do not duplicate) if they are flagged selected.
|
||||
if( item.Type() == LIB_FIELD_T )
|
||||
item.ClearFlags( SELECTED );
|
||||
|
||||
if( !item.IsSelected() )
|
||||
continue;
|
||||
|
||||
// Do not clear the 'selected' flag. It is required to have items drawn when they are pasted.
|
||||
LIB_ITEM* copy = (LIB_ITEM*) item.Clone();
|
||||
|
||||
// In list the wrapper is owner of the schematic item, we can use the UR_DELETED
|
||||
// status for the picker because pickers with this status are owner of the picked item
|
||||
// (or TODO ?: create a new status like UR_DUPLICATE)
|
||||
ITEM_PICKER picker( copy, UR_DELETED );
|
||||
m_clipboard.PushItem( picker );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LIB_EDIT_FRAME::pasteClipboard( const wxPoint& aOffset )
|
||||
{
|
||||
LIB_PART* part = GetCurPart();
|
||||
|
||||
if( !part || m_clipboard.GetCount() == 0 )
|
||||
return;
|
||||
|
||||
for( unsigned int i = 0; i < m_clipboard.GetCount(); i++ )
|
||||
{
|
||||
// Append a copy to the current part, so the clipboard buffer might be pasted multiple times
|
||||
LIB_ITEM* item = (LIB_ITEM*) m_clipboard.GetItem( i )->Clone();
|
||||
item->SetParent( part );
|
||||
item->SetSelected();
|
||||
part->AddDrawItem( item );
|
||||
}
|
||||
|
||||
GetCurPart()->MoveSelectedItems( aOffset );
|
||||
OnModify();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Traces the outline of the search block structures
|
||||
* The entire block follows the cursor
|
||||
|
@ -353,6 +454,12 @@ void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint&
|
|||
{
|
||||
block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
|
||||
component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert, opts );
|
||||
|
||||
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
|
||||
{
|
||||
LIB_ITEM* libItem = (LIB_ITEM*) block->GetItem( ii );
|
||||
libItem->Draw( aPanel, aDC, block->GetMoveVector(), g_GhostColor, g_XorMode, nullptr, opts.transform );
|
||||
}
|
||||
}
|
||||
|
||||
// Repaint new view
|
||||
|
@ -361,5 +468,11 @@ void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint&
|
|||
GRSetDrawMode( aDC, g_XorMode );
|
||||
block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
|
||||
|
||||
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
|
||||
{
|
||||
LIB_ITEM* libItem = (LIB_ITEM*) block->GetItem( ii );
|
||||
libItem->Draw( aPanel, aDC, block->GetMoveVector(), g_GhostColor, g_XorMode, nullptr, opts.transform );
|
||||
}
|
||||
|
||||
component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert, opts );
|
||||
}
|
||||
|
|
|
@ -327,6 +327,9 @@ static EDA_HOTKEY* libEdit_Hotkey_List[] =
|
|||
&HkMoveLibItem,
|
||||
&HkMirrorX,
|
||||
&HkMirrorY,
|
||||
&HkCopyBlock,
|
||||
&HkPasteBlock,
|
||||
&HkCutBlock,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -703,6 +706,9 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
|||
case HK_ZOOM_REDRAW:
|
||||
case HK_ZOOM_CENTER:
|
||||
case HK_ZOOM_AUTO:
|
||||
case HK_PASTE_BLOCK:
|
||||
case HK_COPY_BLOCK:
|
||||
case HK_CUT_BLOCK:
|
||||
cmd.SetId( hotKey->m_IdMenuEvent );
|
||||
GetEventHandler()->ProcessEvent( cmd );
|
||||
break;
|
||||
|
|
|
@ -337,6 +337,14 @@ void AddMenusForBlock( wxMenu* PopMenu, LIB_EDIT_FRAME* frame )
|
|||
{
|
||||
AddMenuItem( PopMenu, ID_POPUP_SELECT_ITEMS_BLOCK, _( "Select Items" ),
|
||||
KiBitmap( green_xpm ) );
|
||||
msg = AddHotkeyName( _( "Cut Block" ), g_Schematic_Hokeys_Descr,
|
||||
HK_CUT_BLOCK );
|
||||
AddMenuItem( PopMenu, wxID_CUT, msg, KiBitmap( cut_xpm ) );
|
||||
msg = AddHotkeyName( _( "Copy Block" ), g_Schematic_Hokeys_Descr,
|
||||
HK_COPY_BLOCK );
|
||||
AddMenuItem( PopMenu, wxID_COPY, msg, KiBitmap( copy_xpm ) );
|
||||
AddMenuItem( PopMenu, ID_POPUP_DUPLICATE_BLOCK, _( "Duplicate Block" ),
|
||||
KiBitmap( duplicate_xpm ) );
|
||||
AddMenuItem( PopMenu, ID_POPUP_DUPLICATE_BLOCK, _( "Duplicate Block" ), KiBitmap( duplicate_xpm ) );
|
||||
msg = AddHotkeyName( _( "Flip Block Horizonal" ), g_Libedit_Hokeys_Descr, HK_MIRROR_Y );
|
||||
AddMenuItem( PopMenu, ID_POPUP_MIRROR_Y_BLOCK, msg,
|
||||
|
|
|
@ -110,6 +110,9 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
|||
|
||||
// Main horizontal toolbar.
|
||||
EVT_TOOL( ID_TO_LIBVIEW, LIB_EDIT_FRAME::OnOpenLibraryViewer )
|
||||
EVT_TOOL( wxID_COPY, LIB_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_TOOL( wxID_PASTE, LIB_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_TOOL( wxID_CUT, LIB_EDIT_FRAME::Process_Special_Functions )
|
||||
EVT_TOOL( wxID_UNDO, LIB_EDIT_FRAME::GetComponentFromUndoList )
|
||||
EVT_TOOL( wxID_REDO, LIB_EDIT_FRAME::GetComponentFromRedoList )
|
||||
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnEditComponentProperties )
|
||||
|
@ -747,6 +750,8 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
|
||||
switch( id ) // Stop placement commands before handling new command.
|
||||
{
|
||||
case wxID_COPY:
|
||||
case wxID_CUT:
|
||||
case ID_POPUP_LIBEDIT_END_CREATE_ITEM:
|
||||
case ID_LIBEDIT_EDIT_PIN:
|
||||
case ID_POPUP_LIBEDIT_BODY_EDIT_ITEM:
|
||||
|
@ -965,6 +970,25 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
HandleBlockPlace( &dc );
|
||||
break;
|
||||
|
||||
case wxID_COPY:
|
||||
block.SetCommand( BLOCK_COPY );
|
||||
block.SetMessageBlock( this );
|
||||
HandleBlockEnd( &dc );
|
||||
break;
|
||||
|
||||
case wxID_PASTE:
|
||||
HandleBlockBegin( &dc, BLOCK_PASTE, GetCrossHairPosition() );
|
||||
break;
|
||||
|
||||
case wxID_CUT:
|
||||
if( block.GetCommand() != BLOCK_MOVE )
|
||||
break;
|
||||
|
||||
block.SetCommand( BLOCK_CUT );
|
||||
block.SetMessageBlock( this );
|
||||
HandleBlockEnd( &dc );
|
||||
break;
|
||||
|
||||
default:
|
||||
DisplayError( this, "LIB_EDIT_FRAME::Process_Special_Functions error" );
|
||||
break;
|
||||
|
|
|
@ -731,7 +731,23 @@ private:
|
|||
///> Renames LIB_PART aliases to avoid conflicts before adding a component to a library
|
||||
void fixDuplicateAliases( LIB_PART* aPart, const wxString& aLibrary );
|
||||
|
||||
// Copy/cut/paste buffer
|
||||
void InitBlockPasteInfos() override;
|
||||
|
||||
/**
|
||||
* Copies items selected in the current part to the internal clipboard.
|
||||
*/
|
||||
void copySelectedItems();
|
||||
|
||||
/**
|
||||
* Pastes items from the internal clipboard to the current part.
|
||||
* @param aOffset is the offset where the pasted items should be located.
|
||||
*/
|
||||
void pasteClipboard( const wxPoint& aOffset );
|
||||
|
||||
///> Clipboard buffer storing LIB_ITEMs
|
||||
BLOCK_SELECTOR m_clipboard;
|
||||
|
||||
// Copy/cut/paste buffer to move parts between libraries
|
||||
std::unique_ptr<LIB_PART> m_copiedPart;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
|
Loading…
Reference in New Issue