← Back to team overview

kicad-developers team mailing list archive

[PATCH] Update the PCB from schematics in one click

 

Hi,

One of the biggest annoyances of Kicad (to me) was the PCB forward
annotation process. The attached patch set attempts to improve this by
adding an "Update PCB From schematics" option in eeschema when Kicad is
open in Project Manager mode. The way it works is:
- press F9 (or select Tools->Update PCB From Schematics) in eeschema
- 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).

Best,
Tom

PS. Henner, thanks for the inspiration by sending your UX improving
patches ;)
>From 997390ebdd58a4827a2a52dab913a7345f2e2ae7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@xxxxxxx>
Date: Mon, 22 Jun 2015 14:24:34 +0200
Subject: [PATCH 1/5] lazy rendering mode for HTML reporter widget (improves
 speed for large reports)

---
 common/dialogs/wx_html_report_panel.cpp      | 49 ++++++++++++++++++++--------
 common/dialogs/wx_html_report_panel.h        | 18 ++++++++++
 common/dialogs/wx_html_report_panel_base.cpp |  7 ++--
 common/dialogs/wx_html_report_panel_base.fbp |  4 +--
 common/dialogs/wx_html_report_panel_base.h   |  1 +
 common/reporter.cpp                          | 17 ++++++++++
 include/reporter.h                           | 18 ++++++++++
 7 files changed, 95 insertions(+), 19 deletions(-)

diff --git a/common/dialogs/wx_html_report_panel.cpp b/common/dialogs/wx_html_report_panel.cpp
index c2eb05b..f9e8528 100644
--- a/common/dialogs/wx_html_report_panel.cpp
+++ b/common/dialogs/wx_html_report_panel.cpp
@@ -24,15 +24,16 @@
 #include <wildcards_and_files_ext.h>
 #include <boost/foreach.hpp>
 
-WX_HTML_REPORT_PANEL::WX_HTML_REPORT_PANEL( wxWindow*      parent,
-                                            wxWindowID     id,
-                                            const wxPoint& pos,
-                                            const wxSize&  size,
-                                            long           style ) :
+WX_HTML_REPORT_PANEL::WX_HTML_REPORT_PANEL( wxWindow*         parent,
+                                            wxWindowID         id,
+                                            const wxPoint&     pos,
+                                            const wxSize&     size,
+                                            long             style ) :
     WX_HTML_REPORT_PANEL_BASE( parent, id, pos, size, style ),
     m_reporter( this ),
-    m_severities( -1 ),
-    m_showAll( true )
+    m_severities ( -1 ),
+    m_showAll ( true ),
+    m_lazyUpdate ( false )
 {
     syncCheckboxes();
 }
@@ -56,10 +57,26 @@ void WX_HTML_REPORT_PANEL::Report( const wxString& aText, REPORTER::SEVERITY aSe
     line.severity = aSeverity;
 
     m_report.push_back( line );
-    m_htmlView->AppendToPage( generateHtml( line ) );
-    scrollToBottom();
+
+    m_html += generateHtml ( line );
+
+    if(!m_lazyUpdate)
+    {
+        m_htmlView->AppendToPage( generateHtml( line ) );
+        scrollToBottom();
+    }
+}
+
+void WX_HTML_REPORT_PANEL::SetLazyUpdate ( bool aLazyUpdate )
+{
+    m_lazyUpdate = aLazyUpdate;
 }
 
