KiCad PCB EDA Suite
zone_filler_tool.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014-2017 CERN
5  * Copyright (C) 2014-2018 KiCad Developers, see AUTHORS.txt for contributors.
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 #include <cstdint>
26 #include <thread>
27 #include <class_zone.h>
29 #include <board_commit.h>
31 #include <wx/event.h>
32 #include <tool/tool_manager.h>
33 #include "pcb_actions.h"
34 #include "zone_filler_tool.h"
35 #include "zone_filler.h"
36 
37 
39  PCB_TOOL_BASE( "pcbnew.ZoneFiller" )
40 {
41 }
42 
43 
45 {
46 }
47 
48 
50 {
51 }
52 
53 
54 void ZONE_FILLER_TOOL::CheckAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter )
55 {
56  if( !getEditFrame<PCB_EDIT_FRAME>()->m_ZoneFillsDirty )
57  return;
58 
59  std::vector<ZONE_CONTAINER*> toFill;
60 
61  for( auto zone : board()->Zones() )
62  toFill.push_back(zone);
63 
64  BOARD_COMMIT commit( this );
65 
66  ZONE_FILLER filler( frame()->GetBoard(), &commit );
67 
68  if( aReporter )
69  filler.SetProgressReporter( aReporter );
70  else
71  filler.InstallNewProgressReporter( aCaller, _( "Checking Zones" ), 4 );
72 
73  if( filler.Fill( toFill, true, aCaller ) )
74  {
75  commit.Push( _( "Fill Zone(s)" ), false );
76  getEditFrame<PCB_EDIT_FRAME>()->m_ZoneFillsDirty = false;
77  }
78  else
79  {
80  commit.Revert();
81  }
82 
83  canvas()->Refresh();
84 }
85 
86 
88 {
89  canvas()->SetFocus();
90  canvas()->Unbind( wxEVT_IDLE, &ZONE_FILLER_TOOL::singleShotRefocus, this );
91 }
92 
93 
94 void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter )
95 {
96  std::vector<ZONE_CONTAINER*> toFill;
97 
98  BOARD_COMMIT commit( this );
99 
100  for( ZONE_CONTAINER* zone : board()->Zones() )
101  toFill.push_back( zone );
102 
103  ZONE_FILLER filler( board(), &commit );
104 
105  if( aReporter )
106  filler.SetProgressReporter( aReporter );
107  else
108  filler.InstallNewProgressReporter( aCaller, _( "Fill All Zones" ), 3 );
109 
110  if( filler.Fill( toFill ) )
111  {
112  commit.Push( _( "Fill Zone(s)" ), false );
113  getEditFrame<PCB_EDIT_FRAME>()->m_ZoneFillsDirty = false;
114  }
115  else
116  {
117  commit.Revert();
118  }
119 
120  canvas()->Refresh();
121 
122  // wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus
123  // here doesn't work, so we delay it to an idle event.
124  canvas()->Bind( wxEVT_IDLE, &ZONE_FILLER_TOOL::singleShotRefocus, this );
125 }
126 
127 
129 {
130  std::vector<ZONE_CONTAINER*> toFill;
131 
132  BOARD_COMMIT commit( this );
133 
134  if( auto passedZone = aEvent.Parameter<ZONE_CONTAINER*>() )
135  {
136  if( passedZone->Type() == PCB_ZONE_AREA_T )
137  toFill.push_back( passedZone );
138  }
139  else
140  {
141  for( auto item : selection() )
142  {
143  if( auto zone = dyn_cast<ZONE_CONTAINER*>( item ) )
144  toFill.push_back( zone );
145  }
146  }
147 
148  ZONE_FILLER filler( board(), &commit );
149  filler.InstallNewProgressReporter( frame(), _( "Fill Zone" ), 4 );
150 
151  if( filler.Fill( toFill ) )
152  commit.Push( _( "Fill Zone(s)" ), false );
153  else
154  commit.Revert();
155 
156  canvas()->Refresh();
157  return 0;
158 }
159 
160 
162 {
163  FillAllZones( frame() );
164  return 0;
165 }
166 
167 
169 {
170  BOARD_COMMIT commit( this );
171 
172  for( EDA_ITEM* item : selection() )
173  {
174  assert( item->Type() == PCB_ZONE_AREA_T );
175 
176  ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
177 
178  commit.Modify( zone );
179 
180  zone->SetIsFilled( false );
181  zone->ClearFilledPolysList();
182  }
183 
184  commit.Push( _( "Unfill Zone" ) );
185  canvas()->Refresh();
186 
187  return 0;
188 }
189 
190 
192 {
193  BOARD_COMMIT commit( this );
194 
195  for( ZONE_CONTAINER* zone : board()->Zones() )
196  {
197  commit.Modify( zone );
198 
199  zone->SetIsFilled( false );
200  zone->ClearFilledPolysList();
201  }
202 
203  commit.Push( _( "Unfill All Zones" ) );
204  canvas()->Refresh();
205 
206  return 0;
207 }
208 
209 
211 {
212  // Zone actions
217 }
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:61
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
BOARD * board() const
int ZoneUnfill(const TOOL_EVENT &aEvent)
static TOOL_ACTION zoneFillAll
Definition: pcb_actions.h:297
A progress reporter for use in multi-threaded environments.
virtual void Revert() override
Revertes the commit by restoring the modifed items state.
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:106
int ZoneUnfillAll(const TOOL_EVENT &aEvent)
void singleShotRefocus(wxIdleEvent &)
Refocuses on an idle event (used after the Progress Reporter messes up the focus)
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
static TOOL_ACTION zoneFill
Definition: pcb_actions.h:296
void InstallNewProgressReporter(wxWindow *aParent, const wxString &aTitle, int aNumPhases)
Definition: zone_filler.cpp:71
PCB_BASE_EDIT_FRAME * frame() const
void FillAllZones(wxWindow *aCaller, PROGRESS_REPORTER *aReporter=nullptr)
void CheckAllZones(wxWindow *aCaller, PROGRESS_REPORTER *aReporter=nullptr)
const PCBNEW_SELECTION & selection() const
int ZoneFill(const TOOL_EVENT &aEvent)
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
Definition: zone_filler.cpp:79
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
TOOL_EVENT.
Definition: tool_event.h:171
virtual void SetFocus() override
static TOOL_ACTION zoneUnfillAll
Definition: pcb_actions.h:299
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
static TOOL_ACTION zoneUnfill
Definition: pcb_actions.h:298
BOARD * GetBoard()
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
void setTransitions() override
Sets up handlers for various events.
#define _(s)
Definition: 3d_actions.cpp:33
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
PCB_DRAW_PANEL_GAL * canvas() const
bool Fill(std::vector< ZONE_CONTAINER * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Definition: zone_filler.cpp:86
int ZoneFillAll(const TOOL_EVENT &aEvent)