KiCad PCB EDA Suite
dialog_swap_layers.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) 2018 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <pcb_edit_frame.h>
25 #include <class_board.h>
26 #include <grid_layer_box_helpers.h>
27 #include <board_commit.h>
28 #include <class_drawsegment.h>
29 #include <class_drawpanel.h>
30 #include <class_track.h>
31 #include <view/view.h>
32 #include <widgets/wx_grid.h>
33 #include <class_zone.h>
34 
36 
37 
38 class LAYER_GRID_TABLE : public wxGridTableBase
39 {
42 
43 public:
44  LAYER_GRID_TABLE( int layerCount ) : m_layerCount( layerCount )
45  { }
46 
47  int GetNumberRows() override { return m_layerCount; }
48  int GetNumberCols() override { return 2; }
49 
50  wxString GetColLabelValue( int aCol ) override
51  {
52  switch( aCol )
53  {
54  case 0: return _( "Move items on:" );
55  case 1: return _( "To layer:" );
56  default: return wxEmptyString;
57  }
58  }
59 
60  wxString GetValue( int row, int col ) override { return "undefined"; }
61  void SetValue( int row, int col, const wxString& value ) override { }
62 
63  long GetValueAsLong( int row, int col ) override
64  {
65  return m_layers[ row ][ col ];
66  }
67 
68  void SetValueAsLong( int row, int col, long value ) override
69  {
70  m_layers[ row ][ col ] = value;
71  }
72 };
73 
74 
76 {
77 private:
80 
82 
83 public:
84  DIALOG_SWAP_LAYERS( PCB_EDIT_FRAME* aParent, PCB_LAYER_ID* aArray );
85  ~DIALOG_SWAP_LAYERS() override;
86 
87 private:
88  bool TransferDataToWindow() override;
89  bool TransferDataFromWindow() override;
90 
91  void OnSize( wxSizeEvent& event ) override;
92 
93  void adjustGridColumns( int aWidth );
94 };
95 
96 
98  DIALOG_SWAP_LAYERS_BASE( aParent ),
99  m_parent( aParent ),
100  m_layerDestinations( aArray )
101 {
104  m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
105  m_grid->SetCellHighlightROPenWidth( 0 );
106 
107  m_sdbSizerOK->SetDefault();
108 
110 }
111 
112 
114 {
116 }
117 
118 
120 {
121  LSET enabledCopperLayers = LSET::AllCuMask( m_parent->GetBoard()->GetCopperLayerCount() );
122  int row = 0;
123 
124  for( size_t layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
125  {
126  if( enabledCopperLayers.test( layer ) )
127  {
128  auto attr = new wxGridCellAttr;
129  attr->SetRenderer( new GRID_CELL_LAYER_RENDERER( m_parent ) );
130  attr->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) );
131  attr->SetReadOnly();
132  m_grid->SetAttr( row, 0, attr );
133 
134  attr = new wxGridCellAttr;
135  attr->SetRenderer( new GRID_CELL_LAYER_RENDERER( m_parent ) );
136  attr->SetEditor( new GRID_CELL_LAYER_SELECTOR( m_parent, LSET::AllNonCuMask() ) );
137  m_grid->SetAttr( row, 1, attr );
138 
139  m_grid->GetTable()->SetValueAsLong( row, 0, (long) layer );
140  m_grid->GetTable()->SetValueAsLong( row, 1, (long) layer );
141 
142  ++row;
143  }
144  }
145 
146  return true;
147 }
148 
149 
151 {
152  if( !m_grid->CommitPendingChanges() )
153  return false;
154 
155  LSET enabledCopperLayers = LSET::AllCuMask( m_parent->GetBoard()->GetCopperLayerCount() );
156  wxGridTableBase* table = m_grid->GetTable();
157  int row = 0;
158 
159  for( size_t layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
160  {
161  if( enabledCopperLayers.test( layer ) )
162  m_layerDestinations[ layer ] = (PCB_LAYER_ID) table->GetValueAsLong( row++, 1 );
163  else
164  m_layerDestinations[ layer ] = (PCB_LAYER_ID) layer;
165  }
166 
167  return true;
168 }
169 
170 
172 {
173  // Account for scroll bars
174  aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x );
175 
176  m_grid->SetColSize( 0, aWidth / 2 );
177  m_grid->SetColSize( 1, aWidth - m_grid->GetColSize( 0 ) );
178 }
179 
180 
181 void DIALOG_SWAP_LAYERS::OnSize( wxSizeEvent& event )
182 {
183  adjustGridColumns( event.GetSize().GetX() );
184 
185  event.Skip();
186 }
187 
188 
190  PCB_LAYER_ID* new_layer )
191 {
192  if( new_layer[ aItem->GetLayer() ] != aItem->GetLayer() )
193  {
194  commit.Modify( aItem );
195  aItem->SetLayer( new_layer[ aItem->GetLayer() ] );
196  aFrame->GetGalCanvas()->GetView()->Update( aItem, KIGFX::GEOMETRY );
197  return true;
198  }
199 
200  return false;
201 }
202 
203 
204 void PCB_EDIT_FRAME::Swap_Layers( wxCommandEvent& event )
205 {
206  PCB_LAYER_ID new_layer[PCB_LAYER_ID_COUNT];
207 
208  DIALOG_SWAP_LAYERS dlg( this, new_layer );
209 
210  if( dlg.ShowModal() != wxID_OK )
211  return;
212 
213  BOARD_COMMIT commit( this );
214  bool hasChanges = false;
215 
216  // Change tracks.
217  for( TRACK* segm = GetBoard()->m_Track; segm; segm = segm->Next() )
218  {
219  if( segm->Type() == PCB_VIA_T )
220  {
221  VIA* via = (VIA*) segm;
222  PCB_LAYER_ID top_layer, bottom_layer;
223 
224  if( via->GetViaType() == VIA_THROUGH )
225  continue;
226 
227  via->LayerPair( &top_layer, &bottom_layer );
228 
229  if( new_layer[bottom_layer] != bottom_layer || new_layer[top_layer] != top_layer )
230  {
231  commit.Modify( via );
232  via->SetLayerPair( new_layer[top_layer], new_layer[bottom_layer] );
233  GetGalCanvas()->GetView()->Update( via, KIGFX::GEOMETRY );
234  hasChanges = true;
235  }
236  }
237  else
238  {
239  hasChanges |= processBoardItem( this, commit, segm, new_layer );
240  }
241  }
242 
243  for( TRACK* segm = GetBoard()->m_SegZoneDeprecated; segm; segm = segm->Next() )
244  {
245  // Note: deprecated zone segment fills only found in very old boards
246  hasChanges |= processBoardItem( this, commit, segm, new_layer );
247  }
248 
249  for( BOARD_ITEM* zone : GetBoard()->Zones() )
250  {
251  hasChanges |= processBoardItem( this, commit, zone, new_layer );
252  }
253 
254  for( BOARD_ITEM* drawing : GetBoard()->Drawings() )
255  {
256  hasChanges |= processBoardItem( this, commit, drawing, new_layer );
257  }
258 
259  if( hasChanges )
260  {
261  OnModify();
262  commit.Push( "Layers moved" );
263  GetCanvas()->Refresh();
264  }
265 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
int GetNumberCols() override
PCB_LAYER_ID * m_layerDestinations
void SetValue(int row, int col, const wxString &value) override
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
wxString GetColLabelValue(int aCol) override
Class BOARD to handle a board.
static LSET AllNonCuMask()
Function AllNonCuMask returns a mask holding all layer minus CU layers.
Definition: lset.cpp:696
int m_layers[MAX_CU_LAYERS][2]
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int GetCopperLayerCount() const
Function GetCopperLayerCount.
LAYER_GRID_TABLE(int layerCount)
BOARD * GetBoard() const
Classes to handle copper zones.
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid&#39;s SetTable() method with one which doesn&#39;t mess up the grid column widths when setting th...
Definition: wx_grid.cpp:46
DIALOG_SWAP_LAYERS(PCB_EDIT_FRAME *aParent, PCB_LAYER_ID *aArray)
void Swap_Layers(wxCommandEvent &event)
Functions relatives to tracks, vias and segments used to fill zones.
wxString GetValue(int row, int col) override
int GetNumberRows() override
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
Definition: wx_grid.cpp:77
BOARD_ITEM * Next() const
long GetValueAsLong(int row, int col) override
void adjustGridColumns(int aWidth)
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
Class DIALOG_SWAP_LAYERS_BASE.
VIATYPE_T GetViaType() const
Definition: class_track.h:457
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_Layer contains the top layer, the other layer is in m_BottomLayer...
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:156
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1521
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
BOARD * GetBoard()
Class to handle a graphic segment.
bool processBoardItem(PCB_EDIT_FRAME *aFrame, BOARD_COMMIT &commit, BOARD_ITEM *aItem, PCB_LAYER_ID *new_layer)
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
bool TransferDataFromWindow() override
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:921
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
PCB_EDIT_FRAME * m_parent
void OnSize(wxSizeEvent &event) override
bool TransferDataToWindow() override
LAYER_GRID_TABLE * m_gridTable
Color has changed.
Definition: view_item.h:57
void SetValueAsLong(int row, int col, long value) override