+void WX_HTML_REPORT_PANEL::Flush()
+{
+    m_htmlView->SetPage( m_html );
+    scrollToBottom();
+}
 
 void WX_HTML_REPORT_PANEL::scrollToBottom()
 {
@@ -135,13 +152,13 @@ void WX_HTML_REPORT_PANEL::onCheckBoxShowAll( wxCommandEvent& event )
 
 void WX_HTML_REPORT_PANEL::syncCheckboxes()
 {
-    m_checkBoxShowWarnings->Enable( !m_showAll );
+    m_checkBoxShowWarnings->Enable( ! m_showAll );
     m_checkBoxShowWarnings->SetValue( m_severities & REPORTER::RPT_WARNING );
-    m_checkBoxShowErrors->Enable( !m_showAll );
+    m_checkBoxShowErrors->Enable( ! m_showAll );
     m_checkBoxShowErrors->SetValue( m_severities & REPORTER::RPT_ERROR );
-    m_checkBoxShowInfos->Enable( !m_showAll );
+    m_checkBoxShowInfos->Enable( ! m_showAll );
     m_checkBoxShowInfos->SetValue( m_severities & REPORTER::RPT_INFO );
-    m_checkBoxShowActions->Enable( !m_showAll );
+    m_checkBoxShowActions->Enable( ! m_showAll );
     m_checkBoxShowActions->SetValue( m_severities & REPORTER::RPT_ACTION );
 }
 
@@ -228,5 +245,11 @@ void WX_HTML_REPORT_PANEL::onBtnSaveToFile( wxCommandEvent& event )
 
 void WX_HTML_REPORT_PANEL::Clear()
 {
+    m_html.clear();
     m_report.clear();
 }
+
+void WX_HTML_REPORT_PANEL::SetLabel ( const wxString& aLabel )
+{
+    m_box->GetStaticBox()->SetLabel ( aLabel );
+}
diff --git a/common/dialogs/wx_html_report_panel.h b/common/dialogs/wx_html_report_panel.h
index 9fe23fb..140ca29 100644
--- a/common/dialogs/wx_html_report_panel.h
+++ b/common/dialogs/wx_html_report_panel.h
@@ -55,6 +55,20 @@ public:
     ///> clears the report panel
     void Clear();
 
+    ///> sets the frame label
+    void SetLabel ( const wxString& aLabel );
+
+    void SetLazyUpdate ( bool aLazyUpdate );
+
+    void Flush();
+
+    void SetVisibleSeverities( int aSeverities )
+    {
+        m_showAll = false;
+        m_severities = aSeverities;
+        syncCheckboxes();
+    }
+
 private:
     struct REPORT_LINE
     {
@@ -90,6 +104,10 @@ private:
 
     ///> show all messages flag (overrides m_severities)
     bool m_showAll;
+
+    wxString m_html;
+
+    bool m_lazyUpdate;
 };
 
 #endif //__WX_HTML_REPORT_PANEL_H__
diff --git a/common/dialogs/wx_html_report_panel_base.cpp b/common/dialogs/wx_html_report_panel_base.cpp
index fc47a8d..80be22c 100644
--- a/common/dialogs/wx_html_report_panel_base.cpp
+++ b/common/dialogs/wx_html_report_panel_base.cpp
@@ -11,8 +11,7 @@
 
 WX_HTML_REPORT_PANEL_BASE::WX_HTML_REPORT_PANEL_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
 {
-	wxStaticBoxSizer* sbSizer3;
-	sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Messages:") ), wxVERTICAL );
+	m_box = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Messages:") ), wxVERTICAL );
 	
 	wxFlexGridSizer* fgSizer4;
 	fgSizer4 = new wxFlexGridSizer( 2, 1, 0, 0 );
@@ -67,10 +66,10 @@ WX_HTML_REPORT_PANEL_BASE::WX_HTML_REPORT_PANEL_BASE( wxWindow* parent, wxWindow
 	fgSizer4->Add( fgSizer3, 1, wxEXPAND, 5 );
 	
 	
-	sbSizer3->Add( fgSizer4, 1, wxEXPAND|wxALL, 5 );
+	m_box->Add( fgSizer4, 1, wxEXPAND|wxALL, 5 );
 	
 	
-	this->SetSizer( sbSizer3 );
+	this->SetSizer( m_box );
 	this->Layout();
 	
 	// Connect Events
diff --git a/common/dialogs/wx_html_report_panel_base.fbp b/common/dialogs/wx_html_report_panel_base.fbp
index 0dc2fc1..f707d9d 100644
--- a/common/dialogs/wx_html_report_panel_base.fbp
+++ b/common/dialogs/wx_html_report_panel_base.fbp
@@ -82,9 +82,9 @@
                 <property name="id">wxID_ANY</property>
                 <property name="label">Messages:</property>
                 <property name="minimum_size"></property>
-                <property name="name">sbSizer3</property>
+                <property name="name">m_box</property>
                 <property name="orient">wxVERTICAL</property>
-                <property name="permission">none</property>
+                <property name="permission">protected</property>
                 <event name="OnUpdateUI"></event>
                 <object class="sizeritem" expanded="1">
                     <property name="border">5</property>
diff --git a/common/dialogs/wx_html_report_panel_base.h b/common/dialogs/wx_html_report_panel_base.h
index 3db31f3..240b08f 100644
--- a/common/dialogs/wx_html_report_panel_base.h
+++ b/common/dialogs/wx_html_report_panel_base.h
@@ -34,6 +34,7 @@ class WX_HTML_REPORT_PANEL_BASE : public wxPanel
 	private:
 	
 	protected:
+		wxStaticBoxSizer* m_box;
 		wxHtmlWindow* m_htmlView;
 		wxStaticText* m_staticText3;
 		wxCheckBox* m_checkBoxShowAll;
diff --git a/common/reporter.cpp b/common/reporter.cpp
index fa64160..2c9176b 100644
--- a/common/reporter.cpp
+++ b/common/reporter.cpp
@@ -62,3 +62,20 @@ REPORTER& WX_HTML_PANEL_REPORTER::Report( const wxString& aText, SEVERITY aSever
     m_panel->Report( aText, aSeverity );
     return *this;
 }
+
+REPORTER& NULL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
+{
+    return *this;
+}
+
+REPORTER& NULL_REPORTER::GetInstance()
+{
+    static REPORTER* s_nullReporter = NULL;
+
+    if(!s_nullReporter)
+    {
+        s_nullReporter = new NULL_REPORTER();
+    }
+
+    return *s_nullReporter;
+}
diff --git a/include/reporter.h b/include/reporter.h
index 117e56f..2300bb5 100644
--- a/include/reporter.h
+++ b/include/reporter.h
@@ -147,4 +147,22 @@ public:
     REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED );
 };
 
+/**
+ * Class NULL_REPORTER
+ *
+ * A singleton reporter that reports to nowhere. Used as to simplify code by
+ * avoiding the reportee to check for a non-NULL reporter object.
+ */
+class NULL_REPORTER : public REPORTER 
+{
+    public:
+        NULL_REPORTER()
+        {
+        };
+
+        static REPORTER& GetInstance();
+
+        REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_UNDEFINED );
+};
+
 #endif     // _REPORTER_H_
