KiCad PCB EDA Suite
dialog_dxf_import.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
10  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 #include <dialog_dxf_import.h>
31 #include <kiface_i.h>
32 #include <convert_to_biu.h>
33 #include <pcb_layer_box_selector.h>
35 
36 #include <class_board.h>
37 #include <class_module.h>
38 #include <class_edge_mod.h>
39 #include <class_text_mod.h>
40 #include <class_pcb_text.h>
41 
42 // Keys to store setup in config
43 #define DXF_IMPORT_LAYER_OPTION_KEY "DxfImportBrdLayer"
44 #define DXF_IMPORT_COORD_ORIGIN_KEY "DxfImportCoordOrigin"
45 #define DXF_IMPORT_LAST_FILE_KEY "DxfImportLastFile"
46 #define DXF_IMPORT_IMPORT_UNITS_KEY "DxfImportOffsetUnits"
47 #define DXF_IMPORT_IMPORT_OFFSET_X_KEY "DxfImportOffsetX"
48 #define DXF_IMPORT_IMPORT_OFFSET_Y_KEY "DxfImportOffsetY"
49 #define DXF_IMPORT_LINEWIDTH_UNITS_KEY "DxfImportLineWidthUnits"
50 #define DXF_IMPORT_LINEWIDTH_KEY "DxfImportLineWidth"
51 
52 
53 // Static members of DIALOG_DXF_IMPORT, to remember
54 // the user's choices during the session
58 
59 
60 DIALOG_DXF_IMPORT::DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent, bool aImportAsFootprintGraphic )
61  : DIALOG_DXF_IMPORT_BASE( aParent )
62 {
63  m_parent = aParent;
64  m_dxfImporter.ImportAsFootprintGraphic( aImportAsFootprintGraphic );
66  m_PcbImportUnits = 0;
67  m_PcbImportOffsetX = 0.0; // always in mm
68  m_PcbImportOffsetY = 0.0; // always in mm
69  m_PCBdefaultLineWidth = 0.2; // in mm
71 
72  if( m_config )
73  {
76  m_dxfFilename = m_config->Read( DXF_IMPORT_LAST_FILE_KEY, wxEmptyString );
82  }
83 
87 
88  m_DxfPcbPositionUnits->SetSelection( m_PcbImportUnits );
90 
91  m_textCtrlFileName->SetValue( m_dxfFilename );
92  m_rbOffsetOption->SetSelection( m_offsetSelection );
93 
94  // Configure the layers list selector
95  m_SelLayerBox->SetLayersHotkeys( false ); // Do not display hotkeys
96  m_SelLayerBox->SetNotAllowedLayerSet( LSET::AllCuMask() ); // Do not use copper layers
99 
101  {
102  m_layer = Dwgs_User;
104  }
105 
106  m_sdbSizerOK->SetDefault();
107  GetSizer()->Fit( this );
108  GetSizer()->SetSizeHints( this );
109  Centre();
110 }
111 
112 
114 {
115  m_offsetSelection = m_rbOffsetOption->GetSelection();
118 
119  if( m_config )
120  {
124 
128 
132  }
133 }
134 
135 
136 void DIALOG_DXF_IMPORT::DIALOG_DXF_IMPORT::onUnitPositionSelection( wxCommandEvent& event )
137 {
138  // Collect last entered values:
140 
141  m_PcbImportUnits = m_DxfPcbPositionUnits->GetSelection();;
143 }
144 
145 
147 {
148  double value = DoubleValueFromString( UNSCALED_UNITS, m_textCtrlLineWidth->GetValue() );
149 
150  switch( m_PCBLineWidthUnits )
151  {
152  default:
153  case 0: // display units = mm
154  break;
155 
156  case 1: // display units = mil
157  value *= 25.4 / 1000;
158  break;
159 
160  case 2: // display units = inch
161  value *= 25.4;
162  break;
163  }
164 
165  return value; // value is in mm
166 }
167 
168 
169 void DIALOG_DXF_IMPORT::onUnitWidthSelection( wxCommandEvent& event )
170 {
172 
173  // Switch to new units
174  m_PCBLineWidthUnits = m_choiceUnitLineWidth->GetSelection();
176 }
177 
178 
180 {
181  // Display m_PcbImportOffsetX and m_PcbImportOffsetY values according to
182  // the unit selection:
183  double xoffset = m_PcbImportOffsetX;
184  double yoffset = m_PcbImportOffsetY;
185 
186  if( m_PcbImportUnits ) // Units are inches
187  {
188  xoffset /= 25.4;
189  yoffset /= 25.4;
190  }
191 
192  m_DxfPcbXCoord->SetValue( wxString::Format( "%f", xoffset ) );
193  m_DxfPcbYCoord->SetValue( wxString::Format( "%f", yoffset ) );
194 
195 }
196 
197 
199 {
200  double value;
201 
202  switch( m_PCBLineWidthUnits )
203  {
204  default:
205  case 0: // display units = mm
206  value = m_PCBdefaultLineWidth;
207  break;
208 
209  case 1: // display units = mil
210  value = m_PCBdefaultLineWidth / 25.4 * 1000;
211  break;
212 
213  case 2: // display units = inch
214  value = m_PCBdefaultLineWidth / 25.4;
215  break;
216  }
217 
218  m_textCtrlLineWidth->SetValue( wxString::Format( "%f", value ) );
219 }
220 
221 
222 void DIALOG_DXF_IMPORT::OnBrowseDxfFiles( wxCommandEvent& event )
223 {
224  wxString path;
225  wxString filename;
226 
227  if( !m_dxfFilename.IsEmpty() )
228  {
229  wxFileName fn( m_dxfFilename );
230  path = fn.GetPath();
231  filename = fn.GetFullName();
232  }
233 
234  wxFileDialog dlg( m_parent,
235  _( "Open File" ),
236  path, filename,
237  DxfFileWildcard(),
238  wxFD_OPEN|wxFD_FILE_MUST_EXIST );
239 
240  if( dlg.ShowModal() != wxID_OK )
241  return;
242 
243  wxString fileName = dlg.GetPath();
244 
245  if( fileName.IsEmpty() )
246  return;
247 
248  m_dxfFilename = fileName;
249  m_textCtrlFileName->SetValue( fileName );
250 }
251 
252 
254 {
255  m_dxfFilename = m_textCtrlFileName->GetValue();
256 
257  if( m_dxfFilename.IsEmpty() )
258  {
259  wxMessageBox( _( "Error: No DXF filename!" ) );
260  return false;
261  }
262 
263  double offsetX = 0;
264  double offsetY = 0;
265 
266  m_offsetSelection = m_rbOffsetOption->GetSelection();
267 
268  switch( m_offsetSelection )
269  {
270  case 0:
271  offsetX = m_parent->GetPageSizeIU().x * MM_PER_IU / 2;
272  offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU / 2;
273  break;
274 
275  case 1:
276  break;
277 
278  case 2:
279  offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU / 2;
280  break;
281 
282  case 3:
283  offsetY = m_parent->GetPageSizeIU().y * MM_PER_IU;
284  break;
285 
286  case 4:
288  offsetX = m_PcbImportOffsetX;
289  offsetY = m_PcbImportOffsetY;
290  break;
291  }
292 
293  // Set coordinates offset for import (offset is given in mm)
294  m_dxfImporter.SetOffset( offsetX, offsetY );
296 
297  if( m_layer < 0 )
298  {
299  wxMessageBox( _( "Please, select a valid layer " ) );
300  return false;
301  }
302 
306 
307  // Read dxf file:
309 
310  // Get messages:
311  std::string& messages = m_dxfImporter.GetMessages();
312 
313  if( messages.empty() )
314  return true;
315 
316  // Show messages (list of net handled dxf items
317  wxMessageBox( messages.c_str(), _( "Not Handled DXF Items" ) );
318  return true;
319 }
320 
321 
323 {
324  DIALOG_DXF_IMPORT dlg( aCaller );
325  bool success = ( dlg.ShowModal() == wxID_OK );
326 
327  if( success )
328  {
329  const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
330  PICKED_ITEMS_LIST picklist;
331  BOARD* board = aCaller->GetBoard();
332 
333  std::list<BOARD_ITEM*>::const_iterator it, itEnd;
334  for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
335  {
336  BOARD_ITEM* item = *it;
337  board->Add( item );
338 
339  ITEM_PICKER itemWrapper( item, UR_NEW );
340  picklist.PushItem( itemWrapper );
341  }
342 
343  aCaller->SaveCopyInUndoList( picklist, UR_NEW, wxPoint( 0, 0 ) );
344  aCaller->OnModify();
345  }
346 
347  return success;
348 }
349 
350 
352 {
353  wxASSERT( aModule );
354 
355  DIALOG_DXF_IMPORT dlg( aCaller, true );
356  bool success = ( dlg.ShowModal() == wxID_OK );
357 
358  if( success )
359  {
360  const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
361 
362  aCaller->SaveCopyInUndoList( aModule, UR_CHANGED );
363  aCaller->OnModify();
364 
365  std::list<BOARD_ITEM*>::const_iterator it, itEnd;
366 
367  for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
368  {
369  aModule->Add( *it );
370  }
371  }
372 
373  return success;
374 }
375 
376 
377 void DIALOG_DXF_IMPORT::OriginOptionOnUpdateUI( wxUpdateUIEvent& event )
378 {
379  bool enable = m_rbOffsetOption->GetSelection() == 4;
380 
381  m_DxfPcbPositionUnits->Enable( enable );
382  m_DxfPcbXCoord->Enable( enable );
383  m_DxfPcbYCoord->Enable( enable );
384 }
385 
386 
388 {
391 
392  if( m_PcbImportUnits ) // Units are inches
393  {
394  m_PcbImportOffsetX *= 25.4;
395  m_PcbImportOffsetY *= 25.4;
396  }
397 
398  return;
399 }
DXF2BRD_CONVERTER m_dxfImporter
Class DIALOG_DXF_IMPORT_BASE.
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
#define DXF_IMPORT_LINEWIDTH_KEY
PCB_BASE_FRAME * m_parent
TEXTE_PCB class definition.
void OnBrowseDxfFiles(wxCommandEvent &event) override
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
void onUnitWidthSelection(wxCommandEvent &event) override
void SetNotAllowedLayerSet(LSET aMask)
#define DXF_IMPORT_LAYER_OPTION_KEY
Class BOARD to handle a board.
bool InvokeDXFDialogBoardImport(PCB_BASE_FRAME *aCaller)
Function InvokeDXFDialogBoardImport shows the modal DIALOG_DXF_IMPORT for importing a DXF file to a b...
wxString DxfFileWildcard()
#define DXF_IMPORT_IMPORT_UNITS_KEY
BOARD * GetBoard() const
void PushItem(const ITEM_PICKER &aItem)
Function PushItem pushes aItem to the top of the list.
bool InvokeDXFDialogModuleImport(PCB_BASE_FRAME *aCaller, MODULE *aModule)
Function InvokeDXFDialogModuleImport shows the modal DIALOG_DXF_IMPORT for importing a DXF file as fo...
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
void ImportAsFootprintGraphic(bool aImportAsFootprintGraphic)
Allows the import DXF items converted to board graphic items or footprint graphic items...
static LAYER_NUM m_layer
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
>
PCB_LAYER_BOX_SELECTOR * m_SelLayerBox
Footprint text class description.
wxConfigBase * m_config
std::string & GetMessages()
double DoubleValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue, bool aUseMils)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:302
bool ImportDxfFile(const wxString &aFile)
Implementation of the method used for communicate with this filter.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
The common library.
#define DXF_IMPORT_IMPORT_OFFSET_X_KEY
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
int SetLayerSelection(LAYER_NUM layer)
static int m_offsetSelection
#define DXF_IMPORT_LAST_FILE_KEY
void OriginOptionOnUpdateUI(wxUpdateUIEvent &event) override
Class PICKED_ITEMS_LIST is a holder to handle information on schematic or board items.
bool SetLayersHotkeys(bool value)
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
static wxString m_dxfFilename
void SetOffset(double aOffsetX, double aOffsetY)
Set the coordinate offset between the imported dxf items and Pcbnew.
virtual void OnModify()
Function OnModify Virtual Must be called after a change in order to set the "modify" flag of the curr...
const std::list< BOARD_ITEM * > & GetImportedItems() const
Function GetImportedItems()
#define DXF_IMPORT_IMPORT_OFFSET_Y_KEY
bool TransferDataFromWindow() override
void SetBrdLayer(int aBrdLayer)
Set the layer number to import dxf items.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
#define DXF_IMPORT_LINEWIDTH_UNITS_KEY
LAYER_NUM GetLayerSelection() const
virtual void SaveCopyInUndoList(BOARD_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, const wxPoint &aTransformPoint=wxPoint(0, 0))=0
Function SaveCopyInUndoList (virtual pure) Creates a new entry in undo list of commands.
const wxSize GetPageSizeIU() const override
Function GetPageSizeIU works off of GetPageSettings() to return the size of the paper page in the int...
Module description (excepted pads)
DIALOG_DXF_IMPORT(PCB_BASE_FRAME *aParent, bool aUseModuleItems=false)
EDGE_MODULE class definition.
void SetDefaultLineWidthMM(double aWidth)
Set the default line width when importing dxf items like lines to Pcbnew.
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
#define DXF_IMPORT_COORD_ORIGIN_KEY