diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index b39de81b7d..e526ade49e 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -1006,6 +1006,18 @@ bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent ) return false; } + ZONE_FILLER_TOOL* zoneFillerTool = m_toolManager->GetTool(); + + if( zoneFillerTool->IsBusy() ) + { + wxBell(); + + if( wxWindow* reporter = dynamic_cast( zoneFillerTool->GetProgressReporter() ) ) + reporter->ShowWithEffect( wxSHOW_EFFECT_EXPAND ); + + return false; + } + if( Kiface().IsSingle() ) { auto* fpEditor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_FOOTPRINT_EDITOR, false ); diff --git a/pcbnew/tools/zone_filler_tool.cpp b/pcbnew/tools/zone_filler_tool.cpp index 9853a609e7..3505be2b08 100644 --- a/pcbnew/tools/zone_filler_tool.cpp +++ b/pcbnew/tools/zone_filler_tool.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2014-2017 CERN - * Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors. * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -75,19 +75,20 @@ void ZONE_FILLER_TOOL::CheckAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRep BOARD_COMMIT commit( this ); std::unique_ptr reporter; - ZONE_FILLER filler( frame()->GetBoard(), &commit ); + + m_filler = std::make_unique( frame()->GetBoard(), &commit ); if( aReporter ) { - filler.SetProgressReporter( aReporter ); + m_filler->SetProgressReporter( aReporter ); } else { reporter = std::make_unique( aCaller, _( "Checking Zones" ), 4 ); - filler.SetProgressReporter( reporter.get() ); + m_filler->SetProgressReporter( reporter.get() ); } - if( filler.Fill( toFill, true, aCaller ) ) + if( m_filler->Fill( toFill, true, aCaller ) ) { commit.Push( _( "Fill Zone(s)" ), SKIP_CONNECTIVITY | ZONE_FILL_OP ); getEditFrame()->m_ZoneFillsDirty = false; @@ -101,6 +102,7 @@ void ZONE_FILLER_TOOL::CheckAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRep refresh(); m_fillInProgress = false; + m_filler.reset( nullptr ); } @@ -128,7 +130,8 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo BOARD_COMMIT commit( this ); std::unique_ptr reporter; - ZONE_FILLER filler( board(), &commit ); + + m_filler = std::make_unique( board(), &commit ); if( !board()->GetDesignSettings().m_DRCEngine->RulesValid() ) { @@ -152,17 +155,17 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo if( aReporter ) { - filler.SetProgressReporter( aReporter ); + m_filler->SetProgressReporter( aReporter ); } else { reporter = std::make_unique( aCaller, _( "Fill All Zones" ), 5 ); - filler.SetProgressReporter( reporter.get() ); + m_filler->SetProgressReporter( reporter.get() ); } - if( filler.Fill( toFill ) ) + if( m_filler->Fill( toFill ) ) { - filler.GetProgressReporter()->AdvancePhase(); + m_filler->GetProgressReporter()->AdvancePhase(); commit.Push( _( "Fill Zone(s)" ), SKIP_CONNECTIVITY | ZONE_FILL_OP ); frame->m_ZoneFillsDirty = false; @@ -175,10 +178,11 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo rebuildConnectivity(); refresh(); - if( filler.IsDebug() ) + if( m_filler->IsDebug() ) frame->UpdateUserInterface(); m_fillInProgress = false; + m_filler.reset( nullptr ); // wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus // here doesn't work, so we delay it to an idle event. @@ -212,9 +216,10 @@ int ZONE_FILLER_TOOL::ZoneFillDirty( const TOOL_EVENT& aEvent ) BOARD_COMMIT commit( this ); std::unique_ptr reporter; - ZONE_FILLER filler( board(), &commit ); int pts = 0; + m_filler = std::make_unique( board(), &commit ); + if( !board()->GetDesignSettings().m_DRCEngine->RulesValid() ) { WX_INFOBAR* infobar = frame->GetInfoBar(); @@ -245,12 +250,12 @@ int ZONE_FILLER_TOOL::ZoneFillDirty( const TOOL_EVENT& aEvent ) wxString title = wxString::Format( _( "Refill %d Zones" ), (int) toFill.size() ); reporter = std::make_unique( frame, title, 5 ); - filler.SetProgressReporter( reporter.get() ); + m_filler->SetProgressReporter( reporter.get() ); break; } } - if( filler.Fill( toFill ) ) + if( m_filler->Fill( toFill ) ) commit.Push( _( "Auto-fill Zone(s)" ), APPEND_UNDO | SKIP_CONNECTIVITY | ZONE_FILL_OP ); else commit.Revert(); @@ -279,10 +284,11 @@ int ZONE_FILLER_TOOL::ZoneFillDirty( const TOOL_EVENT& aEvent ) 10000, wxICON_INFORMATION, WX_INFOBAR::MESSAGE_TYPE::GENERIC ); } - if( filler.IsDebug() ) + if( m_filler->IsDebug() ) frame->UpdateUserInterface(); m_fillInProgress = false; + m_filler.reset( nullptr ); // wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus // here doesn't work, so we delay it to an idle event. @@ -319,12 +325,13 @@ int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent ) BOARD_COMMIT commit( this ); std::unique_ptr reporter; - ZONE_FILLER filler( board(), &commit ); + + m_filler = std::make_unique( board(), &commit ); reporter = std::make_unique( frame(), _( "Fill Zone" ), 5 ); - filler.SetProgressReporter( reporter.get() ); + m_filler->SetProgressReporter( reporter.get() ); - if( filler.Fill( toFill ) ) + if( m_filler->Fill( toFill ) ) { reporter->AdvancePhase(); commit.Push( _( "Fill Zone(s)" ), SKIP_CONNECTIVITY | ZONE_FILL_OP ); @@ -338,6 +345,7 @@ int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent ) refresh(); m_fillInProgress = false; + m_filler.reset( nullptr ); return 0; } @@ -391,6 +399,15 @@ int ZONE_FILLER_TOOL::ZoneUnfillAll( const TOOL_EVENT& aEvent ) } +PROGRESS_REPORTER* ZONE_FILLER_TOOL::GetProgressReporter() +{ + if( m_fillInProgress && m_filler ) + return m_filler->GetProgressReporter(); + else + return nullptr; +} + + void ZONE_FILLER_TOOL::rebuildConnectivity() { board()->BuildConnectivity(); diff --git a/pcbnew/tools/zone_filler_tool.h b/pcbnew/tools/zone_filler_tool.h index b1a56e7998..2c1cf80a46 100644 --- a/pcbnew/tools/zone_filler_tool.h +++ b/pcbnew/tools/zone_filler_tool.h @@ -34,6 +34,7 @@ class PCB_EDIT_FRAME; class PROGRESS_REPORTER; class WX_PROGRESS_REPORTER; +class ZONE_FILLER; /** @@ -59,6 +60,8 @@ public: bool IsBusy() { return m_fillInProgress; } + PROGRESS_REPORTER* GetProgressReporter(); + void DirtyZone( ZONE* aZone ) { m_dirtyZoneIDs.insert( aZone->m_Uuid ); @@ -77,9 +80,10 @@ private: void setTransitions() override; private: - bool m_fillInProgress; + std::unique_ptr m_filler; + bool m_fillInProgress; - std::set m_dirtyZoneIDs; + std::set m_dirtyZoneIDs; }; #endif