KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_import_gfx_sch.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
27#include <map>
28
32
33#include <base_units.h>
34#include <kiface_base.h>
35#include <locale_io.h>
36#include <bitmaps.h>
38
39#include <eeschema_settings.h>
40#include <sch_edit_frame.h>
42#include <symbol_edit_frame.h>
43
44#include <wx/filedlg.h>
45#include <wx/msgdlg.h>
46
49
50#include <memory>
51
52// Static members of DIALOG_IMPORT_GFX_SCH, to remember the user's choices during the session
54double DIALOG_IMPORT_GFX_SCH::m_importScale = 1.0; // Do not change the imported items size
55
56
57const std::map<DXF_IMPORT_UNITS, wxString> dxfUnitsMap = {
58 { DXF_IMPORT_UNITS::INCHES, _( "Inches" ) },
59 { DXF_IMPORT_UNITS::MILLIMETERS, _( "Millimeters" ) },
60 { DXF_IMPORT_UNITS::MILS, _( "Mils" ) },
61 { DXF_IMPORT_UNITS::CENTIMETERS, _( "Centimeter" ) },
62 { DXF_IMPORT_UNITS::FEET, _( "Feet" ) },
63};
64
65
68 m_parent( aParent ),
69 m_xOrigin( aParent, m_xLabel, m_xCtrl, m_xUnits ),
70 m_yOrigin( aParent, m_yLabel, m_yCtrl, m_yUnits ),
71 m_defaultLineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits )
72{
73 m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
74
75 auto initWidgetsFromSettings = [&]( const auto& aCfg )
76 {
77 m_placementInteractive = aCfg->m_ImportGraphics.interactive_placement;
78
79 m_xOrigin.SetValue( aCfg->m_ImportGraphics.origin_x * schIUScale.IU_PER_MM );
80 m_yOrigin.SetValue( aCfg->m_ImportGraphics.origin_y * schIUScale.IU_PER_MM );
81 m_defaultLineWidth.SetValue( aCfg->m_ImportGraphics.dxf_line_width * schIUScale.IU_PER_MM );
82
83 m_textCtrlFileName->SetValue( aCfg->m_ImportGraphics.last_file );
86
87 m_importScaleCtrl->SetValue( wxString::Format( wxT( "%f" ), m_importScale ) );
88
89 for( const std::pair<const DXF_IMPORT_UNITS, wxString>& unitEntry : dxfUnitsMap )
90 m_choiceDxfUnits->Append( unitEntry.second );
91
92 m_choiceDxfUnits->SetSelection( aCfg->m_ImportGraphics.dxf_units );
93 };
94
95 if( SYMBOL_EDIT_FRAME* symFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( aParent ) )
96 {
97 m_importer = std::make_unique<GRAPHICS_IMPORTER_LIB_SYMBOL>( symFrame->GetCurSymbol(),
98 symFrame->GetUnit() );
99
100 SYMBOL_EDITOR_SETTINGS* cfg = aParent->libeditconfig();
101 initWidgetsFromSettings( cfg );
102 }
103 else if( dynamic_cast<SCH_EDIT_FRAME*>( aParent ) )
104 {
105 m_importer = std::make_unique<GRAPHICS_IMPORTER_SCH>();
106
107 EESCHEMA_SETTINGS* cfg = aParent->eeconfig();
108 initWidgetsFromSettings( cfg );
109 }
110
111 m_gfxImportMgr = std::make_unique<GRAPHICS_IMPORT_MGR>();
112
113 wxCommandEvent dummy;
114 onFilename( dummy );
115
118
119 GetSizer()->Fit( this );
120 GetSizer()->SetSizeHints( this );
121 Centre();
122
123 m_textCtrlFileName->Connect( wxEVT_COMMAND_TEXT_UPDATED,
124 wxCommandEventHandler( DIALOG_IMPORT_GFX_SCH::onFilename ),
125 nullptr, this );
126}
127
128
130{
131 auto saveToSettings = [&]( const auto& aCfg )
132 {
133 aCfg->m_ImportGraphics.interactive_placement = m_placementInteractive;
134 aCfg->m_ImportGraphics.last_file = m_textCtrlFileName->GetValue();
135 aCfg->m_ImportGraphics.dxf_line_width = schIUScale.IUTomm( m_defaultLineWidth.GetValue() );
136 aCfg->m_ImportGraphics.origin_x = schIUScale.IUTomm( m_xOrigin.GetValue() );
137 aCfg->m_ImportGraphics.origin_y = schIUScale.IUTomm( m_yOrigin.GetValue() );
138 aCfg->m_ImportGraphics.dxf_units = m_choiceDxfUnits->GetSelection();
139
141 };
142
143 if( SYMBOL_EDIT_FRAME* symFrame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_parent ) )
144 {
145 SYMBOL_EDITOR_SETTINGS* cfg = symFrame->libeditconfig();
146 saveToSettings( cfg );
147 }
148 else if( SCH_EDIT_FRAME* schFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_parent ) )
149 {
150 EESCHEMA_SETTINGS* cfg = schFrame->eeconfig();
151 saveToSettings( cfg );
152 }
153
154 m_textCtrlFileName->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
155 wxCommandEventHandler( DIALOG_IMPORT_GFX_SCH::onFilename ),
156 nullptr, this );
157}
158
159
160void DIALOG_IMPORT_GFX_SCH::onFilename( wxCommandEvent& event )
161{
162 bool enableDXFControls = true;
163 wxString ext = wxFileName( m_textCtrlFileName->GetValue() ).GetExt();
164
165 if( std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> plugin = m_gfxImportMgr->GetPluginByExt( ext ) )
166 enableDXFControls = dynamic_cast<DXF_IMPORT_PLUGIN*>( plugin.get() ) != nullptr;
167
168 m_defaultLineWidth.Enable( enableDXFControls );
169
170 m_staticTextLineWidth1->Enable( enableDXFControls );
171 m_choiceDxfUnits->Enable( enableDXFControls );
172}
173
174
175void DIALOG_IMPORT_GFX_SCH::onBrowseFiles( wxCommandEvent& event )
176{
177 wxString path;
178 wxString filename = m_textCtrlFileName->GetValue();
179
180 if( !filename.IsEmpty() )
181 {
182 wxFileName fn( filename );
183 path = fn.GetPath();
184 filename = fn.GetFullName();
185 }
186
187 // Generate the list of handled file formats
188 wxString wildcardsDesc;
189 wxString allWildcards;
190
191 for( GRAPHICS_IMPORT_MGR::GFX_FILE_T pluginType : m_gfxImportMgr->GetImportableFileTypes() )
192 {
193 std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> plugin = m_gfxImportMgr->GetPlugin( pluginType );
194 const std::vector<std::string> extensions = plugin->GetFileExtensions();
195
196 wildcardsDesc += wxT( "|" ) + plugin->GetName() + AddFileExtListToFilter( extensions );
197 allWildcards += plugin->GetWildcards() + wxT( ";" );
198 }
199
200 wildcardsDesc = _( "All supported formats" ) + wxT( "|" ) + allWildcards + wildcardsDesc;
201
202 wxFileDialog dlg( m_parent, _( "Import Graphics" ), path, filename, wildcardsDesc,
203 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
204
205 if( dlg.ShowModal() == wxID_OK && !dlg.GetPath().IsEmpty() )
206 m_textCtrlFileName->SetValue( dlg.GetPath() );
207}
208
209
211{
212 if( !wxDialog::TransferDataFromWindow() )
213 return false;
214
215 if( m_textCtrlFileName->GetValue().IsEmpty() )
216 {
217 wxMessageBox( _( "No file selected!" ) );
218 return false;
219 }
220
221 wxString ext = wxFileName( m_textCtrlFileName->GetValue() ).GetExt();
223 double xscale = scale;
224 double yscale = scale;
225
226 if( dynamic_cast<SYMBOL_EDIT_FRAME*>( m_parent ) )
227 yscale *= -1;
228
229 VECTOR2D origin( m_xOrigin.GetValue() / xscale, m_yOrigin.GetValue() / yscale );
230
231 if( std::unique_ptr<GRAPHICS_IMPORT_PLUGIN> plugin = m_gfxImportMgr->GetPluginByExt( ext ) )
232 {
233 if( DXF_IMPORT_PLUGIN* dxfPlugin = dynamic_cast<DXF_IMPORT_PLUGIN*>( plugin.get() ) )
234 {
235 auto it = dxfUnitsMap.begin();
236 std::advance( it, m_choiceDxfUnits->GetSelection() );
237
238 if( it == dxfUnitsMap.end() )
239 dxfPlugin->SetUnit( DXF_IMPORT_UNITS::DEFAULT );
240 else
241 dxfPlugin->SetUnit( it->first );
242
244 }
245 else
246 {
247 m_importer->SetLineWidthMM( 0.0 );
248 }
249
250 m_importer->SetPlugin( std::move( plugin ) );
251 m_importer->SetImportOffsetMM( { schIUScale.IUTomm( origin.x ), schIUScale.IUTomm( origin.y ) } );
252
253 LOCALE_IO dummy; // Ensure floats can be read.
254
255 if( m_importer->Load( m_textCtrlFileName->GetValue() ) )
256 m_importer->Import( VECTOR2D( xscale, yscale ) );
257
258 // Get warning messages:
259 wxString warnings = m_importer->GetMessages();
260
261 // This isn't a fatal error so allow the dialog to close with wxID_OK.
262 if( !warnings.empty() )
263 {
264 HTML_MESSAGE_BOX dlg( this, _( "Warning" ) );
265 dlg.MessageSet( _( "Items in the imported file could not be handled properly." ) );
266 warnings.Replace( wxT( "\n" ), wxT( "<br/>" ) );
267 dlg.AddHTML_Text( warnings );
268 dlg.ShowModal();
269 }
270
271 return true;
272 }
273 else
274 {
275 wxMessageBox( _( "There is no plugin to handle this file type." ) );
276 return false;
277 }
278}
279
280
282{
285
288
291}
292
293
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
Class DIALOG_IMPORT_GFX_SCH_BASE.
void onBrowseFiles(wxCommandEvent &event) override
std::unique_ptr< GRAPHICS_IMPORTER > m_importer
void onFilename(wxCommandEvent &event)
DIALOG_IMPORT_GFX_SCH(SCH_BASE_FRAME *aParent)
void originOptionOnUpdateUI(wxUpdateUIEvent &event) override
bool TransferDataFromWindow() override
std::unique_ptr< GRAPHICS_IMPORT_MGR > m_gfxImportMgr
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.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
SYMBOL_EDITOR_SETTINGS * libeditconfig() const
EESCHEMA_SETTINGS * eeconfig() const
Schematic editor (Eeschema) main window.
void SetBitmap(const wxBitmapBundle &aBmp)
The symbol library editor main window.
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
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
#define _(s)
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
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.