← Back to team overview

kicad-developers team mailing list archive

[RFC PATCH] Single-click board update, take 2.

 

Dear all,

This patchset contains an updated version of the single-click SCH->PCB
update tool.

The way it works is:
- press F9 (or select Tools->Update PCB From Schematics) in eeschema or
pcbnew
- a window with changes to be applied to PCB will appear
- you can check for errors/warnings/review what is going to be changed
- click "Perform PCB update" or press Enter to proceed (or cancel).
- netlist updates can be undone (Ctrl-Z restores PCB state after wrong
netlist load).

The changes since the previous version are:
- automatic spreading of the new footprints outside board area,
- fixed undo-related crashes,
- the tool can be now invoked both from the schematics & PCB editor.
- pcbnew window is now automagically opened the first time user calls
for an update.

Note it will only work when Kicad is opened in Project Manager mode.

Thanks in advance for testing & comments,

Cheers,
Tom
>From 56e61c3ea69ffbf0da6d6bd13e9c36cbafeb3ba1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Thu, 21 Jan 2016 23:21:21 +0100
Subject: [PATCH 7/7] One-click PCB updater: fix Python build error & add
 spread footprints

---
 pcbnew/board_netlist_updater.cpp     |  1 +
 pcbnew/board_netlist_updater.h       |  7 +++++++
 pcbnew/dialogs/dialog_update_pcb.cpp | 18 ++++++++++++++++++
 pcbnew/netlist.cpp                   |  3 +--
 pcbnew/scripting/pcbnew.i            |  1 +
 5 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/pcbnew/board_netlist_updater.cpp b/pcbnew/board_netlist_updater.cpp
index 9a90fbf..217f39f 100644
--- a/pcbnew/board_netlist_updater.cpp
+++ b/pcbnew/board_netlist_updater.cpp
@@ -129,6 +129,7 @@ MODULE* BOARD_NETLIST_UPDATER::addNewComponent( COMPONENT* aComponent )
             footprint->SetTimeStamp( GetNewTimeStamp() );
 
             m_board->Add( footprint, ADD_APPEND );
+	    m_addedComponents.push_back( footprint );
 
             pushUndo( footprint, UR_NEW );
 
diff --git a/pcbnew/board_netlist_updater.h b/pcbnew/board_netlist_updater.h
index 0e8a6b0..2070b5d 100644
--- a/pcbnew/board_netlist_updater.h
+++ b/pcbnew/board_netlist_updater.h
@@ -127,6 +127,11 @@ public:
 		m_lookupByTimestamp = aEnabled;
 	}
 
+	std::vector<MODULE *> GetAddedComponents() const
+	{
+		return m_addedComponents;
+	}
+
 private:
 
 	void pushUndo( BOARD_ITEM*    aItem, UNDO_REDO_T    aCommandType );
@@ -145,6 +150,8 @@ private:
 	BOARD *m_board;
 	REPORTER *m_reporter;
 
+	std::vector<MODULE *> m_addedComponents;
+
 	bool m_deleteSinglePadNets;
 	bool m_deleteUnusedComponents;
 	bool m_isDryRun;
diff --git a/pcbnew/dialogs/dialog_update_pcb.cpp b/pcbnew/dialogs/dialog_update_pcb.cpp
index 8515ef0..584549d 100644
--- a/pcbnew/dialogs/dialog_update_pcb.cpp
+++ b/pcbnew/dialogs/dialog_update_pcb.cpp
@@ -84,6 +84,11 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
     if( aDryRun )
         return;
 
+    std::vector<MODULE*> newFootprints = updater.GetAddedComponents();
+
+
+
+
     m_frame->OnModify();
 
     m_frame->SetCurItem( NULL );
@@ -104,8 +109,21 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
 
     m_frame->SetMsgPanel( board );
 
+
+    if( m_frame->IsGalCanvasActive() )
+    {
+        m_frame->SpreadFootprints( &newFootprints, false, false );
+
+        BOOST_FOREACH( MODULE* footprint, newFootprints )
+        {
+            toolManager->RunAction( COMMON_ACTIONS::selectItem, true, footprint );
+        }
+        toolManager->InvokeTool( "pcbnew.InteractiveEdit" );
+    }
+
     m_btnPerformUpdate->Enable( false );
     m_btnPerformUpdate->SetLabel ( _("Update complete") );
+    m_btnCancel->SetLabel ( _("Close") );
     m_btnCancel->SetFocus( );
 }
 
diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp
index 99e7632..51f45fa 100644
--- a/pcbnew/netlist.cpp
+++ b/pcbnew/netlist.cpp
@@ -115,7 +115,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
 
     netlist.SortByReference();
     board->ReplaceNetlist( netlist, aDeleteSinglePadNets, &newFootprints, aReporter );
-   
+
 
     // If it was a dry run, nothing has changed so we're done.
     if( netlist.IsDryRun() )
@@ -329,4 +329,3 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
             component->SetModule( module );
     }
 }
-
diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i
index 4e8c7b4..11af4cc 100644
--- a/pcbnew/scripting/pcbnew.i
+++ b/pcbnew/scripting/pcbnew.i
@@ -39,6 +39,7 @@
 
 // ignore a couple of items that generate warnings from swig built code
 
+%ignore NETINFO_ITEM;
 %ignore BOARD_ITEM::ZeroOffset;
 %ignore D_PAD::m_PadSketchModePenSize;
 
-- 
1.9.1

>From 4d627aa54dcc443ad457ddb605214819acb08314 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Mon, 11 Jan 2016 00:01:31 +0100
Subject: [PATCH 6/7] Fix repetitive undo/redo segfaults & assertions. Added
 Update menu entry on PCB side.

---
 eeschema/cross-probing.cpp       |  8 ++++++++
 eeschema/hotkeys.cpp             |  5 +++--
 eeschema/hotkeys.h               |  4 ++--
 eeschema/menubar.cpp             | 23 ++++++++++-------------
 include/mail_type.h              |  4 +++-
 include/wxPcbStruct.h            |  8 +-------
 pcbnew/board_netlist_updater.cpp | 22 ++++++++++++++--------
 pcbnew/board_netlist_updater.h   |  2 --
 pcbnew/board_undo_redo.cpp       | 31 +++++++++++++++++++++++++------
 pcbnew/class_board.cpp           | 12 ++++++++++--
 pcbnew/class_module.cpp          |  1 +
 pcbnew/class_netinfo.h           |  2 +-
 pcbnew/class_netinfolist.cpp     |  4 +++-
 pcbnew/menubar_pcbframe.cpp      |  8 ++++++++
 pcbnew/pcbframe.cpp              | 35 ++++++++++++++++++++++++++++++++++-
 pcbnew/pcbnew_id.h               |  1 +
 pcbnew/tools/drawing_tool.cpp    |  2 +-
 17 files changed, 125 insertions(+), 47 deletions(-)

diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp
index f9b67e7..a0b31a2 100644
--- a/eeschema/cross-probing.cpp
+++ b/eeschema/cross-probing.cpp
@@ -197,6 +197,14 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
         ExecuteRemoteCommand( payload.c_str() );
         break;
 
+    case MAIL_SCH_PCB_UPDATE_REQUEST:
+    {
+        wxCommandEvent dummy;
+
+        OnUpdatePCB ( dummy );
+        break;
+    }
+
     case MAIL_BACKANNOTATE_FOOTPRINTS:
         try
         {
diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp
index b69cb87..5308754 100644
--- a/eeschema/hotkeys.cpp
+++ b/eeschema/hotkeys.cpp
@@ -225,6 +225,7 @@ static EDA_HOTKEY HkAutoplaceFields( _HKI( "Autoplace Fields" ), HK_AUTOPLACE_FI
 
 static EDA_HOTKEY HkUpdatePcbFromSch( _HKI( "Update PCB from Schematics" ), HK_UPDATE_PCB_FROM_SCH, WXK_F9 );
 
+
 // List of common hotkey descriptors
 static EDA_HOTKEY* common_Hotkey_List[] =
 {
@@ -297,9 +298,9 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
     &HkAddBusEntry,
     &HkAddGraphicPolyLine,
     &HkAddGraphicText,
-    &HkLeaveSheet,
     &HkUpdatePcbFromSch,
     &HkAutoplaceFields,
+    &HkLeaveSheet,
     &HkDeleteNode,
     NULL
 };
@@ -345,7 +346,7 @@ struct EDA_HOTKEY_CONFIG g_Eeschema_Hokeys_Descr[] =
 struct EDA_HOTKEY_CONFIG g_Schematic_Hokeys_Descr[] =
 {
     { &g_CommonSectionTag,    common_Hotkey_List,    &commonSectionTitle    },
-    { &schematicSectionTag,   schematic_Hotkey_List, &schematicSectionTitle },
+    { &schematicSectionTag, schematic_Hotkey_List, &schematicSectionTitle },
     { NULL,                   NULL,                  NULL }
 };
 
diff --git a/eeschema/hotkeys.h b/eeschema/hotkeys.h
index 4963fa8..926288c 100644
--- a/eeschema/hotkeys.h
+++ b/eeschema/hotkeys.h
@@ -78,9 +78,9 @@ enum hotkey_id_commnand {
     HK_LEFT_CLICK,
     HK_LEFT_DCLICK,
     HK_LEAVE_SHEET,
-    HK_UPDATE_PCB_FROM_SCH,
+    HK_DELETE_NODE,
     HK_AUTOPLACE_FIELDS,
-    HK_DELETE_NODE
+    HK_UPDATE_PCB_FROM_SCH
 };
 
 // List of hotkey descriptors for Eeschema
diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp
index a6a7455..ba88ad4 100644
--- a/eeschema/menubar.cpp
+++ b/eeschema/menubar.cpp
@@ -119,7 +119,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
                  _( "Save only current schematic sheet" ),
                  KiBitmap( save_xpm ) );
 
-
     if( Kiface().IsSingle() )   // not when under a project mgr
     {
         AddMenuItem( fileMenu,
@@ -430,15 +429,18 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
 
     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,
                  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,
+                 ID_RUN_PCB,
+                 _( "&Open PCB Editor" ),
+                 _( "Run Pcbnew" ),
+                 KiBitmap( pcbnew_xpm ) );
 
-    //if( Kiface().IsSingle() || !pcbFrame )   FIXME: refresh
-        //updItem->Enable( false );
 
     toolsMenu->AppendSeparator();
 
@@ -489,16 +491,11 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
     // Run CvPcb
     AddMenuItem( toolsMenu,
                  ID_RUN_CVPCB,
-                 _( "A&ssign Component Footprint" ),
+                 _( "A&ssign Component Footprints" ),
                  _( "Run CvPcb" ),
                  KiBitmap( cvpcb_xpm ) );
 
-    // Run Pcbnew
-    AddMenuItem( toolsMenu,
-                 ID_RUN_PCB,
-                 _( "&Layout Printed Circuit Board" ),
-                 _( "Run Pcbnew" ),
-                 KiBitmap( pcbnew_xpm ) );
+
 
     // Help Menu:
     wxMenu* helpMenu = new wxMenu;
diff --git a/include/mail_type.h b/include/mail_type.h
index 57ca1a4..c55ef66 100644
--- a/include/mail_type.h
+++ b/include/mail_type.h
@@ -39,7 +39,9 @@ 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
+    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_
diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h
index fd4b8f3..8e99e31 100644
--- a/include/wxPcbStruct.h
+++ b/include/wxPcbStruct.h
@@ -91,8 +91,6 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
 
 
 protected:
-    bool m_undoDisabled;
-
     PCB_LAYER_WIDGET* m_Layers;
 
     DRC* m_drc;                                 ///< the DRC controller, see drc.cpp
@@ -230,11 +228,6 @@ public:
         throw( IO_ERROR, PARSE_ERROR );
 
 
-    void DisableUndo (bool aDisable = true)
-    {
-        m_undoDisabled = aDisable;
-    }
-
     void OnQuit( wxCommandEvent& event );
 
     /**
@@ -290,6 +283,7 @@ public:
     void OnUpdateMuWaveToolbar( wxUpdateUIEvent& aEvent );
     void OnLayerColorChange( wxCommandEvent& aEvent );
     void OnConfigurePaths( wxCommandEvent& aEvent );
+    void OnUpdatePCBFromSch( wxCommandEvent& event );
 
     /**
      * Function RecordMacros.
diff --git a/pcbnew/board_netlist_updater.cpp b/pcbnew/board_netlist_updater.cpp
index 0559baa..9a90fbf 100644
--- a/pcbnew/board_netlist_updater.cpp
+++ b/pcbnew/board_netlist_updater.cpp
@@ -64,7 +64,12 @@ BOARD_NETLIST_UPDATER::~BOARD_NETLIST_UPDATER ()
 
 void BOARD_NETLIST_UPDATER::pushUndo( BOARD_ITEM*    aItem, UNDO_REDO_T    aCommandType )
 {
-    m_undoList->PushItem( ITEM_PICKER( aItem, aCommandType ) );
+    ITEM_PICKER picker( aItem, aCommandType );
+
+    if( aCommandType == UR_CHANGED )
+        picker.SetLink ( aItem->Clone() );
+
+    m_undoList->PushItem( picker );
 }
 
 wxPoint BOARD_NETLIST_UPDATER::estimateComponentInsertionPosition()
@@ -192,7 +197,7 @@ MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE *aPcb
             else
                 newFootprint->SetPath( aPcbComponent->GetPath() );
 
-            aPcbComponent->CopyNetlistSettings( newFootprint );
+            aPcbComponent->CopyNetlistSettings( newFootprint, false );
             m_board->Remove( aPcbComponent );
             m_board->Add( newFootprint, ADD_APPEND );
 
@@ -231,7 +236,8 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
     if( !aPcbComponent )
         return false;
 
-    pushUndo ( aPcbComponent, UR_CHANGED );
+    if ( !m_isDryRun )
+        pushUndo ( aPcbComponent, UR_CHANGED );
 
     // Test for reference designator field change.
     if( aPcbComponent->GetReference() != aNewComponent->GetReference() )
@@ -320,7 +326,6 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
 
             if( !m_isDryRun )
             {
-                pushUndo( pad, UR_CHANGED );
                 pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
             }
         }
@@ -375,7 +380,6 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
 
                 if ( !m_isDryRun )
                 {
-                    pushUndo( pad, UR_CHANGED );
                     pad->SetNetCode( netinfo->GetNet() );
                 }
             }
@@ -417,7 +421,7 @@ bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
             if( !m_isDryRun )
             {
                 pushUndo( module, UR_DELETED );
-                module->DeleteStructure();
+                m_board->Remove ( module );
             }
         }
     }
@@ -488,7 +492,7 @@ bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
                                 GetChars( previouspad->GetPadName() ) );
                     m_reporter->Report( msg, REPORTER::RPT_ACTION );
 
-                    pushUndo( previouspad, UR_CHANGED );
+                    //pushUndo( previouspad, UR_CHANGED );
                     previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
                 }
             }
@@ -507,7 +511,7 @@ bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
     // Examine last pad
     if( pad && count == 1 )
     {
-        pushUndo( pad, UR_CHANGED );
+        //pushUndo( pad, UR_CHANGED );
         pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
     }
     return true;
@@ -584,6 +588,7 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
     m_errorCount = 0;
     m_warningCount = 0;
 
+
     if( !m_isDryRun )
     {
         m_board->SetStatus( 0 );
@@ -643,6 +648,7 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
     }
 
     // Update the ratsnest
+    m_frame->Compile_Ratsnest( NULL, true );
     m_board->GetRatsnest()->ProcessBoard();
 
     testConnectivity( aNetlist );
diff --git a/pcbnew/board_netlist_updater.h b/pcbnew/board_netlist_updater.h
index 9d06952..0e8a6b0 100644
--- a/pcbnew/board_netlist_updater.h
+++ b/pcbnew/board_netlist_updater.h
@@ -156,5 +156,3 @@ private:
 };
 
 #endif
-
-
diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp
index fe6e25e..16ac356 100644
--- a/pcbnew/board_undo_redo.cpp
+++ b/pcbnew/board_undo_redo.cpp
@@ -116,6 +116,7 @@
  * @param aItem = item to find
  *              = NULL to build the list of existing items
  */
+
 static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
 {
     static std::vector<BOARD_ITEM*> itemsList;
@@ -448,7 +449,10 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
              * If this link is not null, the copy is already done
              */
             if( commandToUndo->GetPickedItemLink( ii ) == NULL )
-                commandToUndo->SetPickedItemLink( item->Clone(), ii );
+            {
+                EDA_ITEM *cloned = item->Clone();
+                commandToUndo->SetPickedItemLink( cloned, ii );
+            }
             break;
 
         case UR_MOVED:
@@ -492,6 +496,8 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
     BOARD_ITEM* item;
     bool        not_found = false;
     bool        reBuild_ratsnest = false;
+    bool        deep_reBuild_ratsnest = false;
+
     KIGFX::VIEW* view = GetGalCanvas()->GetView();
     RN_DATA* ratsnest = GetBoard()->GetRatsnest();
 
@@ -545,10 +551,17 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
             reBuild_ratsnest = true;
             break;
 
+        case PCB_NETINFO_T:
+            reBuild_ratsnest = true;
+            deep_reBuild_ratsnest = true;
+
+            break;
+
         default:
             break;
         }
 
+
         switch( aList->GetPickedItemStatus( ii ) )
         {
         case UR_CHANGED:    /* Exchange old and new data for each item */
@@ -584,6 +597,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
 
         case UR_NEW:        /* new items are deleted */
             aList->SetPickedItemStatus( UR_DELETED, ii );
+
             GetBoard()->Remove( item );
 
             if( item->Type() == PCB_MODULE_T )
@@ -592,7 +606,6 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
                 module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
             }
             view->Remove( item );
-
             item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
             break;
 
@@ -652,12 +665,18 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
         wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) );
 
     // Rebuild pointers and ratsnest that can be changed.
-    if( reBuild_ratsnest && aRebuildRatsnet )
+    if( reBuild_ratsnest ) //&& aRebuildRatsnet )
     {
+        Compile_Ratsnest( NULL, true );
+
         if( IsGalCanvasActive() )
-            ratsnest->Recalculate();
-        else
-            Compile_Ratsnest( NULL, true );
+        {
+            if (deep_reBuild_ratsnest)
+                ratsnest->ProcessBoard();
+            else
+                ratsnest->Recalculate();
+        }
+
     }
 }
 
diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
index 44917d4..e1bedcf 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -673,9 +673,14 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
     switch( aBoardItem->Type() )
     {
     case PCB_NETINFO_T:
+    {
+        NETINFO_ITEM *item = (NETINFO_ITEM*) aBoardItem;
         aBoardItem->SetParent ( this );
         m_NetInfo.AppendNet ( (NETINFO_ITEM*) aBoardItem );
 
+        break;
+    }
+
     // this one uses a vector
     case PCB_MARKER_T:
         aBoardItem->SetParent( this );
@@ -764,9 +769,12 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
     switch( aBoardItem->Type() )
     {
     case PCB_NETINFO_T:
-        m_NetInfo.RemoveNet ( (NETINFO_ITEM*) aBoardItem );
-        break;
+    {
+        NETINFO_ITEM *item = (NETINFO_ITEM*) aBoardItem;
+        m_NetInfo.RemoveNet ( item );
 
+        break;
+    }
     case PCB_MARKER_T:
 
         // find the item in the vector, then remove it
diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp
index 4b6c889..2e44bd8 100644
--- a/pcbnew/class_module.cpp
+++ b/pcbnew/class_module.cpp
@@ -115,6 +115,7 @@ MODULE::MODULE( const MODULE& aModule ) :
     for( D_PAD* pad = aModule.m_Pads;  pad;  pad = pad->Next() )
     {
         D_PAD* newpad = new D_PAD( *pad );
+        assert (newpad->GetNet() == pad->GetNet());
         newpad->SetParent( this );
         m_Pads.PushBack( newpad );
     }
diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h
index 635ce86..d3d9f98 100644
--- a/pcbnew/class_netinfo.h
+++ b/pcbnew/class_netinfo.h
@@ -297,7 +297,7 @@ public:
      */
     void AppendNet( NETINFO_ITEM* aNewElement );
 
-	
+
     /**
      * Function RemoveNet
      * Removes a new from the net list.
diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp
index 6b66cfa..9280b14 100644
--- a/pcbnew/class_netinfolist.cpp
+++ b/pcbnew/class_netinfolist.cpp
@@ -88,6 +88,8 @@ void NETINFO_LIST::RemoveNet( NETINFO_ITEM* aNet )
             break;
         }
     }
+
+    m_newNetCode = std::min(m_newNetCode, aNet->m_NetCode - 1);
 }
 
 
@@ -319,4 +321,4 @@ NETINFO_ITEM* NETINFO_MAPPING::iterator::operator->() const
 const int NETINFO_LIST::UNCONNECTED = 0;
 const int NETINFO_LIST::ORPHANED = -1;
 
-NETINFO_ITEM NETINFO_LIST::ORPHANED_ITEM = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED );
\ No newline at end of file
+NETINFO_ITEM NETINFO_LIST::ORPHANED_ITEM = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED );
diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp
index 3d4dd41..c79866b 100644
--- a/pcbnew/menubar_pcbframe.cpp
+++ b/pcbnew/menubar_pcbframe.cpp
@@ -605,6 +605,14 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     //----- Tools menu ----------------------------------------------------------
     wxMenu* toolsMenu = new wxMenu;
 
+    wxMenuItem *updItem = 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,
                  _( "&Netlist" ),
                  _( "Read the netlist and update board connectivity" ),
diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp
index adc68a7..a771914 100644
--- a/pcbnew/pcbframe.cpp
+++ b/pcbnew/pcbframe.cpp
@@ -70,6 +70,8 @@
 #include <tool/tool_dispatcher.h>
 #include <tools/common_actions.h>
 
+#include <wildcards_and_files_ext.h>
+
 #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON)
 #include <python_scripting.h>
 #endif
@@ -232,6 +234,8 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
     EVT_TOOL( ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE,
                     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,
                     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,
         wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME )
 {
-    m_undoDisabled = false;
     m_showBorderAndTitleBlock = true;   // true to display sheet references
     m_showAxis = false;                 // true to display X and Y axis
     m_showOriginAxis = true;
@@ -1081,3 +1084,33 @@ void PCB_EDIT_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
 {
     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
+            );
+
+    }
+}
diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h
index 3578126..3862896 100644
--- a/pcbnew/pcbnew_id.h
+++ b/pcbnew/pcbnew_id.h
@@ -393,6 +393,7 @@ enum pcbnew_ids
     ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
     ID_FOOTPRINT_WIZARD_EXPORT_TO_BOARD,
 
+    ID_UPDATE_PCB_FROM_SCH,
     ID_PCBNEW_END_LIST
 };
 
diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp
index 17ce79e..eb73489 100644
--- a/pcbnew/tools/drawing_tool.cpp
+++ b/pcbnew/tools/drawing_tool.cpp
@@ -357,7 +357,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
 
                         m_view->Add( dimension );
                         m_board->Add( dimension );
-                        dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+                        //dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
 
                         m_frame->OnModify();
                         m_frame->SaveCopyInUndoList( dimension, UR_NEW );
-- 
1.9.1

>From 3d9821022c05fb96347efe84e70108f8aa6954c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Mon, 6 Jul 2015 11:00:24 +0200
Subject: [PATCH 5/7] PCB updater: open PCBnew automagically, minor fixes to
 the dialog

---
 eeschema/menubar.cpp                 |  3 +--
 eeschema/schframe.cpp                | 31 +++++++++++++++++++++++++++++++
 pcbnew/dialogs/dialog_update_pcb.cpp |  3 +++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp
index 5c934c4..a6a7455 100644
--- a/eeschema/menubar.cpp
+++ b/eeschema/menubar.cpp
@@ -430,10 +430,9 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
 
     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." ),
+                 text, _( "Updates the PCB design with the current schematic (forward annotation)." ),
                  KiBitmap( libedit_xpm ) );
 
     KIWAY_PLAYER* pcbFrame = Kiway().Player( FRAME_PCB, false );  // test open already.
diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp
index ca81854..28b06eb 100644
--- a/eeschema/schframe.cpp
+++ b/eeschema/schframe.cpp
@@ -823,6 +823,37 @@ void SCH_EDIT_FRAME::OnErc( wxCommandEvent& event )
 
 void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event )
 {
+    wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );
+
+    fn.SetExt( PcbFileExtension );
+
+    if( Kiface().IsSingle() )
+    {
+		DisplayError( this,  _( "Cannot update the PCB, because the Schematic Editor 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_PCB, true );
+
+        // a pcb frame can be already existing, but not yet used.
+        // this is the case when running the footprint editor, or the footprint viewer first
+        // if the frame is not visible, the board is not yet loaded
+        if( !frame->IsVisible() )
+        {
+            frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
+            frame->Show( true );
+        }
+
+        // On Windows, Raise() does not bring the window on screen, when iconized
+        if( frame->IsIconized() )
+            frame->Iconize( false );
+
+        frame->Raise();
+    }
+
     NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
 
     NETLIST_EXPORTER_KICAD exporter( net_atoms, Prj().SchLibs() );
diff --git a/pcbnew/dialogs/dialog_update_pcb.cpp b/pcbnew/dialogs/dialog_update_pcb.cpp
index 640016b..8515ef0 100644
--- a/pcbnew/dialogs/dialog_update_pcb.cpp
+++ b/pcbnew/dialogs/dialog_update_pcb.cpp
@@ -104,6 +104,9 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
 
     m_frame->SetMsgPanel( board );
 
+    m_btnPerformUpdate->Enable( false );
+    m_btnPerformUpdate->SetLabel ( _("Update complete") );
+    m_btnCancel->SetFocus( );
 }
 
 void DIALOG_UPDATE_PCB::OnMatchChange( wxCommandEvent& event )
-- 
1.9.1

>From 58f150d1b163a97f4d9617a82e97d7dc1b2e4fa2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Mon, 22 Jun 2015 17:50:01 +0200
Subject: [PATCH 4/7] set up netlist footprint loader before attempting pcb
 update...

---
 pcbnew/dialogs/dialog_update_pcb.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/pcbnew/dialogs/dialog_update_pcb.cpp b/pcbnew/dialogs/dialog_update_pcb.cpp
index b8d34e9..640016b 100644
--- a/pcbnew/dialogs/dialog_update_pcb.cpp
+++ b/pcbnew/dialogs/dialog_update_pcb.cpp
@@ -52,6 +52,11 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
         toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
     }
 
+    m_netlist->SetDeleteExtraFootprints( true );
+    m_netlist->SetFindByTimeStamp( m_matchByTimestamp->GetValue() );
+    m_netlist->SetReplaceFootprints( true );
+
+
     try {
         m_frame->LoadFootprints( *m_netlist, &reporter );
     }
-- 
1.9.1

>From 9d004a42a4383702c3573f114df7d7a05f15a018 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Mon, 22 Jun 2015 01:56:04 +0200
Subject: [PATCH 3/7] pcbnew: support for removing NETINFO_ITEMS from BOARD for
 proper netlist undo

---
 pcbnew/class_board.cpp                | 20 +++++++++-----------
 pcbnew/class_board_connected_item.cpp |  4 ++--
 pcbnew/class_module.cpp               |  2 +-
 pcbnew/class_netinfo.h                | 14 ++++++++++----
 pcbnew/class_netinfolist.cpp          | 26 ++++++++++++++++++++++++--
 pcbnew/dialogs/dialog_update_pcb.cpp  | 15 ++++++++++++---
 6 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
index 14e3c98..44917d4 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -672,6 +672,10 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
 
     switch( aBoardItem->Type() )
     {
+    case PCB_NETINFO_T:
+        aBoardItem->SetParent ( this );
+        m_NetInfo.AppendNet ( (NETINFO_ITEM*) aBoardItem );
+
     // this one uses a vector
     case PCB_MARKER_T:
         aBoardItem->SetParent( this );
@@ -737,11 +741,6 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
         aBoardItem->SetParent( this );
         break;
 
-    case PCB_NETINFO_T:
-        m_NetInfo.AppendNet( (NETINFO_ITEM *) aBoardItem );
-        break;
-
-
     // other types may use linked list
     default:
         {
@@ -764,6 +763,10 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
 
     switch( aBoardItem->Type() )
     {
+    case PCB_NETINFO_T:
+        m_NetInfo.RemoveNet ( (NETINFO_ITEM*) aBoardItem );
+        break;
+
     case PCB_MARKER_T:
 
         // find the item in the vector, then remove it
@@ -812,11 +815,6 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
         m_Drawings.Remove( aBoardItem );
         break;
 
-    case PCB_NETINFO_T:
-        printf("Unimpl! remove netinfo!\n");
-		assert(false);
-        break;
-
     // other types may use linked list
     default:
         wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
@@ -1262,7 +1260,7 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
     wxASSERT( m_NetInfo.GetNetCount() > 0 );    // net zero should exist
 
     if( aNetcode == NETINFO_LIST::UNCONNECTED && m_NetInfo.GetNetCount() == 0 )
-        return &NETINFO_LIST::ORPHANED;
+        return &NETINFO_LIST::ORPHANED_ITEM;
     else
         return m_NetInfo.GetNetItem( aNetcode );
 }
diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp
index 1666674..0843728 100644
--- a/pcbnew/class_board_connected_item.cpp
+++ b/pcbnew/class_board_connected_item.cpp
@@ -35,7 +35,7 @@
 #include <class_board_item.h>
 
 BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
-    BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED ),
+    BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED_ITEM ),
     m_Subnet( 0 ), m_ZoneSubnet( 0 )
 {
 }
@@ -59,7 +59,7 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
     if( ( aNetCode >= 0 ) && board )
         m_netinfo = board->FindNet( aNetCode );
     else
-        m_netinfo = &NETINFO_LIST::ORPHANED;
+        m_netinfo = &NETINFO_LIST::ORPHANED_ITEM;
 
     if( !aNoAssert )
         assert( m_netinfo );
diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp
index b44f8d1..4b6c889 100644
--- a/pcbnew/class_module.cpp
+++ b/pcbnew/class_module.cpp
@@ -186,7 +186,7 @@ void MODULE::ClearAllNets()
     // Force the ORPHANED dummy net info for all pads.
     // ORPHANED dummy net does not depend on a board
     for( D_PAD* pad = Pads(); pad; pad = pad->Next() )
-        pad->SetNetCode( NETINFO_LIST::FORCE_ORPHANED );
+        pad->SetNetCode( NETINFO_LIST::ORPHANED );
 }
 
 
diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h
index efc0409..635ce86 100644
--- a/pcbnew/class_netinfo.h
+++ b/pcbnew/class_netinfo.h
@@ -291,12 +291,18 @@ public:
     unsigned GetNetCount() const { return m_netNames.size(); }
 
     /**
-     * Function Append
-     * adds \a aNewElement to the end of the list. Negative net code means it is going to be
+     * Function AppendNet
+     * adds \a aNewElement to the end of the net list. Negative net code means it is going to be
      * auto-assigned.
      */
     void AppendNet( NETINFO_ITEM* aNewElement );
 
+	
+    /**
+     * Function RemoveNet
+     * Removes a new from the net list.
+     */
+    void RemoveNet( NETINFO_ITEM* aNet );
     /**
      * Function GetPadCount
      * @return the number of pads in board
@@ -348,11 +354,11 @@ public:
 
     ///> Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED
     ///> (typically -1) when calling SetNetCode od board connected items
-    static const int FORCE_ORPHANED;
+    static const int ORPHANED;
 
     ///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no
     ///> board storing net list available.
-    static NETINFO_ITEM ORPHANED;
+    static NETINFO_ITEM ORPHANED_ITEM;
 
 #if defined(DEBUG)
     void Show() const;
diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp
index 74b11bf..6b66cfa 100644
--- a/pcbnew/class_netinfolist.cpp
+++ b/pcbnew/class_netinfolist.cpp
@@ -69,6 +69,28 @@ void NETINFO_LIST::clear()
 }
 
 
+void NETINFO_LIST::RemoveNet( NETINFO_ITEM* aNet )
+{
+    for( NETCODES_MAP::iterator i = m_netCodes.begin(); i != m_netCodes.end(); ++i )
+    {
+        if ( i->second == aNet )
+        {
+            m_netCodes.erase(i);
+            break;
+        }
+    }
+
+    for( NETNAMES_MAP::iterator i = m_netNames.begin(); i != m_netNames.end(); ++i )
+    {
+        if ( i->second == aNet )
+        {
+            m_netNames.erase(i);
+            break;
+        }
+    }
+}
+
+
 void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
 {
     // if there is a net with such name then just assign the correct number
@@ -295,6 +317,6 @@ NETINFO_ITEM* NETINFO_MAPPING::iterator::operator->() const
 
 
 const int NETINFO_LIST::UNCONNECTED = 0;
-const int NETINFO_LIST::FORCE_ORPHANED = -1;
+const int NETINFO_LIST::ORPHANED = -1;
 
-NETINFO_ITEM NETINFO_LIST::ORPHANED = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED );
+NETINFO_ITEM NETINFO_LIST::ORPHANED_ITEM = NETINFO_ITEM( NULL, wxEmptyString, NETINFO_LIST::UNCONNECTED );
\ No newline at end of file
diff --git a/pcbnew/dialogs/dialog_update_pcb.cpp b/pcbnew/dialogs/dialog_update_pcb.cpp
index 4a361a1..b8d34e9 100644
--- a/pcbnew/dialogs/dialog_update_pcb.cpp
+++ b/pcbnew/dialogs/dialog_update_pcb.cpp
@@ -52,13 +52,22 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
         toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
     }
 
-    m_frame->LoadFootprints( *m_netlist, &reporter );
+    try {
+        m_frame->LoadFootprints( *m_netlist, &reporter );
+    }
+    catch ( IO_ERROR &error )
+    {
+        wxString msg;
+
+        reporter.Report ( _("Failed to load one or more footprints. Please add the missing libraries in PCBNew configuration. The PCB will not update completely."), REPORTER::RPT_ERROR );
+        reporter.Report ( error.errorText, REPORTER::RPT_INFO );
+    }
 
     BOARD_NETLIST_UPDATER updater( m_frame, m_frame->GetBoard() );
 
     updater.SetReporter ( &reporter );
     updater.SetIsDryRun( aDryRun);
-    updater.SetLookupByTimestamp( true );
+    updater.SetLookupByTimestamp( m_matchByTimestamp->GetValue() );
     updater.SetDeleteUnusedComponents ( true );
     updater.SetReplaceFootprints( true );
     updater.SetDeleteSinglePadNets ( false );
@@ -94,7 +103,7 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
 
 void DIALOG_UPDATE_PCB::OnMatchChange( wxCommandEvent& event )
 {
-
+    PerformUpdate( true );
 }
 
 void DIALOG_UPDATE_PCB::OnCancelClick( wxCommandEvent& event )
-- 
1.9.1

>From c5ff0e2dec19163403c002ca53aadfebbe871aec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Sun, 21 Jun 2015 17:43:40 +0200
Subject: [PATCH 2/7] eeschema: single click PCB update feature added

Conflicts:
	eeschema/hotkeys.cpp
	eeschema/hotkeys.h
---
 eeschema/eeschema_id.h                    |   5 +-
 eeschema/hotkeys.cpp                      |   3 +
 eeschema/hotkeys.h                        |   1 +
 eeschema/menubar.cpp                      |  16 +
 eeschema/schframe.cpp                     |  20 +
 eeschema/schframe.h                       |   1 +
 include/mail_type.h                       |   1 +
 pcbnew/CMakeLists.txt                     |   3 +
 pcbnew/board_netlist_updater.cpp          | 680 ++++++++++++++++++++++++++++++
 pcbnew/board_netlist_updater.h            | 160 +++++++
 pcbnew/cross-probing.cpp                  |  25 ++
 pcbnew/dialogs/dialog_update_pcb.cpp      | 110 +++++
 pcbnew/dialogs/dialog_update_pcb.fbp      | 661 +++++++++++++++++++++++++++++
 pcbnew/dialogs/dialog_update_pcb.h        |  56 +++
 pcbnew/dialogs/dialog_update_pcb_base.cpp |  85 ++++
 pcbnew/dialogs/dialog_update_pcb_base.h   |  60 +++
 16 files changed, 1886 insertions(+), 1 deletion(-)
 create mode 100644 pcbnew/board_netlist_updater.cpp
 create mode 100644 pcbnew/board_netlist_updater.h
 create mode 100644 pcbnew/dialogs/dialog_update_pcb.cpp
 create mode 100644 pcbnew/dialogs/dialog_update_pcb.fbp
 create mode 100644 pcbnew/dialogs/dialog_update_pcb.h
 create mode 100644 pcbnew/dialogs/dialog_update_pcb_base.cpp
 create mode 100644 pcbnew/dialogs/dialog_update_pcb_base.h

diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h
index 2a7e903..c030095 100644
--- a/eeschema/eeschema_id.h
+++ b/eeschema/eeschema_id.h
@@ -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
 };
 
 
diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp
index d31c392..b69cb87 100644
--- a/eeschema/hotkeys.cpp
+++ b/eeschema/hotkeys.cpp
@@ -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_F9 );
+
 // 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
diff --git a/eeschema/hotkeys.h b/eeschema/hotkeys.h
index 22f3f38..4963fa8 100644
--- a/eeschema/hotkeys.h
+++ b/eeschema/hotkeys.h
@@ -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
 };
diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp
index 5ce4edf..5c934c4 100644
--- a/eeschema/menubar.cpp
+++ b/eeschema/menubar.cpp
@@ -119,6 +119,7 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
                  _( "Save only current schematic sheet" ),
                  KiBitmap( save_xpm ) );
 
+
     if( Kiface().IsSingle() )   // not when under a project mgr
     {
         AddMenuItem( fileMenu,
@@ -427,6 +428,21 @@ 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,
diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp
index ea6d2f2..ca81854 100644
--- a/eeschema/schframe.cpp
+++ b/eeschema/schframe.cpp
@@ -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,22 @@ 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 )
 {
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index f057a4f..23a9bb0 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -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 );
diff --git a/include/mail_type.h b/include/mail_type.h
index dc9d03e..57ca1a4 100644
--- a/include/mail_type.h
+++ b/include/mail_type.h
@@ -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_
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index 6f20b73..487f21b 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -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
diff --git a/pcbnew/board_netlist_updater.cpp b/pcbnew/board_netlist_updater.cpp
new file mode 100644
index 0000000..0559baa
--- /dev/null
+++ b/pcbnew/board_netlist_updater.cpp
@@ -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@xxxxxxxxxxx>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
+ *
+ * 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;
+}
diff --git a/pcbnew/board_netlist_updater.h b/pcbnew/board_netlist_updater.h
new file mode 100644
index 0000000..9d06952
--- /dev/null
+++ b/pcbnew/board_netlist_updater.h
@@ -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@xxxxxxxxxxx>
+ * Copyright (C) 2011 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
+ *
+ * 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
+
+
diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp
index 1bd7e00..86f971c 100644
--- a/pcbnew/cross-probing.cpp
+++ b/pcbnew/cross-probing.cpp
@@ -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>
@@ -238,6 +241,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:
         ;
diff --git a/pcbnew/dialogs/dialog_update_pcb.cpp b/pcbnew/dialogs/dialog_update_pcb.cpp
new file mode 100644
index 0000000..4a361a1
--- /dev/null
+++ b/pcbnew/dialogs/dialog_update_pcb.cpp
@@ -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( );
+}
diff --git a/pcbnew/dialogs/dialog_update_pcb.fbp b/pcbnew/dialogs/dialog_update_pcb.fbp
new file mode 100644
index 0000000..69b6cbc
--- /dev/null
+++ b/pcbnew/dialogs/dialog_update_pcb.fbp
@@ -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>
diff --git a/pcbnew/dialogs/dialog_update_pcb.h b/pcbnew/dialogs/dialog_update_pcb.h
new file mode 100644
index 0000000..88b7151
--- /dev/null
+++ b/pcbnew/dialogs/dialog_update_pcb.h
@@ -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
diff --git a/pcbnew/dialogs/dialog_update_pcb_base.cpp b/pcbnew/dialogs/dialog_update_pcb_base.cpp
new file mode 100644
index 0000000..66d3932
--- /dev/null
+++ b/pcbnew/dialogs/dialog_update_pcb_base.cpp
@@ -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 );
+	
+}
diff --git a/pcbnew/dialogs/dialog_update_pcb_base.h b/pcbnew/dialogs/dialog_update_pcb_base.h
new file mode 100644
index 0000000..b414d0e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_update_pcb_base.h
@@ -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__
-- 
1.9.1

>From b99f175c36308618357ee033bc0afaab6b028bcc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Sun, 21 Jun 2015 17:41:06 +0200
Subject: [PATCH 1/7] made netlist entries and netlist update undoable

---
 include/core/typeinfo.h       |  1 +
 include/wxPcbStruct.h         | 32 +++++++++++++++++----------
 pcbnew/board_undo_redo.cpp    | 50 ++++++++++++++++++++++++++++++++-----------
 pcbnew/class_board.cpp        | 10 +++++++++
 pcbnew/class_board.h          |  5 +++++
 pcbnew/class_netinfo.h        | 45 +++++++++++++++++++++++++++++++++++---
 pcbnew/class_netinfo_item.cpp |  3 ++-
 pcbnew/netlist.cpp            |  4 ++--
 pcbnew/pcbframe.cpp           |  1 +
 9 files changed, 122 insertions(+), 29 deletions(-)

diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h
index 8c89e4c..b6f1ce6 100644
--- a/include/core/typeinfo.h
+++ b/include/core/typeinfo.h
@@ -60,6 +60,7 @@ enum KICAD_T
     PCB_TARGET_T,           ///< class PCB_TARGET, a target (graphic item)
     PCB_ZONE_AREA_T,        ///< class ZONE_CONTAINER, a zone area
     PCB_ITEM_LIST_T,        ///< class BOARD_ITEM_LIST, a list of board items
+    PCB_NETINFO_T,          ///< class NETINFO_ITEM, a description of a net
 
     // Schematic draw Items.  The order of these items effects the sort order.
     // It is currently ordered to mimic the old Eeschema locate behavior where
diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h
index 103172c..fd4b8f3 100644
--- a/include/wxPcbStruct.h
+++ b/include/wxPcbStruct.h
@@ -89,19 +89,10 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
     /// The auxiliary right vertical tool bar used to access the microwave tools.
     wxAuiToolBar* m_microWaveToolBar;
 
-    /**
-     * Function loadFootprints
-     * loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries.
-     *
-     * @param aNetlist is the netlist of components to load the footprints into.
-     * @param aReporter is the #REPORTER object to report to.
-     * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
-     *           occurs while reading footprint library files.
-     */
-    void loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
-        throw( IO_ERROR, PARSE_ERROR );
 
 protected:
+    bool m_undoDisabled;
+
     PCB_LAYER_WIDGET* m_Layers;
 
     DRC* m_drc;                                 ///< the DRC controller, see drc.cpp
@@ -225,6 +216,25 @@ public:
 
     virtual ~PCB_EDIT_FRAME();
 
+
+    /**
+     * Function loadFootprints
+     * loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries.
+     *
+     * @param aNetlist is the netlist of components to load the footprints into.
+     * @param aReporter is the #REPORTER object to report to.
+     * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error
+     *           occurs while reading footprint library files.
+     */
+    void LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
+        throw( IO_ERROR, PARSE_ERROR );
+
+
+    void DisableUndo (bool aDisable = true)
+    {
+        m_undoDisabled = aDisable;
+    }
+
     void OnQuit( wxCommandEvent& event );
 
     /**
diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp
index 48bf7eb..fe6e25e 100644
--- a/pcbnew/board_undo_redo.cpp
+++ b/pcbnew/board_undo_redo.cpp
@@ -145,6 +145,10 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
         for( item = aPcb->m_Zone; item != NULL; item = item->Next() )
              icnt++;
 
+        NETINFO_LIST& netInfo = aPcb->GetNetInfo();
+
+        icnt += netInfo.GetNetCount();
+
         // Build candidate list:
         itemsList.clear();
         itemsList.reserve(icnt);
@@ -170,6 +174,9 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
         for( item = aPcb->m_Zone; item != NULL; item = item->Next() )
             itemsList.push_back( item );
 
+        for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
+            itemsList.push_back ( *i );
+
         // Sort list
         std::sort( itemsList.begin(), itemsList.end() );
         return false;
@@ -310,12 +317,11 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM*    aItem,
     if( aItem->Type() == PCB_MODULE_TEXT_T )
     {
         aItem = aItem->GetParent();
+        wxASSERT( aItem->Type() == PCB_MODULE_T );
+        aCommandType = UR_CHANGED;
 
         if( aItem == NULL )
             return;
-
-        wxASSERT( aItem->Type() == PCB_MODULE_T );
-        aCommandType = UR_CHANGED;
     }
 
     PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
@@ -380,27 +386,48 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
 
     commandToUndo->m_TransformPoint = aTransformPoint;
 
-    // Copy picker list:
-    commandToUndo->CopyList( aItemsList );
+    // First, filter unnecessary stuff from the list (i.e. for multiple pads / labels modified),
+    // take the first occurence of the module.
 
-    // Verify list, and creates data if needed
-    for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
+    for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
     {
-        BOARD_ITEM* item    = (BOARD_ITEM*) commandToUndo->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
         if( item->Type() == PCB_MODULE_TEXT_T  || item->Type() == PCB_PAD_T )
         {
             item = item->GetParent();
+            wxASSERT( item->Type() == PCB_MODULE_T );
+
 
             if( item == NULL )
                 continue;
 
-            wxASSERT( item->Type() == PCB_MODULE_T );
+            bool found = false;
+            for(int j = 0; j < commandToUndo->GetCount(); j++)
+            {
+                if ( commandToUndo->GetPickedItem(j) == item && commandToUndo->GetPickedItemStatus(j) == UR_CHANGED )
+                {
+                    found = true;
+                    break;
+                }
+            }
+
+            if(!found)
+                commandToUndo->PushItem ( ITEM_PICKER (item, UR_CHANGED ) );
+            else
+                continue;
 
-            commandToUndo->SetPickedItem( item, ii );
-            commandToUndo->SetPickedItemStatus( UR_CHANGED, ii );
+        } else {
+            commandToUndo->PushItem ( ITEM_PICKER (item, status ) );
         }
+    }
+
+    for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ )
+    {
+        BOARD_ITEM* item    = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii );
+        UNDO_REDO_T status = commandToUndo->GetPickedItemStatus(ii);
 
         UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii );
 
@@ -649,7 +676,6 @@ void PCB_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
 
     /* Get the old list */
     PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList();
-
     /* Undo the command */
     PutDataInPreviousState( List, false );
 
diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
index bfca85d..14e3c98 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -737,6 +737,11 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
         aBoardItem->SetParent( this );
         break;
 
+    case PCB_NETINFO_T:
+        m_NetInfo.AppendNet( (NETINFO_ITEM *) aBoardItem );
+        break;
+
+
     // other types may use linked list
     default:
         {
@@ -807,6 +812,11 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
         m_Drawings.Remove( aBoardItem );
         break;
 
+    case PCB_NETINFO_T:
+        printf("Unimpl! remove netinfo!\n");
+		assert(false);
+        break;
+
     // other types may use linked list
     default:
         wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) );
diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h
index bd9a78d..ba5241f 100644
--- a/pcbnew/class_board.h
+++ b/pcbnew/class_board.h
@@ -821,6 +821,11 @@ public:
         m_NetInfo.AppendNet( aNewNet );
     }
 
+    NETINFO_LIST& GetNetInfo()
+    {
+        return m_NetInfo;
+    }
+
 #ifndef SWIG
     /**
      * Function BeginNets
diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h
index 8fb74d5..efc0409 100644
--- a/pcbnew/class_netinfo.h
+++ b/pcbnew/class_netinfo.h
@@ -36,6 +36,7 @@
 
 #include <gr_basic.h>
 #include <class_netclass.h>
+#include <class_board_item.h>
 #include <boost/unordered_map.hpp>
 #include <hashtables.h>
 
@@ -422,6 +423,12 @@ public:
     }
 #endif
 
+    BOARD* GetParent() const
+    {
+        return m_Parent;
+    }
+
+
 private:
     /**
      * Function clear
@@ -468,7 +475,7 @@ private:
  * Class NETINFO_ITEM
  * handles the data for a net
  */
-class NETINFO_ITEM
+class NETINFO_ITEM : public BOARD_ITEM
 {
     friend class NETINFO_LIST;
 
@@ -485,7 +492,7 @@ private:
                                 // item of the net classes list
     NETCLASSPTR m_NetClass;
 
-    BOARD_ITEM* m_parent;       ///< The parent board item object the net belongs to.
+    BOARD* m_parent;            ///< The parent board the net belongs to.
 
 public:
     std::vector<D_PAD*> m_PadInNetList;    ///< List of pads connected to this net
@@ -498,9 +505,33 @@ public:
     unsigned m_RatsnestEndIdx;         // Ending point of ratsnests of this net
                                        // (excluded) in this buffer
 
-    NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = -1 );
+
+
+    NETINFO_ITEM( BOARD* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = -1 );
     ~NETINFO_ITEM();
 
+    static inline bool ClassOf( const EDA_ITEM* aItem )
+    {
+        return aItem && PCB_T == aItem->Type();
+    }
+
+    wxString GetClass() const
+    {
+        return wxT( "NETINFO_ITEM" );
+    }
+
+    void Show( int nestLevel, std::ostream& os ) const
+    {
+
+    }
+
+    const wxPoint& GetPosition() const {
+        static wxPoint dummy(0, 0);
+        return dummy;
+    };
+    void SetPosition( const wxPoint& aPos ) {};
+
+
     /**
      * Function SetClass
      * sets \a aNetclass into this NET
@@ -622,6 +653,8 @@ public:
      */
     int GetNet() const { return m_NetCode; }
 
+    void SetNetCode( int aNetCode ) { m_NetCode = aNetCode; }
+
     /**
      * Function GetNodesCount
      * @return int - number of nodes in the net
@@ -663,6 +696,12 @@ public:
 
         SetClass( NETCLASSPTR() );
     }
+
+    BOARD* GetParent() const
+    {
+        return m_parent;
+    }
+
 };
 
 
diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp
index 1f1f267..d60ca77 100644
--- a/pcbnew/class_netinfo_item.cpp
+++ b/pcbnew/class_netinfo_item.cpp
@@ -49,7 +49,8 @@
 /* class NETINFO_ITEM: handle data relative to a given net */
 /*********************************************************/
 
-NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) :
+NETINFO_ITEM::NETINFO_ITEM( BOARD* aParent, const wxString& aNetName, int aNetCode ) :
+    BOARD_ITEM ( aParent, PCB_NETINFO_T ),
     m_NetCode( aNetCode ), m_Netname( aNetName ), m_ShortNetname( m_Netname.AfterLast( '/' ) )
 {
     m_parent   = aParent;
diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp
index bbd31bf..99e7632 100644
--- a/pcbnew/netlist.cpp
+++ b/pcbnew/netlist.cpp
@@ -87,7 +87,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
 
         SetLastNetListRead( aNetlistFileName );
         netlistReader->LoadNetlist();
-        loadFootprints( netlist, aReporter );
+        LoadFootprints( netlist, aReporter );
     }
     catch( const IO_ERROR& ioe )
     {
@@ -205,7 +205,7 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName()
 
 #define ALLOW_PARTIAL_FPID      1
 
-void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
+void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter )
     throw( IO_ERROR, PARSE_ERROR )
 {
     wxString   msg;
diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp
index 7c72766..adc68a7 100644
--- a/pcbnew/pcbframe.cpp
+++ b/pcbnew/pcbframe.cpp
@@ -309,6 +309,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
     PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition,
         wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME )
 {
+    m_undoDisabled = false;
     m_showBorderAndTitleBlock = true;   // true to display sheet references
     m_showAxis = false;                 // true to display X and Y axis
     m_showOriginAxis = true;
-- 
1.9.1


Follow ups