Add modern toolset cut/copy/paste. They now use the system clipboard.

This commit is contained in:
Jeff Young 2019-04-28 17:36:31 +01:00
parent 2bd4a1b58c
commit da988428cf
22 changed files with 475 additions and 719 deletions

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2018 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2004-2019 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,10 +23,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file eeschema/block.cpp
*/
#include <fctsys.h>
#include <pgm_base.h>
#include <gr_basic.h>
@ -53,8 +49,6 @@
#include <sch_view.h>
#include <view/view_group.h>
static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aPosition, bool aErase );
int SCH_EDIT_FRAME::BlockCommand( EDA_KEY key )
{
@ -93,471 +87,25 @@ int SCH_EDIT_FRAME::BlockCommand( EDA_KEY key )
void SCH_EDIT_FRAME::InitBlockPasteInfos()
{
BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
block->GetItems().CopyList( m_blockItems.GetItems() );
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
wxFAIL_MSG( "How did we get here? Should have gone through modern toolset..." );
return;
}
void SCH_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
{
BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
wxCHECK_RET( m_canvas->IsMouseCaptured(), "No block mouse capture callback is set" );
if( block->GetCount() == 0 )
{
wxString msg;
msg.Printf( wxT( "HandleBlockPLace() error : no items to place (cmd %d, state %d)" ),
block->GetCommand(), block->GetState() );
wxFAIL_MSG( 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:
case BLOCK_DUPLICATE: /* Duplicate */
if( m_canvas->IsMouseCaptured() )
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
// If the block wasn't changed, don't update the schematic
if( block->GetMoveVector() == wxPoint( 0, 0 ) && !block->AppendUndo() )
{
// This calls the block-abort command routine on cleanup
m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor() );
return;
}
if( block->GetCommand() != BLOCK_DUPLICATE )
SaveCopyInUndoList( block->GetItems(), UR_CHANGED, block->AppendUndo(), block->GetMoveVector() );
for( unsigned ii = 0; ii < block->GetItems().GetCount(); ii++ )
{
SCH_ITEM* item = static_cast<SCH_ITEM*>( block->GetItems().GetPickedItem( ii ) );
item->Move( block->GetMoveVector() );
item->SetFlags( IS_MOVED );
GetCanvas()->GetView()->Update( item, KIGFX::GEOMETRY );
}
break;
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(), UR_CHANGED, block->AppendUndo() );
break;
case BLOCK_PASTE:
if( m_canvas->IsMouseCaptured() )
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
PasteListOfItems( DC );
break;
default: // others are handled by HandleBlockEnd()
break;
}
CheckListConnections( block->GetItems(), true );
block->ClearItemsList();
SchematicCleanUp( true );
TestDanglingEnds();
OnModify();
// clear dome flags and pointers
GetScreen()->ClearDrawingState();
GetScreen()->ClearBlockCommand();
GetScreen()->SetCurItem( NULL );
m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor(), wxEmptyString, false );
GetCanvas()->GetView()->ClearPreview();
GetCanvas()->GetView()->ClearHiddenFlags();
wxFAIL_MSG( "How did we get here? Should have gone through modern toolset..." );
return;
}
bool SCH_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
{
bool nextcmd = false;
bool append = false;
BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
auto panel =static_cast<SCH_DRAW_PANEL*>(m_canvas);
auto view = panel->GetView();
view->ShowSelectionArea( false );
view->ClearHiddenFlags();
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 );
if( block->GetCommand() != BLOCK_ABORT
&& block->GetCommand() != BLOCK_DUPLICATE
&& block->GetCommand() != BLOCK_COPY
&& block->GetCommand() != BLOCK_CUT
&& block->GetCommand() != BLOCK_DELETE )
{
SetCrossHairPosition( block->GetEnd() );
m_canvas->MoveCursorToCrossHair();
}
}
if( m_canvas->IsMouseCaptured() )
{
switch( block->GetCommand() )
{
case BLOCK_IDLE:
DisplayError( this, wxT( "Error in HandleBlockPLace()" ) );
break;
case BLOCK_DRAG:
case BLOCK_DRAG_ITEM: // Drag from a drag command
case BLOCK_MOVE:
case BLOCK_DUPLICATE:
case BLOCK_PRESELECT_MOVE:
if( block->GetCommand() == BLOCK_DRAG_ITEM )
{
// This is a drag command, not a mouse block command
// Only this item is put in list
if( GetScreen()->GetCurItem() )
{
ITEM_PICKER picker;
picker.SetItem( GetScreen()->GetCurItem() );
block->PushItem( picker );
}
}
else if( block->GetCommand() != BLOCK_PRESELECT_MOVE )
{
// Collect all items in the locate block
GetScreen()->UpdatePickList();
}
GetScreen()->SelectBlockItems();
if( block->GetCommand() == BLOCK_DUPLICATE )
{
DuplicateItemsInList( GetScreen(), block->GetItems(), block->GetMoveVector() );
block->SetLastCursorPosition( GetCrossHairPosition() );
SaveCopyInUndoList( block->GetItems(), UR_NEW );
block->SetAppendUndo();
}
if( block->GetCount() )
{
nextcmd = true;
m_toolManager->DeactivateTool();
block->SetState( STATE_BLOCK_MOVE );
if( block->GetCommand() != BLOCK_DRAG && block->GetCommand() != BLOCK_DRAG_ITEM )
{
// Mark dangling pins at the edges of the block:
std::vector<DANGLING_END_ITEM> internalPoints;
for( unsigned i = 0; i < block->GetCount(); ++i )
{
auto item = static_cast<SCH_ITEM*>( block->GetItem( i ) );
item->GetEndPoints( internalPoints );
}
for( unsigned i = 0; i < block->GetCount(); ++i )
{
auto item = static_cast<SCH_ITEM*>( block->GetItem( i ) );
item->UpdateDanglingState( internalPoints );
}
}
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
}
else
{
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
m_canvas->SetMouseCapture( NULL, NULL );
}
break;
case BLOCK_CUT:
case BLOCK_DELETE:
GetScreen()->UpdatePickList();
DrawAndSizingBlockOutlines( m_canvas, aDC, wxDefaultPosition, false );
// The CUT variant needs to copy the items from their originial position
if( ( block->GetCommand() == BLOCK_CUT ) && block->GetCount() )
{
wxPoint move_vector = -GetScreen()->m_BlockLocate.GetLastCursorPosition();
copyBlockItems( block->GetItems(), move_vector );
}
// We set this in a while loop to catch any newly created items
// as a result of the delete (e.g. merged wires)
while( block->GetCount() )
{
DeleteItemsInList( block->GetItems(), append );
SchematicCleanUp( true );
OnModify();
block->ClearItemsList();
GetScreen()->UpdatePickList();
append = true;
}
TestDanglingEnds();
break;
case BLOCK_COPY: // 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(), move_vector );
}
block->ClearItemsList();
break;
case BLOCK_ZOOM:
Window_Zoom( GetScreen()->m_BlockLocate );
break;
default:
break;
}
}
if( block->GetCommand() == BLOCK_ABORT )
{
if( block->AppendUndo() )
{
PICKED_ITEMS_LIST* undo = GetScreen()->PopCommandFromUndoList();
PutDataInPreviousState( undo, false );
undo->ClearListAndDeleteItems();
delete undo;
}
// We set the dangling ends to the block-scope, so we must set them back to
// schematic-scope.
TestDanglingEnds();
view->ShowSelectionArea( false );
view->ClearHiddenFlags();
}
if( !nextcmd )
{
GetScreen()->ClearBlockCommand();
GetScreen()->ClearDrawingState();
GetScreen()->SetCurItem( NULL );
m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor(), wxEmptyString,
false );
}
view->ShowSelectionArea( false );
if( !nextcmd )
view->ClearPreview();
view->ShowPreview( nextcmd );
return nextcmd;
wxFAIL_MSG( "How did we get here? Should have gone through modern toolset..." );
return false;
}
/* Traces the outline of the search block structures
* The entire block follows the cursor
*/
static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase )
{
SCH_DRAW_PANEL* panel =static_cast<SCH_DRAW_PANEL*>( aPanel );
KIGFX::SCH_VIEW* view = panel->GetView();
KIGFX::VIEW_GROUP* preview = view->GetPreview();
BASE_SCREEN* screen = aPanel->GetScreen();
BLOCK_SELECTOR* block = &screen->m_BlockLocate;
SCH_ITEM* schitem;
block->SetMoveVector( panel->GetParent()->GetCrossHairPosition() - block->GetLastCursorPosition() );
preview->Clear();
view->SetVisible( preview, true );
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
{
schitem = (SCH_ITEM*) block->GetItem( ii );
SCH_ITEM* copy = static_cast<SCH_ITEM*>( schitem->Clone() );
copy->Move( block->GetMoveVector() );
copy->SetFlags( IS_MOVED );
preview->Add( copy );
view->Hide( schitem );
}
view->Update( preview );
}
void SCH_EDIT_FRAME::copyBlockItems( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector )
{
m_blockItems.ClearListAndDeleteItems(); // delete previous saved list, if exists
wxRect bounds;
if( aItemsList.GetCount() > 0 )
bounds = aItemsList.GetPickedItem( 0 )->GetBoundingBox();
for( unsigned i = 1; i < aItemsList.GetCount(); ++i )
bounds.Union( aItemsList.GetPickedItem( i )->GetBoundingBox() );
wxPoint center( ( bounds.GetLeft() + bounds.GetRight() ) / 2,
( bounds.GetTop() + bounds.GetBottom() ) / 2 );
center = GetNearestGridPosition( center );
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
// Clear m_Flag member of selected items:
aItemsList.GetPickedItem( ii )->ClearFlags();
/* Make a copy of the original picked item. */
SCH_ITEM* copy = DuplicateStruct( (SCH_ITEM*) aItemsList.GetPickedItem( ii ) );
copy->SetParent( NULL );
copy->SetFlags( UR_TRANSIENT );
copy->Move( -center );
ITEM_PICKER item( copy, UR_NEW );
m_blockItems.PushItem( item );
}
}
void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
{
unsigned i;
SCH_ITEM* item;
SCH_SHEET_LIST hierarchy( g_RootSheet ); // This is the entire schematic hierarcy.
if( m_blockItems.GetCount() == 0 )
{
DisplayError( this, _( "No item to paste." ) );
return;
}
wxFileName destFn = g_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. Moreover new sheets create new sheetpaths, and component
// alternante references must be created and cleared
bool hasSheetPasted = false;
// Keep trace of existing sheet paths. Paste block can modify this list
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
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.
timestamp_t timeStamp = GetNewTimeStamp();
sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)timeStamp ) );
sheet->SetTimeStamp( timeStamp );
hasSheetPasted = true;
}
}
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* cmp = static_cast<SCH_COMPONENT*>( item );
cmp->SetTimeStamp( GetNewTimeStamp() );
// clear the annotation, but preserve the selected unit
int unit = cmp->GetUnit();
cmp->ClearAnnotation( NULL );
cmp->SetUnit( unit );
}
else if( item->Type() == SCH_SHEET_T )
{
( (SCH_SHEET*) item )->SetTimeStamp( GetNewTimeStamp() );
}
}
SaveCopyInUndoList( picklist, UR_NEW );
for( i = 0; i < picklist.GetCount(); ++i )
{
item = (SCH_ITEM*) picklist.GetPickedItem( i );
item->Move( GetScreen()->m_BlockLocate.GetMoveVector() );
SetSchItemParent( item, GetScreen() );
AddToScreen( item );
}
if( hasSheetPasted )
{
// We clear annotation of new sheet paths.
// Annotation of new components added in current sheet is already cleared.
SCH_SCREENS screensList( g_RootSheet );
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
}
// Clear flags for all items.
GetScreen()->ClearDrawingState();
OnModify();
}
void DrawAndSizingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase )
{

View File

@ -392,12 +392,8 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
return false;
// save old cmp in undo list if not already in edit, or moving ...
// or the component to be edited is part of a block
if( m_cmp->GetEditFlags() == 0
|| GetParent()->GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
{
if( m_cmp->GetEditFlags() == 0 )
GetParent()->SaveCopyInUndoList( m_cmp, UR_CHANGED );
}
// Save current flags which could be modified by next change settings
STATUS_FLAGS flags = m_cmp->GetFlags();

View File

@ -300,12 +300,8 @@ bool DIALOG_LABEL_EDITOR::TransferDataFromWindow()
wxString text;
/* save old text in undo list if not already in edit */
/* or the label to be edited is part of a block */
if( m_CurrentText->GetEditFlags() == 0
|| m_Parent->GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
{
if( m_CurrentText->GetEditFlags() == 0 )
m_Parent->SaveCopyInUndoList( m_CurrentText, UR_CHANGED );
}
m_Parent->GetCanvas()->Refresh();

View File

@ -40,8 +40,8 @@ bool SCH_EDIT_FRAME::EditImage( SCH_BITMAP* aItem )
if( dlg.ShowModal() != wxID_OK )
return false;
// save old image in undo list if not already in edit or the image to be edited is part of a block
if( aItem->GetEditFlags() == 0 || GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
// save old image in undo list if not already in edit
if( aItem->GetEditFlags() == 0 )
SaveCopyInUndoList( aItem, UR_CHANGED );
dlg.TransfertToImage( aItem->GetImage() );

View File

@ -135,7 +135,6 @@ enum id_eeschema_frm
ID_POPUP_END_LINE,
ID_POPUP_SCH_DELETE_CONNECTION,
ID_POPUP_SCH_DELETE_NODE,
ID_POPUP_SCH_DELETE_CMP,
ID_POPUP_SCH_ENTRY_SELECT_SLASH,
ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH,

View File

@ -428,14 +428,9 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
// itemInEdit == false means no item currently edited. We can ask for editing a new item
bool itemInEdit = screen->GetCurItem() && screen->GetCurItem()->GetEditFlags();
// blocInProgress == false means no block in progress.
// Because a drag command uses a drag block, false means also no drag in progress
// If false, we can ask for editing a new item
bool blocInProgress = screen->m_BlockLocate.GetState() != STATE_NO_BLOCK;
// notBusy == true means no item currently edited and no other command in progress
// We can change active tool and ask for editing a new item
bool notBusy = (!itemInEdit) && (!blocInProgress);
bool notBusy = !itemInEdit;
/* Convert lower to upper case (the usual toupper function has problem
* with non ascii codes like function keys */

View File

@ -207,8 +207,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
if( GetToolId() == ID_NO_TOOL_SELECTED && m_blockItems.GetCount() > 0 )
{
msg = AddHotkeyName( _( "&Paste" ), g_Schematic_Hotkeys_Descr, HK_EDIT_PASTE );
AddMenuItem( PopMenu, wxID_PASTE, msg,
_( "Pastes item(s) from the Clipboard" ),
AddMenuItem( PopMenu, wxID_PASTE, msg, _( "Pastes item(s) from the Clipboard" ),
KiBitmap( paste_xpm ) );
PopMenu->AppendSeparator();
}
@ -216,8 +215,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
if( g_CurrentSheet->Last() != g_RootSheet )
{
msg = AddHotkeyName( _( "Leave Sheet" ), g_Schematic_Hotkeys_Descr, HK_LEAVE_SHEET );
AddMenuItem( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, msg,
KiBitmap( leave_sheet_xpm ) );
AddMenuItem( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, msg, KiBitmap( leave_sheet_xpm ) );
PopMenu->AppendSeparator();
}
@ -419,7 +417,7 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL_LIB
HK_DUPLICATE );
AddMenuItem( PopMenu, ID_SCH_DUPLICATE, msg, KiBitmap( duplicate_xpm ) );
msg = AddHotkeyName( _( "Delete" ), g_Schematic_Hotkeys_Descr, HK_DELETE );
AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_CMP, msg, KiBitmap( delete_xpm ) );
AddMenuItem( PopMenu, ID_SCH_DELETE, msg, KiBitmap( delete_xpm ) );
}
msg = AddHotkeyName( _( "Autoplace Fields" ), g_Schematic_Hotkeys_Descr, HK_AUTOPLACE_FIELDS );

View File

@ -42,7 +42,7 @@
#include <sch_sheet.h>
#include <sch_component.h>
#include <sch_junction.h>
#include <tool/selection.h>
void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
{
@ -72,15 +72,15 @@ void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
}
void SCH_EDIT_FRAME::CheckListConnections( PICKED_ITEMS_LIST& aItemsList, bool aAppend )
void SCH_EDIT_FRAME::CheckConnections( SELECTION& aSelection, bool aUndoAppend )
{
std::vector< wxPoint > pts;
std::vector< wxPoint > connections;
GetSchematicConnections( connections );
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
for( unsigned ii = 0; ii < aSelection.GetSize(); ii++ )
{
SCH_ITEM* item = static_cast<SCH_ITEM*>( aItemsList.GetPickedItem( ii ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( aSelection.GetItem( ii ) );
std::vector< wxPoint > new_pts;
if( !item->IsConnectable() )
@ -105,7 +105,7 @@ void SCH_EDIT_FRAME::CheckListConnections( PICKED_ITEMS_LIST& aItemsList, bool a
{
for( auto second_point = point + 1; second_point != new_pts.end(); second_point++ )
{
aAppend |= TrimWire( *point, *second_point, aAppend );
aUndoAppend |= TrimWire( *point, *second_point, aUndoAppend );
}
}
}
@ -121,8 +121,8 @@ void SCH_EDIT_FRAME::CheckListConnections( PICKED_ITEMS_LIST& aItemsList, bool a
{
if( GetScreen()->IsJunctionNeeded( point, true ) )
{
AddJunction( point, aAppend );
aAppend = true;
AddJunction( point, aUndoAppend );
aUndoAppend = true;
}
}
}

View File

@ -554,7 +554,6 @@ bool SCH_BASE_FRAME::HandleBlockBegin( wxDC* aDC, EDA_KEY aKey, const wxPoint& a
case BLOCK_ZOOM: // Window Zoom
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y: // mirror
case BLOCK_PRESELECT_MOVE: // Move with preselection list
block->InitData( m_canvas, aPosition );
GetCanvas()->GetView()->ShowSelectionArea();
break;

View File

@ -40,20 +40,15 @@
#include <general.h>
#include <eeschema_id.h>
#include <netlist.h>
#include <lib_pin.h>
#include <class_library.h>
#include <sch_edit_frame.h>
#include <sch_component.h>
#include <symbol_lib_table.h>
#include <dialog_helpers.h>
#include <reporter.h>
#include <lib_edit_frame.h>
#include <viewlib_frame.h>
#include <hotkeys.h>
#include <eeschema_config.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
#include "sim/sim_plot_frame.h"
#include <invoke_sch_dialog.h>
@ -253,9 +248,6 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_TOOL( ID_SHEET_SET, EDA_DRAW_FRAME::Process_PageSettings )
EVT_TOOL( ID_HIERARCHY, SCH_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_CUT, SCH_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_COPY, SCH_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_PASTE, SCH_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_UNDO, SCH_EDIT_FRAME::GetSchematicFromUndoList )
EVT_TOOL( wxID_REDO, SCH_EDIT_FRAME::GetSchematicFromRedoList )
EVT_TOOL( ID_GET_ANNOTATE, SCH_EDIT_FRAME::OnAnnotate )
@ -600,7 +592,7 @@ void SCH_EDIT_FRAME::SetUndoItem( const SCH_ITEM* aItem )
}
void SCH_EDIT_FRAME::SaveUndoItemInUndoList( SCH_ITEM* aItem )
void SCH_EDIT_FRAME::SaveUndoItemInUndoList( SCH_ITEM* aItem, bool aAppend )
{
wxCHECK_RET( aItem != NULL,
wxT( "Cannot swap undo item structures. Bad programmer!." ) );
@ -610,7 +602,7 @@ void SCH_EDIT_FRAME::SaveUndoItemInUndoList( SCH_ITEM* aItem )
wxT( "Cannot swap undo item structures. Bad programmer!." ) );
aItem->SwapData( m_undoItem );
SaveCopyInUndoList( aItem, UR_CHANGED );
SaveCopyInUndoList( aItem, UR_CHANGED, aAppend );
aItem->SwapData( m_undoItem );
}
@ -1251,7 +1243,7 @@ bool SCH_EDIT_FRAME::isAutoSaveRequired() const
}
void SCH_EDIT_FRAME::AddItemToScreen( SCH_ITEM* aItem )
void SCH_EDIT_FRAME::AddItemToScreen( SCH_ITEM* aItem, bool aUndoAppend )
{
SCH_SCREEN* screen = GetScreen();
@ -1307,12 +1299,12 @@ void SCH_EDIT_FRAME::AddItemToScreen( SCH_ITEM* aItem )
AddToScreen( aItem );
SetRepeatItem( aItem );
SaveCopyInUndoList( undoItem, UR_NEW );
SaveCopyInUndoList( undoItem, UR_NEW, aUndoAppend );
}
else if( aItem->Type() == SCH_SHEET_PIN_T )
{
// Sheet pins are owned by their parent sheet.
SaveCopyInUndoList( undoItem, UR_CHANGED ); // save the parent sheet
SaveCopyInUndoList( undoItem, UR_CHANGED, aUndoAppend ); // save the parent sheet
parentSheet->AddPin( (SCH_SHEET_PIN*) aItem );
}
@ -1328,7 +1320,7 @@ void SCH_EDIT_FRAME::AddItemToScreen( SCH_ITEM* aItem )
AddToScreen( aItem );
SetRepeatItem( aItem );
SaveCopyInUndoList( undoItem, UR_NEW );
SaveCopyInUndoList( undoItem, UR_NEW, aUndoAppend );
}
if( doClearAnnotation )
@ -1340,11 +1332,12 @@ void SCH_EDIT_FRAME::AddItemToScreen( SCH_ITEM* aItem )
}
// Update connectivity info for new item
RecalculateConnections();
if( !aItem->IsMoving() )
RecalculateConnections();
}
else
{
SaveUndoItemInUndoList( undoItem );
SaveUndoItemInUndoList( undoItem, aUndoAppend );
}
aItem->ClearFlags();
@ -1356,7 +1349,7 @@ void SCH_EDIT_FRAME::AddItemToScreen( SCH_ITEM* aItem )
RefreshItem( aItem );
if( aItem->IsConnectable() )
if( !aItem->IsMoving() && aItem->IsConnectable() )
{
std::vector< wxPoint > pts;
aItem->GetConnectionPoints( pts );

View File

@ -23,10 +23,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file sch_edit_frame.h
*/
#ifndef SCH_EDIT_FRAME_H
#define SCH_EDIT_FRAME_H
@ -36,11 +32,13 @@
#include <template_fieldnames.h>
#include <block_commande.h>
#include <sch_collectors.h>
#include <tool/selection.h>
#include <erc_settings.h>
#include <sch_draw_panel.h>
// enum PINSHEETLABEL_SHAPE
#include <sch_text.h>
#include <tool/selection.h>
class LIB_EDIT_FRAME;
class LIB_VIEW_FRAME;
@ -379,10 +377,10 @@ public:
double BestZoom() override;
/**
* Add the item currently being edited to the schematic and adds the changes to
* the undo/redo container.
* Add an item to the schematic and adds the changes to the undo/redo container.
* @param aUndoAppend True if the action should be appended to the current undo record.
*/
void AddItemToScreen( SCH_ITEM* aItem );
void AddItemToScreen( SCH_ITEM* aItem, bool aUndoAppend = false );
/**
* Finds a component in the schematic and an item in this component.
@ -1030,9 +1028,9 @@ public:
* moved.
*
* @param aItemsList The list of items to check
* @param aAppend True if we are updating a previous commit
* @param aUndoAppend True if we are updating a previous commit
*/
void CheckListConnections( PICKED_ITEMS_LIST& aItemsList, bool aAppend = false );
void CheckConnections( SELECTION& aSelection, bool aUndoAppend = false );
int GetLabelIncrement() const { return m_repeatLabelDelta; }
@ -1061,11 +1059,6 @@ private:
void OnSelectUnit( wxCommandEvent& aEvent );
void ConvertPart( SCH_COMPONENT* DrawComponent );
/**
* Paste a list of items from the block stack.
*/
void PasteListOfItems( wxDC* DC );
/* Undo - redo */
public:
@ -1145,14 +1138,6 @@ private:
*/
void GetSchematicFromUndoList( wxCommandEvent& event );
/**
* Copy the list of block item.
*
* @sa m_blockItems
* @param aItemsList List to copy the block select items into.
*/
void copyBlockItems( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector );
/**
* Add the context menu items to \a aMenu for \a aJunction.
*
@ -1229,8 +1214,9 @@ public:
* swap the actual item pointers themselves.
*
* @param aItem The item to swap with the current undo item.
* @param aAppend True if the action should be appended to the current undo record.
*/
void SaveUndoItemInUndoList( SCH_ITEM* aItem );
void SaveUndoItemInUndoList( SCH_ITEM* aItem, bool aAppend = false );
/**
* Performs an undo of the last edit WITHOUT logging a corresponding redo. Used to cancel

View File

@ -64,6 +64,7 @@
#include <eeschema_id.h> // for MAX_UNIT_COUNT_PER_PACKAGE definition
#include <symbol_lib_table.h> // for PropPowerSymsOnly definintion.
#include <confirm.h>
#include <tool/selection.h>
// Must be the first line of part library document (.dcm) files.
@ -479,27 +480,26 @@ class SCH_LEGACY_PLUGIN_CACHE
int m_versionMinor;
int m_libType; // Is this cache a component or symbol library.
void loadHeader( FILE_LINE_READER& aReader );
static void loadAliases( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader );
static void loadField( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader );
static void loadDrawEntries( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader,
int aMajorVersion, int aMinorVersion );
static void loadFootprintFilters( std::unique_ptr< LIB_PART >& aPart,
LINE_READER& aReader );
void loadDocs();
static LIB_ARC* loadArc( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader );
static LIB_CIRCLE* loadCircle( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader );
static LIB_TEXT* loadText( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader,
int aMajorVersion, int aMinorVersion );
static LIB_RECTANGLE* loadRectangle( std::unique_ptr< LIB_PART >& aPart,
LINE_READER& aReader );
static LIB_PIN* loadPin( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader );
static LIB_POLYLINE* loadPolyLine( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader );
static LIB_BEZIER* loadBezier( std::unique_ptr< LIB_PART >& aPart, LINE_READER& aReader );
void loadHeader( FILE_LINE_READER& aReader );
static void loadAliases( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static void loadField( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static void loadDrawEntries( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader,
int aMajorVersion, int aMinorVersion );
static void loadFootprintFilters( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader );
void loadDocs();
static LIB_ARC* loadArc( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static LIB_CIRCLE* loadCircle( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static LIB_TEXT* loadText( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader,
int aMajorVersion, int aMinorVersion );
static LIB_RECTANGLE* loadRectangle( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader );
static LIB_PIN* loadPin( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static LIB_POLYLINE* loadPolyLine( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static LIB_BEZIER* loadBezier( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static FILL_T parseFillMode( LINE_READER& aReader, const char* aLine,
static FILL_T parseFillMode( LINE_READER& aReader, const char* aLine,
const char** aOutput );
// bool checkForDuplicates( wxString& aAliasName );
LIB_ALIAS* removeAlias( LIB_ALIAS* aAlias );
void saveDocFile();
@ -735,47 +735,63 @@ void SCH_LEGACY_PLUGIN::loadFile( const wxString& aFileName, SCH_SCREEN* aScreen
loadHeader( reader, aScreen );
while( reader.ReadLine() )
LoadContent( reader, aScreen, m_version );
// Unfortunately schematic files prior to version 2 are not terminated with $EndSCHEMATC
// so checking for it's existance will fail so just exit here and take our chances. :(
if( m_version > 1 )
{
char* line = reader.Line();
while( *line && *line == ' ' )
while( *line == ' ' )
line++;
if( !strCompare( "$EndSCHEMATC", line ) )
THROW_IO_ERROR( "'$EndSCHEMATC' not found" );
}
}
void SCH_LEGACY_PLUGIN::LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen, int version )
{
m_version = version;
while( aReader.ReadLine() )
{
char* line = aReader.Line();
while( *line == ' ' )
line++;
// Either an object will be loaded properly or the file load will fail and raise
// an exception.
if( strCompare( "$Descr", line ) )
loadPageSettings( reader, aScreen );
loadPageSettings( aReader, aScreen );
else if( strCompare( "$Comp", line ) )
aScreen->Append( loadComponent( reader ) );
aScreen->Append( loadComponent( aReader ) );
else if( strCompare( "$Sheet", line ) )
aScreen->Append( loadSheet( reader ) );
aScreen->Append( loadSheet( aReader ) );
else if( strCompare( "$Bitmap", line ) )
aScreen->Append( loadBitmap( reader ) );
aScreen->Append( loadBitmap( aReader ) );
else if( strCompare( "Connection", line ) )
aScreen->Append( loadJunction( reader ) );
aScreen->Append( loadJunction( aReader ) );
else if( strCompare( "NoConn", line ) )
aScreen->Append( loadNoConnect( reader ) );
aScreen->Append( loadNoConnect( aReader ) );
else if( strCompare( "Wire", line ) )
aScreen->Append( loadWire( reader ) );
aScreen->Append( loadWire( aReader ) );
else if( strCompare( "Entry", line ) )
aScreen->Append( loadBusEntry( reader ) );
aScreen->Append( loadBusEntry( aReader ) );
else if( strCompare( "Text", line ) )
aScreen->Append( loadText( reader ) );
aScreen->Append( loadText( aReader ) );
else if( strCompare( "BusAlias", line ) )
aScreen->AddBusAlias( loadBusAlias( reader, aScreen ) );
aScreen->AddBusAlias( loadBusAlias( aReader, aScreen ) );
else if( strCompare( "$EndSCHEMATC", line ) )
return;
}
// Unfortunately schematic files prior to version 2 are not terminated with $EndSCHEMATC
// so checking for it's existance will fail so just exit here and take our chances. :(
if( m_version > 1 )
THROW_IO_ERROR( "'$EndSCHEMATC' not found" );
}
void SCH_LEGACY_PLUGIN::loadHeader( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen )
void SCH_LEGACY_PLUGIN::loadHeader( LINE_READER& aReader, SCH_SCREEN* aScreen )
{
const char* line = aReader.ReadLine();
@ -813,7 +829,7 @@ void SCH_LEGACY_PLUGIN::loadHeader( FILE_LINE_READER& aReader, SCH_SCREEN* aScre
}
void SCH_LEGACY_PLUGIN::loadPageSettings( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen )
void SCH_LEGACY_PLUGIN::loadPageSettings( LINE_READER& aReader, SCH_SCREEN* aScreen )
{
wxASSERT( aScreen != NULL );
@ -917,7 +933,7 @@ void SCH_LEGACY_PLUGIN::loadPageSettings( FILE_LINE_READER& aReader, SCH_SCREEN*
}
SCH_SHEET* SCH_LEGACY_PLUGIN::loadSheet( FILE_LINE_READER& aReader )
SCH_SHEET* SCH_LEGACY_PLUGIN::loadSheet( LINE_READER& aReader )
{
std::unique_ptr< SCH_SHEET > sheet( new SCH_SHEET() );
@ -1054,7 +1070,7 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::loadSheet( FILE_LINE_READER& aReader )
}
SCH_BITMAP* SCH_LEGACY_PLUGIN::loadBitmap( FILE_LINE_READER& aReader )
SCH_BITMAP* SCH_LEGACY_PLUGIN::loadBitmap( LINE_READER& aReader )
{
std::unique_ptr< SCH_BITMAP > bitmap( new SCH_BITMAP );
@ -1139,7 +1155,7 @@ SCH_BITMAP* SCH_LEGACY_PLUGIN::loadBitmap( FILE_LINE_READER& aReader )
}
SCH_JUNCTION* SCH_LEGACY_PLUGIN::loadJunction( FILE_LINE_READER& aReader )
SCH_JUNCTION* SCH_LEGACY_PLUGIN::loadJunction( LINE_READER& aReader )
{
std::unique_ptr< SCH_JUNCTION > junction( new SCH_JUNCTION );
@ -1161,7 +1177,7 @@ SCH_JUNCTION* SCH_LEGACY_PLUGIN::loadJunction( FILE_LINE_READER& aReader )
}
SCH_NO_CONNECT* SCH_LEGACY_PLUGIN::loadNoConnect( FILE_LINE_READER& aReader )
SCH_NO_CONNECT* SCH_LEGACY_PLUGIN::loadNoConnect( LINE_READER& aReader )
{
std::unique_ptr< SCH_NO_CONNECT > no_connect( new SCH_NO_CONNECT );
@ -1183,7 +1199,7 @@ SCH_NO_CONNECT* SCH_LEGACY_PLUGIN::loadNoConnect( FILE_LINE_READER& aReader )
}
SCH_LINE* SCH_LEGACY_PLUGIN::loadWire( FILE_LINE_READER& aReader )
SCH_LINE* SCH_LEGACY_PLUGIN::loadWire( LINE_READER& aReader )
{
std::unique_ptr< SCH_LINE > wire( new SCH_LINE );
@ -1281,7 +1297,7 @@ SCH_LINE* SCH_LEGACY_PLUGIN::loadWire( FILE_LINE_READER& aReader )
}
SCH_BUS_ENTRY_BASE* SCH_LEGACY_PLUGIN::loadBusEntry( FILE_LINE_READER& aReader )
SCH_BUS_ENTRY_BASE* SCH_LEGACY_PLUGIN::loadBusEntry( LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -1326,7 +1342,7 @@ SCH_BUS_ENTRY_BASE* SCH_LEGACY_PLUGIN::loadBusEntry( FILE_LINE_READER& aReader )
}
SCH_TEXT* SCH_LEGACY_PLUGIN::loadText( FILE_LINE_READER& aReader )
SCH_TEXT* SCH_LEGACY_PLUGIN::loadText( LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -1426,7 +1442,7 @@ SCH_TEXT* SCH_LEGACY_PLUGIN::loadText( FILE_LINE_READER& aReader )
}
SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( FILE_LINE_READER& aReader )
SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -1723,8 +1739,8 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( FILE_LINE_READER& aReader )
}
std::shared_ptr< BUS_ALIAS > SCH_LEGACY_PLUGIN::loadBusAlias( FILE_LINE_READER& aReader,
SCH_SCREEN* aScreen )
std::shared_ptr<BUS_ALIAS> SCH_LEGACY_PLUGIN::loadBusAlias( LINE_READER& aReader,
SCH_SCREEN* aScreen )
{
auto busAlias = std::make_shared< BUS_ALIAS >( aScreen );
const char* line = aReader.Line();
@ -1859,6 +1875,51 @@ void SCH_LEGACY_PLUGIN::Format( SCH_SCREEN* aScreen )
}
void SCH_LEGACY_PLUGIN::Format( SELECTION* aSelection, OUTPUTFORMATTER* aFormatter )
{
m_out = aFormatter;
for( int i = 0; i < aSelection->GetSize(); ++i )
{
SCH_ITEM* item = (SCH_ITEM*) aSelection->GetItem( i );
switch( item->Type() )
{
case SCH_COMPONENT_T:
saveComponent( static_cast< SCH_COMPONENT* >( item ) );
break;
case SCH_BITMAP_T:
saveBitmap( static_cast< SCH_BITMAP* >( item ) );
break;
case SCH_SHEET_T:
saveSheet( static_cast< SCH_SHEET* >( item ) );
break;
case SCH_JUNCTION_T:
saveJunction( static_cast< SCH_JUNCTION* >( item ) );
break;
case SCH_NO_CONNECT_T:
saveNoConnect( static_cast< SCH_NO_CONNECT* >( item ) );
break;
case SCH_BUS_WIRE_ENTRY_T:
case SCH_BUS_BUS_ENTRY_T:
saveBusEntry( static_cast< SCH_BUS_ENTRY_BASE* >( item ) );
break;
case SCH_LINE_T:
saveLine( static_cast< SCH_LINE* >( item ) );
break;
case SCH_TEXT_T:
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T:
saveText( static_cast< SCH_TEXT* >( item ) );
break;
default:
wxASSERT( "Unexpected schematic object type in SCH_LEGACY_PLUGIN::Format()" );
}
}
}
void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent )
{
std::string name1;
@ -2242,7 +2303,7 @@ void SCH_LEGACY_PLUGIN::saveText( SCH_TEXT* aText )
}
void SCH_LEGACY_PLUGIN::saveBusAlias( std::shared_ptr< BUS_ALIAS > aAlias )
void SCH_LEGACY_PLUGIN::saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
{
wxCHECK_RET( aAlias != NULL, "BUS_ALIAS* is NULL" );
@ -2872,7 +2933,7 @@ bool SCH_LEGACY_PLUGIN_CACHE::checkForDuplicates( wxString& aAliasName )
#endif
void SCH_LEGACY_PLUGIN_CACHE::loadAliases( std::unique_ptr< LIB_PART >& aPart,
void SCH_LEGACY_PLUGIN_CACHE::loadAliases( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
wxString newAlias;
@ -2892,7 +2953,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadAliases( std::unique_ptr< LIB_PART >& aPart,
}
void SCH_LEGACY_PLUGIN_CACHE::loadField( std::unique_ptr< LIB_PART >& aPart,
void SCH_LEGACY_PLUGIN_CACHE::loadField( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3035,7 +3096,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadField( std::unique_ptr< LIB_PART >& aPart,
}
void SCH_LEGACY_PLUGIN_CACHE::loadDrawEntries( std::unique_ptr< LIB_PART >& aPart,
void SCH_LEGACY_PLUGIN_CACHE::loadDrawEntries( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader,
int aMajorVersion,
int aMinorVersion )
@ -3111,7 +3172,7 @@ FILL_T SCH_LEGACY_PLUGIN_CACHE::parseFillMode( LINE_READER& aReader, const char*
}
LIB_ARC* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr< LIB_PART >& aPart,
LIB_ARC* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3177,7 +3238,7 @@ LIB_ARC* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr< LIB_PART >& aPart,
}
LIB_CIRCLE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr< LIB_PART >& aPart,
LIB_CIRCLE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3204,7 +3265,7 @@ LIB_CIRCLE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr< LIB_PART >& aP
}
LIB_TEXT* SCH_LEGACY_PLUGIN_CACHE::loadText( std::unique_ptr< LIB_PART >& aPart,
LIB_TEXT* SCH_LEGACY_PLUGIN_CACHE::loadText( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader,
int aMajorVersion,
int aMinorVersion )
@ -3297,7 +3358,7 @@ LIB_TEXT* SCH_LEGACY_PLUGIN_CACHE::loadText( std::unique_ptr< LIB_PART >& aPart,
}
LIB_RECTANGLE* SCH_LEGACY_PLUGIN_CACHE::loadRectangle( std::unique_ptr< LIB_PART >& aPart,
LIB_RECTANGLE* SCH_LEGACY_PLUGIN_CACHE::loadRectangle( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3329,7 +3390,7 @@ LIB_RECTANGLE* SCH_LEGACY_PLUGIN_CACHE::loadRectangle( std::unique_ptr< LIB_PART
}
LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr< LIB_PART >& aPart,
LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3511,7 +3572,7 @@ LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr< LIB_PART >& aPart,
}
LIB_POLYLINE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr< LIB_PART >& aPart,
LIB_POLYLINE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3542,7 +3603,7 @@ LIB_POLYLINE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr< LIB_PART >
}
LIB_BEZIER* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr< LIB_PART >& aPart,
LIB_BEZIER* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3573,7 +3634,7 @@ LIB_BEZIER* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr< LIB_PART >& aP
}
void SCH_LEGACY_PLUGIN_CACHE::loadFootprintFilters( std::unique_ptr< LIB_PART >& aPart,
void SCH_LEGACY_PLUGIN_CACHE::loadFootprintFilters( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
{
const char* line = aReader.Line();

View File

@ -26,6 +26,7 @@
#include <memory>
#include <sch_io_mgr.h>
#include <stack>
#include <general.h>
class KIWAY;
@ -41,6 +42,7 @@ class SCH_TEXT;
class SCH_COMPONENT;
class SCH_FIELD;
class PROPERTIES;
class SELECTION;
class SCH_LEGACY_PLUGIN_CACHE;
class LIB_PART;
class PART_LIB;
@ -96,58 +98,64 @@ public:
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway,
SCH_SHEET* aAppendToMe = NULL, const PROPERTIES* aProperties = NULL ) override;
SCH_SHEET* aAppendToMe = nullptr,
const PROPERTIES* aProperties = nullptr ) override;
void LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen,
int version = EESCHEMA_VERSION );
void Save( const wxString& aFileName, SCH_SCREEN* aScreen, KIWAY* aKiway,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void Format( SCH_SCREEN* aScreen );
void Format( SELECTION* aSelection, OUTPUTFORMATTER* aFormatter );
size_t GetSymbolLibCount( const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void EnumerateSymbolLib( wxArrayString& aAliasNameList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
LIB_ALIAS* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void CreateSymbolLib( const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
bool DeleteSymbolLib( const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL ) override;
void SaveLibrary( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL ) override;
const PROPERTIES* aProperties = nullptr ) override;
void SaveLibrary( const wxString& aLibraryPath,
const PROPERTIES* aProperties = nullptr ) override;
bool CheckHeader( const wxString& aFileName ) override;
bool IsSymbolLibWritable( const wxString& aLibraryPath ) override;
const wxString& GetError() const override { return m_error; }
static LIB_PART * ParsePart( LINE_READER& reader, int aMajorVersion = 0,
int aMinorVersion = 0 );
static void FormatPart( LIB_PART* part, OUTPUTFORMATTER& formatter );
static LIB_PART* ParsePart( LINE_READER& aReader, int majorVersion = 0, int minorVersion = 0 );
static void FormatPart( LIB_PART* aPart, OUTPUTFORMATTER& aFormatter );
private:
void loadHierarchy( SCH_SHEET* aSheet );
void loadHeader( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen );
void loadPageSettings( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen );
void loadHeader( LINE_READER& aReader, SCH_SCREEN* aScreen );
void loadPageSettings( LINE_READER& aReader, SCH_SCREEN* aScreen );
void loadFile( const wxString& aFileName, SCH_SCREEN* aScreen );
SCH_SHEET* loadSheet( FILE_LINE_READER& aReader );
SCH_BITMAP* loadBitmap( FILE_LINE_READER& aReader );
SCH_JUNCTION* loadJunction( FILE_LINE_READER& aReader );
SCH_NO_CONNECT* loadNoConnect( FILE_LINE_READER& aReader );
SCH_LINE* loadWire( FILE_LINE_READER& aReader );
SCH_BUS_ENTRY_BASE* loadBusEntry( FILE_LINE_READER& aReader );
SCH_TEXT* loadText( FILE_LINE_READER& aReader );
SCH_COMPONENT* loadComponent( FILE_LINE_READER& aReader );
std::shared_ptr< BUS_ALIAS > loadBusAlias( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen );
SCH_SHEET* loadSheet( LINE_READER& aReader );
SCH_BITMAP* loadBitmap( LINE_READER& aReader );
SCH_JUNCTION* loadJunction( LINE_READER& aReader );
SCH_NO_CONNECT* loadNoConnect( LINE_READER& aReader );
SCH_LINE* loadWire( LINE_READER& aReader );
SCH_BUS_ENTRY_BASE* loadBusEntry( LINE_READER& aReader );
SCH_TEXT* loadText( LINE_READER& aReader );
SCH_COMPONENT* loadComponent( LINE_READER& aReader );
std::shared_ptr<BUS_ALIAS> loadBusAlias( LINE_READER& aReader, SCH_SCREEN* aScreen );
void saveComponent( SCH_COMPONENT* aComponent );
void saveField( SCH_FIELD* aField );
@ -158,28 +166,28 @@ private:
void saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry );
void saveLine( SCH_LINE* aLine );
void saveText( SCH_TEXT* aText );
void saveBusAlias( std::shared_ptr< BUS_ALIAS > aAlias );
void saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias );
void cacheLib( const wxString& aLibraryFileName );
bool writeDocFile( const PROPERTIES* aProperties );
bool isBuffering( const PROPERTIES* aProperties );
protected:
int m_version; ///< Version of file being loaded.
int m_version; ///< Version of file being loaded.
/** For throwing exceptions or errors on partial schematic loads. */
wxString m_error;
wxString m_error;
wxString m_path; ///< Root project path for loading child sheets.
std::stack<wxString> m_currentPath; ///< Stack to maintain nested sheet paths
const PROPERTIES* m_props; ///< Passed via Save() or Load(), no ownership, may be NULL.
KIWAY* m_kiway; ///< Required for path to legacy component libraries.
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded..
FILE_OUTPUTFORMATTER* m_out; ///< The output formatter for saving SCH_SCREEN objects.
wxString m_path; ///< Root project path for loading child sheets.
std::stack<wxString> m_currentPath;///< Stack to maintain nested sheet paths
const PROPERTIES* m_props; ///< Passed via Save() or Load(), no ownership, may be nullptr.
KIWAY* m_kiway; ///< Required for path to legacy component libraries.
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded..
OUTPUTFORMATTER* m_out; ///< The output formatter for saving SCH_SCREEN objects.
SCH_LEGACY_PLUGIN_CACHE* m_cache;
/// initialize PLUGIN like a constructor would.
void init( KIWAY* aKiway, const PROPERTIES* aProperties = NULL );
void init( KIWAY* aKiway, const PROPERTIES* aProperties = nullptr );
};
#endif // _SCH_LEGACY_PLUGIN_H_

View File

@ -62,13 +62,9 @@
// If needed, stop the current command and deselect current tool
switch( id )
{
case wxID_CUT:
case wxID_COPY:
case ID_POPUP_CANCEL_CURRENT_COMMAND:
case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
case ID_POPUP_SCH_BEGIN_WIRE:
case ID_POPUP_SCH_BEGIN_BUS:
case ID_POPUP_END_LINE:
case ID_POPUP_SCH_CLEANUP_SHEET:
case ID_POPUP_SCH_END_SHEET:
@ -76,10 +72,6 @@
case ID_POPUP_IMPORT_HLABEL_TO_SHEETPIN:
case ID_POPUP_SCH_INIT_CMP:
case ID_POPUP_SCH_EDIT_CONVERT_CMP:
case ID_POPUP_PLACE_BLOCK:
case ID_POPUP_ZOOM_BLOCK:
case ID_POPUP_DRAG_BLOCK:
case ID_POPUP_DUPLICATE_BLOCK:
case ID_POPUP_SCH_DELETE_NODE:
case ID_POPUP_SCH_DELETE_CONNECTION:
case ID_POPUP_SCH_ENTER_SHEET:
@ -93,12 +85,6 @@
*/
break;
case ID_POPUP_SCH_DELETE_CMP:
case ID_SCH_DELETE:
// Stop the current command (if any) but keep the current tool
m_canvas->EndMouseCapture();
break;
default:
// Stop the current command and deselect the current tool
SetNoToolSelected();
@ -114,30 +100,6 @@
SetRepeatItem( NULL );
break;
case wxID_CUT: // save and delete block
case ID_POPUP_CUT_BLOCK:
if( screen->m_BlockLocate.GetCommand() != BLOCK_MOVE )
break;
screen->m_BlockLocate.SetCommand( BLOCK_CUT );
screen->m_BlockLocate.SetMessageBlock( this );
HandleBlockEnd( nullptr );
SetRepeatItem( NULL );
SetSheetNumberAndCount();
break;
case wxID_COPY: // really this is a Save block for paste
case ID_POPUP_COPY_BLOCK:
screen->m_BlockLocate.SetCommand( BLOCK_COPY );
screen->m_BlockLocate.SetMessageBlock( this );
HandleBlockEnd( nullptr );
break;
case wxID_PASTE:
case ID_POPUP_PASTE_BLOCK:
HandleBlockBegin( nullptr, BLOCK_PASTE, GetCrossHairPosition() );
break;
case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
m_canvas->MoveCursorToCrossHair();
SetBusEntryShape( nullptr, dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ), '/' );

View File

@ -186,7 +186,7 @@ OPT<TOOL_EVENT> SCH_ACTIONS::TranslateLegacyId( int aId )
return SCH_ACTIONS::drag.MakeEvent();
case ID_SCH_DELETE:
return SCH_ACTIONS::remove.MakeEvent();
return SCH_ACTIONS::doDelete.MakeEvent();
case ID_SIM_PROBE:
return SCH_ACTIONS::simProbe.MakeEvent();
@ -223,6 +223,15 @@ OPT<TOOL_EVENT> SCH_ACTIONS::TranslateLegacyId( int aId )
case ID_SCH_EDIT_COMPONENT_FOOTPRINT:
return SCH_ACTIONS::editFootprint.MakeEvent();
case wxID_CUT:
return SCH_ACTIONS::cut.MakeEvent();
case wxID_COPY:
return SCH_ACTIONS::copy.MakeEvent();
case wxID_PASTE:
return SCH_ACTIONS::paste.MakeEvent();
}
return OPT<TOOL_EVENT>();

View File

@ -124,15 +124,15 @@ public:
static TOOL_ACTION editReference;
static TOOL_ACTION editValue;
static TOOL_ACTION editFootprint;
static TOOL_ACTION remove;
static TOOL_ACTION doDelete;
static TOOL_ACTION addJunction;
static TOOL_ACTION addLabel;
static TOOL_ACTION addGlobalLabel;
/// Clipboard
static TOOL_ACTION copyToClipboard;
static TOOL_ACTION pasteFromClipboard;
static TOOL_ACTION cutToClipboard;
static TOOL_ACTION cut;
static TOOL_ACTION copy;
static TOOL_ACTION paste;
// Miscellaneous
static TOOL_ACTION switchCursor;

View File

@ -24,6 +24,7 @@
#include <tool/tool_manager.h>
#include <tools/sch_edit_tool.h>
#include <tools/sch_selection_tool.h>
#include <tools/sch_picker_tool.h>
#include <sch_actions.h>
#include <hotkeys.h>
#include <bitmaps.h>
@ -39,6 +40,7 @@
#include <sch_edit_frame.h>
#include <list_operations.h>
#include <eeschema_id.h>
#include <status_popup.h>
TOOL_ACTION SCH_ACTIONS::move( "eeschema.InteractiveEdit.move",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_MOVE_COMPONENT_OR_ITEM ),
@ -88,10 +90,15 @@ TOOL_ACTION SCH_ACTIONS::editFootprint( "eeschema.InteractiveEdit.editFootprint"
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_COMPONENT_FOOTPRINT ),
_( "Edit Footprint..." ), _( "Displays footprint field dialog" ), config_xpm );
TOOL_ACTION SCH_ACTIONS::remove( "eeschema.InteractiveEdit.remove",
TOOL_ACTION SCH_ACTIONS::doDelete( "eeschema.InteractiveEdit.doDelete",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DELETE ),
_( "Delete" ), _( "Deletes selected item(s)" ), delete_xpm );
TOOL_ACTION SCH_ACTIONS::deleteItemCursor( "eeschema.InteractiveEdit.deleteItemCursor",
AS_GLOBAL, 0,
_( "DoDelete Items" ), _( "DoDelete clicked items" ), NULL, AF_ACTIVATE );
SCH_EDIT_TOOL::SCH_EDIT_TOOL() :
TOOL_INTERACTIVE( "eeschema.InteractiveEdit" ),
@ -323,7 +330,7 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
// Dispatch TOOL_ACTIONs
else if( evt->Category() == TC_COMMAND )
{
if( evt->IsAction( &SCH_ACTIONS::remove ) )
if( evt->IsAction( &SCH_ACTIONS::doDelete ) )
{
// Exit on a remove operation; there is no further processing for removed items.
break;
@ -354,17 +361,21 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
for( auto item : selection )
item->ClearFlags( IS_MOVED );
if( unselect || restore_state )
m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true );
if( restore_state )
m_frame->RollbackSchematicFromUndo();
else
{
m_frame->TestDanglingEnds();
m_frame->OnModify();
m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true );
m_frame->RollbackSchematicFromUndo();
return 0;
}
m_frame->CheckConnections( selection, true );
m_frame->SchematicCleanUp( true );
m_frame->TestDanglingEnds();
m_frame->OnModify();
if( unselect )
m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true );
return 0;
}
@ -928,7 +939,7 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
}
int SCH_EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
{
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
std::vector<SCH_ITEM*> items;
@ -965,6 +976,51 @@ int SCH_EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
}
static bool deleteItem( SCH_EDIT_FRAME* aFrame, const VECTOR2D& aPosition )
{
SCH_SELECTION_TOOL* selectionTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
wxCHECK( selectionTool, false );
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::selectionClear, true );
SCH_ITEM* item = selectionTool->SelectPoint( aPosition );
if( item )
{
if( item->IsLocked() )
{
STATUS_TEXT_POPUP statusPopup( aFrame );
statusPopup.SetText( _( "Item locked." ) );
statusPopup.Expire( 2000 );
statusPopup.Popup();
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
}
else
{
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::doDelete, true );
}
}
return true;
}
int SCH_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent )
{
Activate();
SCH_PICKER_TOOL* picker = m_toolMgr->GetTool<SCH_PICKER_TOOL>();
wxCHECK( picker, 0 );
m_frame->SetToolID( ID_SCHEMATIC_DELETE_ITEM_BUTT, wxCURSOR_BULLSEYE, _( "DoDelete item" ) );
picker->SetClickHandler( std::bind( deleteItem, m_frame, std::placeholders::_1 ) );
picker->Activate();
Wait();
return 0;
}
int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent )
{
static KICAD_T Nothing[] = { EOT };
@ -1130,9 +1186,12 @@ void SCH_EDIT_TOOL::setTransitions()
Go( &SCH_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCCW.MakeEvent() );
Go( &SCH_EDIT_TOOL::Mirror, SCH_ACTIONS::mirrorX.MakeEvent() );
Go( &SCH_EDIT_TOOL::Mirror, SCH_ACTIONS::mirrorY.MakeEvent() );
Go( &SCH_EDIT_TOOL::Remove, SCH_ACTIONS::remove.MakeEvent() );
Go( &SCH_EDIT_TOOL::DoDelete, SCH_ACTIONS::doDelete.MakeEvent() );
Go( &SCH_EDIT_TOOL::DeleteItemCursor, SCH_ACTIONS::deleteItemCursor.MakeEvent() );
Go( &SCH_EDIT_TOOL::Properties, SCH_ACTIONS::properties.MakeEvent() );
Go( &SCH_EDIT_TOOL::EditField, SCH_ACTIONS::editReference.MakeEvent() );
Go( &SCH_EDIT_TOOL::EditField, SCH_ACTIONS::editValue.MakeEvent() );
Go( &SCH_EDIT_TOOL::EditField, SCH_ACTIONS::editFootprint.MakeEvent() );
}

