Moved module editor-specific tools to a separate class (MODULE_TOOLS).
This commit is contained in:
parent
f5e9774d55
commit
d87232f652
|
@ -264,6 +264,7 @@ set( PCBNEW_CLASS_SRCS
|
||||||
tools/edit_tool.cpp
|
tools/edit_tool.cpp
|
||||||
tools/pcbnew_control.cpp
|
tools/pcbnew_control.cpp
|
||||||
tools/pcb_editor_control.cpp
|
tools/pcb_editor_control.cpp
|
||||||
|
tools/module_tools.cpp
|
||||||
tools/placement_tool.cpp
|
tools/placement_tool.cpp
|
||||||
tools/common_actions.cpp
|
tools/common_actions.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include "tools/drawing_tool.h"
|
#include "tools/drawing_tool.h"
|
||||||
#include "tools/point_editor.h"
|
#include "tools/point_editor.h"
|
||||||
#include "tools/pcbnew_control.h"
|
#include "tools/pcbnew_control.h"
|
||||||
|
#include "tools/module_tools.h"
|
||||||
#include "tools/placement_tool.h"
|
#include "tools/placement_tool.h"
|
||||||
#include "tools/common_actions.h"
|
#include "tools/common_actions.h"
|
||||||
|
|
||||||
|
@ -280,6 +281,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
m_toolManager->RegisterTool( new DRAWING_TOOL );
|
m_toolManager->RegisterTool( new DRAWING_TOOL );
|
||||||
m_toolManager->RegisterTool( new POINT_EDITOR );
|
m_toolManager->RegisterTool( new POINT_EDITOR );
|
||||||
m_toolManager->RegisterTool( new PCBNEW_CONTROL );
|
m_toolManager->RegisterTool( new PCBNEW_CONTROL );
|
||||||
|
m_toolManager->RegisterTool( new MODULE_TOOLS );
|
||||||
m_toolManager->RegisterTool( new PLACEMENT_TOOL );
|
m_toolManager->RegisterTool( new PLACEMENT_TOOL );
|
||||||
|
|
||||||
m_toolManager->GetTool<SELECTION_TOOL>()->EditModules( true );
|
m_toolManager->GetTool<SELECTION_TOOL>()->EditModules( true );
|
||||||
|
|
|
@ -59,14 +59,6 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
|
||||||
AS_GLOBAL, 'E',
|
AS_GLOBAL, 'E',
|
||||||
"Properties...", "Displays properties window" );
|
"Properties...", "Displays properties window" );
|
||||||
|
|
||||||
TOOL_ACTION COMMON_ACTIONS::copyItems( "pcbnew.InteractiveEdit.copyItems",
|
|
||||||
AS_GLOBAL, MD_CTRL + int( 'C' ),
|
|
||||||
"Copy items", "Copy items", AF_ACTIVATE );
|
|
||||||
|
|
||||||
TOOL_ACTION COMMON_ACTIONS::pasteItems( "pcbnew.InteractiveEdit.pasteItems",
|
|
||||||
AS_GLOBAL, MD_CTRL + int( 'V' ),
|
|
||||||
"Paste items", "Paste items", AF_ACTIVATE );
|
|
||||||
|
|
||||||
|
|
||||||
// Drawing tool actions
|
// Drawing tool actions
|
||||||
TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line",
|
TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line",
|
||||||
|
@ -105,10 +97,6 @@ TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule"
|
||||||
AS_GLOBAL, 'O',
|
AS_GLOBAL, 'O',
|
||||||
"Add modules", "Add modules", AF_ACTIVATE );
|
"Add modules", "Add modules", AF_ACTIVATE );
|
||||||
|
|
||||||
TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.InteractiveDrawing.placePad",
|
|
||||||
AS_GLOBAL, 0,
|
|
||||||
"Add pads", "Add pads", AF_ACTIVATE );
|
|
||||||
|
|
||||||
TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF",
|
TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF",
|
||||||
AS_GLOBAL, 0,
|
AS_GLOBAL, 0,
|
||||||
"", "", AF_ACTIVATE );
|
"", "", AF_ACTIVATE );
|
||||||
|
@ -276,6 +264,20 @@ TOOL_ACTION COMMON_ACTIONS::trackViaSizeChanged( "pcbnew.EditorControl.trackViaS
|
||||||
"", "" );
|
"", "" );
|
||||||
|
|
||||||
|
|
||||||
|
// Module editor tools
|
||||||
|
TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.ModuleEditor.placePad",
|
||||||
|
AS_GLOBAL, 0,
|
||||||
|
"Add pads", "Add pads", AF_ACTIVATE );
|
||||||
|
|
||||||
|
TOOL_ACTION COMMON_ACTIONS::copyItems( "pcbnew.ModuleEditor.copyItems",
|
||||||
|
AS_GLOBAL, MD_CTRL + int( 'C' ),
|
||||||
|
"Copy items", "Copy items", AF_ACTIVATE );
|
||||||
|
|
||||||
|
TOOL_ACTION COMMON_ACTIONS::pasteItems( "pcbnew.ModuleEditor.pasteItems",
|
||||||
|
AS_GLOBAL, MD_CTRL + int( 'V' ),
|
||||||
|
"Paste items", "Paste items", AF_ACTIVATE );
|
||||||
|
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.Control.resetCoords",
|
TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.Control.resetCoords",
|
||||||
AS_GLOBAL, ' ',
|
AS_GLOBAL, ' ',
|
||||||
|
|
|
@ -62,11 +62,6 @@ public:
|
||||||
/// Deleting a BOARD_ITEM
|
/// Deleting a BOARD_ITEM
|
||||||
static TOOL_ACTION remove;
|
static TOOL_ACTION remove;
|
||||||
|
|
||||||
/// Copying pad to clipboard
|
|
||||||
static TOOL_ACTION copyItems;
|
|
||||||
|
|
||||||
/// Pasting a pad from clipboard
|
|
||||||
static TOOL_ACTION pasteItems;
|
|
||||||
|
|
||||||
// Drawing Tool
|
// Drawing Tool
|
||||||
/// Activation of the drawing tool (line)
|
/// Activation of the drawing tool (line)
|
||||||
|
@ -96,9 +91,6 @@ public:
|
||||||
/// Activation of the drawing tool (placing a MODULE)
|
/// Activation of the drawing tool (placing a MODULE)
|
||||||
static TOOL_ACTION placeModule;
|
static TOOL_ACTION placeModule;
|
||||||
|
|
||||||
/// Activation of the drawing tool (placing a PAD)
|
|
||||||
static TOOL_ACTION placePad;
|
|
||||||
|
|
||||||
/// Activation of the drawing tool (placing a drawing from DXF file)
|
/// Activation of the drawing tool (placing a drawing from DXF file)
|
||||||
static TOOL_ACTION placeDXF;
|
static TOOL_ACTION placeDXF;
|
||||||
|
|
||||||
|
@ -180,6 +172,18 @@ public:
|
||||||
|
|
||||||
static TOOL_ACTION trackViaSizeChanged; // notification
|
static TOOL_ACTION trackViaSizeChanged; // notification
|
||||||
|
|
||||||
|
|
||||||
|
// Module editor tools
|
||||||
|
/// Activation of the drawing tool (placing a PAD)
|
||||||
|
static TOOL_ACTION placePad;
|
||||||
|
|
||||||
|
/// Copying module items to clipboard
|
||||||
|
static TOOL_ACTION copyItems;
|
||||||
|
|
||||||
|
/// Pasting module items from clipboard
|
||||||
|
static TOOL_ACTION pasteItems;
|
||||||
|
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
static TOOL_ACTION resetCoords;
|
static TOOL_ACTION resetCoords;
|
||||||
static TOOL_ACTION switchUnits;
|
static TOOL_ACTION switchUnits;
|
||||||
|
|
|
@ -615,110 +615,6 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int DRAWING_TOOL::PlacePad( TOOL_EVENT& aEvent )
|
|
||||||
{
|
|
||||||
assert( m_editModules );
|
|
||||||
|
|
||||||
m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) );
|
|
||||||
|
|
||||||
MODULE* module = m_board->m_Modules;
|
|
||||||
assert( module );
|
|
||||||
|
|
||||||
D_PAD* pad = new D_PAD( module );
|
|
||||||
m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad
|
|
||||||
|
|
||||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
|
||||||
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
|
||||||
KIGFX::VIEW_GROUP preview( m_view );
|
|
||||||
preview.Add( pad );
|
|
||||||
m_view->Add( &preview );
|
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear );
|
|
||||||
m_controls->ShowCursor( true );
|
|
||||||
m_controls->SetSnapping( true );
|
|
||||||
|
|
||||||
Activate();
|
|
||||||
|
|
||||||
// Main loop: keep receiving events
|
|
||||||
while( OPT_TOOL_EVENT evt = Wait() )
|
|
||||||
{
|
|
||||||
cursorPos = m_controls->GetCursorPosition();
|
|
||||||
|
|
||||||
if( evt->IsMotion() )
|
|
||||||
{
|
|
||||||
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
|
||||||
preview.ViewUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( evt->Category() == TC_COMMAND )
|
|
||||||
{
|
|
||||||
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
|
|
||||||
{
|
|
||||||
pad->Rotate( pad->GetPosition(), m_frame->GetRotationAngle() );
|
|
||||||
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
|
||||||
{
|
|
||||||
pad->Flip( pad->GetPosition() );
|
|
||||||
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
|
||||||
}
|
|
||||||
else if( evt->IsCancel() || evt->IsActivate() )
|
|
||||||
{
|
|
||||||
preview.Clear();
|
|
||||||
delete pad;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( evt->IsClick( BUT_LEFT ) )
|
|
||||||
{
|
|
||||||
m_frame->OnModify();
|
|
||||||
m_frame->SaveCopyInUndoList( module, UR_MODEDIT );
|
|
||||||
|
|
||||||
m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
|
|
||||||
module->SetLastEditTime();
|
|
||||||
module->Pads().PushBack( pad );
|
|
||||||
|
|
||||||
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
|
||||||
|
|
||||||
// Set the relative pad position
|
|
||||||
// ( pad position for module orient, 0, and relative to the module position)
|
|
||||||
pad->SetLocalCoord();
|
|
||||||
|
|
||||||
/* NPTH pads take empty pad number (since they can't be connected),
|
|
||||||
* other pads get incremented from the last one edited */
|
|
||||||
wxString padName;
|
|
||||||
|
|
||||||
if( pad->GetAttribute() != PAD_HOLE_NOT_PLATED )
|
|
||||||
padName = getNextPadName();
|
|
||||||
|
|
||||||
pad->SetPadName( padName );
|
|
||||||
|
|
||||||
// Handle the view aspect
|
|
||||||
preview.Remove( pad );
|
|
||||||
m_view->Add( pad );
|
|
||||||
|
|
||||||
// Start placing next pad
|
|
||||||
pad = new D_PAD( module );
|
|
||||||
m_frame->Import_Pad_Settings( pad, false );
|
|
||||||
preview.Add( pad );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_controls->ShowCursor( false );
|
|
||||||
m_controls->SetSnapping( false );
|
|
||||||
m_controls->SetAutoPan( false );
|
|
||||||
m_view->Remove( &preview );
|
|
||||||
|
|
||||||
setTransitions();
|
|
||||||
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DRAWING_TOOL::PlaceDXF( TOOL_EVENT& aEvent )
|
int DRAWING_TOOL::PlaceDXF( TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
DIALOG_DXF_IMPORT dlg( m_frame );
|
DIALOG_DXF_IMPORT dlg( m_frame );
|
||||||
|
@ -1735,53 +1631,6 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isNotDigit( char aChar )
|
|
||||||
{
|
|
||||||
return ( aChar < '0' || aChar > '9' );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxString DRAWING_TOOL::getNextPadName() const
|
|
||||||
{
|
|
||||||
std::set<int> usedNumbers;
|
|
||||||
|
|
||||||
// Find the first, not used pad number
|
|
||||||
for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
|
|
||||||
{
|
|
||||||
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
|
|
||||||
{
|
|
||||||
wxString padName = pad->GetPadName();
|
|
||||||
int padNumber = 0;
|
|
||||||
int base = 1;
|
|
||||||
|
|
||||||
// Trim and extract the trailing numeric part
|
|
||||||
while( padName.Len() && padName.Last() >= '0' && padName.Last() <= '9' )
|
|
||||||
{
|
|
||||||
padNumber += ( padName.Last() - '0' ) * base;
|
|
||||||
padName.RemoveLast();
|
|
||||||
base *= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
usedNumbers.insert( padNumber );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int candidate = *usedNumbers.begin();
|
|
||||||
|
|
||||||
// Look for a gap in pad numbering
|
|
||||||
for( std::set<int>::iterator it = usedNumbers.begin(),
|
|
||||||
itEnd = usedNumbers.end(); it != itEnd; ++it )
|
|
||||||
{
|
|
||||||
if( *it - candidate > 1 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
candidate = *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxString::Format( wxT( "%i" ), ++candidate );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DRAWING_TOOL::setTransitions()
|
void DRAWING_TOOL::setTransitions()
|
||||||
{
|
{
|
||||||
Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() );
|
||||||
|
@ -1793,7 +1642,6 @@ void DRAWING_TOOL::setTransitions()
|
||||||
Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() );
|
|
||||||
Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() );
|
Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,12 +120,6 @@ public:
|
||||||
*/
|
*/
|
||||||
int PlaceModule( TOOL_EVENT& aEvent );
|
int PlaceModule( TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
/**
|
|
||||||
* Function PlacePad()
|
|
||||||
* Places a pad in module editor.
|
|
||||||
*/
|
|
||||||
int PlacePad( TOOL_EVENT& aEvent );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function PlaceDXF()
|
* Function PlaceDXF()
|
||||||
* Places a drawing imported from a DXF file in module editor.
|
* Places a drawing imported from a DXF file in module editor.
|
||||||
|
@ -192,12 +186,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const;
|
void make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Function getNextPadName()
|
|
||||||
* Compute the 'next' pad number for autoincrement.
|
|
||||||
* */
|
|
||||||
wxString getNextPadName() const;
|
|
||||||
|
|
||||||
///> Sets up handlers for various events.
|
///> Sets up handlers for various events.
|
||||||
void setTransitions();
|
void setTransitions();
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
#include <ratsnest_data.h>
|
#include <ratsnest_data.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <kicad_plugin.h>
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -431,229 +430,6 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent )
|
|
||||||
{
|
|
||||||
const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection();
|
|
||||||
|
|
||||||
if( !m_editModules || !makeSelection( selection ) )
|
|
||||||
{
|
|
||||||
setTransitions();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Activate();
|
|
||||||
|
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
|
||||||
controls->SetSnapping( true );
|
|
||||||
controls->ShowCursor( true );
|
|
||||||
controls->SetAutoPan( true );
|
|
||||||
|
|
||||||
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
|
|
||||||
frame->DisplayToolMsg( _( "Select reference point" ) );
|
|
||||||
|
|
||||||
bool cancelled = false;
|
|
||||||
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
|
||||||
|
|
||||||
while( OPT_TOOL_EVENT evt = Wait() )
|
|
||||||
{
|
|
||||||
if( evt->IsMotion() )
|
|
||||||
{
|
|
||||||
cursorPos = getViewControls()->GetCursorPosition();
|
|
||||||
}
|
|
||||||
else if( evt->IsClick( BUT_LEFT ) )
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if( evt->IsCancel() || evt->IsActivate() )
|
|
||||||
{
|
|
||||||
cancelled = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !cancelled )
|
|
||||||
{
|
|
||||||
PCB_IO io( CTL_FOR_CLIPBOARD );
|
|
||||||
|
|
||||||
// Create a temporary module that contains selected items to ease serialization
|
|
||||||
MODULE module( getModel<BOARD>() );
|
|
||||||
|
|
||||||
for( int i = 0; i < selection.Size(); ++i )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( selection.Item<BOARD_ITEM>( i )->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 );
|
|
||||||
|
|
||||||
module.Add( clone );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the new relative internal local coordinates of copied items
|
|
||||||
MODULE* editedModule = getModel<BOARD>()->m_Modules;
|
|
||||||
wxPoint moveVector = module.GetPosition() + editedModule->GetPosition() -
|
|
||||||
wxPoint( cursorPos.x, cursorPos.y );
|
|
||||||
module.MoveAnchorPosition( moveVector );
|
|
||||||
|
|
||||||
io.Format( &module, 0 );
|
|
||||||
std::string data = io.GetStringOutput( true );
|
|
||||||
m_toolMgr->SaveClipboard( data );
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) );
|
|
||||||
controls->SetSnapping( false );
|
|
||||||
controls->ShowCursor( false );
|
|
||||||
controls->SetAutoPan( false );
|
|
||||||
|
|
||||||
setTransitions();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent )
|
|
||||||
{
|
|
||||||
if( !m_editModules )
|
|
||||||
{
|
|
||||||
setTransitions();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse clipboard
|
|
||||||
PCB_IO io( CTL_FOR_CLIPBOARD );
|
|
||||||
MODULE* currentModule = getModel<BOARD>()->m_Modules;
|
|
||||||
MODULE* pastedModule = NULL;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
BOARD_ITEM* item = io.Parse( wxString( m_toolMgr->GetClipboard().c_str(), wxConvUTF8 ) );
|
|
||||||
assert( item->Type() == PCB_MODULE_T );
|
|
||||||
pastedModule = dyn_cast<MODULE*>( item );
|
|
||||||
}
|
|
||||||
catch( ... )
|
|
||||||
{
|
|
||||||
setTransitions();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Placement tool part
|
|
||||||
KIGFX::VIEW* view = getView();
|
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
|
||||||
BOARD* board = getModel<BOARD>();
|
|
||||||
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
|
|
||||||
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
|
||||||
|
|
||||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
|
||||||
KIGFX::VIEW_GROUP preview( view );
|
|
||||||
pastedModule->SetParent( board );
|
|
||||||
pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
|
||||||
pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) );
|
|
||||||
preview.Add( pastedModule );
|
|
||||||
view->Add( &preview );
|
|
||||||
|
|
||||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear );
|
|
||||||
controls->ShowCursor( true );
|
|
||||||
controls->SetSnapping( true );
|
|
||||||
controls->SetAutoPan( true );
|
|
||||||
|
|
||||||
Activate();
|
|
||||||
|
|
||||||
// Main loop: keep receiving events
|
|
||||||
while( OPT_TOOL_EVENT evt = Wait() )
|
|
||||||
{
|
|
||||||
cursorPos = controls->GetCursorPosition();
|
|
||||||
|
|
||||||
if( evt->IsMotion() )
|
|
||||||
{
|
|
||||||
pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
|
||||||
preview.ViewUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( evt->Category() == TC_COMMAND )
|
|
||||||
{
|
|
||||||
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
|
|
||||||
{
|
|
||||||
pastedModule->Rotate( pastedModule->GetPosition(), frame->GetRotationAngle() );
|
|
||||||
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
|
||||||
{
|
|
||||||
pastedModule->Flip( pastedModule->GetPosition() );
|
|
||||||
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
|
||||||
}
|
|
||||||
else if( evt->IsCancel() || evt->IsActivate() )
|
|
||||||
{
|
|
||||||
preview.Clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( evt->IsClick( BUT_LEFT ) )
|
|
||||||
{
|
|
||||||
frame->OnModify();
|
|
||||||
frame->SaveCopyInUndoList( currentModule, UR_MODEDIT );
|
|
||||||
|
|
||||||
board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
|
|
||||||
currentModule->SetLastEditTime();
|
|
||||||
|
|
||||||
// MODULE::RunOnChildren is infeasible here: we need to create copies of items, do not
|
|
||||||
// directly modify them
|
|
||||||
|
|
||||||
for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() )
|
|
||||||
{
|
|
||||||
D_PAD* clone = static_cast<D_PAD*>( pad->Clone() );
|
|
||||||
|
|
||||||
currentModule->Add( clone );
|
|
||||||
clone->SetLocalCoord();
|
|
||||||
view->Add( clone );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( BOARD_ITEM* drawing = pastedModule->GraphicalItems();
|
|
||||||
drawing; drawing = drawing->Next() )
|
|
||||||
{
|
|
||||||
BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( drawing->Clone() );
|
|
||||||
|
|
||||||
if( TEXTE_MODULE* text = dyn_cast<TEXTE_MODULE*>( clone ) )
|
|
||||||
{
|
|
||||||
// Do not add reference/value - convert them to the common type
|
|
||||||
text->SetType( TEXTE_MODULE::TEXT_is_DIVERS );
|
|
||||||
currentModule->Add( text );
|
|
||||||
text->SetLocalCoord();
|
|
||||||
|
|
||||||
// Whyyyyyyyyyyyyyyyyyyyyyy?! All other items conform to rotation performed
|
|
||||||
// on its parent module, but texts are so independent..
|
|
||||||
text->Rotate( text->GetPosition(), pastedModule->GetOrientation() );
|
|
||||||
}
|
|
||||||
else if( EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( clone ) )
|
|
||||||
{
|
|
||||||
currentModule->Add( edge );
|
|
||||||
edge->SetLocalCoord();
|
|
||||||
}
|
|
||||||
|
|
||||||
view->Add( clone );
|
|
||||||
}
|
|
||||||
|
|
||||||
preview.Clear();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete pastedModule;
|
|
||||||
controls->ShowCursor( false );
|
|
||||||
controls->SetSnapping( false );
|
|
||||||
controls->SetAutoPan( false );
|
|
||||||
view->Remove( &preview );
|
|
||||||
|
|
||||||
setTransitions();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EDIT_TOOL::remove( BOARD_ITEM* aItem )
|
void EDIT_TOOL::remove( BOARD_ITEM* aItem )
|
||||||
{
|
{
|
||||||
BOARD* board = getModel<BOARD>();
|
BOARD* board = getModel<BOARD>();
|
||||||
|
@ -741,8 +517,6 @@ void EDIT_TOOL::setTransitions()
|
||||||
Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() );
|
Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() );
|
Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() );
|
Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() );
|
|
||||||
Go( &EDIT_TOOL::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -91,20 +91,6 @@ public:
|
||||||
*/
|
*/
|
||||||
int Remove( TOOL_EVENT& aEvent );
|
int Remove( TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CopyItems()
|
|
||||||
*
|
|
||||||
* Copies selected items to the clipboard. Works only in "edit modules" mode.
|
|
||||||
*/
|
|
||||||
int CopyItems( TOOL_EVENT& aEvent );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function PastePad()
|
|
||||||
*
|
|
||||||
* Pastes items from the clipboard. Works only in "edit modules" mode.
|
|
||||||
*/
|
|
||||||
int PasteItems( TOOL_EVENT& aEvent );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function EditModules()
|
* Function EditModules()
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,422 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "module_tools.h"
|
||||||
|
#include "selection_tool.h"
|
||||||
|
#include "common_actions.h"
|
||||||
|
|
||||||
|
#include <class_draw_panel_gal.h>
|
||||||
|
#include <view/view_controls.h>
|
||||||
|
#include <view/view_group.h>
|
||||||
|
|
||||||
|
#include <kicad_plugin.h>
|
||||||
|
#include <pcbnew_id.h>
|
||||||
|
|
||||||
|
#include <wxPcbStruct.h>
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <class_module.h>
|
||||||
|
#include <class_edge_mod.h>
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
MODULE_TOOLS::MODULE_TOOLS() :
|
||||||
|
TOOL_INTERACTIVE( "pcbnew.ModuleEditor" )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MODULE_TOOLS::Reset( RESET_REASON aReason )
|
||||||
|
{
|
||||||
|
// Init variables used by every drawing tool
|
||||||
|
m_view = getView();
|
||||||
|
m_controls = getViewControls();
|
||||||
|
m_board = getModel<BOARD>();
|
||||||
|
m_frame = getEditFrame<PCB_EDIT_FRAME>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MODULE_TOOLS::Init()
|
||||||
|
{
|
||||||
|
setTransitions();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static wxString getNextPadName( MODULE* aModule )
|
||||||
|
{
|
||||||
|
std::set<int> usedNumbers;
|
||||||
|
|
||||||
|
// Create a set of used pad numbers
|
||||||
|
for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
|
||||||
|
{
|
||||||
|
wxString padName = pad->GetPadName();
|
||||||
|
int padNumber = 0;
|
||||||
|
int base = 1;
|
||||||
|
|
||||||
|
// Trim and extract the trailing numeric part
|
||||||
|
while( padName.Len() && padName.Last() >= '0' && padName.Last() <= '9' )
|
||||||
|
{
|
||||||
|
padNumber += ( padName.Last() - '0' ) * base;
|
||||||
|
padName.RemoveLast();
|
||||||
|
base *= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
usedNumbers.insert( padNumber );
|
||||||
|
}
|
||||||
|
|
||||||
|
int candidate = *usedNumbers.begin();
|
||||||
|
|
||||||
|
// Look for a gap in pad numbering
|
||||||
|
for( std::set<int>::iterator it = usedNumbers.begin(),
|
||||||
|
itEnd = usedNumbers.end(); it != itEnd; ++it )
|
||||||
|
{
|
||||||
|
if( *it - candidate > 1 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
candidate = *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxString::Format( wxT( "%i" ), ++candidate );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MODULE_TOOLS::PlacePad( TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) );
|
||||||
|
|
||||||
|
MODULE* module = m_board->m_Modules;
|
||||||
|
assert( module );
|
||||||
|
|
||||||
|
D_PAD* pad = new D_PAD( module );
|
||||||
|
m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad
|
||||||
|
|
||||||
|
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||||
|
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
|
||||||
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
|
KIGFX::VIEW_GROUP preview( m_view );
|
||||||
|
preview.Add( pad );
|
||||||
|
m_view->Add( &preview );
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear );
|
||||||
|
m_controls->ShowCursor( true );
|
||||||
|
m_controls->SetSnapping( true );
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
cursorPos = m_controls->GetCursorPosition();
|
||||||
|
|
||||||
|
if( evt->IsMotion() )
|
||||||
|
{
|
||||||
|
pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
preview.ViewUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->Category() == TC_COMMAND )
|
||||||
|
{
|
||||||
|
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
|
||||||
|
{
|
||||||
|
pad->Rotate( pad->GetPosition(), m_frame->GetRotationAngle() );
|
||||||
|
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
||||||
|
{
|
||||||
|
pad->Flip( pad->GetPosition() );
|
||||||
|
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
|
}
|
||||||
|
else if( evt->IsCancel() || evt->IsActivate() )
|
||||||
|
{
|
||||||
|
preview.Clear();
|
||||||
|
delete pad;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->IsClick( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
m_frame->OnModify();
|
||||||
|
m_frame->SaveCopyInUndoList( module, UR_MODEDIT );
|
||||||
|
|
||||||
|
m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
|
||||||
|
module->SetLastEditTime();
|
||||||
|
module->Pads().PushBack( pad );
|
||||||
|
|
||||||
|
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
||||||
|
|
||||||
|
// Set the relative pad position
|
||||||
|
// ( pad position for module orient, 0, and relative to the module position)
|
||||||
|
pad->SetLocalCoord();
|
||||||
|
|
||||||
|
/* NPTH pads take empty pad number (since they can't be connected),
|
||||||
|
* other pads get incremented from the last one edited */
|
||||||
|
wxString padName;
|
||||||
|
|
||||||
|
if( pad->GetAttribute() != PAD_HOLE_NOT_PLATED )
|
||||||
|
padName = getNextPadName( module );
|
||||||
|
|
||||||
|
pad->SetPadName( padName );
|
||||||
|
|
||||||
|
// Handle the view aspect
|
||||||
|
preview.Remove( pad );
|
||||||
|
m_view->Add( pad );
|
||||||
|
|
||||||
|
// Start placing next pad
|
||||||
|
pad = new D_PAD( module );
|
||||||
|
m_frame->Import_Pad_Settings( pad, false );
|
||||||
|
preview.Add( pad );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_controls->ShowCursor( false );
|
||||||
|
m_controls->SetSnapping( false );
|
||||||
|
m_controls->SetAutoPan( false );
|
||||||
|
m_view->Remove( &preview );
|
||||||
|
|
||||||
|
setTransitions();
|
||||||
|
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
const SELECTION_TOOL::SELECTION& selection = m_toolMgr->GetTool<SELECTION_TOOL>()->GetSelection();
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
|
controls->SetSnapping( true );
|
||||||
|
controls->ShowCursor( true );
|
||||||
|
controls->SetAutoPan( true );
|
||||||
|
|
||||||
|
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
|
||||||
|
frame->DisplayToolMsg( _( "Select reference point" ) );
|
||||||
|
|
||||||
|
bool cancelled = false;
|
||||||
|
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
||||||
|
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
if( evt->IsMotion() )
|
||||||
|
{
|
||||||
|
cursorPos = getViewControls()->GetCursorPosition();
|
||||||
|
}
|
||||||
|
else if( evt->IsClick( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if( evt->IsCancel() || evt->IsActivate() )
|
||||||
|
{
|
||||||
|
cancelled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !cancelled )
|
||||||
|
{
|
||||||
|
PCB_IO io( CTL_FOR_CLIPBOARD );
|
||||||
|
|
||||||
|
// Create a temporary module that contains selected items to ease serialization
|
||||||
|
MODULE module( getModel<BOARD>() );
|
||||||
|
|
||||||
|
for( int i = 0; i < selection.Size(); ++i )
|
||||||
|
{
|
||||||
|
BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( selection.Item<BOARD_ITEM>( i )->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 );
|
||||||
|
|
||||||
|
module.Add( clone );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the new relative internal local coordinates of copied items
|
||||||
|
MODULE* editedModule = getModel<BOARD>()->m_Modules;
|
||||||
|
wxPoint moveVector = module.GetPosition() + editedModule->GetPosition() -
|
||||||
|
wxPoint( cursorPos.x, cursorPos.y );
|
||||||
|
module.MoveAnchorPosition( moveVector );
|
||||||
|
|
||||||
|
io.Format( &module, 0 );
|
||||||
|
std::string data = io.GetStringOutput( true );
|
||||||
|
m_toolMgr->SaveClipboard( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) );
|
||||||
|
controls->SetSnapping( false );
|
||||||
|
controls->ShowCursor( false );
|
||||||
|
controls->SetAutoPan( false );
|
||||||
|
|
||||||
|
setTransitions();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
// Parse clipboard
|
||||||
|
PCB_IO io( CTL_FOR_CLIPBOARD );
|
||||||
|
MODULE* currentModule = getModel<BOARD>()->m_Modules;
|
||||||
|
MODULE* pastedModule = NULL;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BOARD_ITEM* item = io.Parse( wxString( m_toolMgr->GetClipboard().c_str(), wxConvUTF8 ) );
|
||||||
|
assert( item->Type() == PCB_MODULE_T );
|
||||||
|
pastedModule = dyn_cast<MODULE*>( item );
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{
|
||||||
|
m_frame->DisplayToolMsg( _( "Invalid clipboard contents" ) );
|
||||||
|
setTransitions();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placement tool part
|
||||||
|
KIGFX::VIEW* view = getView();
|
||||||
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
|
BOARD* board = getModel<BOARD>();
|
||||||
|
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
|
||||||
|
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
||||||
|
|
||||||
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
|
KIGFX::VIEW_GROUP preview( view );
|
||||||
|
pastedModule->SetParent( board );
|
||||||
|
pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) );
|
||||||
|
preview.Add( pastedModule );
|
||||||
|
view->Add( &preview );
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear );
|
||||||
|
controls->ShowCursor( true );
|
||||||
|
controls->SetSnapping( true );
|
||||||
|
controls->SetAutoPan( true );
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
while( OPT_TOOL_EVENT evt = Wait() )
|
||||||
|
{
|
||||||
|
cursorPos = controls->GetCursorPosition();
|
||||||
|
|
||||||
|
if( evt->IsMotion() )
|
||||||
|
{
|
||||||
|
pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
|
||||||
|
preview.ViewUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->Category() == TC_COMMAND )
|
||||||
|
{
|
||||||
|
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
|
||||||
|
{
|
||||||
|
pastedModule->Rotate( pastedModule->GetPosition(), frame->GetRotationAngle() );
|
||||||
|
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
|
}
|
||||||
|
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
|
||||||
|
{
|
||||||
|
pastedModule->Flip( pastedModule->GetPosition() );
|
||||||
|
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
|
||||||
|
}
|
||||||
|
else if( evt->IsCancel() || evt->IsActivate() )
|
||||||
|
{
|
||||||
|
preview.Clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( evt->IsClick( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
frame->OnModify();
|
||||||
|
frame->SaveCopyInUndoList( currentModule, UR_MODEDIT );
|
||||||
|
|
||||||
|
board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
|
||||||
|
currentModule->SetLastEditTime();
|
||||||
|
|
||||||
|
// MODULE::RunOnChildren is infeasible here: we need to create copies of items, do not
|
||||||
|
// directly modify them
|
||||||
|
|
||||||
|
for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() )
|
||||||
|
{
|
||||||
|
D_PAD* clone = static_cast<D_PAD*>( pad->Clone() );
|
||||||
|
|
||||||
|
currentModule->Add( clone );
|
||||||
|
clone->SetLocalCoord();
|
||||||
|
view->Add( clone );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( BOARD_ITEM* drawing = pastedModule->GraphicalItems();
|
||||||
|
drawing; drawing = drawing->Next() )
|
||||||
|
{
|
||||||
|
BOARD_ITEM* clone = static_cast<BOARD_ITEM*>( drawing->Clone() );
|
||||||
|
|
||||||
|
if( TEXTE_MODULE* text = dyn_cast<TEXTE_MODULE*>( clone ) )
|
||||||
|
{
|
||||||
|
// Do not add reference/value - convert them to the common type
|
||||||
|
text->SetType( TEXTE_MODULE::TEXT_is_DIVERS );
|
||||||
|
currentModule->Add( text );
|
||||||
|
text->SetLocalCoord();
|
||||||
|
|
||||||
|
// Whyyyyyyyyyyyyyyyyyyyyyy?! All other items conform to rotation performed
|
||||||
|
// on its parent module, but texts are so independent..
|
||||||
|
text->Rotate( text->GetPosition(), pastedModule->GetOrientation() );
|
||||||
|
}
|
||||||
|
else if( EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( clone ) )
|
||||||
|
{
|
||||||
|
currentModule->Add( edge );
|
||||||
|
edge->SetLocalCoord();
|
||||||
|
}
|
||||||
|
|
||||||
|
view->Add( clone );
|
||||||
|
}
|
||||||
|
|
||||||
|
preview.Clear();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pastedModule;
|
||||||
|
controls->ShowCursor( false );
|
||||||
|
controls->SetSnapping( false );
|
||||||
|
controls->SetAutoPan( false );
|
||||||
|
view->Remove( &preview );
|
||||||
|
|
||||||
|
setTransitions();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MODULE_TOOLS::setTransitions()
|
||||||
|
{
|
||||||
|
Go( &MODULE_TOOLS::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() );
|
||||||
|
Go( &MODULE_TOOLS::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() );
|
||||||
|
Go( &MODULE_TOOLS::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() );
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MODULE_TOOLS_H
|
||||||
|
#define MODULE_TOOLS_H
|
||||||
|
|
||||||
|
#include <tool/tool_interactive.h>
|
||||||
|
|
||||||
|
namespace KIGFX
|
||||||
|
{
|
||||||
|
class VIEW;
|
||||||
|
class VIEW_CONTROLS;
|
||||||
|
}
|
||||||
|
class BOARD;
|
||||||
|
class PCB_EDIT_FRAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MODULE_TOOLS
|
||||||
|
*
|
||||||
|
* Module editor specific tools.
|
||||||
|
*/
|
||||||
|
class MODULE_TOOLS : public TOOL_INTERACTIVE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MODULE_TOOLS();
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Reset()
|
||||||
|
void Reset( RESET_REASON aReason );
|
||||||
|
|
||||||
|
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||||
|
bool Init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function PlacePad()
|
||||||
|
* Places a pad in module editor.
|
||||||
|
*/
|
||||||
|
int PlacePad( TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CopyItems()
|
||||||
|
*
|
||||||
|
* Copies selected items to the clipboard. Works only in "edit modules" mode.
|
||||||
|
*/
|
||||||
|
int CopyItems( TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function PastePad()
|
||||||
|
*
|
||||||
|
* Pastes items from the clipboard. Works only in "edit modules" mode.
|
||||||
|
*/
|
||||||
|
int PasteItems( TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
private:
|
||||||
|
///> Sets up handlers for various events.
|
||||||
|
void setTransitions();
|
||||||
|
|
||||||
|
KIGFX::VIEW* m_view;
|
||||||
|
KIGFX::VIEW_CONTROLS* m_controls;
|
||||||
|
BOARD* m_board;
|
||||||
|
PCB_EDIT_FRAME* m_frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -55,7 +55,7 @@ private:
|
||||||
///> Sets up handlers for various events.
|
///> Sets up handlers for various events.
|
||||||
void setTransitions();
|
void setTransitions();
|
||||||
|
|
||||||
///> Pointerto the currently used edit frame.
|
///> Pointer to the currently used edit frame.
|
||||||
PCB_EDIT_FRAME* m_frame;
|
PCB_EDIT_FRAME* m_frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue