One-click PCB update improvements

- Fix repetitive undo/redo segfaults & assertions.
- Add Update menu entry on PCB side.
- Fix Python build error
- Add spread footprints after updating
This commit is contained in:
Tomasz Wlostowski 2016-01-29 15:43:40 +01:00 committed by Maciej Suminski
parent 689072c0e1
commit ee3418e90b
20 changed files with 160 additions and 63 deletions

View File

@ -197,6 +197,14 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
ExecuteRemoteCommand( payload.c_str() ); ExecuteRemoteCommand( payload.c_str() );
break; break;
case MAIL_SCH_PCB_UPDATE_REQUEST:
{
wxCommandEvent dummy;
OnUpdatePCB( dummy );
break;
}
case MAIL_BACKANNOTATE_FOOTPRINTS: case MAIL_BACKANNOTATE_FOOTPRINTS:
try try
{ {

View File

@ -297,9 +297,9 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
&HkAddBusEntry, &HkAddBusEntry,
&HkAddGraphicPolyLine, &HkAddGraphicPolyLine,
&HkAddGraphicText, &HkAddGraphicText,
&HkLeaveSheet,
&HkUpdatePcbFromSch, &HkUpdatePcbFromSch,
&HkAutoplaceFields, &HkAutoplaceFields,
&HkLeaveSheet,
&HkDeleteNode, &HkDeleteNode,
NULL NULL
}; };

View File

@ -78,9 +78,9 @@ enum hotkey_id_commnand {
HK_LEFT_CLICK, HK_LEFT_CLICK,
HK_LEFT_DCLICK, HK_LEFT_DCLICK,
HK_LEAVE_SHEET, HK_LEAVE_SHEET,
HK_UPDATE_PCB_FROM_SCH, HK_DELETE_NODE,
HK_AUTOPLACE_FIELDS, HK_AUTOPLACE_FIELDS,
HK_DELETE_NODE HK_UPDATE_PCB_FROM_SCH
}; };
// List of hotkey descriptors for Eeschema // List of hotkey descriptors for Eeschema

View File

@ -429,15 +429,17 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
text = AddHotkeyName( _( "Update PCB from Schematics" ), g_Schematic_Hokeys_Descr, HK_UPDATE_PCB_FROM_SCH ); text = AddHotkeyName( _( "Update PCB from Schematics" ), g_Schematic_Hokeys_Descr, HK_UPDATE_PCB_FROM_SCH );
wxMenuItem* updItem = AddMenuItem( toolsMenu, AddMenuItem( toolsMenu,
ID_UPDATE_PCB_FROM_SCH, ID_UPDATE_PCB_FROM_SCH,
text, _( "Updates the PCB design with the current schematic (forward annotation)." ), text, _( "Updates the PCB design with the current schematic (forward annotation)." ),
KiBitmap( libedit_xpm ) ); KiBitmap( pcbnew_xpm ) );
KIWAY_PLAYER* pcbFrame = Kiway().Player( FRAME_PCB, false ); // test open already. // Run Pcbnew
AddMenuItem( toolsMenu,
//if( Kiface().IsSingle() || !pcbFrame ) FIXME: refresh ID_RUN_PCB,
//updItem->Enable( false ); _( "&Open PCB Editor" ),
_( "Run Pcbnew" ),
KiBitmap( pcbnew_xpm ) );
toolsMenu->AppendSeparator(); toolsMenu->AppendSeparator();
@ -488,17 +490,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Run CvPcb // Run CvPcb
AddMenuItem( toolsMenu, AddMenuItem( toolsMenu,
ID_RUN_CVPCB, ID_RUN_CVPCB,
_( "A&ssign Component Footprint" ), _( "A&ssign Component Footprints" ),
_( "Run CvPcb" ), _( "Run CvPcb" ),
KiBitmap( cvpcb_xpm ) ); KiBitmap( cvpcb_xpm ) );
// Run Pcbnew
AddMenuItem( toolsMenu,
ID_RUN_PCB,
_( "&Layout Printed Circuit Board" ),
_( "Run Pcbnew" ),
KiBitmap( pcbnew_xpm ) );
// Help Menu: // Help Menu:
wxMenu* helpMenu = new wxMenu; wxMenu* helpMenu = new wxMenu;

View File

