← Back to team overview

kicad-developers team mailing list archive

[PATCH] Add duplicate zone onto layer tool

 

Hi,

This patch adds a missing tool to GAL: duplicate zone onto layer.

It's accessed through the zones context menu and does the same as the
legacy mode version.

Cheers,

John
From 031b15406695e60b17af6bb9e8b984e662c728d8 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Mon, 6 Feb 2017 11:45:56 +0800
Subject: [PATCH] Add zone duplicate onto layer to GAL

This adds it into the PCB_EDITOR_CONTROL tool, alongside the zone merge
tool.
---
 pcbnew/tools/common_actions.cpp     |  5 +++
 pcbnew/tools/common_actions.h       |  3 ++
 pcbnew/tools/pcb_editor_control.cpp | 66 +++++++++++++++++++++++++++++++++++++
 pcbnew/tools/pcb_editor_control.h   |  3 ++
 4 files changed, 77 insertions(+)

diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp
index d6cfd3b74..78102f576 100644
--- a/pcbnew/tools/common_actions.cpp
+++ b/pcbnew/tools/common_actions.cpp
@@ -415,6 +415,11 @@ TOOL_ACTION COMMON_ACTIONS::zoneMerge( "pcbnew.EditorControl.zoneMerge",
         AS_GLOBAL, 0,
         _( "Merge zones" ), _( "Merge zones" ) );
 
+TOOL_ACTION COMMON_ACTIONS::zoneDuplicate( "pcbnew.EditorControl.zoneDuplicate",
+        AS_GLOBAL, 0,
+        _( "Duplicate zone onto layer" ), _( "Duplicate zone outline onto a different layer" ),
+        zone_duplicate_xpm );
+
 
 TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.EditorControl.placeTarget",
         AS_GLOBAL, 0,
diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h
index 42a3f1528..c81b9e073 100644
--- a/pcbnew/tools/common_actions.h
+++ b/pcbnew/tools/common_actions.h
@@ -262,6 +262,9 @@ public:
     static TOOL_ACTION zoneUnfillAll;
     static TOOL_ACTION zoneMerge;
 
+    /// Duplicate zone onto another layer
+    static TOOL_ACTION zoneDuplicate;
+
     // Module editor tools
     /// Activation of the drawing tool (placing a PAD)
     static TOOL_ACTION placePad;
diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp
index 614bd14f5..0c2fdd57e 100644
--- a/pcbnew/tools/pcb_editor_control.cpp
+++ b/pcbnew/tools/pcb_editor_control.cpp
@@ -45,6 +45,7 @@
 #include <collectors.h>
 #include <zones_functions_for_undo_redo.h>
 #include <board_commit.h>
+#include <confirm.h>
 
 #include <view/view_group.h>
 #include <view/view_controls.h>
@@ -68,7 +69,11 @@ public:
         Add( COMMON_ACTIONS::zoneFillAll );
         Add( COMMON_ACTIONS::zoneUnfill );
         Add( COMMON_ACTIONS::zoneUnfillAll );
+
+        AppendSeparator();
+
         Add( COMMON_ACTIONS::zoneMerge );
+        Add( COMMON_ACTIONS::zoneDuplicate );
     }
 
 protected:
@@ -82,6 +87,13 @@ private:
     {
         SELECTION_TOOL* selTool = getToolManager()->GetTool<SELECTION_TOOL>();
 
+        // enable zone actions that act on a single zone
+        bool singleZoneActionsEnabled = ( SELECTION_CONDITIONS::Count( 1 )
+                                          && SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T )
+                                        )( selTool->GetSelection() );
+
+        Enable( getMenuId( COMMON_ACTIONS::zoneDuplicate), singleZoneActionsEnabled );
+
         // enable zone actions that ably to a specific set of zones (as opposed to all of them)
         bool nonGlobalActionsEnabled = ( SELECTION_CONDITIONS::MoreThan( 0 ) )( selTool->GetSelection() );
 
@@ -721,6 +733,59 @@ int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
 }
 
 
+int PCB_EDITOR_CONTROL::ZoneDuplicate( const TOOL_EVENT& aEvent )
+{
+    auto selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+    const auto& selection = selTool->GetSelection();
+
+    // because this pops up the zone editor, it would be confusing
+    // to handle multiple zones, so just handle single selections
+    // containing exactly one zone
+    if ( selection.Size() != 1 )
+        return 0;
+
+    auto oldZone = dyn_cast<ZONE_CONTAINER*>( selection[0] );
+
+    if ( !oldZone )
+        return 0;
+
+    auto newZone = std::make_unique<ZONE_CONTAINER>( *oldZone );
+    newZone->UnFill();
+    ZONE_SETTINGS zoneSettings;
+    zoneSettings << *oldZone;
+
+    bool success = false;
+
+    if( oldZone->GetIsKeepout() )
+        success = InvokeKeepoutAreaEditor( m_frame, &zoneSettings );
+    else if( oldZone->IsOnCopperLayer() )
+        success = InvokeCopperZonesEditor( m_frame, &zoneSettings );
+    else
+        success = InvokeNonCopperZonesEditor( m_frame, oldZone, &zoneSettings );
+
+    // If the new zone is on the same layer as the the initial zone,
+    // do nothing
+    if( success && ( oldZone->GetLayer() == zoneSettings.m_CurrentZone_Layer ) )
+    {
+        DisplayError( m_frame,
+            _( "The duplicated zone cannot be on the same layer as the original zone." ) );
+        success = false;
+    }
+
+    // duplicate the zone
+    if( success )
+    {
+        BOARD_COMMIT commit( m_frame );
+        zoneSettings.ExportSetting( *newZone );
+
+        commit.Add( newZone.release() );
+        commit.Push( _( "Duplicate zone" ) );
+    }
+
+    return 0;
+}
+
+
 int PCB_EDITOR_CONTROL::CrossProbePcbToSch( const TOOL_EVENT& aEvent )
 {
     if( m_probingSchToPcb )
@@ -887,6 +952,7 @@ void PCB_EDITOR_CONTROL::SetTransitions()
     Go( &PCB_EDITOR_CONTROL::ZoneUnfill,         COMMON_ACTIONS::zoneUnfill.MakeEvent() );
     Go( &PCB_EDITOR_CONTROL::ZoneUnfillAll,      COMMON_ACTIONS::zoneUnfillAll.MakeEvent() );
     Go( &PCB_EDITOR_CONTROL::ZoneMerge,          COMMON_ACTIONS::zoneMerge.MakeEvent() );
+    Go( &PCB_EDITOR_CONTROL::ZoneDuplicate,      COMMON_ACTIONS::zoneDuplicate.MakeEvent() );
 
     // Placing tools
     Go( &PCB_EDITOR_CONTROL::PlaceTarget,        COMMON_ACTIONS::placeTarget.MakeEvent() );
diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h
index 1647297d1..3684a1b1e 100644
--- a/pcbnew/tools/pcb_editor_control.h
+++ b/pcbnew/tools/pcb_editor_control.h
@@ -63,6 +63,9 @@ public:
     int ZoneUnfillAll( const TOOL_EVENT& aEvent );
     int ZoneMerge( const TOOL_EVENT& aEvent );
 
+    ///> Duplicates a zone onto a layer (prompts for new layer)
+    int ZoneDuplicate( const TOOL_EVENT& aEvent );
+
     /**
      * Function PlaceTarget()
      * Allows user to place a layer alignment target.
-- 
2.11.0


Follow ups