← Back to team overview

kicad-developers team mailing list archive

[PATCH] Add exchange footprints to GAL

 

Hi,

The attached patches add the "exchange footprints" command to the GAL edit tool.

This is 1 out of 3 parts of
https://bugs.launchpad.net/kicad/+bug/1541460. I'm not sure how to put
this as a commit comment exactly.

This is implemented as two segments:

* Put the dialog/exchange FP code into pcbnew/dialogs directory (as a
header/implementation pair) where it can be reached by bother
pcbframe.cpp and GAL tools. This also makes it easier to remove legacy
calling code in future. No change is made to the functionality of the
dialog.
* Add the tool to the GAL, calling the dialog as needed.

The third patch is optional, but tidies up a copy-pasted selection
routine into a named function and adds a little commentary to a couple
of related existing functions.

Cheers,

John
From fd30b0465e0b627a4f69fa574f077396ea3f7861 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 31 Jan 2017 17:54:54 +0800
Subject: [PATCH 3/3] Factor an EDIT_TOOL selection routine

Also add some commentary to other EDIT_TOOL selection functions.
---
 pcbnew/tools/edit_tool.cpp | 10 ++-------
 pcbnew/tools/edit_tool.h   | 51 +++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp
index d2af32568..651ea5bab 100644
--- a/pcbnew/tools/edit_tool.cpp
+++ b/pcbnew/tools/edit_tool.cpp
@@ -783,10 +783,7 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
 
 int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
 {
-    if( !hoverSelection() )
-        return 0;
-
-    MODULE* mod = uniqueSelected<MODULE>();
+    MODULE* mod = uniqueHoverSelection<MODULE>();
 
     if( !mod )
         return 0;
@@ -895,10 +892,7 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
     SELECTION& selection = m_selectionTool->GetSelection();
     bool unselect = selection.Empty();
 
-    if( !hoverSelection() )
-        return 0;
-
-    MODULE* mod = uniqueSelected<MODULE>();
+    MODULE* mod = uniqueHoverSelection<MODULE>();
 
     if( !mod )
         return 0;
diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h
index 83f2b493e..2cf158636 100644
--- a/pcbnew/tools/edit_tool.h
+++ b/pcbnew/tools/edit_tool.h
@@ -151,15 +151,34 @@ private:
     ///> selected items.
     wxPoint getModificationPoint( const SELECTION& aSelection );
 
-    ///> If there are no items currently selected, it tries to choose the item that is under
-    ///> the cursor or displays a disambiguation menu if there are multiple items.
-    bool hoverSelection( bool aSanitize = true );
-
     int editFootprintInFpEditor( const TOOL_EVENT& aEvent );
 
     bool invokeInlineRouter();
 
-    template<class T> T* uniqueSelected()
+    /**
+     * Function hoverSelection()
+     *
+     * If there are no items currently selected, it tries to choose the
+     * item that is under he cursor or displays a disambiguation menu
+     * if there are multiple items.
+     *
+     * @param aSanitize sanitize selection using SanitizeSelection()
+     * @return true if the eventual selection contains any items, or
+     * false if it fails to select any items.
+     */
+    bool hoverSelection( bool aSanitize = true );
+
+    /**
+     * Function uniqueSelected()
+     *
+     * Get a single selected item of a certain type
+     *
+     * @tparam T type of item to select
+     * @return pointer to the item (of type T), or nullptr if there isn't
+     * a single selected item, or it's not of the right type.
+     */
+    template<class T>
+    T* uniqueSelected()
     {
         const SELECTION& selection = m_selectionTool->GetSelection();
 
@@ -170,6 +189,28 @@ private:
         return dyn_cast<T*>( item );
     }
 
+    /**
+     * Function uniqueHoverSelection()
+     *
+     * Get a single unique selection of an item, either from the
+     * current selection, or from the items under cursor via
+     * hoverSelection()
+     *
+     * @tparam T type of item to select
+     * @return pointer to a selected item, or nullptr if none could
+     * be found.
+     */
+    template<class T>
+    T* uniqueHoverSelection( bool aSanitize = true )
+    {
+        if( !hoverSelection( aSanitize ) )
+            return nullptr;
+
+        T* item = uniqueSelected<T>();
+
+        return item;
+    }
+
     std::unique_ptr<BOARD_COMMIT> m_commit;
 };
 
-- 
2.11.0

From 60ef3d4789c8abcf8e8808a236c7f661f49d0de3 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 31 Jan 2017 16:03:07 +0800
Subject: [PATCH 2/3] Add exchange modules GAL tool (in EDIT_TOOL)