View File

@ -68,11 +68,14 @@ public:
int EditField( const TOOL_EVENT& aEvent );
/**
* Function Remove()
* Function DoDelete()
*
* Deletes the selected items, or the item under the cursor.
*/
int Remove( const TOOL_EVENT& aEvent );
int DoDelete( const TOOL_EVENT& aEvent );
///> Runs the deletion tool.
int DeleteItemCursor( const TOOL_EVENT& aEvent );
private:
void moveItem( SCH_ITEM* aItem, VECTOR2I aDelta, bool isDrag );

View File

@ -41,9 +41,11 @@
#include <project.h>
#include <hotkeys.h>
#include <advanced_config.h>
#include <status_popup.h>
#include <simulation_cursors.h>
#include <sim/sim_plot_frame.h>
#include <sch_legacy_plugin.h>
#include <class_library.h>
#include <confirm.h>
TOOL_ACTION SCH_ACTIONS::refreshPreview( "eeschema.EditorControl.refreshPreview",
AS_GLOBAL, 0, "", "" );
@ -69,9 +71,17 @@ TOOL_ACTION SCH_ACTIONS::highlightNetCursor( "eeschema.EditorControl.highlightNe
AS_GLOBAL, 0,
_( "Highlight Net" ), _( "Highlight wires and pins of a net" ), NULL, AF_ACTIVATE );
TOOL_ACTION SCH_ACTIONS::deleteItemCursor( "eeschema.EditorControl.deleteItemCursor",
AS_GLOBAL, 0,
_( "Delete Items" ), _( "Delete clicked items" ), NULL, AF_ACTIVATE );
TOOL_ACTION SCH_ACTIONS::cut( "eeschema.EditorControl.cut",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_CUT ),
_( "Cut" ), _( "Cut selected item(s) to clipboard" ), NULL );
TOOL_ACTION SCH_ACTIONS::copy( "eeschema.EditorControl.copy",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_COPY ),
_( "Copy" ), _( "Copy selected item(s) to clipboard" ), NULL );
TOOL_ACTION SCH_ACTIONS::paste( "eeschema.EditorControl.paste",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_PASTE ),
_( "Paste" ), _( "Paste clipboard into schematic" ), NULL );
SCH_EDITOR_CONTROL::SCH_EDITOR_CONTROL() :
@ -446,46 +456,171 @@ int SCH_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
}
static bool deleteItem( SCH_EDIT_FRAME* aFrame, const VECTOR2D& aPosition )
bool SCH_EDITOR_CONTROL::doCopy()
{
SCH_SELECTION_TOOL* selectionTool = aFrame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
wxCHECK( selectionTool, false );
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::selectionClear, true );
if( !selection.GetSize() )
return false;
SCH_ITEM* item = selectionTool->SelectPoint( aPosition );
STRING_FORMATTER formatter;
SCH_LEGACY_PLUGIN plugin;
if( item )
{
if( item->IsLocked() )
{
STATUS_TEXT_POPUP statusPopup( aFrame );
statusPopup.SetText( _( "Item locked." ) );
statusPopup.Expire( 2000 );
statusPopup.Popup();
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
}
else
{
aFrame->GetToolManager()->RunAction( SCH_ACTIONS::remove, true );
}
}
plugin.Format( &selection, &formatter );
return true;
return m_toolMgr->SaveClipboard( formatter.GetString() );
}
int SCH_EDITOR_CONTROL::DeleteItemCursor( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::Cut( const TOOL_EVENT& aEvent )
{
Activate();
if( doCopy() )
m_toolMgr->RunAction( SCH_ACTIONS::doDelete, true );
SCH_PICKER_TOOL* picker = m_toolMgr->GetTool<SCH_PICKER_TOOL>();
wxCHECK( picker, 0 );
return 0;
}
m_frame->SetToolID( ID_SCHEMATIC_DELETE_ITEM_BUTT, wxCURSOR_BULLSEYE, _( "Delete item" ) );
picker->SetClickHandler( std::bind( deleteItem, m_frame, std::placeholders::_1 ) );
picker->Activate();
Wait();
int SCH_EDITOR_CONTROL::Copy( const TOOL_EVENT& aEvent )
{
doCopy();
return 0;
}
int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
{
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
DLIST<SCH_ITEM>& dlist = m_frame->GetScreen()->GetDrawList();
SCH_ITEM* last = dlist.GetLast();
std::string text = m_toolMgr->GetClipboard();
STRING_LINE_READER reader( text, "Clipboard" );
SCH_LEGACY_PLUGIN plugin;
try
{
plugin.LoadContent( reader, m_frame->GetScreen() );
}
catch( IO_ERROR& e )
{
wxLogError( wxString::Format( "Malformed clipboard: %s" ), GetChars( e.What() ) );
return 0;
}
// SCH_LEGACY_PLUGIN added the items to the DLIST, but not to the view or anything
// else. Pull them back out to start with.
//
std::vector<SCH_ITEM*> loadedItems;
SCH_ITEM* next = nullptr;
// We also make sure any pasted sheets will not cause recursion in the destination.
// Moreover new sheets create new sheetpaths, and component alternate references must
// be created and cleared
//
bool hasSheetPasted = false;
SCH_SHEET_LIST hierarchy( g_RootSheet );
SCH_SHEET_LIST initialHierarchy( g_RootSheet );
wxFileName destFn = g_CurrentSheet->Last()->GetFileName();
if( destFn.IsRelative() )
destFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
for( SCH_ITEM* item = last ? last->Next() : dlist.GetFirst(); item; item = next )
{
next = item->Next();
dlist.Remove( item );
loadedItems.push_back( item );
if( item->Type() == SCH_COMPONENT_T )
{
SCH_COMPONENT* component = (SCH_COMPONENT*) item;
component->SetTimeStamp( GetNewTimeStamp() );
// clear the annotation, but preserve the selected unit
int unit = component->GetUnit();
component->ClearAnnotation( nullptr );
component->SetUnit( unit );
}
if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = (SCH_SHEET*) item;
wxFileName srcFn = sheet->GetFileName();
if( srcFn.IsRelative() )
srcFn.MakeAbsolute( m_frame->Prj().GetProjectPath() );
SCH_SHEET_LIST sheetHierarchy( sheet );
if( hierarchy.TestForRecursion( sheetHierarchy, destFn.GetFullPath( wxPATH_UNIX ) ) )
{
auto msg = wxString::Format( _( "The pasted sheet \"%s\"\n"
"was dropped because the destination already has "
"the sheet or one of its subsheets as a parent." ),
sheet->GetFileName() );
DisplayError( m_frame, msg );
loadedItems.pop_back();
}
else
{
// 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.
timestamp_t uid = GetNewTimeStamp();
sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)uid ) );
sheet->SetTimeStamp( uid );
hasSheetPasted = true;
}
}
}
// Now we can resolve the components and add everything to the screen, view, etc.
//
SYMBOL_LIB_TABLE* symLibTable = m_frame->Prj().SchSymbolLibTable();
PART_LIB* partLib = m_frame->Prj().SchLibs()->GetCacheLibrary();
for( int i = 0; i < loadedItems.size(); ++i )
{
SCH_ITEM* item = loadedItems[i];
if( item->Type() == SCH_COMPONENT_T )
{
SCH_COMPONENT* component = (SCH_COMPONENT*) item;
component->Resolve( *symLibTable, partLib );
}
item->SetFlags( IS_NEW | IS_MOVED );
m_frame->AddItemToScreen( item, i > 0 );
}
if( hasSheetPasted )
{
// We clear annotation of new sheet paths.
SCH_SCREENS screensList( g_RootSheet );
screensList.ClearAnnotationOfNewSheetPaths( initialHierarchy );
}
// Now clear the previous selection, select the pasted items, and fire up the "move"
// tool.
//
m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( SCH_ACTIONS::selectItems, true, &loadedItems );
SELECTION& selection = selTool->GetSelection();
if( !selection.Empty() )
{
SCH_ITEM* item = (SCH_ITEM*) selection.GetTopLeftItem();
selection.SetReferencePoint( item->GetPosition() );
m_toolMgr->RunAction( SCH_ACTIONS::move, true );
}
return 0;
}
@ -516,5 +651,7 @@ void SCH_EDITOR_CONTROL::setTransitions()
Go( &SCH_EDITOR_CONTROL::HighlightNetCursor, SCH_ACTIONS::highlightNetCursor.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::HighlightNetSelection, SCH_ACTIONS::highlightNetSelection.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::DeleteItemCursor, SCH_ACTIONS::deleteItemCursor.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::Cut, SCH_ACTIONS::cut.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::Copy, SCH_ACTIONS::copy.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::Paste, SCH_ACTIONS::paste.MakeEvent() );
}

View File

@ -76,10 +76,14 @@ public:
///> Launches a tool to highlight nets.
int HighlightNetCursor( const TOOL_EVENT& aEvent );
///> Runs the deletion tool.
int DeleteItemCursor( const TOOL_EVENT& aEvent );
///> Clipboard support.
int Cut( const TOOL_EVENT& aEvent );
int Copy( const TOOL_EVENT& aEvent );
int Paste( const TOOL_EVENT& aEvent );
private:
///> copy selection to clipboard
bool doCopy();
///> Sets up handlers for various events.
void setTransitions() override;

View File

@ -271,6 +271,7 @@ SCH_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T
}
}
// JEY TODO: move to own action triggered by selection event....
if( collector.GetCount() == 1 )
{
SCH_ITEM* item = collector[ 0 ];

View File

@ -160,6 +160,8 @@ enum main_id
ID_POPUP_GENERAL_START_RANGE, // first number
ID_POPUP_CANCEL_CURRENT_COMMAND,
ID_POPUP_CLOSE_CURRENT_TOOL,
// JEY TODO: all the block-specific commands are obsolet after LibEdit moves to modern toolset
ID_POPUP_MOVE_BLOCK,
ID_POPUP_MOVE_BLOCK_EXACT,
ID_POPUP_DRAG_BLOCK,