diff --git a/pcbnew/dialogs/dialog_pns_settings.cpp b/pcbnew/dialogs/dialog_pns_settings.cpp
index 04424e611b..fd2e1337eb 100644
--- a/pcbnew/dialogs/dialog_pns_settings.cpp
+++ b/pcbnew/dialogs/dialog_pns_settings.cpp
@@ -49,6 +49,7 @@ DIALOG_PNS_SETTINGS::DIALOG_PNS_SETTINGS( wxWindow* aParent, PNS::ROUTING_SETTIN
m_dragToolMode->SetSelection ( m_settings.InlineDragEnabled() ? 1 : 0 );
m_optimizeDraggedTrack->SetValue( m_settings.GetOptimizeDraggedTrack() );
m_autoPosture->SetValue( m_settings.GetAutoPosture() );
+ m_fixAllSegments->SetValue( m_settings.GetFixAllSegments() );
// Enable/disable some options
wxCommandEvent event;
@@ -78,6 +79,7 @@ void DIALOG_PNS_SETTINGS::OnOkClick( wxCommandEvent& aEvent )
m_settings.SetInlineDragEnabled( m_dragToolMode->GetSelection () ? true : false );
m_settings.SetOptimizeDraggedTrack( m_optimizeDraggedTrack->GetValue() );
m_settings.SetAutoPosture( m_autoPosture->GetValue() );
+ m_settings.SetFixAllSegments( m_fixAllSegments->GetValue() );
if( m_mode->GetSelection() == PNS::RM_MarkObstacles )
{
diff --git a/pcbnew/dialogs/dialog_pns_settings_base.cpp b/pcbnew/dialogs/dialog_pns_settings_base.cpp
index 531b481929..e5449ccfbc 100644
--- a/pcbnew/dialogs/dialog_pns_settings_base.cpp
+++ b/pcbnew/dialogs/dialog_pns_settings_base.cpp
@@ -91,6 +91,11 @@ DIALOG_PNS_SETTINGS_BASE::DIALOG_PNS_SETTINGS_BASE( wxWindow* parent, wxWindowID
bOptions->Add( m_autoPosture, 0, wxALL, 5 );
+ m_fixAllSegments = new wxCheckBox( bOptions->GetStaticBox(), wxID_ANY, _("Fix all segments on click"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_fixAllSegments->SetToolTip( _("When enabled, all track segments will be fixed in place up to the cursor location. When disabled, the last segment (closest to the cursor) will remain free and follow the cursor.") );
+
+ bOptions->Add( m_fixAllSegments, 0, wxALL, 5 );
+
wxBoxSizer* bEffort;
bEffort = new wxBoxSizer( wxHORIZONTAL );
diff --git a/pcbnew/dialogs/dialog_pns_settings_base.fbp b/pcbnew/dialogs/dialog_pns_settings_base.fbp
index 318c6af399..e6264aaafd 100644
--- a/pcbnew/dialogs/dialog_pns_settings_base.fbp
+++ b/pcbnew/dialogs/dialog_pns_settings_base.fbp
@@ -921,6 +921,70 @@
+
5
wxEXPAND|wxALL
diff --git a/pcbnew/dialogs/dialog_pns_settings_base.h b/pcbnew/dialogs/dialog_pns_settings_base.h
index ea76737e04..db8a83ca1b 100644
--- a/pcbnew/dialogs/dialog_pns_settings_base.h
+++ b/pcbnew/dialogs/dialog_pns_settings_base.h
@@ -50,6 +50,7 @@ class DIALOG_PNS_SETTINGS_BASE : public DIALOG_SHIM
wxCheckBox* m_suggestEnding;
wxCheckBox* m_optimizeDraggedTrack;
wxCheckBox* m_autoPosture;
+ wxCheckBox* m_fixAllSegments;
wxStaticText* m_effortLabel;
wxSlider* m_effort;
wxStaticText* m_lowLabel;
diff --git a/pcbnew/pcbnew_settings.cpp b/pcbnew/pcbnew_settings.cpp
index 5898632f7d..c884c61737 100644
--- a/pcbnew/pcbnew_settings.cpp
+++ b/pcbnew/pcbnew_settings.cpp
@@ -722,6 +722,9 @@ bool PCBNEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
ret &= fromLegacy( aCfg, p + "FreeAngleMode", "tools.pns.free_angle_mode" );
ret &= fromLegacy( aCfg, p + "InlineDragEnabled", "tools.pns.inline_drag" );
+ // Initialize some new PNS settings to legacy behaviors if coming from legacy
+ ( *this )[PointerFromString( "tools.pns.fix_all_segments" )] = false;
+
// Migrate color settings that were stored in the pcbnew config file
COLOR_SETTINGS* cs = Pgm().GetSettingsManager().GetMigratedColorSettings();
diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp
index a3c2be400e..281ee7795b 100644
--- a/pcbnew/router/pns_line_placer.cpp
+++ b/pcbnew/router/pns_line_placer.cpp
@@ -1089,6 +1089,7 @@ bool LINE_PLACER::Move( const VECTOR2I& aP, ITEM* aEndItem )
bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish )
{
+ bool fixAll = Settings().GetFixAllSegments();
bool realEnd = false;
int lastV;
@@ -1148,7 +1149,7 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
if( aForceFinish )
realEnd = true;
- if( realEnd || m_placingVia )
+ if( realEnd || m_placingVia || fixAll )
lastV = l.SegmentCount();
else
lastV = std::max( 1, l.SegmentCount() - 1 );
@@ -1193,7 +1194,7 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis
if( !realEnd )
{
setInitialDirection( d_last );
- m_currentStart = m_placingVia ? p_last : p_pre_last;
+ m_currentStart = ( m_placingVia || fixAll ) ? p_last : p_pre_last;
m_fixedTail.AddStage( m_p_start, m_currentLayer, m_placingVia, m_direction, m_currentNode );
@@ -1251,7 +1252,7 @@ bool LINE_PLACER::UnfixRoute()
m_head.RemoveVia();
m_tail.RemoveVia();
- if (m_shove)
+ if( m_shove )
{
m_shove->RewindSpringbackTo( m_currentNode );
m_shove->UnlockSpringbackNode( m_currentNode );
diff --git a/pcbnew/router/pns_routing_settings.cpp b/pcbnew/router/pns_routing_settings.cpp
index 0f5a5463cf..c4dae8e996 100644
--- a/pcbnew/router/pns_routing_settings.cpp
+++ b/pcbnew/router/pns_routing_settings.cpp
@@ -55,6 +55,7 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
m_maxRadius = 1000000;
m_roundedCorners = false;
m_autoPosture = true;
+ m_fixAllSegments = true;
m_params.emplace_back( new PARAM( "mode", reinterpret_cast( &m_routingMode ),
static_cast( RM_Walkaround ) ) );
@@ -97,6 +98,7 @@ ROUTING_SETTINGS::ROUTING_SETTINGS( JSON_SETTINGS* aParent, const std::string& a
m_params.emplace_back( new PARAM( "max_radius", &m_maxRadius, 1000000 ) );
m_params.emplace_back( new PARAM( "use_rounded", &m_roundedCorners, false ) );
m_params.emplace_back( new PARAM( "auto_posture", &m_autoPosture, true ) );
+ m_params.emplace_back( new PARAM( "fix_all_segments", &m_fixAllSegments, true ) );
LoadFromFile();
}
diff --git a/pcbnew/router/pns_routing_settings.h b/pcbnew/router/pns_routing_settings.h
index 19f9ca3edf..b46dd72f99 100644
--- a/pcbnew/router/pns_routing_settings.h
+++ b/pcbnew/router/pns_routing_settings.h
@@ -150,6 +150,9 @@ public:
bool GetAutoPosture() const { return m_autoPosture; }
void SetAutoPosture( bool aEnable ) { m_autoPosture = aEnable; }
+ bool GetFixAllSegments() const { return m_fixAllSegments; }
+ void SetFixAllSegments( bool aEnable ) { m_fixAllSegments = aEnable; }
+
void SetMinRadius( int aRadius )
{
m_minRadius = aRadius;
@@ -186,6 +189,7 @@ private:
bool m_roundedCorners;
bool m_optimizeDraggedTrack;
bool m_autoPosture;
+ bool m_fixAllSegments;
int m_minRadius;
int m_maxRadius;