Includes tool action and the transistion binding in EDIT_TOOL.

Partial fix for lp:1541460 (1 of 3 items)
* https://bugs.launchpad.net/kicad/+bug/1541460
---
 pcbnew/tools/common_actions.cpp |  5 +++++
 pcbnew/tools/common_actions.h   |  3 +++
 pcbnew/tools/edit_tool.cpp      | 42 +++++++++++++++++++++++++++++++++++++++--
 pcbnew/tools/edit_tool.h        |  8 ++++++++
 4 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp
index da2694db5..9a7b45cae 100644
--- a/pcbnew/tools/common_actions.cpp
+++ b/pcbnew/tools/common_actions.cpp
@@ -137,6 +137,11 @@ TOOL_ACTION COMMON_ACTIONS::removeAlt( "pcbnew.InteractiveEdit.removeAlt",
         AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_BACK_SPACE ),
         _( "Remove (alterative)" ), _( "Deletes selected item(s)" ), delete_xpm );
 
+TOOL_ACTION COMMON_ACTIONS::exchangeFootprints( "pcbnew.InteractiveEdit.ExchangeFootprints",
+        AS_GLOBAL, 0,
+        _( "Exchange footprint(s)" ), _( "Change the footprint used for modules" ),
+        import_module_xpm );
+
 
 TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
         AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_ITEM ),
diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h
index a878520da..b8167cf3c 100644
--- a/pcbnew/tools/common_actions.h
+++ b/pcbnew/tools/common_actions.h
@@ -94,6 +94,9 @@ public:
     /// Activation of the duplication tool with incrementing (e.g. pad number)
     static TOOL_ACTION duplicateIncrement;
 
+    /// Exchange footprints of modules
+    static TOOL_ACTION exchangeFootprints;
+
     /// Deleting a BOARD_ITEM
     static TOOL_ACTION remove;
     static TOOL_ACTION removeAlt;
diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp
index 4847fc57e..d2af32568 100644
--- a/pcbnew/tools/edit_tool.cpp
+++ b/pcbnew/tools/edit_tool.cpp
@@ -56,6 +56,7 @@ using namespace std::placeholders;
 
 #include <dialogs/dialog_move_exact.h>
 #include <dialogs/dialog_track_via_properties.h>
+#include <dialogs/dialog_exchange_modules.h>
 
 #include <board_commit.h>
 
@@ -90,6 +91,9 @@ bool EDIT_TOOL::Init()
         return m_editModules;
     };
 
+    auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T )
+                                    && SELECTION_CONDITIONS::Count( 1 );
+
     // Add context menu entries that are displayed when selection tool is active
     CONDITIONAL_MENU& menu = m_selectionTool->GetToolMenu().GetMenu();
     menu.AddItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty );
@@ -107,8 +111,9 @@ bool EDIT_TOOL::Init()
 
     // Footprint actions
     menu.AddItem( COMMON_ACTIONS::editFootprintInFpEditor,
-                                        SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) &&
-                                        SELECTION_CONDITIONS::Count( 1 ) );
+                  singleModuleCondition );
+    menu.AddItem( COMMON_ACTIONS::exchangeFootprints,
+                  singleModuleCondition );
 
     m_offset.x = 0;
     m_offset.y = 0;
@@ -776,6 +781,38 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
 }
 
 
+int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
+{
+    if( !hoverSelection() )
+        return 0;
+
+    MODULE* mod = uniqueSelected<MODULE>();
+
+    if( !mod )
+        return 0;
+
+    auto& editFrame = *getEditFrame<PCB_EDIT_FRAME>();
+
+    editFrame.SetCurItem( mod );
+
+    // Footprint exchange could remove modules, so they have to be
+    // removed from the selection first
+    m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+    // invoke the exchange dialog process
+    {
+        DIALOG_EXCHANGE_MODULE dialog( &editFrame, mod );
+        dialog.ShowQuasiModal();
+    }
+
+    // The current item can be deleted by exchange module, and the
+    // selection is emptied, so remove current item from frame info area
+    editFrame.SetCurItem( nullptr );
+
+    return 0;
+}
+
+
 void EDIT_TOOL::SetTransitions()
 {
     Go( &EDIT_TOOL::Main,       COMMON_ACTIONS::editActivate.MakeEvent() );
@@ -789,6 +826,7 @@ void EDIT_TOOL::SetTransitions()
     Go( &EDIT_TOOL::CreateArray,COMMON_ACTIONS::createArray.MakeEvent() );
     Go( &EDIT_TOOL::Mirror,     COMMON_ACTIONS::mirror.MakeEvent() );
     Go( &EDIT_TOOL::editFootprintInFpEditor, COMMON_ACTIONS::editFootprintInFpEditor.MakeEvent() );
+    Go( &EDIT_TOOL::ExchangeFootprints,      COMMON_ACTIONS::exchangeFootprints.MakeEvent() );
 }
 
 
diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h
index 260cdeab9..83f2b493e 100644
--- a/pcbnew/tools/edit_tool.h
+++ b/pcbnew/tools/edit_tool.h
@@ -116,6 +116,14 @@ public:
      */
     int CreateArray( const TOOL_EVENT& aEvent );
 
+    /**
+     * Function ExchangeFootprints()
+     *
+     * Invoke the dialog used to change the footprints used for modules
+     * and update module footprints based on result
+     */
+    int ExchangeFootprints( const TOOL_EVENT& aEvent );
+
 
     ///> Sets up handlers for various events.
     void SetTransitions() override;
-- 
2.11.0

From f0c2a27edf27fcc6191267688bf99c5b69921855 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 31 Jan 2017 15:55:02 +0800
Subject: [PATCH 1/3] Move DIALOG_EXCHANGE_MODULE to dialogs dir

DIALOG_EXCHANGE_MODULE class now has its own header file in the
pcbnew/dialogs directory, and the xchgmod.cpp files was moved along with
it. This has two aims:

* (minor) Standardise the location of "base dialog" derived classes,
  like most other dialogs in KiCad.
* (major) Allow inclusion of this dialog class into both legacy-mode
  pcbframe.cpp and into GAL tools.
---
 pcbnew/CMakeLists.txt                              |  2 +-
 .../dialog_exchange_modules.cpp}                   | 47 +---------------
 pcbnew/dialogs/dialog_exchange_modules.h           | 65 ++++++++++++++++++++++
 pcbnew/pcbframe.cpp                                |  9 +++
 4 files changed, 77 insertions(+), 46 deletions(-)
 rename pcbnew/{xchgmod.cpp => dialogs/dialog_exchange_modules.cpp} (91%)
 create mode 100644 pcbnew/dialogs/dialog_exchange_modules.h

diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index e2f23e300..eedb3a6f0 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -62,6 +62,7 @@ set( PCBNEW_DIALOGS
     dialogs/dialog_enum_pads.cpp
     dialogs/dialog_enum_pads_base.cpp
     dialogs/dialog_exchange_modules_base.cpp
+    dialogs/dialog_exchange_modules.cpp
     dialogs/dialog_export_idf.cpp
     dialogs/dialog_export_idf_base.cpp
     dialogs/dialog_export_vrml_base.cpp
@@ -264,7 +265,6 @@ set( PCBNEW_CLASS_SRCS
     tracepcb.cpp
     tr_modif.cpp
     undo_redo.cpp
-    xchgmod.cpp
     zones_convert_brd_items_to_polygons_with_Boost.cpp
     zones_convert_to_polygons_aux_functions.cpp
     zones_by_polygon.cpp
diff --git a/pcbnew/xchgmod.cpp b/pcbnew/dialogs/dialog_exchange_modules.cpp
similarity index 91%
rename from pcbnew/xchgmod.cpp
rename to pcbnew/dialogs/dialog_exchange_modules.cpp
index 59fe23855..8004e72e9 100644
--- a/pcbnew/xchgmod.cpp
+++ b/pcbnew/dialogs/dialog_exchange_modules.cpp
@@ -1,14 +1,10 @@
-/**
- * @file xchgmod.cpp
- */
-
 /*
  * 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) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@xxxxxxxxxxx>
  * Copyright (C) 2013-2016 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
- * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2017 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
@@ -42,7 +38,7 @@
 #include <project.h>
 
 #include <pcbnew.h>
-#include <dialog_exchange_modules_base.h>
+#include <dialog_exchange_modules.h>
 #include <wildcards_and_files_ext.h>
 #include <kiway.h>
 
@@ -50,37 +46,6 @@
 static bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName );
 
 
-class DIALOG_EXCHANGE_MODULE : public DIALOG_EXCHANGE_MODULE_BASE
-{
-private:
-    PCB_EDIT_FRAME* m_parent;
-    MODULE*         m_currentModule;
-    static int      m_selectionMode;    // Remember the last exchange option
-
-public:
-    DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* aParent, MODULE* aModule );
-    ~DIALOG_EXCHANGE_MODULE() { };
-
-private:
-    void OnSelectionClicked( wxCommandEvent& event ) override;
-    void OnOkClick( wxCommandEvent& event ) override;
-    void OnQuit( wxCommandEvent& event ) override;
-    void BrowseAndSelectFootprint( wxCommandEvent& event ) override;
-    void ViewAndSelectFootprint( wxCommandEvent& event ) override;
-    void RebuildCmpList( wxCommandEvent& event ) override;
-    void init();
-
-    bool changeCurrentFootprint();
-    bool changeSameFootprints( bool aUseValue);
-    bool changeAllFootprints();
-    bool change_1_Module( MODULE*            aModule,
-                          const LIB_ID&      aNewFootprintFPID,
-                          bool               eShowError );
-
-    BOARD_COMMIT m_commit;
-};
-
-
 int DIALOG_EXCHANGE_MODULE::m_selectionMode = 0;
 
 
@@ -96,14 +61,6 @@ DIALOG_EXCHANGE_MODULE::DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* parent, MODULE*
 }
 
 
-int PCB_EDIT_FRAME::InstallExchangeModuleFrame( MODULE* Module )
-{
-    DIALOG_EXCHANGE_MODULE dialog( this, Module );
-
-    return dialog.ShowQuasiModal();
-}
-
-
 void DIALOG_EXCHANGE_MODULE::OnQuit( wxCommandEvent& event )
 {
     m_selectionMode = m_Selection->GetSelection();
diff --git a/pcbnew/dialogs/dialog_exchange_modules.h b/pcbnew/dialogs/dialog_exchange_modules.h
new file mode 100644
index 000000000..7c225791b
--- /dev/null
+++ b/pcbnew/dialogs/dialog_exchange_modules.h
@@ -0,0 +1,65 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
+ * Copyright (C) 1992-2017 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 DIALOG_EXCHANGE_MODULES_H_
+#define DIALOG_EXCHANGE_MODULES_H_
+
+#include <dialog_exchange_modules_base.h>
+
+#include <board_commit.h>
+
+class PCB_EDIT_FRAME;
+class MODULE;
+
+class DIALOG_EXCHANGE_MODULE : public DIALOG_EXCHANGE_MODULE_BASE
+{
+private:
+    PCB_EDIT_FRAME* m_parent;
+    MODULE*         m_currentModule;
+    static int      m_selectionMode;    // Remember the last exchange option
+
+public:
+    DIALOG_EXCHANGE_MODULE( PCB_EDIT_FRAME* aParent, MODULE* aModule );
+    ~DIALOG_EXCHANGE_MODULE() { };
+
+private:
+    void OnSelectionClicked( wxCommandEvent& event ) override;
+    void OnOkClick( wxCommandEvent& event ) override;
+    void OnQuit( wxCommandEvent& event ) override;
+    void BrowseAndSelectFootprint( wxCommandEvent& event ) override;
+    void ViewAndSelectFootprint( wxCommandEvent& event ) override;
+    void RebuildCmpList( wxCommandEvent& event ) override;
+    void init();
+
+    bool changeCurrentFootprint();
+    bool changeSameFootprints( bool aUseValue);
+    bool changeAllFootprints();
+    bool change_1_Module( MODULE*            aModule,
+                          const LIB_ID&      aNewFootprintFPID,
+                          bool               eShowError );
+
+    BOARD_COMMIT m_commit;
+};
+
+#endif // DIALOG_EXCHANGE_MODULES_H_
diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp
index f208c6f23..97f56838b 100644
--- a/pcbnew/pcbframe.cpp
+++ b/pcbnew/pcbframe.cpp
@@ -54,6 +54,7 @@
 #include <module_editor_frame.h>
 #include <dialog_helpers.h>
 #include <dialog_plot.h>
+#include <dialog_exchange_modules.h>
 #include <convert_to_biu.h>
 #include <view/view.h>
 #include <view/view_controls.h>
@@ -1182,3 +1183,11 @@ void PCB_EDIT_FRAME::PythonPluginsReload()
     #endif
 #endif
 }
+
+
+int PCB_EDIT_FRAME::InstallExchangeModuleFrame( MODULE* Module )
+{
+    DIALOG_EXCHANGE_MODULE dialog( this, Module );
+
+    return dialog.ShowQuasiModal();
+}
-- 
2.11.0


Follow ups