@ -39,7 +39,9 @@ enum MAIL_T
MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing. MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing.
MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing at cvpcb termination MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing at cvpcb termination
MAIL_EESCHEMA_NETLIST, ///< EESCHEMA->CVPCB netlist immediately after launching CVPCB MAIL_EESCHEMA_NETLIST, ///< EESCHEMA->CVPCB netlist immediately after launching CVPCB
MAIL_SCH_PCB_UPDATE ///< Sch->PCB forward update MAIL_SCH_PCB_UPDATE, ///< Sch->PCB forward update
MAIL_SCH_PCB_UPDATE_REQUEST ///< Sch->PCB forward update, requests SCH to re-generate netlist and send it to PCB via another mail (kind of bootstrap)
}; };
#endif // MAIL_TYPE_H_ #endif // MAIL_TYPE_H_

View File

@ -91,8 +91,6 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
protected: protected:
bool m_undoDisabled;
PCB_LAYER_WIDGET* m_Layers; PCB_LAYER_WIDGET* m_Layers;
DRC* m_drc; ///< the DRC controller, see drc.cpp DRC* m_drc; ///< the DRC controller, see drc.cpp
@ -228,11 +226,6 @@ public:
void LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) void LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
throw( IO_ERROR, PARSE_ERROR ); throw( IO_ERROR, PARSE_ERROR );
void DisableUndo( bool aDisable = true )
{
m_undoDisabled = aDisable;
}
void OnQuit( wxCommandEvent& event ); void OnQuit( wxCommandEvent& event );
/** /**
@ -288,6 +281,7 @@ public:
void OnUpdateMuWaveToolbar( wxUpdateUIEvent& aEvent ); void OnUpdateMuWaveToolbar( wxUpdateUIEvent& aEvent );
void OnLayerColorChange( wxCommandEvent& aEvent ); void OnLayerColorChange( wxCommandEvent& aEvent );
void OnConfigurePaths( wxCommandEvent& aEvent ); void OnConfigurePaths( wxCommandEvent& aEvent );
void OnUpdatePCBFromSch( wxCommandEvent& event );
/** /**
* called when the alt key is pressed during a mouse wheel action * called when the alt key is pressed during a mouse wheel action

View File

@ -62,9 +62,19 @@ BOARD_NETLIST_UPDATER::~BOARD_NETLIST_UPDATER ()
delete m_undoList; delete m_undoList;
} }
void BOARD_NETLIST_UPDATER::pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType ) void BOARD_NETLIST_UPDATER::pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, BOARD_ITEM* aCopy )
{ {
m_undoList->PushItem( ITEM_PICKER( aItem, aCommandType ) ); ITEM_PICKER picker( aItem, aCommandType );
if( aCommandType == UR_CHANGED )
{
if( m_undoList->FindItem ( aItem ) >= 0 ) // add only once
return;
picker.SetLink( aCopy ? aCopy : aItem->Clone() );
}
m_undoList->PushItem( picker );
} }
wxPoint BOARD_NETLIST_UPDATER::estimateComponentInsertionPosition() wxPoint BOARD_NETLIST_UPDATER::estimateComponentInsertionPosition()
@ -124,6 +134,7 @@ MODULE* BOARD_NETLIST_UPDATER::addNewComponent( COMPONENT* aComponent )
footprint->SetTimeStamp( GetNewTimeStamp() ); footprint->SetTimeStamp( GetNewTimeStamp() );
m_board->Add( footprint, ADD_APPEND ); m_board->Add( footprint, ADD_APPEND );
m_addedComponents.push_back( footprint );
pushUndo( footprint, UR_NEW ); pushUndo( footprint, UR_NEW );
@ -192,7 +203,7 @@ MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE *aPcb
else else
newFootprint->SetPath( aPcbComponent->GetPath() ); newFootprint->SetPath( aPcbComponent->GetPath() );
aPcbComponent->CopyNetlistSettings( newFootprint ); aPcbComponent->CopyNetlistSettings( newFootprint, false );
m_board->Remove( aPcbComponent ); m_board->Remove( aPcbComponent );
m_board->Add( newFootprint, ADD_APPEND ); m_board->Add( newFootprint, ADD_APPEND );
@ -231,7 +242,8 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
if( !aPcbComponent ) if( !aPcbComponent )
return false; return false;
pushUndo ( aPcbComponent, UR_CHANGED ); bool changed = false;
MODULE* copy = (MODULE*) aPcbComponent->Clone();
// Test for reference designator field change. // Test for reference designator field change.
if( aPcbComponent->GetReference() != aNewComponent->GetReference() ) if( aPcbComponent->GetReference() != aNewComponent->GetReference() )
@ -250,7 +262,10 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
m_reporter->Report( msg, REPORTER::RPT_INFO ); m_reporter->Report( msg, REPORTER::RPT_INFO );
if ( !m_isDryRun ) if ( !m_isDryRun )
aPcbComponent->SetReference( aNewComponent->GetReference() ); {
changed = true;
aPcbComponent->SetReference( aNewComponent->GetReference() );
}
} }
// Test for value field change. // Test for value field change.
@ -271,7 +286,10 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
m_reporter->Report( msg, REPORTER::RPT_ACTION ); m_reporter->Report( msg, REPORTER::RPT_ACTION );
if ( !m_isDryRun ) if ( !m_isDryRun )
{
changed = true;
aPcbComponent->SetValue( aNewComponent->GetValue() ); aPcbComponent->SetValue( aNewComponent->GetValue() );
}
} }
// Test for time stamp change. // Test for time stamp change.
@ -284,9 +302,17 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
m_reporter->Report( msg, REPORTER::RPT_INFO ); m_reporter->Report( msg, REPORTER::RPT_INFO );
if ( !m_isDryRun ) if ( !m_isDryRun )
{
changed = true;
aPcbComponent->SetPath( aNewComponent->GetTimeStamp() ); aPcbComponent->SetPath( aNewComponent->GetTimeStamp() );
}
} }
if( changed )
pushUndo( aPcbComponent, UR_CHANGED, copy );
else
delete copy;
return true; return true;
} }
@ -294,6 +320,9 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
{ {
wxString msg; wxString msg;
bool changed = false;
MODULE* copy = (MODULE*) aPcbComponent->Clone();
// At this point, the component footprint is updated. Now update the nets. // At this point, the component footprint is updated. Now update the nets.
for( D_PAD *pad = aPcbComponent->Pads(); pad; pad = pad->Next() ) for( D_PAD *pad = aPcbComponent->Pads(); pad; pad = pad->Next() )
{ {
@ -316,11 +345,9 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
} }
if( !m_isDryRun ) if( !m_isDryRun )
{ {
pushUndo( pad, UR_CHANGED ); changed = true;
pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
} }
@ -335,6 +362,7 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
// It is a new net, we have to add it // It is a new net, we have to add it
if( !m_isDryRun ) if( !m_isDryRun )
{ {
changed = true;
netinfo = new NETINFO_ITEM( m_board, net.GetNetName() ); netinfo = new NETINFO_ITEM( m_board, net.GetNetName() );
m_board->AppendNet( netinfo ); m_board->AppendNet( netinfo );
pushUndo( netinfo, UR_NEW ); pushUndo( netinfo, UR_NEW );
@ -375,13 +403,18 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
if ( !m_isDryRun ) if ( !m_isDryRun )
{ {
pushUndo( pad, UR_CHANGED ); changed = true;
pad->SetNetCode( netinfo->GetNet() ); pad->SetNetCode( netinfo->GetNet() );
} }
} }
} }
} }
if( changed )
pushUndo( aPcbComponent, UR_CHANGED, copy );
else
delete copy;
return true; return true;
} }
@ -417,7 +450,7 @@ bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
if( !m_isDryRun ) if( !m_isDryRun )
{ {
pushUndo( module, UR_DELETED ); pushUndo( module, UR_DELETED );
module->DeleteStructure(); m_board->Remove( module );
} }
} }
} }
@ -488,7 +521,7 @@ bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
GetChars( previouspad->GetPadName() ) ); GetChars( previouspad->GetPadName() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION ); m_reporter->Report( msg, REPORTER::RPT_ACTION );
pushUndo( previouspad, UR_CHANGED ); //pushUndo( previouspad, UR_CHANGED );
previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED ); previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
} }
@ -507,7 +540,7 @@ bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
// Examine last pad // Examine last pad
if( pad && count == 1 ) if( pad && count == 1 )
{ {
pushUndo( pad, UR_CHANGED ); //pushUndo( pad, UR_CHANGED );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
} }
return true; return true;
@ -640,12 +673,14 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
{ {
m_frame->SaveCopyInUndoList( *m_undoList, UR_UNSPECIFIED, wxPoint(0, 0) ); m_frame->SaveCopyInUndoList( *m_undoList, UR_UNSPECIFIED, wxPoint(0, 0) );
m_frame->OnModify(); m_frame->OnModify();
m_frame->Compile_Ratsnest( NULL, true );
m_board->GetRatsnest()->ProcessBoard();
testConnectivity( aNetlist );
} }
// Update the ratsnest // Update the ratsnest
m_board->GetRatsnest()->ProcessBoard();
testConnectivity( aNetlist );
m_reporter->Report( _(""), REPORTER::RPT_ACTION ); m_reporter->Report( _(""), REPORTER::RPT_ACTION );
m_reporter->Report( _(""), REPORTER::RPT_ACTION ); m_reporter->Report( _(""), REPORTER::RPT_ACTION );

View File

@ -127,9 +127,14 @@ public:
m_lookupByTimestamp = aEnabled; m_lookupByTimestamp = aEnabled;
} }
std::vector<MODULE*> GetAddedComponents() const
{
return m_addedComponents;
}
private: private:
void pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType ); void pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, BOARD_ITEM* aCopy = NULL );
wxPoint estimateComponentInsertionPosition(); wxPoint estimateComponentInsertionPosition();
MODULE* addNewComponent( COMPONENT* aComponent ); MODULE* addNewComponent( COMPONENT* aComponent );
@ -145,6 +150,8 @@ private:
BOARD *m_board; BOARD *m_board;
REPORTER *m_reporter; REPORTER *m_reporter;
std::vector<MODULE*> m_addedComponents;
bool m_deleteSinglePadNets; bool m_deleteSinglePadNets;
bool m_deleteUnusedComponents; bool m_deleteUnusedComponents;
bool m_isDryRun; bool m_isDryRun;
@ -156,5 +163,3 @@ private:
}; };
#endif #endif

View File

@ -116,6 +116,7 @@
* @param aItem = item to find * @param aItem = item to find
* = NULL to build the list of existing items * = NULL to build the list of existing items
*/ */
static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem ) static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
{ {
static std::vector<BOARD_ITEM*> itemsList; static std::vector<BOARD_ITEM*> itemsList;
@ -391,8 +392,8 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{ {
ITEM_PICKER picker = aItemsList.GetItemWrapper(ii);
BOARD_ITEM* item = (BOARD_ITEM*) aItemsList.GetPickedItem( ii ); BOARD_ITEM* item = (BOARD_ITEM*) aItemsList.GetPickedItem( ii );
UNDO_REDO_T status = aItemsList.GetPickedItemStatus( ii );
// For texts belonging to modules, we need to save state of the parent module // For texts belonging to modules, we need to save state of the parent module
if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_PAD_T ) if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_PAD_T )
@ -405,7 +406,7 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
bool found = false; bool found = false;
for( int j = 0; j < commandToUndo->GetCount(); j++ ) for( unsigned j = 0; j < commandToUndo->GetCount(); j++ )
{ {
if( commandToUndo->GetPickedItem( j ) == item && commandToUndo->GetPickedItemStatus( j ) == UR_CHANGED ) if( commandToUndo->GetPickedItem( j ) == item && commandToUndo->GetPickedItemStatus( j ) == UR_CHANGED )
{ {
@ -420,15 +421,13 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
continue; continue;
} else { } else {
commandToUndo->PushItem( ITEM_PICKER( item, status ) ); commandToUndo->PushItem( picker );
} }
} }
for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ ) for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
{ {
BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii ); BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii );
UNDO_REDO_T status = commandToUndo->GetPickedItemStatus( ii );
UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii ); UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii );
if( command == UR_UNSPECIFIED ) if( command == UR_UNSPECIFIED )
@ -448,7 +447,10 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
* If this link is not null, the copy is already done * If this link is not null, the copy is already done
*/ */
if( commandToUndo->GetPickedItemLink( ii ) == NULL ) if( commandToUndo->GetPickedItemLink( ii ) == NULL )
commandToUndo->SetPickedItemLink( item->Clone(), ii ); {
EDA_ITEM* cloned = item->Clone();
commandToUndo->SetPickedItemLink( cloned, ii );
}
break; break;
case UR_MOVED: case UR_MOVED:
@ -492,6 +494,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
BOARD_ITEM* item; BOARD_ITEM* item;
bool not_found = false; bool not_found = false;
bool reBuild_ratsnest = false; bool reBuild_ratsnest = false;
bool deep_reBuild_ratsnest = false;
KIGFX::VIEW* view = GetGalCanvas()->GetView(); KIGFX::VIEW* view = GetGalCanvas()->GetView();
RN_DATA* ratsnest = GetBoard()->GetRatsnest(); RN_DATA* ratsnest = GetBoard()->GetRatsnest();
@ -545,6 +549,11 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
reBuild_ratsnest = true; reBuild_ratsnest = true;
break; break;
case PCB_NETINFO_T:
reBuild_ratsnest = true;
deep_reBuild_ratsnest = true;
break;
default: default:
break; break;
} }
@ -591,8 +600,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
MODULE* module = static_cast<MODULE*>( item ); MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
} }
view->Remove( item );
view->Remove( item );
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
break; break;
@ -652,12 +661,18 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) ); wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) );
// Rebuild pointers and ratsnest that can be changed. // Rebuild pointers and ratsnest that can be changed.
if( reBuild_ratsnest && aRebuildRatsnet ) if( reBuild_ratsnest )
{ {
Compile_Ratsnest( NULL, true );
if( IsGalCanvasActive() ) if( IsGalCanvasActive() )
ratsnest->Recalculate(); {
else if( deep_reBuild_ratsnest )
Compile_Ratsnest( NULL, true ); ratsnest->ProcessBoard();
else
ratsnest->Recalculate();
}
} }
} }