-- 
1.9.1

>From 3cfd1bf72c24ddf9da18e6226dbc58d4ef315b92 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 2/5] made netlist entries and netlist update undoable

---
 include/core/typeinfo.h       |  1 +
 include/wxPcbStruct.h         | 32 ++++++++++++++++---------
 pcbnew/board_undo_redo.cpp    | 55 +++++++++++++++++++++++++++++++++++++------
 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, 132 insertions(+), 24 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 53689c4..8f21268 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 fff523b..6a5f0c6 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;
@@ -379,13 +386,13 @@ 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 )
@@ -393,12 +400,34 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
             item = item->GetParent();
             wxASSERT( item->Type() == PCB_MODULE_T );
 
+
             if( item == NULL )
                 continue;
 
-            commandToUndo->SetPickedItem( item, ii );
-            commandToUndo->SetPickedItemStatus( UR_CHANGED, ii );
+            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;
+
+        } 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 );
 
@@ -635,6 +664,12 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed
 
 void PCB_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
 {
+    if( m_undoDisabled )
+    {
+        printf("undo is temporarily disabled.\n");
+        return;
+    }
+
     if( GetScreen()->GetUndoCommandCount() <= 0 )
         return;
 
@@ -658,6 +693,12 @@ void PCB_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
 
 void PCB_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
 {
+    if( m_undoDisabled )
+    {
+        printf("redo is temporarily disabled.\n");
+        return;
+    }
+
     if( GetScreen()->GetRedoCommandCount() == 0 )
         return;
 
diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
index 862ab31..3ad9012 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -736,6 +736,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:
         {
@@ -806,6 +811,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 9e565bc..38a3622 100644
--- a/pcbnew/class_board.h
+++ b/pcbnew/class_board.h
@@ -828,6 +828,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 85dbc70..e9c8290 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>
 
@@ -407,6 +408,12 @@ public:
     }
 #endif
 
+    BOARD* GetParent() const
+    {
+        return m_Parent;
+    }
+
+
 private:
     /**
      * Function DeleteData
@@ -453,7 +460,7 @@ private:
  * Class NETINFO_ITEM
  * handles the data for a net
  */
-class NETINFO_ITEM
+class NETINFO_ITEM : public BOARD_ITEM
 {
     friend class NETINFO_LIST;
 
@@ -470,7 +477,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
@@ -483,9 +490,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
@@ -607,6 +638,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
@@ -648,6 +681,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 bdba316..7ffa398 100644
--- a/pcbnew/netlist.cpp
+++ b/pcbnew/netlist.cpp
@@ -86,7 +86,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
 
         SetLastNetListRead( aNetlistFileName );
         netlistReader->LoadNetlist();
-        loadFootprints( netlist, aReporter );
+        LoadFootprints( netlist, aReporter );
     }
     catch( const IO_ERROR& ioe )
     {
@@ -194,7 +194,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 fab3ed5..ee12b44 100644
--- a/pcbnew/pcbframe.cpp
+++ b/pcbnew/pcbframe.cpp
@@ -307,6 +307,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

>From 923ce109f86b6d1432bbb0a4bcbd09c594aa9568 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 3/5] eeschema: single click PCB update feature added

Conflicts:
	eeschema/hotkeys.cpp
	eeschema/hotkeys.h
---
 eeschema/eeschema_id.h                    |   5 +-
 eeschema/hotkeys.cpp                      |   9 +-
 eeschema/hotkeys.h                        |   5 +-
 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, 1891 insertions(+), 6 deletions(-)
 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 98c3282..75e047e 100644
--- a/eeschema/eeschema_id.h
+++ b/eeschema/eeschema_id.h
@@ -245,7 +245,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 c10549c..83ffe15 100644
--- a/eeschema/hotkeys.cpp
+++ b/eeschema/hotkeys.cpp
@@ -219,6 +219,8 @@ static EDA_HOTKEY HkSaveLib( _HKI( "Save Library" ), HK_SAVE_LIB, 'S' + GR_KB_CT
 static EDA_HOTKEY HkSaveSchematic( _HKI( "Save Schematic" ), HK_SAVE_SCH, 'S' + GR_KB_CTRL );
 static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' + GR_KB_CTRL );
 
+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[] =
 {
@@ -291,7 +293,8 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
     &HkAddBusEntry,
     &HkAddGraphicPolyLine,
     &HkAddGraphicText,
-    &HkLeaveSheet,
+    &HkUpdatePcbFromSch,
+	&HkLeaveSheet,
     &HkDeleteNode,
     NULL
 };
@@ -444,9 +447,9 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
     case HK_ZOOM_REDRAW:
     case HK_ZOOM_CENTER:
     case HK_ZOOM_AUTO:
-    case HK_LEAVE_SHEET:
+	case HK_LEAVE_SHEET:
     case HK_DELETE_NODE:
-    case HK_MOVEBLOCK_TO_DRAGBLOCK:          // Switch to drag mode, when block moving
+	case HK_MOVEBLOCK_TO_DRAGBLOCK:          // Switch to drag mode, when block moving
     case HK_SAVE_BLOCK:                      // Copy block to paste buffer.
         cmd.SetId( hotKey->m_IdMenuEvent );
         GetEventHandler()->ProcessEvent( cmd );
diff --git a/eeschema/hotkeys.h b/eeschema/hotkeys.h
index afcebca..1adc986 100644
--- a/eeschema/hotkeys.h
+++ b/eeschema/hotkeys.h
@@ -77,8 +77,9 @@ enum hotkey_id_commnand {
     HK_LOAD_SCH,
     HK_LEFT_CLICK,
     HK_LEFT_DCLICK,
-    HK_LEAVE_SHEET,
-    HK_DELETE_NODE
+	HK_LEAVE_SHEET,
+    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 23ae7ff..f1615ed 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,
@@ -419,6 +420,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 769d6cd..86ed014 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.
@@ -261,6 +264,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 )
@@ -815,6 +819,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 9f55bb1..4671d87 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -800,6 +800,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 7a969d9..3114010 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -135,6 +135,8 @@ set( PCBNEW_DIALOGS
     dialogs/dialog_target_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
@@ -182,6 +184,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 37566fd..9161edd 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>
@@ -240,6 +243,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 88aa3dad9c78ff60b0216b847dc4d276ea5082e2 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 4/5] 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 3ad9012..0ed4b78 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -671,6 +671,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 );
@@ -736,11 +740,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:
         {
@@ -763,6 +762,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
@@ -811,11 +814,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" ) );
@@ -1261,7 +1259,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 82a2153..0f52cd2 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 e8e6944..8a60200 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 e9c8290..ed659e3 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
@@ -333,11 +339,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 2e03c86..a0dbe44 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
@@ -292,6 +314,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 be50ab479bae8102e929b4557da1464c73035e17 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 5/5] 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


Follow ups