eeschema: Duplicate() is a Copy() followed by a Paste()
The only subtle difference is that Duplicate() does not modify the clipboard contents so we need to keep a local variable in which to store the result of a Copy()
This commit is contained in:
parent
2131a44889
commit
5cf3e6d31a
|
@ -795,135 +795,6 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static KICAD_T duplicatableItems[] =
|
|
||||||
{
|
|
||||||
SCH_JUNCTION_T,
|
|
||||||
SCH_LINE_T,
|
|
||||||
SCH_BUS_BUS_ENTRY_T,
|
|
||||||
SCH_BUS_WIRE_ENTRY_T,
|
|
||||||
SCH_TEXT_T,
|
|
||||||
SCH_LABEL_T,
|
|
||||||
SCH_GLOBAL_LABEL_T,
|
|
||||||
SCH_HIER_LABEL_T,
|
|
||||||
SCH_NO_CONNECT_T,
|
|
||||||
SCH_SHEET_T,
|
|
||||||
SCH_COMPONENT_T,
|
|
||||||
EOT
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|
||||||
{
|
|
||||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( duplicatableItems );
|
|
||||||
|
|
||||||
if( selection.GetSize() == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Doing a duplicate of a new object doesn't really make any sense; we'd just end
|
|
||||||
// up dragging around a stack of objects...
|
|
||||||
if( selection.Front()->IsNew() )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
EDA_ITEMS newItems;
|
|
||||||
|
|
||||||
// Keep track of existing sheet paths. Duplicating a selection can modify this list
|
|
||||||
bool copiedSheets = false;
|
|
||||||
SCH_SHEET_LIST initial_sheetpathList = m_frame->Schematic().GetSheets();
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < selection.GetSize(); ++ii )
|
|
||||||
{
|
|
||||||
SCH_ITEM* oldItem = static_cast<SCH_ITEM*>( selection.GetItem( ii ) );
|
|
||||||
SCH_ITEM* newItem = oldItem->Duplicate();
|
|
||||||
newItem->SetFlags( IS_NEW );
|
|
||||||
newItems.push_back( newItem );
|
|
||||||
saveCopyInUndoList( newItem, UNDO_REDO::NEWITEM, ii > 0 );
|
|
||||||
|
|
||||||
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_HIER_LABEL_T:
|
|
||||||
case SCH_NO_CONNECT_T:
|
|
||||||
newItem->SetParent( m_frame->GetScreen() );
|
|
||||||
m_frame->AddToScreen( newItem, m_frame->GetScreen() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCH_SHEET_T:
|
|
||||||
{
|
|
||||||
SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetSheets();
|
|
||||||
SCH_SHEET* sheet = (SCH_SHEET*) newItem;
|
|
||||||
SCH_FIELD& nameField = sheet->GetFields()[SHEETNAME];
|
|
||||||
wxString baseName = nameField.GetText();
|
|
||||||
wxString number;
|
|
||||||
|
|
||||||
while( !baseName.IsEmpty() && wxIsdigit( baseName.Last() ) )
|
|
||||||
{
|
|
||||||
number = baseName.Last() + number;
|
|
||||||
baseName.RemoveLast();
|
|
||||||
}
|
|
||||||
|
|
||||||
int uniquifier = std::max( 0, wxAtoi( number ) ) + 1;
|
|
||||||
wxString candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ );
|
|
||||||
|
|
||||||
while( hierarchy.NameExists( candidateName ) )
|
|
||||||
candidateName = wxString::Format( wxT( "%s%d" ), baseName, uniquifier++ );
|
|
||||||
|
|
||||||
nameField.SetText( candidateName );
|
|
||||||
|
|
||||||
sheet->SetParent( m_frame->GetCurrentSheet().Last() );
|
|
||||||
|
|
||||||
SCH_SHEET_PATH sheetpath = m_frame->GetCurrentSheet();
|
|
||||||
sheetpath.push_back( sheet );
|
|
||||||
int page = 1;
|
|
||||||
wxString pageNum = wxString::Format( "%d", page );
|
|
||||||
|
|
||||||
while( hierarchy.PageNumberExists( pageNum ) )
|
|
||||||
pageNum = wxString::Format( "%d", ++page );
|
|
||||||
|
|
||||||
sheet->AddInstance( sheetpath.Path() );
|
|
||||||
sheet->SetPageNumber( sheetpath, pageNum );
|
|
||||||
m_frame->AddToScreen( sheet, m_frame->GetScreen() );
|
|
||||||
|
|
||||||
copiedSheets = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SCH_COMPONENT_T:
|
|
||||||
{
|
|
||||||
SCH_COMPONENT* symbol = (SCH_COMPONENT*) newItem;
|
|
||||||
symbol->ClearAnnotation( NULL );
|
|
||||||
symbol->SetParent( m_frame->GetScreen() );
|
|
||||||
m_frame->AddToScreen( symbol, m_frame->GetScreen() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( copiedSheets )
|
|
||||||
{
|
|
||||||
// We clear annotation of new sheet paths.
|
|
||||||
// Annotation of new symbols added in current sheet is already cleared.
|
|
||||||
SCH_SCREENS screensList( &m_frame->Schematic().Root() );
|
|
||||||
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
|
||||||
m_frame->SetSheetNumberAndCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
|
|
||||||
m_toolMgr->RunAction( EE_ACTIONS::addItemsToSel, true, &newItems );
|
|
||||||
m_toolMgr->RunAction( EE_ACTIONS::move, false );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
SCH_ITEM* sourceItem = m_frame->GetRepeatItem();
|
SCH_ITEM* sourceItem = m_frame->GetRepeatItem();
|
||||||
|
@ -1848,7 +1719,6 @@ int SCH_EDIT_TOOL::EditPageNumber( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
void SCH_EDIT_TOOL::setTransitions()
|
void SCH_EDIT_TOOL::setTransitions()
|
||||||
{
|
{
|
||||||
Go( &SCH_EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() );
|
|
||||||
Go( &SCH_EDIT_TOOL::RepeatDrawItem, EE_ACTIONS::repeatDrawItem.MakeEvent() );
|
Go( &SCH_EDIT_TOOL::RepeatDrawItem, EE_ACTIONS::repeatDrawItem.MakeEvent() );
|
||||||
Go( &SCH_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCW.MakeEvent() );
|
Go( &SCH_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCW.MakeEvent() );
|
||||||
Go( &SCH_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCCW.MakeEvent() );
|
Go( &SCH_EDIT_TOOL::Rotate, EE_ACTIONS::rotateCCW.MakeEvent() );
|
||||||
|
|
|
@ -45,7 +45,6 @@ public:
|
||||||
int Rotate( const TOOL_EVENT& aEvent );
|
int Rotate( const TOOL_EVENT& aEvent );
|
||||||
int Mirror( const TOOL_EVENT& aEvent );
|
int Mirror( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
int Duplicate( const TOOL_EVENT& aEvent );
|
|
||||||
int RepeatDrawItem( const TOOL_EVENT& aEvent );
|
int RepeatDrawItem( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
int Properties( const TOOL_EVENT& aEvent );
|
int Properties( const TOOL_EVENT& aEvent );
|
||||||
|
|
|
@ -1222,7 +1222,7 @@ int SCH_EDITOR_CONTROL::Redo( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDITOR_CONTROL::doCopy()
|
bool SCH_EDITOR_CONTROL::doCopy( bool aUseLocalClipboard )
|
||||||
{
|
{
|
||||||
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
||||||
EE_SELECTION& selection = selTool->RequestSelection();
|
EE_SELECTION& selection = selTool->RequestSelection();
|
||||||
|
@ -1250,6 +1250,12 @@ bool SCH_EDITOR_CONTROL::doCopy()
|
||||||
|
|
||||||
plugin.Format( &selection, &selPath, &hiearchy, &formatter );
|
plugin.Format( &selection, &selPath, &hiearchy, &formatter );
|
||||||
|
|
||||||
|
if( aUseLocalClipboard )
|
||||||
|
{
|
||||||
|
m_localClipboard = formatter.GetString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return m_toolMgr->SaveClipboard( formatter.GetString() );
|
return m_toolMgr->SaveClipboard( formatter.GetString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1267,6 +1273,15 @@ bool SCH_EDITOR_CONTROL::searchSupplementaryClipboard( const wxString& aSheetFil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SCH_EDITOR_CONTROL::Duplicate( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
doCopy( true ); // Use the local clipboard
|
||||||
|
Paste( aEvent );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_EDITOR_CONTROL::Cut( const TOOL_EVENT& aEvent )
|
int SCH_EDITOR_CONTROL::Cut( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
|
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
|
||||||
|
@ -1426,7 +1441,12 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
||||||
std::string text = m_toolMgr->GetClipboardUTF8();
|
std::string text;
|
||||||
|
|
||||||
|
if( aEvent.IsAction( &ACTIONS::duplicate ) )
|
||||||
|
text = m_localClipboard;
|
||||||
|
else
|
||||||
|
text = m_toolMgr->GetClipboardUTF8();
|
||||||
|
|
||||||
if( text.empty() )
|
if( text.empty() )
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1990,6 +2010,7 @@ void SCH_EDITOR_CONTROL::setTransitions()
|
||||||
Go( &SCH_EDITOR_CONTROL::Copy, ACTIONS::copy.MakeEvent() );
|
Go( &SCH_EDITOR_CONTROL::Copy, ACTIONS::copy.MakeEvent() );
|
||||||
Go( &SCH_EDITOR_CONTROL::Paste, ACTIONS::paste.MakeEvent() );
|
Go( &SCH_EDITOR_CONTROL::Paste, ACTIONS::paste.MakeEvent() );
|
||||||
Go( &SCH_EDITOR_CONTROL::Paste, ACTIONS::pasteSpecial.MakeEvent() );
|
Go( &SCH_EDITOR_CONTROL::Paste, ACTIONS::pasteSpecial.MakeEvent() );
|
||||||
|
Go( &SCH_EDITOR_CONTROL::Duplicate, ACTIONS::duplicate.MakeEvent() );
|
||||||
|
|
||||||
Go( &SCH_EDITOR_CONTROL::EditWithSymbolEditor, EE_ACTIONS::editWithLibEdit.MakeEvent() );
|
Go( &SCH_EDITOR_CONTROL::EditWithSymbolEditor, EE_ACTIONS::editWithLibEdit.MakeEvent() );
|
||||||
Go( &SCH_EDITOR_CONTROL::ShowCvpcb, EE_ACTIONS::assignFootprints.MakeEvent() );
|
Go( &SCH_EDITOR_CONTROL::ShowCvpcb, EE_ACTIONS::assignFootprints.MakeEvent() );
|
||||||
|
|
|
@ -111,6 +111,7 @@ public:
|
||||||
int Cut( const TOOL_EVENT& aEvent );
|
int Cut( const TOOL_EVENT& aEvent );
|
||||||
int Copy( const TOOL_EVENT& aEvent );
|
int Copy( const TOOL_EVENT& aEvent );
|
||||||
int Paste( const TOOL_EVENT& aEvent );
|
int Paste( const TOOL_EVENT& aEvent );
|
||||||
|
int Duplicate( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
int EditWithSymbolEditor( const TOOL_EVENT& aEvent );
|
int EditWithSymbolEditor( const TOOL_EVENT& aEvent );
|
||||||
int ShowCvpcb( const TOOL_EVENT& aEvent );
|
int ShowCvpcb( const TOOL_EVENT& aEvent );
|
||||||
|
@ -150,8 +151,8 @@ public:
|
||||||
SCH_SEARCH_T aSearchType, const wxString& aSearchText );
|
SCH_SEARCH_T aSearchType, const wxString& aSearchText );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///< copy selection to clipboard
|
///< copy selection to clipboard or to m_localClipboard if aUseLocalClipboard is true
|
||||||
bool doCopy();
|
bool doCopy( bool aUseLocalClipboard = false );
|
||||||
|
|
||||||
bool rescueProject( RESCUER& aRescuer, bool aRunningOnDemand );
|
bool rescueProject( RESCUER& aRescuer, bool aRunningOnDemand );
|
||||||
|
|
||||||
|
@ -211,6 +212,9 @@ private:
|
||||||
bool m_probingPcbToSch; // Recursion guard when cross-probing to PcbNew
|
bool m_probingPcbToSch; // Recursion guard when cross-probing to PcbNew
|
||||||
EDA_ITEM* m_pickerItem; // Current item for picker highlighting.
|
EDA_ITEM* m_pickerItem; // Current item for picker highlighting.
|
||||||
|
|
||||||
|
// Temporary storage location for Duplicate action
|
||||||
|
std::string m_localClipboard;
|
||||||
|
|
||||||
// A map of sheet filename --> screens for the clipboard contents. We use these to hook up
|
// A map of sheet filename --> screens for the clipboard contents. We use these to hook up
|
||||||
// cut/paste operations for unsaved sheet content.
|
// cut/paste operations for unsaved sheet content.
|
||||||
std::map<wxString, SCH_SCREEN*> m_supplementaryClipboard;
|
std::map<wxString, SCH_SCREEN*> m_supplementaryClipboard;
|
||||||
|
|
Loading…
Reference in New Issue