KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_import_graphics.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 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
26
29#include <base_units.h>
30#include <kiface_base.h>
31#include <locale_io.h>
34#include <bitmaps.h>
36#include <map>
37#include <footprint.h>
38#include <wx/filedlg.h>
39#include <wx/msgdlg.h>
40
41#include <memory>
42
43// Static members of DIALOG_IMPORT_GRAPHICS, to remember the user's choices during the session
49double DIALOG_IMPORT_GRAPHICS::s_importScale = 1.0; // Do not change the imported items size
50
51
52const std::map<DXF_IMPORT_UNITS, wxString> dxfUnitsMap = {
53 { DXF_IMPORT_UNITS::INCHES, _( "Inches" ) },
54 { DXF_IMPORT_UNITS::MILLIMETERS, _( "Millimeters" ) },
55 { DXF_IMPORT_UNITS::MILS, _( "Mils" ) },
56 { DXF_IMPORT_UNITS::CENTIMETERS, _( "Centimeter" ) },
57 { DXF_IMPORT_UNITS::FEET, _( "Feet" ) },
58};
59
60
63 m_parent( aParent ),
64 m_xOrigin( aParent, nullptr, m_xCtrl, nullptr ),
65 m_yOrigin( aParent, m_yLabel, m_yCtrl, m_yUnits ),
66 m_defaultLineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits ),
67 m_tolerance( aParent, m_toleranceLabel, m_toleranceCtrl, m_toleranceUnits )
68{
69 // The SVG import has currently a flaw: all SVG shapes are imported as curves and
70 // converted to a lot of segments. A better approach is to convert to polylines
71 // (not yet existing in Pcbnew) and keep arcs and circles as primitives (not yet
72 // possible with tinysvg library).
73
74 m_importer = std::make_unique<GRAPHICS_IMPORTER_PCBNEW>( aParent->GetModel() );
75 m_gfxImportMgr = std::make_unique<GRAPHICS_IMPORT_MGR>();
76
78
83
87
91
92 m_importScaleCtrl->SetValue( wxString::Format( wxT( "%f" ), s_importScale ) );
93
96
99
100 // Configure the layers list selector
101 m_SelLayerBox->SetLayersHotkeys( false ); // Do not display hotkeys
104
107
108 for( const std::pair<const DXF_IMPORT_UNITS, wxString>& unitEntry : dxfUnitsMap )
109 m_dxfUnitsChoice->Append( unitEntry.second );
110
111 m_dxfUnitsChoice->SetSelection( cfg->m_ImportGraphics.dxf_units );
112
113 m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
114
115 wxCommandEvent dummy;
116 onFilename( dummy );
117
120
121 GetSizer()->Fit( this );
122 GetSizer()->SetSizeHints( this );
123 Centre();
124
125 m_textCtrlFileName->Connect( wxEVT_COMMAND_TEXT_UPDATED,
126 wxCommandEventHandler( DIALOG_IMPORT_GRAPHICS::onFilename ),
127 nullptr, this );
128}
129
130
132{
136 s_shouldGroupItems = m_cbGroupItems->IsChecked();
138
139 PCBNEW_SETTINGS* cfg = nullptr;
140
141 try
142 {
144 }
145 catch( const std::runtime_error& e )
146 {
147 wxFAIL_MSG( e.what() );
148 }
149
150 if( cfg )
151 {
159 cfg->m_ImportGraphics.dxf_units = m_dxfUnitsChoice->GetSelection();
163 }
164
166
167 m_textCtrlFileName->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
168 wxCommandEventHandler( DIALOG_IMPORT_GRAPHICS::onFilename ),
169 nullptr, this );
170}
171
172
173void DIALOG_IMPORT_GRAPHICS::onFilename( wxCommandEvent& event )
174{
175 bool enableDXFControls = true;
176 wxString ext = wxFileName( m_textCtrlFileName->GetValue() ).GetExt();
177
178 if( std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> plugin = m_gfxImportMgr->GetPluginByExt( ext ) )
179 enableDXFControls = dynamic_cast<DXF_IMPORT_PLUGIN*>( plugin.get() ) != nullptr;
180
181 m_defaultLineWidth.Enable( enableDXFControls );
182
183 m_dxfUnitsLabel->Enable( enableDXFControls );
184 m_dxfUnitsChoice->Enable( enableDXFControls );
185}
186
187
188void DIALOG_IMPORT_GRAPHICS::onBrowseFiles( wxCommandEvent& event )
189{
190 wxString path;
191 wxString filename = m_textCtrlFileName->GetValue();
192
193 if( !filename.IsEmpty() )
194 {
195 wxFileName fn( filename );
196 path = fn.GetPath();
197 filename = fn.GetFullName();
198 }
199
200 // Generate the list of handled file formats
201 wxString wildcardsDesc;
202 wxString allWildcards;
203
204 for( GRAPHICS_IMPORT_MGR::GFX_FILE_T pluginType : m_gfxImportMgr->GetImportableFileTypes() )
205 {
206 std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> plugin = m_gfxImportMgr->GetPlugin( pluginType );
207 const std::vector<std::string> extensions = plugin->GetFileExtensions();
208
209 wildcardsDesc += wxT( "|" ) + plugin->GetName() + AddFileExtListToFilter( extensions );
210 allWildcards += plugin->GetWildcards() + wxT( ";" );
211 }
212
213 wildcardsDesc = _( "All supported formats" ) + wxT( "|" ) + allWildcards + wildcardsDesc;
214
215 wxFileDialog dlg( m_parent, _( "Import Graphics" ), path, filename, wildcardsDesc,
216 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
217
218 if( dlg.ShowModal() == wxID_OK && !dlg.GetPath().IsEmpty() )
219 m_textCtrlFileName->SetValue( dlg.GetPath() );
220}
221
222
224{
225 if( !wxDialog::TransferDataFromWindow() )
226 return false;
227
228 if( m_textCtrlFileName->GetValue().IsEmpty() )
229 {
230 wxMessageBox( _( "Please select a file to import." ) );
231 return false;
232 }
233
234 if( m_setLayerCheckbox->GetValue() && m_SelLayerBox->GetLayerSelection() < 0 )
235 {
236 wxMessageBox( _( "Please select a valid layer." ) );
237 return false;
238 }
239
241 wxString ext = wxFileName( m_textCtrlFileName->GetValue() ).GetExt();
243 double xscale = scale;
244 double yscale = scale;
245
247 xscale *= -1.0;
248
250 yscale *= -1.0;
251
252 VECTOR2D origin( m_xOrigin.GetDoubleValue() / xscale, m_yOrigin.GetDoubleValue() / yscale );
253
254 if( std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> plugin = m_gfxImportMgr->GetPluginByExt( ext ) )
255 {
256 if( DXF_IMPORT_PLUGIN* dxfPlugin = dynamic_cast<DXF_IMPORT_PLUGIN*>( plugin.get() ) )
257 {
258 auto it = dxfUnitsMap.begin();
259 std::advance( it, m_dxfUnitsChoice->GetSelection() );
260
261 if( it == dxfUnitsMap.end() )
262 dxfPlugin->SetUnit( DXF_IMPORT_UNITS::DEFAULT );
263 else
264 dxfPlugin->SetUnit( it->first );
265
267 }
268 else
269 {
270 m_importer->SetLineWidthMM( 0.0 );
271 }
272
273 m_importer->SetPlugin( std::move( plugin ) );
274
275 if( m_setLayerCheckbox->GetValue() )
277 else
278 m_importer->SetLayer( m_parent->GetActiveLayer() );
279
280 m_importer->SetImportOffsetMM( origin * pcbIUScale.IUTomm( 1 ) );
281
282 LOCALE_IO dummy; // Ensure floats can be read.
283
284 if( m_importer->Load( m_textCtrlFileName->GetValue() ) )
285 m_importer->Import( VECTOR2D( scale, scale ) );
286
287 // Get warning messages:
288 wxString warnings = m_importer->GetMessages();
289
290 // This isn't a fatal error so allow the dialog to close with wxID_OK.
291 if( !warnings.empty() )
292 {
293 HTML_MESSAGE_BOX dlg( this, _( "Warning" ) );
294 dlg.MessageSet( _( "Items in the imported file could not be handled properly." ) );
295 warnings.Replace( wxT( "\n" ), wxT( "<br/>" ) );
296 dlg.AddHTML_Text( warnings );
297 dlg.ShowModal();
298 }
299
300 return true;
301 }
302 else
303 {
304 wxMessageBox( _( "There is no plugin to handle this file type." ) );
305 return false;
306 }
307}
308
309
310void DIALOG_IMPORT_GRAPHICS::onUpdateUI( wxUpdateUIEvent& event )
311{
312 m_xOrigin.Enable( m_placeAtCheckbox->GetValue() );
313 m_yOrigin.Enable( m_placeAtCheckbox->GetValue() );
314
316
317 m_SelLayerBox->Enable( m_setLayerCheckbox->GetValue() );
318}
319
320
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
Class DIALOG_IMPORT_GRAPHICS_BASE.
PCB_LAYER_BOX_SELECTOR * m_SelLayerBox
std::unique_ptr< GRAPHICS_IMPORT_MGR > m_gfxImportMgr
void onFilename(wxCommandEvent &event)
std::unique_ptr< GRAPHICS_IMPORTER_PCBNEW > m_importer
void onBrowseFiles(wxCommandEvent &event) override
void onUpdateUI(wxUpdateUIEvent &event) override
DIALOG_IMPORT_GRAPHICS(PCB_BASE_FRAME *aParent)
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowModal() override
GFX_FILE_T
< List of handled file types.
void MessageSet(const wxString &message)
Add a message (in bold) to message list.
void AddHTML_Text(const wxString &message)
Add HTML text (without any change) to message list.
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
DISPLAY_OPTIONS m_Display
DIALOG_IMPORT_GRAPHICS m_ImportGraphics
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
PCBNEW_SETTINGS * GetPcbNewSettings() const
virtual PCB_LAYER_ID GetActiveLayer() const
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetBitmap(const wxBitmapBundle &aBmp)
int GetIntValue()
Definition: unit_binder.h:129
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual double GetDoubleValue()
Return the current value in Internal Units.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
const std::map< DXF_IMPORT_UNITS, wxString > dxfUnitsMap
const std::map< DXF_IMPORT_UNITS, wxString > dxfUnitsMap
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ Dwgs_User
Definition: layer_ids.h:107
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Function DoubleValueFromString converts aTextValue to a double.
Definition: eda_units.cpp:576
const int scale
std::vector< FAB_LAYER_COLOR > dummy
constexpr double IUTomm(int iu) const
Definition: base_units.h:86
const double IU_PER_MM
Definition: base_units.h:76
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
VECTOR2< double > VECTOR2D
Definition: vector2d.h:690
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
Definition of file extensions used in Kicad.