eeschema: single click PCB update feature added

This commit is contained in:
Tomasz Wlostowski 2016-01-29 11:24:39 +01:00 committed by Maciej Suminski
parent 9e609acae3
commit 867a0444bd
16 changed files with 1882 additions and 1 deletions

View File

@ -247,7 +247,10 @@ enum id_eeschema_frm
ID_LIBVIEW_CMP_EXPORT_TO_SCHEMATIC,
ID_SET_RELATIVE_OFFSET,
ID_END_EESCHEMA_ID_LIST
ID_END_EESCHEMA_ID_LIST,
ID_UPDATE_PCB_FROM_SCH,
ID_UPDATE_SCH_FROM_PCB
};

View File

@ -223,6 +223,8 @@ static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' +
static EDA_HOTKEY HkAutoplaceFields( _HKI( "Autoplace Fields" ), HK_AUTOPLACE_FIELDS, 'O',
ID_AUTOPLACE_FIELDS );
static EDA_HOTKEY HkUpdatePcbFromSch( _HKI( "Update PCB from Schematics" ), HK_UPDATE_PCB_FROM_SCH, WXK_F8 );
// List of common hotkey descriptors
static EDA_HOTKEY* common_Hotkey_List[] =
{
@ -296,6 +298,7 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
&HkAddGraphicPolyLine,
&HkAddGraphicText,
&HkLeaveSheet,
&HkUpdatePcbFromSch,
&HkAutoplaceFields,
&HkDeleteNode,
NULL

View File

@ -78,6 +78,7 @@ enum hotkey_id_commnand {
HK_LEFT_CLICK,
HK_LEFT_DCLICK,
HK_LEAVE_SHEET,
HK_UPDATE_PCB_FROM_SCH,
HK_AUTOPLACE_FIELDS,
HK_DELETE_NODE
};

View File

@ -427,6 +427,20 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Menu Tools:
wxMenu* toolsMenu = new wxMenu;
text = AddHotkeyName( _( "Update PCB from Schematics" ), g_Schematic_Hokeys_Descr, HK_UPDATE_PCB_FROM_SCH );
wxMenuItem* updItem = AddMenuItem( toolsMenu,
ID_UPDATE_PCB_FROM_SCH,
text, _( "Updates the PCB design with the current schematic." ),
KiBitmap( libedit_xpm ) );
KIWAY_PLAYER* pcbFrame = Kiway().Player( FRAME_PCB, false ); // test open already.
//if( Kiface().IsSingle() || !pcbFrame ) FIXME: refresh
//updItem->Enable( false );
toolsMenu->AppendSeparator();
AddMenuItem( toolsMenu,
ID_RUN_LIBRARY,
_( "Library &Editor" ), HELP_RUN_LIB_EDITOR,

View File

@ -60,6 +60,9 @@
#include <build_version.h>
#include <wildcards_and_files_ext.h>
#include <netlist_exporter_kicad.h>
#include <kiway.h>
// non-member so it can be moved easily, and kept REALLY private.
// Do NOT Clear() in here.
@ -260,6 +263,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_TOOL( wxID_PRINT, SCH_EDIT_FRAME::OnPrint )
EVT_TOOL( ID_GET_ERC, SCH_EDIT_FRAME::OnErc )
EVT_TOOL( ID_GET_NETLIST, SCH_EDIT_FRAME::OnCreateNetlist )
EVT_TOOL( ID_UPDATE_PCB_FROM_SCH, SCH_EDIT_FRAME::OnUpdatePCB )
EVT_TOOL( ID_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
EVT_TOOL( ID_FIND_ITEMS, SCH_EDIT_FRAME::OnFindItems )
EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
@ -817,6 +821,20 @@ void SCH_EDIT_FRAME::OnErc( wxCommandEvent& event )
InvokeDialogERC( this );
}
void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event )
{
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
NETLIST_EXPORTER_KICAD exporter( net_atoms, Prj().SchLibs() );
STRING_FORMATTER formatter;
exporter.Format( &formatter, GNL_ALL );
Kiway().ExpressMail( FRAME_PCB,
MAIL_SCH_PCB_UPDATE,
formatter.GetString(), // an abbreviated "kicad" (s-expr) netlist
this
);
}
void SCH_EDIT_FRAME::OnCreateNetlist( wxCommandEvent& event )
{

View File

@ -809,6 +809,7 @@ private:
void OnAnnotate( wxCommandEvent& event );
void OnErc( wxCommandEvent& event );
void OnCreateNetlist( wxCommandEvent& event );
void OnUpdatePCB( wxCommandEvent& event );
void OnCreateBillOfMaterials( wxCommandEvent& event );
void OnFindItems( wxCommandEvent& event );
void OnFindDialogClose( wxFindDialogEvent& event );

View File

@ -39,6 +39,7 @@ enum MAIL_T
MAIL_CROSS_PROBE, ///< PCB<->SCH, CVPCB->SCH cross-probing.
MAIL_BACKANNOTATE_FOOTPRINTS, ///< CVPCB->SCH footprint stuffing at cvpcb termination
MAIL_EESCHEMA_NETLIST, ///< EESCHEMA->CVPCB netlist immediately after launching CVPCB
MAIL_SCH_PCB_UPDATE ///< Sch->PCB forward update
};
#endif // MAIL_TYPE_H_

View File

@ -145,6 +145,8 @@ set( PCBNEW_DIALOGS
dialogs/dialog_track_via_properties_base.cpp
dialogs/dialog_track_via_size.cpp
dialogs/dialog_track_via_size_base.cpp
dialogs/dialog_update_pcb_base.cpp
dialogs/dialog_update_pcb.cpp
footprint_wizard.cpp
footprint_wizard_frame.cpp
dialogs/dialog_footprint_wizard_list_base.cpp
@ -193,6 +195,7 @@ set( PCBNEW_CLASS_SRCS
attribut.cpp
board_items_to_polygon_shape_transform.cpp
board_undo_redo.cpp
board_netlist_updater.cpp
block.cpp
block_module_editor.cpp
build_BOM_from_board.cpp

View File

@ -0,0 +1,680 @@
/**
* @file board_netlist_updater.h
* @brief BOARD_NETLIST_UPDATER class definition
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 CERN
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
*
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 <common.h> // for PAGE_INFO
#include <class_board.h>
#include <class_netinfo.h>
#include <class_module.h>
#include <class_pad.h>
#include <class_zone.h>
#include <pcb_netlist.h>
#include <ratsnest_data.h>
#include <reporter.h>
#include <board_netlist_updater.h>
#include <wxPcbStruct.h>
BOARD_NETLIST_UPDATER::BOARD_NETLIST_UPDATER ( PCB_EDIT_FRAME *aFrame, BOARD *aBoard ) :
m_frame ( aFrame ),
m_board( aBoard )
{
m_reporter = &NULL_REPORTER::GetInstance();
m_undoList = new PICKED_ITEMS_LIST;
}
BOARD_NETLIST_UPDATER::~BOARD_NETLIST_UPDATER ()
{
delete m_undoList;
}
void BOARD_NETLIST_UPDATER::pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType )
{
m_undoList->PushItem( ITEM_PICKER( aItem, aCommandType ) );
}
wxPoint BOARD_NETLIST_UPDATER::estimateComponentInsertionPosition()
{
wxPoint bestPosition;
if( !m_board->IsEmpty() )
{
// Position new components below any existing board features.
EDA_RECT bbox = m_board->ComputeBoundingBox( true );
if( bbox.GetWidth() || bbox.GetHeight() )
{
bestPosition.x = bbox.Centre().x;
bestPosition.y = bbox.GetBottom() + Millimeter2iu( 10 );
}
}
else
{
// Position new components in the center of the page when the board is empty.
wxSize pageSize = m_board->GetPageSettings().GetSizeIU();
bestPosition.x = pageSize.GetWidth() / 2;
bestPosition.y = pageSize.GetHeight() / 2;
}
return bestPosition;
}
MODULE* BOARD_NETLIST_UPDATER::addNewComponent( COMPONENT* aComponent )
{
wxString msg;
if( aComponent->GetModule() != NULL )
{
msg.Printf( _( "Adding new component \"%s:%s\" footprint \"%s\".\n" ),
GetChars( aComponent->GetReference() ),
GetChars( aComponent->GetTimeStamp() ),
GetChars( aComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
msg.Printf( _( "Add component %s, footprint: %s.\n" ),
GetChars( aComponent->GetReference() ),
GetChars( aComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
if( !m_isDryRun )
{
// Owned by NETLIST, can only copy it.
MODULE *footprint = new MODULE( *aComponent->GetModule() );
footprint->SetParent( m_board );
footprint->SetPosition( estimateComponentInsertionPosition( ) );
footprint->SetTimeStamp( GetNewTimeStamp() );
m_board->Add( footprint, ADD_APPEND );
pushUndo( footprint, UR_NEW );
return footprint;
}
}
else
{
msg.Printf( _( "Cannot add component %s due to missing footprint %s.\n" ),
GetChars( aComponent->GetReference() ),
GetChars( aComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_ERROR );
msg.Printf( _( "Cannot add new component \"%s:%s\" due to missing "
"footprint \"%s\".\n" ),
GetChars( aComponent->GetReference() ),
GetChars( aComponent->GetTimeStamp() ),
GetChars( aComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
m_errorCount ++;
}
return NULL;
}
MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE *aPcbComponent, COMPONENT* aNewComponent )
{
wxString msg;
if( !m_replaceFootprints )
return NULL;
// Test if the footprint has not changed
if( aNewComponent->GetFPID().empty() ||
aPcbComponent->GetFPID() == aNewComponent->GetFPID() )
return NULL;
if( aNewComponent->GetModule() != NULL )
{
msg.Printf( _( "Change component %s footprint from %s to %s.\n"),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetFPID().Format() ),
GetChars( aNewComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Replacing component \"%s:%s\" footprint \"%s\" with "
"\"%s\".\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( aPcbComponent->GetFPID().Format() ),
GetChars( aNewComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if( !m_isDryRun )
{
wxASSERT( aPcbComponent != NULL );
MODULE* newFootprint = new MODULE( *aNewComponent->GetModule() );
if( aNetlist.IsFindByTimeStamp() )
newFootprint->SetReference( aPcbComponent->GetReference() );
else
newFootprint->SetPath( aPcbComponent->GetPath() );
aPcbComponent->CopyNetlistSettings( newFootprint );
m_board->Remove( aPcbComponent );
m_board->Add( newFootprint, ADD_APPEND );
pushUndo( aPcbComponent, UR_DELETED );
pushUndo( newFootprint, UR_NEW );
return newFootprint;
}
} else {
msg.Printf( _( "Cannot change component %s footprint due to missing "
"footprint %s.\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aNewComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_ERROR );
msg.Printf( _( "Cannot replace component \"%s:%s\" due to missing "
"footprint \"%s\".\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( aNewComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
m_errorCount ++;
}
return NULL;
}
bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, COMPONENT* aNewComponent )
{
wxString msg;
if( !aPcbComponent )
return false;
pushUndo ( aPcbComponent, UR_CHANGED );
// Test for reference designator field change.
if( aPcbComponent->GetReference() != aNewComponent->GetReference() )
{
msg.Printf( _( "Change component %s reference to %s.\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aNewComponent->GetReference() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Changing component \"%s:%s\" reference to \"%s\".\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( aNewComponent->GetReference() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if ( !m_isDryRun )
aPcbComponent->SetReference( aNewComponent->GetReference() );
}
// Test for value field change.
if( aPcbComponent->GetValue() != aNewComponent->GetValue() )
{
msg.Printf( _( "Change component %s value from %s to %s.\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetValue() ),
GetChars( aNewComponent->GetValue() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Changing component \"%s:%s\" value from \"%s\" to \"%s\".\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( aPcbComponent->GetValue() ),
GetChars( aNewComponent->GetValue() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
if ( !m_isDryRun )
aPcbComponent->SetValue( aNewComponent->GetValue() );
}
// Test for time stamp change.
if( aPcbComponent->GetPath() != aNewComponent->GetTimeStamp() )
{
msg.Printf( _( "Changing component path \"%s:%s\" to \"%s\".\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( aNewComponent->GetTimeStamp() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if ( !m_isDryRun )
aPcbComponent->SetPath( aNewComponent->GetTimeStamp() );
}
return true;
}
bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent, COMPONENT* aNewComponent )
{
wxString msg;
// At this point, the component footprint is updated. Now update the nets.
for( D_PAD *pad = aPcbComponent->Pads(); pad; pad = pad->Next() )
{
COMPONENT_NET net = aNewComponent->GetNet( pad->GetPadName() );
if( !net.IsValid() ) // New footprint pad has no net.
{
if( !pad->GetNetname().IsEmpty() )
{
msg.Printf( _( "Disconnect component %s pin %s.\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( pad->GetPadName() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Clearing component \"%s:%s\" pin \"%s\" net name.\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( pad->GetPadName() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
}
if( !m_isDryRun )
{
pushUndo( pad, UR_CHANGED );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
}
else // New footprint pad has a net.
{
if( net.GetNetName() != pad->GetNetname() )
{
NETINFO_ITEM* netinfo = m_board->FindNet( net.GetNetName() );
if( netinfo == NULL )
{
// It is a new net, we have to add it
if( !m_isDryRun )
{
netinfo = new NETINFO_ITEM( m_board, net.GetNetName() );
m_board->AppendNet( netinfo );
pushUndo( netinfo, UR_NEW );
}
msg.Printf( _( "Add net %s.\n" ),
GetChars( net.GetNetName() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
}
if( pad->GetNetname() != wxString("") )
{
msg.Printf( _( "Reconnect component %s pin %s from net %s to net %s.\n"),
GetChars( aPcbComponent->GetReference() ),
GetChars( pad->GetPadName() ),
GetChars( pad->GetNetname() ),
GetChars( net.GetNetName() ) );
} else {
msg.Printf( _( "Connect component %s pin %s to net %s.\n"),
GetChars( aPcbComponent->GetReference() ),
GetChars( pad->GetPadName() ),
GetChars( net.GetNetName() ) );
}
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Changing component \"%s:%s\" pin \"%s\" net name from "
"\"%s\" to \"%s\".\n" ),
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( pad->GetPadName() ),
GetChars( pad->GetNetname() ),
GetChars( net.GetNetName() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if ( !m_isDryRun )
{
pushUndo( pad, UR_CHANGED );
pad->SetNetCode( netinfo->GetNet() );
}
}
}
}
return true;
}
bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
{
wxString msg;
MODULE* nextModule;
const COMPONENT* component;
for( MODULE* module = m_board->m_Modules; module != NULL; module = nextModule )
{
nextModule = module->Next();
if( module->IsLocked() )
continue;
if( m_lookupByTimestamp )
component = aNetlist.GetComponentByTimeStamp( module->GetPath() );
else
component = aNetlist.GetComponentByReference( module->GetReference() );
if( component == NULL )
{
msg.Printf( _( "Remove component %s." ),
GetChars( module->GetReference() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Removing unused component \"%s:%s\".\n" ),
GetChars( module->GetReference() ),
GetChars( module->GetPath() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if( !m_isDryRun )
{
pushUndo( module, UR_DELETED );
module->DeleteStructure();
}
}
}
return true;
}
bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
{
int count = 0;
wxString netname;
wxString msg;
D_PAD* pad = NULL;
D_PAD* previouspad = NULL;
// We need the pad list, for next tests.
// padlist is the list of pads, sorted by netname.
m_board->BuildListOfNets();
if( m_isDryRun )
return false;
std::vector<D_PAD*> padlist = m_board->GetPads();
for( unsigned ii = 0; ii < padlist.size(); ii++ )
{
pad = padlist[ii];
if( pad->GetNetname().IsEmpty() )
continue;
if( netname != pad->GetNetname() ) // End of net
{
if( previouspad && count == 1 )
{
// First, see if we have a copper zone attached to this pad.
// If so, this is not really a single pad net
for( int ii = 0; ii < m_board->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* zone = m_board->GetArea( ii );
if( !zone->IsOnCopperLayer() )
continue;
if( zone->GetIsKeepout() )
continue;
if( zone->GetNet() == previouspad->GetNet() )
{
count++;
break;
}
}
if( count == 1 ) // Really one pad, and nothing else
{
msg.Printf( _( "Remove single pad net %s." ),
GetChars( previouspad->GetNetname() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Remove single pad net \"%s\" on \"%s\" pad '%s'\n" ),
GetChars( previouspad->GetNetname() ),
GetChars( previouspad->GetParent()->GetReference() ),
GetChars( previouspad->GetPadName() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
pushUndo( previouspad, UR_CHANGED );
previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
}
netname = pad->GetNetname();
count = 1;
}
else
{
count++;
}
previouspad = pad;
}
// Examine last pad
if( pad && count == 1 )
{
pushUndo( pad, UR_CHANGED );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
return true;
}
bool BOARD_NETLIST_UPDATER::testConnectivity( NETLIST& aNetlist )
{
// Last step: Some tests:
// verify all pads found in netlist:
// They should exist in footprints, otherwise the footprint is wrong
// note also references or time stamps are updated, so we use only
// the reference to find a footprint
//
// Also verify if zones have acceptable nets, i.e. nets with pads.
// Zone with no pad belongs to a "dead" net which happens after changes in schematic
// when no more pad use this net name.
wxString msg;
wxString padname;
for( int i = 0; i < (int) aNetlist.GetCount(); i++ )
{
const COMPONENT* component = aNetlist.GetComponent( i );
MODULE* footprint = m_board->FindModuleByReference( component->GetReference() );
if( footprint == NULL ) // It can be missing in partial designs
continue;
// Explore all pins/pads in component
for( unsigned jj = 0; jj < component->GetNetCount(); jj++ )
{
COMPONENT_NET net = component->GetNet( jj );
padname = net.GetPinName();
if( footprint->FindPadByName( padname ) )
continue; // OK, pad found
// not found: bad footprint, report error
msg.Printf( _( "Component %s pad %s not found in footprint %s\n" ),
GetChars( component->GetReference() ),
GetChars( padname ),
GetChars( footprint->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_ERROR );
m_errorCount ++;
}
}
// Test copper zones to detect "dead" nets (nets without any pad):
for( int i = 0; i < m_board->GetAreaCount(); i++ )
{
ZONE_CONTAINER* zone = m_board->GetArea( i );
if( !zone->IsOnCopperLayer() || zone->GetIsKeepout() )
continue;
int nc = zone->GetNet()->GetNodesCount();
if( nc == 0 )
{
msg.Printf( _( "Copper zone (net name %s): net has no pads connected." ),
GetChars( zone->GetNet()->GetNetname() ) );
m_reporter->Report( msg, REPORTER::RPT_WARNING );
m_warningCount ++;
}
}
return true;
}
bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
{
wxString msg;
m_errorCount = 0;
m_warningCount = 0;
if( !m_isDryRun )
{
m_board->SetStatus( 0 );
}
for( int i = 0; i < (int) aNetlist.GetCount(); i++ )
{
COMPONENT* component = aNetlist.GetComponent( i );
MODULE *footprint = NULL;
msg.Printf( _( "Processing component \"%s:%s:%s\".\n" ),
GetChars( component->GetReference() ),
GetChars( component->GetTimeStamp() ),
GetChars( component->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if( aNetlist.IsFindByTimeStamp() )
footprint = m_board->FindModule( component->GetTimeStamp(), true );
else
footprint = m_board->FindModule( component->GetReference() );
if( footprint ) // An existing footprint.
{
MODULE *newFootprint = replaceComponent ( aNetlist, footprint, component );
if ( newFootprint )
footprint = newFootprint;
}
else
{
footprint = addNewComponent( component );
}
if( footprint )
{
updateComponentParameters( footprint, component );
updateComponentPadConnections( footprint, component );
}
}
//aNetlist.GetDeleteExtraFootprints()
if( m_deleteUnusedComponents )
deleteUnusedComponents( aNetlist );
if( m_deleteSinglePadNets )
deleteSinglePadNets();
if ( !m_isDryRun )
{
m_frame->SaveCopyInUndoList( *m_undoList, UR_UNSPECIFIED, wxPoint(0, 0) );
m_frame->OnModify();
}
// Update the ratsnest
m_board->GetRatsnest()->ProcessBoard();
testConnectivity( aNetlist );
m_reporter->Report( _(""), REPORTER::RPT_ACTION );
m_reporter->Report( _(""), REPORTER::RPT_ACTION );
msg.Printf( _( "Total warnings: %d, errors: %d." ),
m_warningCount, m_errorCount );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
if ( m_errorCount )
{
m_reporter->Report( _("Errors occured during the netlist update. Unless you "
"fix them, your board will not be consistent with the schematics." ),
REPORTER::RPT_ERROR );
return false;
} else {
m_reporter->Report( _("Netlist update successful!" ),
REPORTER::RPT_ACTION );
}
return true;
}
bool BOARD_NETLIST_UPDATER::UpdateNetlist( const wxString& aNetlistFileName,
const wxString& aCmpFileName )
{
return false;
}

View File

@ -0,0 +1,160 @@
/**
* @file board_netlist_updater.h
* @brief BOARD_NETLIST_UPDATER class definition
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 CERN
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
*
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 __BOARD_NETLIST_UPDATER_H
#define __BOARD_NETLIST_UPDATER_H
class BOARD;
class REPORTER;
class NETLIST;
class COMPONENT;
class MODULE;
class PICKED_ITEMS_LIST;
class PCB_EDIT_FRAME;
#include <class_undoredo_container.h>
/**
* Class BOARD_NETLIST_UPDATER
* updates the #BOARD with a new netlist.
*
* The changes are made to the board are as follows they are not disabled in the status
* settings in the #NETLIST:
* - If a new component is found in the #NETLIST and not in the #BOARD, it is added
* to the #BOARD.
* - If a the component in the #NETLIST is already on the #BOARD, then one or more of the
* following actions can occur:
* + If the footprint name in the #NETLIST does not match the footprint name on the
* #BOARD, the footprint on the #BOARD is replaced with the footprint specified in
* the #NETLIST and the proper parameters are copied from the existing footprint.
* + If the reference designator in the #NETLIST does not match the reference designator
* on the #BOARD, the reference designator is updated from the #NETLIST.
* + If the value field in the #NETLIST does not match the value field on the #BOARD,
* the value field is updated from the #NETLIST.
* + If the time stamp in the #NETLIST does not match the time stamp on the #BOARD,
* the time stamp is updated from the #NETLIST.
* - After each footprint is added or update as described above, each footprint pad net
* name is compared and updated to the value defined in the #NETLIST.
* - After all of the footprints have been added, updated, and net names properly set,
* any extra unlock footprints are removed from the #BOARD.
*
*/
class BOARD_NETLIST_UPDATER
{
public:
BOARD_NETLIST_UPDATER( PCB_EDIT_FRAME *aFrame, BOARD *aBoard );
~BOARD_NETLIST_UPDATER();
/**
* Function UpdateNetlist()
*
* Updates the board's components according to the new netlist.
* See BOARD_NETLIST_UPDATER class description for the details of the process.
* @param aNetlist the new netlist
* @return true if process was completed successfully
*/
bool UpdateNetlist( NETLIST& aNetlist );
// @todo: implement and move NETLIST::ReadPcbNetlist here
bool UpdateNetlist( const wxString& aNetlistFileName,
const wxString& aCmpFileName );
///> Sets the reporter object
void SetReporter ( REPORTER *aReporter )
{
m_reporter = aReporter;
}
///> Enables "delete single pad nets" option
void SetDeleteSinglePadNets( bool aEnabled )
{
m_deleteSinglePadNets = aEnabled;
}
///> Enables dry run mode (just report, no changes to PCB)
void SetIsDryRun ( bool aEnabled )
{
m_isDryRun = aEnabled;
}
///> Enables replacing footprints with new ones
void SetReplaceFootprints ( bool aEnabled )
{
m_replaceFootprints = aEnabled;
}
///> Enables removing unused components
void SetDeleteUnusedComponents ( bool aEnabled )
{
m_deleteUnusedComponents = aEnabled;
}
///> Enables component lookup by timestamp instead of reference
void SetLookupByTimestamp ( bool aEnabled )
{
m_lookupByTimestamp = aEnabled;
}
private:
void pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType );
wxPoint estimateComponentInsertionPosition();
MODULE* addNewComponent( COMPONENT* aComponent );
MODULE* replaceComponent( NETLIST& aNetlist, MODULE *aPcbComponent, COMPONENT* aNewComponent );
bool updateComponentParameters( MODULE *aPcbComponent, COMPONENT* aNewComponent );
bool updateComponentPadConnections( MODULE *aPcbComponent, COMPONENT* aNewComponent );
bool deleteUnusedComponents( NETLIST& aNetlist );
bool deleteSinglePadNets();
bool testConnectivity( NETLIST& aNetlist );
PICKED_ITEMS_LIST *m_undoList;
PCB_EDIT_FRAME *m_frame;
BOARD *m_board;
REPORTER *m_reporter;
bool m_deleteSinglePadNets;
bool m_deleteUnusedComponents;
bool m_isDryRun;
bool m_replaceFootprints;
bool m_lookupByTimestamp;
int m_warningCount;
int m_errorCount;
};
#endif

View File

@ -24,6 +24,9 @@
#include <collectors.h>
#include <pcbnew.h>
#include <netlist_reader.h>
#include <pcb_netlist.h>
#include <dialogs/dialog_update_pcb.h>
#include <tools/common_actions.h>
#include <tool/tool_manager.h>
@ -243,6 +246,28 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
ExecuteRemoteCommand( payload.c_str() );
break;
case MAIL_SCH_PCB_UPDATE:
{
NETLIST netlist;
try {
STRING_LINE_READER* lineReader = new STRING_LINE_READER( payload, _( "EEschema netlist" ) );
KICAD_NETLIST_READER netlistReader( lineReader, &netlist );
netlistReader.LoadNetlist();
}
catch( const IO_ERROR& ioe )
{
assert( false ); // should never happen
}
DIALOG_UPDATE_PCB updateDialog( this, &netlist );
updateDialog.PerformUpdate( true );
updateDialog.ShowModal();
break;
}
// many many others.
default:
;

View File

@ -0,0 +1,110 @@
#include <common.h>
#include <wxPcbStruct.h>
#include <pcb_netlist.h>
#include <dialog_update_pcb.h>
#include <wx_html_report_panel.h>
#include <board_netlist_updater.h>
#include <tool/tool_manager.h>
#include <tools/common_actions.h>
#include <class_draw_panel_gal.h>
#include <class_board.h>
#include <ratsnest_data.h>
#include <boost/bind.hpp>
DIALOG_UPDATE_PCB::DIALOG_UPDATE_PCB( PCB_EDIT_FRAME* aParent, NETLIST *aNetlist ) :
DIALOG_UPDATE_PCB_BASE ( aParent ),
m_frame (aParent),
m_netlist (aNetlist)
{
m_messagePanel->SetLabel( _("Changes to be applied:") );
m_messagePanel->SetLazyUpdate ( true );
m_netlist->SortByReference();
m_btnPerformUpdate->SetFocus();
m_messagePanel->SetVisibleSeverities( REPORTER::RPT_WARNING | REPORTER::RPT_ERROR | REPORTER::RPT_ACTION );
}
DIALOG_UPDATE_PCB::~DIALOG_UPDATE_PCB()
{
}
void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
{
m_messagePanel->Clear();
REPORTER &reporter = m_messagePanel->Reporter();
KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView();
TOOL_MANAGER *toolManager = m_frame->GetToolManager();
BOARD *board = m_frame->GetBoard();
if( !aDryRun )
{
// Remove old modules
for( MODULE* module = board->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
view->Remove( module );
}
// Clear selection, just in case a selected item has to be removed
toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
}
m_frame->LoadFootprints( *m_netlist, &reporter );
BOARD_NETLIST_UPDATER updater( m_frame, m_frame->GetBoard() );
updater.SetReporter ( &reporter );
updater.SetIsDryRun( aDryRun);
updater.SetLookupByTimestamp( true );
updater.SetDeleteUnusedComponents ( true );
updater.SetReplaceFootprints( true );
updater.SetDeleteSinglePadNets ( false );
updater.UpdateNetlist( *m_netlist );
m_messagePanel->Flush();
if( aDryRun )
return;
m_frame->OnModify();
m_frame->SetCurItem( NULL );
// Reload modules
for( MODULE* module = board->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
view->Add( module );
module->ViewUpdate();
}
// Rebuild the board connectivity:
if( m_frame->IsGalCanvasActive() )
board->GetRatsnest()->ProcessBoard();
m_frame->Compile_Ratsnest( NULL, true );
m_frame->SetMsgPanel( board );
}
void DIALOG_UPDATE_PCB::OnMatchChange( wxCommandEvent& event )
{
}
void DIALOG_UPDATE_PCB::OnCancelClick( wxCommandEvent& event )
{
EndModal( wxID_CANCEL );
}
void DIALOG_UPDATE_PCB::OnUpdateClick( wxCommandEvent& event )
{
m_messagePanel->SetLabel( _("Changes applied to the PCB:") );
PerformUpdate( false );
m_btnCancel->SetFocus( );
}

View File

@ -0,0 +1,661 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="13" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_update_pcb_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="internationalize">1</property>
<property name="name">dialog_update_pcb_base</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">800,700</property>
<property name="name">DIALOG_UPDATE_PCB_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Update PCB from Schematics</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnAuiFindManager"></event>
<event name="OnAuiPaneButton"></event>
<event name="OnAuiPaneClose"></event>
<event name="OnAuiPaneMaximize"></event>
<event name="OnAuiPaneRestore"></event>
<event name="OnAuiRender"></event>
<event name="OnChar"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bMainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxFlexGridSizer" expanded="1">
<property name="cols">3</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">fgSizer2</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="rows">0</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Match components by:</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxRadioButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Reference</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_matchByReference</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRadioButton">OnMatchChange</event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxRadioButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Timestamp</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_matchByTimestamp</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRadioButton">OnMatchChange</event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bLowerSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">1</property>
<object class="wxPanel" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-300,150</property>
<property name="moveable">1</property>
<property name="name">m_messagePanel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">WX_HTML_REPORT_PANEL; wx_html_report_panel.h</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxFlexGridSizer" expanded="1">
<property name="cols">5</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">0</property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">fgSizer1</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="rows">1</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_CANCEL</property>
<property name="label">Close</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_btnCancel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnCancelClick</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Perform PCB Update</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_btnPerformUpdate</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnUpdateClick</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@ -0,0 +1,56 @@
/**
* @file pcbnew/dialogs/dialog_update_pcb.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 _DIALOG_UPDATE_PCB_H_
#define _DIALOG_UPDATE_PCB_H_
#include <dialog_update_pcb_base.h>
class NETLIST;
class PCB_EDIT_FRAME;
class DIALOG_UPDATE_PCB : public DIALOG_UPDATE_PCB_BASE
{
private:
PCB_EDIT_FRAME* m_frame;
NETLIST *m_netlist;
public:
DIALOG_UPDATE_PCB( PCB_EDIT_FRAME* aParent, NETLIST *aNetlist );
~DIALOG_UPDATE_PCB();
void PerformUpdate( bool aDryRun );
private:
virtual void OnMatchChange( wxCommandEvent& event );
virtual void OnCancelClick( wxCommandEvent& event );
virtual void OnUpdateClick( wxCommandEvent& event );
};
#endif

View File

@ -0,0 +1,85 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 6 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "wx_html_report_panel.h"
#include "dialog_update_pcb_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_UPDATE_PCB_BASE::DIALOG_UPDATE_PCB_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( 800,700 ), wxDefaultSize );
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgSizer2;
fgSizer2 = new wxFlexGridSizer( 0, 3, 0, 0 );
fgSizer2->SetFlexibleDirection( wxBOTH );
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText1 = new wxStaticText( this, wxID_ANY, _("Match components by:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText1->Wrap( -1 );
fgSizer2->Add( m_staticText1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_matchByReference = new wxRadioButton( this, wxID_ANY, _("Reference"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_matchByReference, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_matchByTimestamp = new wxRadioButton( this, wxID_ANY, _("Timestamp"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_matchByTimestamp, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bMainSizer->Add( fgSizer2, 0, wxEXPAND|wxALL, 5 );
wxBoxSizer* bLowerSizer;
bLowerSizer = new wxBoxSizer( wxVERTICAL );
m_messagePanel = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_messagePanel->SetMinSize( wxSize( -300,150 ) );
bLowerSizer->Add( m_messagePanel, 1, wxEXPAND | wxALL, 5 );
bMainSizer->Add( bLowerSizer, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 1, 5, 0, 0 );
fgSizer1->AddGrowableCol( 0 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_btnCancel = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_btnCancel, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
m_btnPerformUpdate = new wxButton( this, wxID_ANY, _("Perform PCB Update"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_btnPerformUpdate, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
bMainSizer->Add( fgSizer1, 0, wxEXPAND, 5 );
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
// Connect Events
m_matchByReference->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnMatchChange ), NULL, this );
m_matchByTimestamp->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnMatchChange ), NULL, this );
m_btnCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnCancelClick ), NULL, this );
m_btnPerformUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnUpdateClick ), NULL, this );
}
DIALOG_UPDATE_PCB_BASE::~DIALOG_UPDATE_PCB_BASE()
{
// Disconnect Events
m_matchByReference->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnMatchChange ), NULL, this );
m_matchByTimestamp->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnMatchChange ), NULL, this );
m_btnCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnCancelClick ), NULL, this );
m_btnPerformUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_PCB_BASE::OnUpdateClick ), NULL, this );
}

View File

@ -0,0 +1,60 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 6 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_UPDATE_PCB_BASE_H__
#define __DIALOG_UPDATE_PCB_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class DIALOG_SHIM;
class WX_HTML_REPORT_PANEL;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/radiobut.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_UPDATE_PCB_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_UPDATE_PCB_BASE : public DIALOG_SHIM
{
private:
protected:
wxStaticText* m_staticText1;
wxRadioButton* m_matchByReference;
wxRadioButton* m_matchByTimestamp;
WX_HTML_REPORT_PANEL* m_messagePanel;
wxButton* m_btnCancel;
wxButton* m_btnPerformUpdate;
// Virtual event handlers, overide them in your derived class
virtual void OnMatchChange( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnUpdateClick( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_UPDATE_PCB_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Update PCB from Schematics"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_UPDATE_PCB_BASE();
};
#endif //__DIALOG_UPDATE_PCB_BASE_H__