KiCad PCB EDA Suite
Loading...
Searching...
No Matches
bitmap2cmp_frame.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) 1992-2010 jean-pierre.charras
5 * Copyright The 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, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <bitmap2component.h>
22#include <bitmap2cmp_frame.h>
23#include <bitmap2cmp_panel.h>
24#include <bitmap2cmp_settings.h>
25#include <bitmap_io.h>
26#include <bitmaps.h>
27#include <common.h>
28#include <id.h>
29#include <widgets/wx_menubar.h>
31#include <file_history.h>
32#include <tool/tool_manager.h>
34#include <tool/common_control.h>
35#include <tool/action_manager.h>
36#include <bitmap2cmp_control.h>
37#include <tool/actions.h>
38
39#include <wx/filedlg.h>
40#include <wx/msgdlg.h>
41#include <kiplatform/ui.h>
42
43
44#define DEFAULT_DPI 300 // the image DPI used in formats that do not define a DPI
45
53
54
56{
57 // Safety-check to guarantee no divide-by-zero
58 m_originalDPI = std::max( 1, m_originalDPI );
59
60 // Set the m_outputSize value from the m_originalSizePixels and the selected unit
61 if( m_unit == EDA_UNITS::MM )
63 else if( m_unit == EDA_UNITS::INCH )
65 else
67}
68
69
71{
72 int outputDPI;
73
74 if( m_unit == EDA_UNITS::MM )
75 outputDPI = GetOriginalSizePixels() / ( m_outputSize / 25.4 );
76 else if( m_unit == EDA_UNITS::INCH )
77 outputDPI = GetOriginalSizePixels() / m_outputSize;
78 else
79 outputDPI = KiROUND( m_outputSize );
80
81 // Zero is not a DPI, and may cause divide-by-zero errors...
82 outputDPI = std::max( 1, outputDPI );
83
84 return outputDPI;
85}
86
87
89{
90 // Set the unit used for m_outputSize, and convert the old m_outputSize value
91 // to the value in new unit
92 if( aUnit == m_unit )
93 return;
94
95 // Convert m_outputSize to mm:
96 double size_mm;
97
98 if( m_unit == EDA_UNITS::MM )
99 {
100 size_mm = m_outputSize;
101 }
102 else if( m_unit == EDA_UNITS::INCH )
103 {
104 size_mm = m_outputSize * 25.4;
105 }
106 else
107 {
108 // m_outputSize is the DPI, not an image size
109 // the image size is m_originalSizePixels / m_outputSize (in inches)
110 if( m_outputSize )
111 size_mm = m_originalSizePixels / m_outputSize * 25.4;
112 else
113 size_mm = 0;
114 }
115
116 // Convert m_outputSize to new value:
117 if( aUnit == EDA_UNITS::MM )
118 {
119 m_outputSize = size_mm;
120 }
121 else if( aUnit == EDA_UNITS::INCH )
122 {
123 m_outputSize = size_mm / 25.4;
124 }
125 else
126 {
127 if( size_mm )
128 m_outputSize = m_originalSizePixels / size_mm * 25.4;
129 else
130 m_outputSize = 0;
131 }
132
133 m_unit = aUnit;
134}
135
136
137BEGIN_EVENT_TABLE( BITMAP2CMP_FRAME, KIWAY_PLAYER )
140
143END_EVENT_TABLE()
144
145
146BITMAP2CMP_FRAME::BITMAP2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
147 KIWAY_PLAYER( aKiway, aParent, FRAME_BM2CMP, _( "Image Converter" ), wxDefaultPosition,
148 wxDefaultSize, wxDEFAULT_FRAME_STYLE, wxT( "bitmap2cmp" ), unityScale ),
149 m_panel( nullptr ),
150 m_statusBar( nullptr )
151{
152 m_aboutTitle = _HKI( "KiCad Image Converter" );
153
154 // Give an icon
155 wxIcon icon;
156 wxIconBundle icon_bundle;
157
158 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_bitmap2component, 48 ) );
159 icon_bundle.AddIcon( icon );
160 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_bitmap2component, 128 ) );
161 icon_bundle.AddIcon( icon );
162 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_bitmap2component, 256 ) );
163 icon_bundle.AddIcon( icon );
164 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_bitmap2component_32 ) );
165 icon_bundle.AddIcon( icon );
166 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_bitmap2component_16 ) );
167 icon_bundle.AddIcon( icon );
168
169 SetIcons( icon_bundle );
170
171 wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
172 SetSizer( mainSizer );
173
174 m_panel = new BITMAP2CMP_PANEL( this );
175 mainSizer->Add( m_panel, 1, wxEXPAND, 5 );
176
177 m_statusBar = this->CreateStatusBar( 1, wxSTB_SIZEGRIP, wxID_ANY );
178
179 LoadSettings( config() );
180
182 m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
183
185
186 // Register tools
187 m_toolManager->RegisterTool( new COMMON_CONTROL );
188 m_toolManager->RegisterTool( new BITMAP2CMP_CONTROL );
189 m_toolManager->InitTools();
190
193
194 GetSizer()->SetSizeHints( this );
195
196 SetSize( m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y );
197
198 if ( m_framePos == wxDefaultPosition )
199 Centre();
200}
201
202
204{
205 // Shutdown all running tools
206 if( m_toolManager )
207 m_toolManager->ShutdownAllTools();
208
209 SaveSettings( config() );
210
211 /*
212 * This needed for OSX: avoids further OnDraw processing after this
213 * destructor and before the native window is destroyed
214 */
215 Freeze();
216}
217
218
219void BITMAP2CMP_FRAME::OnExit( wxCommandEvent& aEvent )
220{
221 // Just generate a wxCloseEvent
222 Close( false );
223}
224
225
227{
228 return m_panel->GetCurrentPage();
229}
230
231
232void BITMAP2CMP_FRAME::OnFileHistory( wxCommandEvent& event )
233{
234 wxString fn = GetFileFromHistory( event.GetId(), _( "Image files" ) );
235
236 if( !fn.IsEmpty() )
237 {
238 OpenProjectFiles( std::vector<wxString>( 1, fn ) );
239 Refresh();
240 }
241}
242
243
244void BITMAP2CMP_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
245{
247}
248
249
251{
252 COMMON_CONTROL* tool = m_toolManager->GetTool<COMMON_CONTROL>();
253 EDA_BASE_FRAME* base_frame = dynamic_cast<EDA_BASE_FRAME*>( this );
254
255 // base_frame == nullptr should not happen, but it makes Coverity happy
256 wxCHECK( base_frame, /* void */ );
257
258 // wxWidgets handles the OSX Application menu behind the scenes, but that means
259 // we always have to start from scratch with a new wxMenuBar.
260 wxMenuBar* oldMenuBar = base_frame->GetMenuBar();
261 WX_MENUBAR* menuBar = new WX_MENUBAR();
262
263 //-- File menu -----------------------------------------------------------
264 //
265 ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
266
267 fileMenu->Add( ACTIONS::open );
268
269 static ACTION_MENU* openRecentMenu;
270 FILE_HISTORY& fileHistory = GetFileHistory();
271
272 // Create the menu if it does not exist. Adding a file to/from the history
273 // will automatically refresh the menu.
274 if( !openRecentMenu )
275 {
276 openRecentMenu = new ACTION_MENU( false, tool );
277 openRecentMenu->SetIcon( BITMAPS::recent );
278
279 fileHistory.UseMenu( openRecentMenu );
280 fileHistory.AddFilesToMenu();
281 }
282
283 // Ensure the title is up to date after changing language
284 openRecentMenu->SetTitle( _( "Open Recent" ) );
285 fileHistory.UpdateClearText( openRecentMenu, _( "Clear Recent Files" ) );
286
287 wxMenuItem* item = fileMenu->Add( openRecentMenu->Clone() );
288
289 // Add the file menu condition here since it needs the item ID for the submenu
291 cond.Enable( FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) );
292 RegisterUIUpdateHandler( item->GetId(), cond );
293
294 fileMenu->AppendSeparator();
295 fileMenu->AddQuit( _( "Image Converter" ) );
296
297 //-- Preferences menu -----------------------------------------------
298 //
299 ACTION_MENU* prefsMenu = new ACTION_MENU( false, tool );
300
301 prefsMenu->Add( ACTIONS::openPreferences );
302
303 prefsMenu->AppendSeparator();
304 AddMenuLanguageList( prefsMenu, tool );
305
306
307 //-- Menubar -------------------------------------------------------------
308 //
309 menuBar->Append( fileMenu, _( "&File" ) );
310 menuBar->Append( prefsMenu, _( "&Preferences" ) );
311 base_frame->AddStandardHelpMenu( menuBar );
312
313 base_frame->SetMenuBar( menuBar );
314 delete oldMenuBar;
315}
316
317
319{
321
322 UpdateTitle();
323
324 SaveSettings( config() );
325 IMAGE_SIZE imageSizeX = m_panel->GetOutputSizeX();
326 IMAGE_SIZE imageSizeY = m_panel->GetOutputSizeY();
327 Freeze();
328
329 wxSizer* mainSizer = m_panel->GetContainingSizer();
330 mainSizer->Detach( m_panel );
331 m_panel->Destroy();
332
333 m_panel = new BITMAP2CMP_PANEL( this );
334 mainSizer->Add( m_panel, 1, wxEXPAND, 5 );
335 Layout();
336
337 if( !m_srcFileName.IsEmpty() )
338 OpenProjectFiles( std::vector<wxString>( 1, m_srcFileName ) );
339
340 LoadSettings( config() );
341 m_panel->SetOutputSize( imageSizeX, imageSizeY );
342
343 Thaw();
344 Refresh();
345}
346
347
349{
350 wxString title;
351
352 if( !m_srcFileName.IsEmpty() )
353 {
354 wxFileName filename( m_srcFileName );
355 title = filename.GetFullName() + wxT( " \u2014 " );
356 }
357
358 title += _( "Image Converter" );
359
360 SetTitle( title );
361}
362
363
365{
367
368 if( BITMAP2CMP_SETTINGS* cfg = dynamic_cast<BITMAP2CMP_SETTINGS*>( aCfg ) )
369 {
370 m_srcFileName = cfg->m_BitmapFileName;
371 m_outFileName = cfg->m_ConvertedFileName;
372 m_panel->LoadSettings( cfg );
373 }
374}
375
376
378{
380
381 if( BITMAP2CMP_SETTINGS* cfg = dynamic_cast<BITMAP2CMP_SETTINGS*>( aCfg ) )
382 {
383 cfg->m_BitmapFileName = m_srcFileName;
384 cfg->m_ConvertedFileName = m_outFileName;
385 m_panel->SaveSettings( cfg );
386 }
387}
388
389
391{
392 wxFileName fn( m_srcFileName );
393 wxString path = fn.GetPath();
394
395 if( path.IsEmpty() || !wxDirExists( path ) )
396 path = m_mruPath;
397
398 wxFileDialog fileDlg( this, _( "Choose Image" ), path, wxEmptyString,
399 FILEEXT::ImageFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
400
402
403 if( fileDlg.ShowModal() != wxID_OK )
404 return;
405
406 wxString fullFilename = fileDlg.GetPath();
407
408 if( !OpenProjectFiles( std::vector<wxString>( 1, fullFilename ) ) )
409 return;
410
411 fn = fullFilename;
412 m_mruPath = fn.GetPath();
413 SetStatusText( fullFilename );
414 UpdateTitle();
415 Refresh();
416}
417
418
419bool BITMAP2CMP_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
420{
421 m_srcFileName = aFileSet[0];
422
423 if( m_panel->OpenProjectFiles( aFileSet, aCtl ) )
424 {
426 return true;
427 }
428
429 return false;
430}
431
432
434{
435 wxFileName fn( m_outFileName );
436 wxString path = fn.GetPath();
437
438 if( path.IsEmpty() || !wxDirExists(path) )
439 path = ::wxGetCwd();
440
441 wxFileDialog fileDlg( this, _( "Create Drawing Sheet File" ), path, wxEmptyString,
442 FILEEXT::DrawingSheetFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
443
445
446 if( fileDlg.ShowModal() != wxID_OK )
447 return;
448
449 fn = fileDlg.GetPath();
451 m_outFileName = fn.GetFullPath();
452
453 FILE* outfile = wxFopen( m_outFileName, wxT( "w" ) );
454
455 if( !outfile )
456 {
457 wxMessageBox( wxString::Format( _( "File '%s' could not be created." ), m_outFileName ) );
458 return;
459 }
460
461 std::string buffer;
462 m_panel->ExportToBuffer( buffer, DRAWING_SHEET_FMT );
463 fputs( buffer.c_str(), outfile );
464 fclose( outfile );
465}
466
467
469{
470 wxFileName fn( m_outFileName );
471 wxString path = fn.GetPath();
472
473 if( path.IsEmpty() || !wxDirExists( path ) )
474 path = ::wxGetCwd();
475
476 wxFileDialog fileDlg( this, _( "Create PostScript File" ), path, wxEmptyString,
477 FILEEXT::PSFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
478
480
481 if( fileDlg.ShowModal() != wxID_OK )
482 return;
483
484 fn = fileDlg.GetPath();
485 fn.SetExt( wxT( "ps" ) );
486 m_outFileName = fn.GetFullPath();
487
488 FILE* outfile = wxFopen( m_outFileName, wxT( "w" ) );
489
490 if( !outfile )
491 {
492 wxMessageBox( wxString::Format( _( "File '%s' could not be created." ), m_outFileName ) );
493 return;
494 }
495
496 std::string buffer;
497 m_panel->ExportToBuffer( buffer, POSTSCRIPT_FMT );
498 fputs( buffer.c_str(), outfile );
499 fclose( outfile );
500}
501
502
504{
505 wxFileName fn( m_outFileName );
506 wxString path = fn.GetPath();
507
508 if( path.IsEmpty() || !wxDirExists( path ) )
509 path = ::wxGetCwd();
510
511 wxFileDialog fileDlg( this, _( "Create Symbol Library" ), path, wxEmptyString,
513 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
514
516
517 if( fileDlg.ShowModal() != wxID_OK )
518 return;
519
521 m_outFileName = fn.GetFullPath();
522
523 FILE* outfile = wxFopen( m_outFileName, wxT( "w" ) );
524
525 if( !outfile )
526 {
527 wxMessageBox( wxString::Format( _( "File '%s' could not be created." ), m_outFileName ) );
528 return;
529 }
530
531 std::string buffer;
532 m_panel->ExportToBuffer( buffer, SYMBOL_FMT );
533 fputs( buffer.c_str(), outfile );
534 fclose( outfile );
535}
536
537
539{
540 wxFileName fn( m_outFileName );
541 wxString path = fn.GetPath();
542
543 if( path.IsEmpty() || !wxDirExists( path ) )
544 path = m_mruPath;
545
546 wxFileDialog fileDlg( this, _( "Create Footprint Library" ), path, wxEmptyString,
548 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
549
551
552 if( fileDlg.ShowModal() != wxID_OK )
553 return;
554
556 m_outFileName = fn.GetFullPath();
557
558 FILE* outfile = wxFopen( m_outFileName, wxT( "w" ) );
559
560 if( !outfile )
561 {
562 wxMessageBox( wxString::Format( _( "File '%s' could not be created." ), m_outFileName ) );
563 return;
564 }
565
566 std::string buffer;
567 m_panel->ExportToBuffer( buffer, FOOTPRINT_FMT );
568 fputs( buffer.c_str(), outfile );
569 fclose( outfile );
570 m_mruPath = fn.GetPath();
571}
572
573
constexpr EDA_IU_SCALE unityScale
Definition base_units.h:124
#define DEFAULT_DPI
@ DRAWING_SHEET_FMT
@ SYMBOL_FMT
@ POSTSCRIPT_FMT
@ FOOTPRINT_FMT
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:100
@ icon_bitmap2component
@ icon_bitmap2component_32
@ icon_bitmap2component_16
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
static TOOL_ACTION openPreferences
Definition actions.h:276
static TOOL_ACTION open
Definition actions.h:53
Define the structure of a menu based on ACTIONs.
Definition action_menu.h:43
void AddQuit(const wxString &aAppname="")
Add a standard Quit item to the menu.
ACTION_MENU * Clone() const
Create a deep, recursive copy of this ACTION_MENU.
void SetTitle(const wxString &aTitle) override
Set title for the menu.
void SetIcon(BITMAPS aIcon)
Assign an icon for the entry.
wxMenuItem * Add(const wxString &aLabel, int aId, BITMAPS aIcon)
Add a wxWidgets-style entry to the menu.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Handle actions for the various symbol editor and viewers.
void ExportPcbnewFormat()
Generate a footprint in S expr format.
void ExportDrawingSheetFormat()
Generate a file suitable to be copied into a drawing sheet (.kicad_wks) file.
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
void ExportEeschemaFormat()
Generate a schematic library which contains one component: the logo.
wxStatusBar * m_statusBar
void OnExit(wxCommandEvent &aEvent)
Event handler for the wxID_EXIT and wxID_CLOSE events.
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
void OnFileHistory(wxCommandEvent &event)
BITMAP2CMP_FRAME(KIWAY *aKiway, wxWindow *aParent)
void doReCreateMenuBar() override
wxWindow * GetToolCanvas() const override
Canvas access.
void ExportPostScriptFormat()
Generate a postscript file.
BITMAP2CMP_PANEL * m_panel
bool OpenProjectFiles(const std::vector< wxString > &aFilenames, int aCtl=0) override
Open a project or set of files given by aFileList.
void OnClearFileHistory(wxCommandEvent &event)
void ShowChangedLanguage() override
Handle actions that are shared between different applications.
virtual APP_SETTINGS_BASE * config() const
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
EDA_BASE_FRAME(wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, KIWAY *aKiway, const EDA_IU_SCALE &aIuScale)
void AddMenuLanguageList(ACTION_MENU *aMasterMenu, TOOL_INTERACTIVE *aControlTool)
Create a menu list for language choice, and add it as submenu to MasterMenu.
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
FILE_HISTORY & GetFileHistory()
Get the frame's main file history.
virtual void ClearFileHistory()
Remove all files from the file history.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetch the file name from the file history list.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
virtual void RegisterUIUpdateHandler(int aID, const ACTION_CONDITIONS &aConditions) override
Register a UI update handler for the control with ID aID.
wxString m_aboutTitle
void ReCreateMenuBar()
Recreate the menu bar.
This class implements a file history object to store a list of files, that can then be added to a men...
static SELECTION_CONDITION FileHistoryNotEmpty(const FILE_HISTORY &aHistory)
Create a SELECTION_CONDITION that can be used to enable a menu item when the file history has items i...
void UpdateClearText(wxMenu *aMenu, wxString aClearText)
Update the text displayed on the menu item that clears the entire menu.
void AddFilesToMenu() override
Add the files to all registered menus.
void SetUnit(EDA_UNITS aUnit)
double m_outputSize
EDA_UNITS m_unit
int GetOriginalSizePixels()
void SetOutputSizeFromInitialImageSize()
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
KIWAY_PLAYER(KIWAY *aKiway, wxWindow *aParent, FRAME_T aFrameType, const wxString &aTitle, const wxPoint &aPos, const wxSize &aSize, long aStyle, const wxString &aFrameName, const EDA_IU_SCALE &aIuScale)
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:311
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
Master controller class:
Wrapper around a wxMenuBar object that prevents the accelerator table from being used.
Definition wx_menubar.h:43
wxString EnsureFileExtension(const wxString &aFilename, const wxString &aExtension)
It's annoying to throw up nag dialogs when the extension isn't right.
Definition common.cpp:775
The common library.
#define _(s)
EDA_UNITS
Definition eda_units.h:44
EVT_MENU_RANGE(ID_GERBVIEW_DRILL_FILE1, ID_GERBVIEW_DRILL_FILEMAX, GERBVIEW_FRAME::OnDrlFileHistory) EVT_MENU_RANGE(ID_GERBVIEW_ZIP_FILE1
@ FRAME_BM2CMP
Definition frame_type.h:57
static const std::string KiCadSymbolLibFileExtension
static const std::string DrawingSheetFileExtension
static const std::string KiCadFootprintFileExtension
static wxString ImageFileWildcard()
static wxString KiCadSymbolLibFileWildcard()
static wxString KiCadFootprintLibFileWildcard()
static wxString PSFileWildcard()
static wxString DrawingSheetFileWildcard()
@ ID_FILE_LIST_CLEAR
Definition id.h:58
@ ID_FILEMAX
Definition id.h:56
@ ID_FILE1
Definition id.h:55
EVT_MENU(ID_COMPARE_PROJECT_BRANCHES, KICAD_MANAGER_FRAME::OnCompareProjectBranches) KICAD_MANAGER_FRAME
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:448
#define _HKI(x)
Definition page_info.cpp:40
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
ACTION_CONDITIONS & Enable(const SELECTION_CONDITION &aCondition)
std::string path
Definition of file extensions used in Kicad.