View File

@ -764,9 +764,11 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
switch( aBoardItem->Type() ) switch( aBoardItem->Type() )
{ {
case PCB_NETINFO_T: case PCB_NETINFO_T:
m_NetInfo.RemoveNet ( (NETINFO_ITEM*) aBoardItem ); {
NETINFO_ITEM* item = (NETINFO_ITEM*) aBoardItem;
m_NetInfo.RemoveNet( item );
break; break;
}
case PCB_MARKER_T: case PCB_MARKER_T:
// find the item in the vector, then remove it // find the item in the vector, then remove it

View File

@ -115,6 +115,7 @@ MODULE::MODULE( const MODULE& aModule ) :
for( D_PAD* pad = aModule.m_Pads; pad; pad = pad->Next() ) for( D_PAD* pad = aModule.m_Pads; pad; pad = pad->Next() )
{ {
D_PAD* newpad = new D_PAD( *pad ); D_PAD* newpad = new D_PAD( *pad );
assert( newpad->GetNet() == pad->GetNet() );
newpad->SetParent( this ); newpad->SetParent( this );
m_Pads.PushBack( newpad ); m_Pads.PushBack( newpad );
} }

View File

@ -297,7 +297,6 @@ public:
*/ */
void AppendNet( NETINFO_ITEM* aNewElement ); void AppendNet( NETINFO_ITEM* aNewElement );
/** /**
* Function RemoveNet * Function RemoveNet
* Removes a new from the net list. * Removes a new from the net list.

View File

@ -88,6 +88,8 @@ void NETINFO_LIST::RemoveNet( NETINFO_ITEM* aNet )
break; break;
} }
} }
m_newNetCode = std::min( m_newNetCode, aNet->m_NetCode - 1 );
} }

View File

@ -84,8 +84,9 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
if( aDryRun ) if( aDryRun )
return; return;
m_frame->OnModify(); std::vector<MODULE*> newFootprints = updater.GetAddedComponents();
m_frame->OnModify();
m_frame->SetCurItem( NULL ); m_frame->SetCurItem( NULL );
// Reload modules // Reload modules

View File

@ -605,6 +605,14 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
//----- Tools menu ---------------------------------------------------------- //----- Tools menu ----------------------------------------------------------
wxMenu* toolsMenu = new wxMenu; wxMenu* toolsMenu = new wxMenu;
AddMenuItem( toolsMenu,
ID_UPDATE_PCB_FROM_SCH,
_( "Update PCB from Schematics" ),
_( "Updates the PCB design with the current schematic (forward annotation)." ),
KiBitmap( libedit_xpm ) );
toolsMenu->AppendSeparator( );
AddMenuItem( toolsMenu, ID_GET_NETLIST, AddMenuItem( toolsMenu, ID_GET_NETLIST,
_( "&Netlist" ), _( "&Netlist" ),
_( "Read the netlist and update board connectivity" ), _( "Read the netlist and update board connectivity" ),

View File

@ -116,7 +116,6 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
netlist.SortByReference(); netlist.SortByReference();
board->ReplaceNetlist( netlist, aDeleteSinglePadNets, &newFootprints, aReporter ); board->ReplaceNetlist( netlist, aDeleteSinglePadNets, &newFootprints, aReporter );
// If it was a dry run, nothing has changed so we're done. // If it was a dry run, nothing has changed so we're done.
if( netlist.IsDryRun() ) if( netlist.IsDryRun() )
return; return;
@ -329,4 +328,3 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
component->SetModule( module ); component->SetModule( module );
} }
} }

View File

@ -70,6 +70,8 @@
#include <tool/tool_dispatcher.h> #include <tool/tool_dispatcher.h>
#include <tools/common_actions.h> #include <tools/common_actions.h>
#include <wildcards_and_files_ext.h>
#if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON) #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
#include <python_scripting.h> #include <python_scripting.h>
#endif #endif
@ -232,6 +234,8 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_TOOL( ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE, EVT_TOOL( ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE,
PCB_EDIT_FRAME::OnSelectOptionToolbar ) PCB_EDIT_FRAME::OnSelectOptionToolbar )
EVT_TOOL( ID_UPDATE_PCB_FROM_SCH, PCB_EDIT_FRAME::OnUpdatePCBFromSch )
EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_ZONES, ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY, EVT_TOOL_RANGE( ID_TB_OPTIONS_SHOW_ZONES, ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY,
PCB_EDIT_FRAME::OnSelectOptionToolbar ) PCB_EDIT_FRAME::OnSelectOptionToolbar )
@ -309,7 +313,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition, PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition,
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME ) wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME )
{ {
m_undoDisabled = false;
m_showBorderAndTitleBlock = true; // true to display sheet references m_showBorderAndTitleBlock = true; // true to display sheet references
m_showAxis = false; // true to display X and Y axis m_showAxis = false; // true to display X and Y axis
m_showOriginAxis = true; m_showOriginAxis = true;
@ -1081,3 +1084,30 @@ void PCB_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
{ {
Pgm().ConfigurePaths( this ); Pgm().ConfigurePaths( this );
} }
void PCB_EDIT_FRAME::OnUpdatePCBFromSch( wxCommandEvent& event )
{
if( Kiface().IsSingle() )
{
DisplayError( this, _( "Cannot update the PCB, because the Kicad is"
" opened in stand-alone mode. In order to create/update"
" PCBs from schematics, you need to launch Kicad shell"
" and create a PCB project." ) );
return;
} else {
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true );
wxFileName schfn = Prj().AbsolutePath( Prj().GetProjectName() );
schfn.SetExt( SchematicFileExtension );
if( !frame->IsVisible() )
{
frame->OpenProjectFiles( std::vector<wxString>( 1, schfn.GetFullPath() ) );
frame->Show( false );
}
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST, "", this );
}
}

View File

@ -393,6 +393,7 @@ enum pcbnew_ids
ID_FOOTPRINT_WIZARD_SELECT_WIZARD, ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD, ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD,
ID_UPDATE_PCB_FROM_SCH,
ID_PCBNEW_END_LIST ID_PCBNEW_END_LIST
}; };

View File

@ -39,6 +39,7 @@
// ignore a couple of items that generate warnings from swig built code // ignore a couple of items that generate warnings from swig built code
%ignore NETINFO_ITEM;
%ignore BOARD_ITEM::ZeroOffset; %ignore BOARD_ITEM::ZeroOffset;
%ignore D_PAD::m_PadSketchModePenSize; %ignore D_PAD::m_PadSketchModePenSize;

View File

@ -357,7 +357,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
m_view->Add( dimension ); m_view->Add( dimension );
m_board->Add( dimension ); m_board->Add( dimension );
dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); //dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify(); m_frame->OnModify();
m_frame->SaveCopyInUndoList( dimension, UR_NEW ); m_frame->SaveCopyInUndoList( dimension, UR_NEW );