Improvements to copy-paste
-Can paste items from board to module-editor (only module parts) -Can paste entire modules just as copy -Can copy items inside module-editor Known limitations: -Will crash if trying to paste a module containing module_text inside the module editor ( dont know why, problem existed before ) -If copying things with strange layer names, the layer names will be changed.
This commit is contained in:
parent
05d8f1071e
commit
84b803042c
|
@ -39,7 +39,7 @@
|
||||||
#include <kicad_clipboard.h>
|
#include <kicad_clipboard.h>
|
||||||
|
|
||||||
CLIPBOARD_IO::CLIPBOARD_IO():
|
CLIPBOARD_IO::CLIPBOARD_IO():
|
||||||
PCB_IO(),
|
PCB_IO( CTL_STD_LAYER_NAMES ),
|
||||||
m_formatter(),
|
m_formatter(),
|
||||||
m_parser( new CLIPBOARD_PARSER() )
|
m_parser( new CLIPBOARD_PARSER() )
|
||||||
{
|
{
|
||||||
|
@ -58,49 +58,110 @@ void CLIPBOARD_IO::setBoard(BOARD* aBoard)
|
||||||
m_board = aBoard;
|
m_board = aBoard;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLIPBOARD_IO::writeHeader(BOARD* aBoard)
|
|
||||||
{
|
|
||||||
formatHeader( aBoard );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CLIPBOARD_IO::SaveSelection( SELECTION& aSelected )
|
void CLIPBOARD_IO::SaveSelection( SELECTION& aSelected )
|
||||||
{
|
{
|
||||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||||
|
|
||||||
// Prepare net mapping that assures that net codes saved in a file are consecutive integers
|
// dont even start if the selection is empty
|
||||||
m_mapping->SetBoard( m_board );
|
|
||||||
|
|
||||||
// we will fake being a .kicad_pcb to get the full parser kicking
|
|
||||||
// This means we also need layers and nets
|
|
||||||
|
|
||||||
m_formatter.Print( 0, "(kicad_pcb (version %d) (host pcbnew %s)\n", SEXPR_BOARD_FILE_VERSION,
|
|
||||||
m_formatter.Quotew( GetBuildVersion() ).c_str() );
|
|
||||||
|
|
||||||
if( aSelected.Empty() )
|
if( aSelected.Empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
writeHeader( m_board );
|
// Prepare net mapping that assures that net codes saved in a file are consecutive integers
|
||||||
|
m_mapping->SetBoard( m_board );
|
||||||
m_formatter.Print( 0, "\n" );
|
|
||||||
|
|
||||||
|
// Differentiate how it is formatted depending on what selection contains
|
||||||
|
bool onlyModuleParts = true;
|
||||||
for( auto i : aSelected )
|
for( auto i : aSelected )
|
||||||
{
|
{
|
||||||
|
// check if it not one of the module primitives
|
||||||
// Dont format stuff that cannot exist standalone!
|
|
||||||
if( ( i->Type() != PCB_MODULE_EDGE_T ) &&
|
if( ( i->Type() != PCB_MODULE_EDGE_T ) &&
|
||||||
( i->Type() != PCB_MODULE_TEXT_T ) &&
|
( i->Type() != PCB_MODULE_TEXT_T ) &&
|
||||||
( i->Type() != PCB_PAD_T ) )
|
( i->Type() != PCB_PAD_T ) )
|
||||||
{
|
{
|
||||||
//std::cout <<"type "<< i->Type() << std::endl;
|
onlyModuleParts = false;
|
||||||
auto item = static_cast<BOARD_ITEM*>( i );
|
continue;
|
||||||
Format( item, 1 );
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is only parts of a module selected, format it as a new module else
|
||||||
|
// format it as an entire board
|
||||||
|
MODULE module( m_board );
|
||||||
|
|
||||||
|
// only a module selected.
|
||||||
|
if( aSelected.Size() == 1 && aSelected.Front()->Type() == PCB_MODULE_T )
|
||||||
|
{
|
||||||
|
// make the module safe to transfer to other pcbs
|
||||||
|
MODULE* mod = static_cast<MODULE*>( aSelected.Front() );
|
||||||
|
for( D_PAD* pad = mod->Pads().GetFirst(); pad; pad = pad->Next() )
|
||||||
|
{
|
||||||
|
pad->SetNetCode( 0,0 );
|
||||||
|
}
|
||||||
|
mod->SetPath( "" );
|
||||||
|
Format(static_cast<BOARD_ITEM*>( mod ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// partial module selected.
|
||||||
|
else if( onlyModuleParts )
|
||||||
|
{
|
||||||
|
for( auto item : aSelected )
|
||||||
|
{
|
||||||
|
auto clone = static_cast<BOARD_ITEM*>( item->Clone() );
|
||||||
|
|
||||||
|
// Do not add reference/value - convert them to the common type
|
||||||
|
if( TEXTE_MODULE* text = dyn_cast<TEXTE_MODULE*>( clone ) )
|
||||||
|
text->SetType( TEXTE_MODULE::TEXT_is_DIVERS );
|
||||||
|
|
||||||
|
// If it is only a module, clear the nets from the pads
|
||||||
|
if( clone->Type() == PCB_PAD_T )
|
||||||
|
{
|
||||||
|
D_PAD* pad = static_cast<D_PAD*>(clone);
|
||||||
|
pad->SetNetCode(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.Add( clone );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the new relative internal local coordinates of copied items
|
||||||
|
MODULE* editedModule = m_board->m_Modules;
|
||||||
|
wxPoint moveVector = module.GetPosition() + editedModule->GetPosition();
|
||||||
|
|
||||||
|
module.MoveAnchorPosition( moveVector );
|
||||||
|
|
||||||
|
Format( &module, 0 );
|
||||||
|
|
||||||
}
|
}
|
||||||
m_formatter.Print( 0, "\n)" );
|
// lots of shite selected
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we will fake being a .kicad_pcb to get the full parser kicking
|
||||||
|
// This means we also need layers and nets
|
||||||
|
m_formatter.Print( 0, "(kicad_pcb (version %d) (host pcbnew %s)\n", SEXPR_BOARD_FILE_VERSION,
|
||||||
|
m_formatter.Quotew( GetBuildVersion() ).c_str() );
|
||||||
|
|
||||||
|
|
||||||
|
m_formatter.Print( 0, "\n" );
|
||||||
|
|
||||||
|
formatBoardLayers( m_board );
|
||||||
|
formatNetInformation( m_board );
|
||||||
|
|
||||||
|
m_formatter.Print( 0, "\n" );
|
||||||
|
|
||||||
|
|
||||||
|
for( auto i : aSelected )
|
||||||
|
{
|
||||||
|
// Dont format stuff that cannot exist standalone!
|
||||||
|
if( ( i->Type() != PCB_MODULE_EDGE_T ) &&
|
||||||
|
( i->Type() != PCB_MODULE_TEXT_T ) &&
|
||||||
|
( i->Type() != PCB_PAD_T ) )
|
||||||
|
{
|
||||||
|
//std::cout <<"type "<< i->Type() << std::endl;
|
||||||
|
auto item = static_cast<BOARD_ITEM*>( i );
|
||||||
|
Format( item, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
m_formatter.Print( 0, "\n)" );
|
||||||
|
}
|
||||||
if( wxTheClipboard->Open() )
|
if( wxTheClipboard->Open() )
|
||||||
{
|
{
|
||||||
wxTheClipboard->SetData( new wxTextDataObject( wxString( m_formatter.GetString().c_str(), wxConvUTF8 ) ) );
|
wxTheClipboard->SetData( new wxTextDataObject( wxString( m_formatter.GetString().c_str(), wxConvUTF8 ) ) );
|
||||||
|
@ -108,6 +169,26 @@ void CLIPBOARD_IO::SaveSelection( SELECTION& aSelected )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOARD_ITEM* CLIPBOARD_IO::Parse()
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
if( wxTheClipboard->Open() )
|
||||||
|
{
|
||||||
|
if( wxTheClipboard->IsSupported( wxDF_TEXT ) )
|
||||||
|
{
|
||||||
|
wxTextDataObject data;
|
||||||
|
wxTheClipboard->GetData( data );
|
||||||
|
|
||||||
|
result = data.GetText().mb_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxTheClipboard->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PCB_IO::Parse( result );
|
||||||
|
}
|
||||||
|
|
||||||
void CLIPBOARD_IO::Save( const wxString& aFileName, BOARD* aBoard,
|
void CLIPBOARD_IO::Save( const wxString& aFileName, BOARD* aBoard,
|
||||||
const PROPERTIES* aProperties )
|
const PROPERTIES* aProperties )
|
||||||
{
|
{
|
||||||
|
@ -163,11 +244,12 @@ BOARD* CLIPBOARD_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, const
|
||||||
m_parser->SetLineReader( &reader );
|
m_parser->SetLineReader( &reader );
|
||||||
m_parser->SetBoard( aAppendToMe );
|
m_parser->SetBoard( aAppendToMe );
|
||||||
|
|
||||||
|
BOARD_ITEM* item;
|
||||||
BOARD* board;
|
BOARD* board;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
board = dynamic_cast<BOARD*>( m_parser->Parse() );
|
item = m_parser->Parse();
|
||||||
}
|
}
|
||||||
catch( const FUTURE_FORMAT_ERROR& )
|
catch( const FUTURE_FORMAT_ERROR& )
|
||||||
{
|
{
|
||||||
|
@ -182,14 +264,17 @@ BOARD* CLIPBOARD_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, const
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !board )
|
if( item->Type() != PCB_T )
|
||||||
{
|
{
|
||||||
// The parser loaded something that was valid, but wasn't a board.
|
// The parser loaded something that was valid, but wasn't a board.
|
||||||
THROW_PARSE_ERROR( _( "Clipboard content is not Kicad compatible" ),
|
THROW_PARSE_ERROR( _( "Clipboard content is not Kicad compatible" ),
|
||||||
m_parser->CurSource(), m_parser->CurLine(),
|
m_parser->CurSource(), m_parser->CurLine(),
|
||||||
m_parser->CurLineNumber(), m_parser->CurOffset() );
|
m_parser->CurLineNumber(), m_parser->CurOffset() );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
board = dynamic_cast<BOARD*>( item );
|
||||||
|
}
|
||||||
// Give the filename to the board if it's new
|
// Give the filename to the board if it's new
|
||||||
if( !aAppendToMe )
|
if( !aAppendToMe )
|
||||||
board->SetFileName( aFileName );
|
board->SetFileName( aFileName );
|
||||||
|
|
|
@ -47,6 +47,8 @@ public:
|
||||||
throw( IO_ERROR, PARSE_ERROR, FUTURE_FORMAT_ERROR ) override
|
throw( IO_ERROR, PARSE_ERROR, FUTURE_FORMAT_ERROR ) override
|
||||||
{
|
{
|
||||||
MODULE* mod = PCB_PARSER::parseMODULE(aInitialComments);
|
MODULE* mod = PCB_PARSER::parseMODULE(aInitialComments);
|
||||||
|
|
||||||
|
//TODO: figure out better way of handling paths
|
||||||
mod->SetPath( wxT( "" ) );
|
mod->SetPath( wxT( "" ) );
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +68,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void SaveSelection( SELECTION& selected );
|
void SaveSelection( SELECTION& selected );
|
||||||
|
|
||||||
|
BOARD_ITEM* Parse();
|
||||||
|
|
||||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties = NULL ) override;
|
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties = NULL ) override;
|
||||||
CLIPBOARD_IO();
|
CLIPBOARD_IO();
|
||||||
~CLIPBOARD_IO();
|
~CLIPBOARD_IO();
|
||||||
|
|
|
@ -188,15 +188,19 @@ protected:
|
||||||
|
|
||||||
void init( const PROPERTIES* aProperties );
|
void init( const PROPERTIES* aProperties );
|
||||||
|
|
||||||
|
/// formats the board setup information
|
||||||
void formatSetup( BOARD* aBoard, int aNestLevel = 0 ) const
|
void formatSetup( BOARD* aBoard, int aNestLevel = 0 ) const
|
||||||
throw( IO_ERROR );
|
throw( IO_ERROR );
|
||||||
|
|
||||||
|
/// formats the General section of the file
|
||||||
void formatGeneral( BOARD* aBoard, int aNestLevel = 0 ) const
|
void formatGeneral( BOARD* aBoard, int aNestLevel = 0 ) const
|
||||||
throw( IO_ERROR );
|
throw( IO_ERROR );
|
||||||
|
|
||||||
|
/// formats the board layer information
|
||||||
void formatBoardLayers( BOARD* aBoard, int aNestLevel = 0 ) const
|
void formatBoardLayers( BOARD* aBoard, int aNestLevel = 0 ) const
|
||||||
throw( IO_ERROR );
|
throw( IO_ERROR );
|
||||||
|
|
||||||
|
/// formats the Nets and Netclasses
|
||||||
void formatNetInformation( BOARD* aBoard, int aNestLevel = 0 ) const
|
void formatNetInformation( BOARD* aBoard, int aNestLevel = 0 ) const
|
||||||
throw( IO_ERROR );
|
throw( IO_ERROR );
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "module_editor_tools.h"
|
#include "module_editor_tools.h"
|
||||||
|
#include "kicad_clipboard.h"
|
||||||
#include "selection_tool.h"
|
#include "selection_tool.h"
|
||||||
#include "pcb_actions.h"
|
#include "pcb_actions.h"
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
|
@ -63,11 +64,11 @@ TOOL_ACTION PCB_ACTIONS::enumeratePads( "pcbnew.ModuleEditor.enumeratePads",
|
||||||
_( "Enumerate Pads" ), _( "Enumerate pads" ), pad_enumerate_xpm, AF_ACTIVATE );
|
_( "Enumerate Pads" ), _( "Enumerate pads" ), pad_enumerate_xpm, AF_ACTIVATE );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::copyItems( "pcbnew.ModuleEditor.copyItems",
|
TOOL_ACTION PCB_ACTIONS::copyItems( "pcbnew.ModuleEditor.copyItems",
|
||||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_COPY_ITEM ),
|
AS_ACTIVE, 0,
|
||||||
_( "Copy" ), _( "Copy items" ), NULL, AF_ACTIVATE );
|
_( "Copy" ), _( "Copy items" ), NULL, AF_ACTIVATE );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::pasteItems( "pcbnew.ModuleEditor.pasteItems",
|
TOOL_ACTION PCB_ACTIONS::pasteItems( "pcbnew.ModuleEditor.pasteItems",
|
||||||
AS_GLOBAL, MD_CTRL + int( 'V' ),
|
AS_GLOBAL, 0,
|
||||||
_( "Paste" ), _( "Paste items" ), NULL, AF_ACTIVATE );
|
_( "Paste" ), _( "Paste items" ), NULL, AF_ACTIVATE );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::moduleEdgeOutlines( "pcbnew.ModuleEditor.graphicOutlines",
|
TOOL_ACTION PCB_ACTIONS::moduleEdgeOutlines( "pcbnew.ModuleEditor.graphicOutlines",
|
||||||
|
@ -333,19 +334,15 @@ int MODULE_EDITOR_TOOLS::CopyItems( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int MODULE_EDITOR_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
|
int MODULE_EDITOR_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
// Parse clipboard
|
|
||||||
PCB_IO io( CTL_FOR_CLIPBOARD );
|
|
||||||
MODULE* pastedModule = NULL;
|
|
||||||
|
|
||||||
try
|
MODULE* pastedModule = aEvent.Parameter<MODULE*>();
|
||||||
{
|
|
||||||
BOARD_ITEM* item = io.Parse( wxString( m_toolMgr->GetClipboard().c_str(), wxConvUTF8 ) );
|
for( BOARD_ITEM* item = pastedModule->GraphicalItems().GetFirst(); item;
|
||||||
assert( item->Type() == PCB_MODULE_T );
|
item = item->Next() )
|
||||||
pastedModule = dyn_cast<MODULE*>( item );
|
|
||||||
}
|
|
||||||
catch( ... )
|
|
||||||
{
|
{
|
||||||
frame()->DisplayToolMsg( _( "Invalid clipboard contents" ) );
|
frame()->DisplayToolMsg( _( "Invalid clipboard contents" ) );
|
||||||
|
if( item->Type() == PCB_MODULE_TEXT_T )
|
||||||
|
std::cout << "Crashing on this" << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ TOOL_ACTION PCB_ACTIONS::appendBoard( "pcbnew.EditorControl.appendBoard",
|
||||||
"", "" );
|
"", "" );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::appendClipboard( "pcbnew.EditorControl.appendClipboard",
|
TOOL_ACTION PCB_ACTIONS::appendClipboard( "pcbnew.EditorControl.appendClipboard",
|
||||||
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'V' ),
|
AS_GLOBAL, MD_CTRL + int( 'V' ),
|
||||||
"", "" );
|
"", "" );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::highlightNet( "pcbnew.EditorControl.highlightNet",
|
TOOL_ACTION PCB_ACTIONS::highlightNet( "pcbnew.EditorControl.highlightNet",
|
||||||
|
@ -394,7 +394,7 @@ int PCB_EDITOR_CONTROL::ViaSizeDec( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
|
int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
MODULE* module = NULL;
|
MODULE* module = aEvent.Parameter<MODULE*>();
|
||||||
KIGFX::VIEW* view = getView();
|
KIGFX::VIEW* view = getView();
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
BOARD* board = getModel<BOARD>();
|
BOARD* board = getModel<BOARD>();
|
||||||
|
@ -410,6 +410,12 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
|
||||||
Activate();
|
Activate();
|
||||||
m_frame->SetToolID( ID_PCB_MODULE_BUTT, wxCURSOR_PENCIL, _( "Add footprint" ) );
|
m_frame->SetToolID( ID_PCB_MODULE_BUTT, wxCURSOR_PENCIL, _( "Add footprint" ) );
|
||||||
|
|
||||||
|
// Add all the drawable parts to preview
|
||||||
|
if( module )
|
||||||
|
{
|
||||||
|
preview.Add( module );
|
||||||
|
}
|
||||||
|
|
||||||
// Main loop: keep receiving events
|
// Main loop: keep receiving events
|
||||||
while( OPT_TOOL_EVENT evt = Wait() )
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "pcb_actions.h"
|
#include "pcb_actions.h"
|
||||||
#include "selection_tool.h"
|
#include "selection_tool.h"
|
||||||
#include "picker_tool.h"
|
#include "picker_tool.h"
|
||||||
|
#include "pcb_editor_control.h"
|
||||||
#include "grid_helper.h"
|
#include "grid_helper.h"
|
||||||
|
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
|
@ -729,11 +730,67 @@ int PCBNEW_CONTROL::DeleteItemCursor( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PCBNEW_CONTROL::AppendBoardFromClipboard( const TOOL_EVENT& aEvent )
|
int PCBNEW_CONTROL::AppendBoardFromClipboard( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
CLIPBOARD_IO pi;
|
CLIPBOARD_IO pi;
|
||||||
wxString noString("");
|
wxString noString( "" );
|
||||||
return AppendBoard( pi, noString );
|
|
||||||
|
BOARD* board = getModel<BOARD>();
|
||||||
|
pi.setBoard( board );
|
||||||
|
|
||||||
|
BOARD_ITEM* clipItem = pi.Parse();
|
||||||
|
TOOL_EVENT event;
|
||||||
|
|
||||||
|
// The clipboard can contain two different things, an entire kicad_pcb
|
||||||
|
// or a single module
|
||||||
|
|
||||||
|
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
|
if(frame->IsType( FRAME_PCB) )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if( frame->IsType( FRAME_PCB_MODULE_EDITOR ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( clipItem->Type() )
|
||||||
|
{
|
||||||
|
case PCB_T:
|
||||||
|
if(frame->IsType( FRAME_PCB ) )
|
||||||
|
{
|
||||||
|
if( AppendBoard( pi, noString ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PCB_MODULE_T:
|
||||||
|
|
||||||
|
if(frame->IsType( FRAME_PCB) )
|
||||||
|
{
|
||||||
|
m_toolMgr->RunAction( "pcbnew.EditorControl.placeModule", true,
|
||||||
|
static_cast<MODULE*>( clipItem ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if( frame->IsType( FRAME_PCB_MODULE_EDITOR ) )
|
||||||
|
{
|
||||||
|
m_toolMgr->RunAction( "pcbnew.ModuleEditor.pasteItems", true,
|
||||||
|
static_cast<MODULE*>( clipItem ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_frame->DisplayToolMsg( _( "Invalid clipboard contents" ) );
|
||||||
|
// FAILED
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PCBNEW_CONTROL::AppendBoardFromFile( const TOOL_EVENT& aEvent )
|
int PCBNEW_CONTROL::AppendBoardFromFile( const TOOL_EVENT& aEvent )
|
||||||
|
@ -744,26 +801,31 @@ int PCBNEW_CONTROL::AppendBoardFromFile( const TOOL_EVENT& aEvent )
|
||||||
PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
|
PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
|
||||||
|
|
||||||
if( !editFrame )
|
if( !editFrame )
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
// Pick a file to append
|
// Pick a file to append
|
||||||
if( !AskLoadBoardFileName( editFrame, &open_ctl, &fileName, true ) )
|
if( !AskLoadBoardFileName( editFrame, &open_ctl, &fileName, true ) )
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
IO_MGR::PCB_FILE_T pluginType = plugin_type( fileName, open_ctl );
|
IO_MGR::PCB_FILE_T pluginType = plugin_type( fileName, open_ctl );
|
||||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
|
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
|
||||||
|
|
||||||
return AppendBoard( *pi, fileName );
|
return AppendBoard( *pi, fileName );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PCBNEW_CONTROL::AppendBoard( PLUGIN& pi, wxString& fileName )
|
int PCBNEW_CONTROL::AppendBoard( PLUGIN& pi, wxString& fileName )
|
||||||
{
|
{
|
||||||
|
|
||||||
PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
|
PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
|
||||||
|
if(!editFrame)
|
||||||
|
return 1;
|
||||||
|
|
||||||
// Mark existing tracks, in order to know what are the new tracks
|
// Mark existing tracks, in order to know what are the new tracks
|
||||||
// Tracks are inserted, not appended, so mark existing tracks to be
|
// Tracks are inserted, not appended, so mark existing tracks to be
|
||||||
// able to select the new tracks only later
|
// able to select the new tracks only later
|
||||||
BOARD* board = getModel<BOARD>();
|
BOARD* board = getModel<BOARD>();
|
||||||
|
if(!board)
|
||||||
|
return 1;
|
||||||
|
|
||||||
for( TRACK* track = board->m_Track; track; track = track->Next() )
|
for( TRACK* track = board->m_Track; track; track = track->Next() )
|
||||||
track->SetFlags( FLAG0 );
|
track->SetFlags( FLAG0 );
|
||||||
|
|
|
@ -124,7 +124,7 @@ TOOL_ACTION PCB_ACTIONS::filterSelection( "pcbnew.InteractiveSelection.FilterSel
|
||||||
nullptr );
|
nullptr );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::selectionToClipboard( "pcbnew.InteractiveSelection.CopyToClipboard",
|
TOOL_ACTION PCB_ACTIONS::selectionToClipboard( "pcbnew.InteractiveSelection.CopyToClipboard",
|
||||||
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'C' ),
|
AS_GLOBAL, MD_CTRL + int( 'C' ),
|
||||||
_( "Copy to Clipboard" ), _( "Copy selected content to clipboard" ),
|
_( "Copy to Clipboard" ), _( "Copy selected content to clipboard" ),
|
||||||
nullptr );
|
nullptr );
|
||||||
|
|
||||||
|
@ -631,7 +631,8 @@ int SELECTION_TOOL::selectionToClipboard( const TOOL_EVENT& aEvent )
|
||||||
BOARD* board = getModel<BOARD>();
|
BOARD* board = getModel<BOARD>();
|
||||||
|
|
||||||
io.setBoard( board );
|
io.setBoard( board );
|
||||||
auto& selection = RequestSelection( SELECTION_DELETABLE | SELECTION_SANITIZE_PADS );
|
//auto& selection = RequestSelection( SELECTION_DELETABLE | SELECTION_SANITIZE_PADS );
|
||||||
|
auto& selection = GetSelection();
|
||||||
io.SaveSelection( selection );
|
io.SaveSelection( selection );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue