KiCad PCB EDA Suite
Loading...
Searching...
No Matches
import_proj.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) 2019 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "import_proj.h"
23#include <macros.h>
24#include <string_utils.h>
25#include <richio.h>
26
27#include <wx/fileconf.h>
28#include <wx/msgdlg.h>
29#include <wx/wfstream.h>
30
31#include <kiway.h>
32#include <kiway_player.h>
33#include <kicad_manager_frame.h>
34#include <pcb_edit_frame.h>
35#include <sch_edit_frame.h>
36
37#include <fp_lib_table.h>
38
39#include <sch_io/sch_io_mgr.h>
40#include <pcb_io/pcb_io_mgr.h>
41#include <project_sch.h>
42#include <project_pcb.h>
43
48
49#include <wx/log.h>
50
51
53 const std::vector<wxString>& aSchFileExtensions,
54 const std::vector<wxString>& aPcbFileExtensions ) :
55 m_frame( aFrame ),
56 m_schExtenstions( aSchFileExtensions ), m_pcbExtenstions( aPcbFileExtensions )
57{
58}
59
60
62{
63 // Append a new directory with the same name of the project file
64 // Keep iterating until we find an empty directory
65 wxString newDir = m_TargetProj.GetName();
66 int attempt = 0;
67
68 m_TargetProj.AppendDir( newDir );
69
70 while( m_TargetProj.DirExists() )
71 {
72 m_TargetProj.RemoveLastDir();
73 wxString suffix = wxString::Format( "_%d", ++attempt );
74 m_TargetProj.AppendDir( newDir + suffix );
75 }
76}
77
78
80{
81 wxString m_file;
82
83public:
84 SCOPED_FILE_REMOVER( const wxString& aFile ) : m_file( aFile ) {}
85 ~SCOPED_FILE_REMOVER() { wxRemoveFile( m_file ); }
86};
87
88
89void IMPORT_PROJ_HELPER::ImportIndividualFile( KICAD_T aFT, int aImportedFileType )
90{
91 FRAME_T frame_type;
92 wxString appImportFile;
93 std::vector<wxString> neededExts;
94
95 switch( aFT )
96 {
97 case SCHEMATIC_T:
98 neededExts = m_schExtenstions;
99 frame_type = FRAME_SCH;
100 break;
101
102 case PCB_T:
103 neededExts = m_pcbExtenstions;
104 frame_type = FRAME_PCB_EDITOR;
105 break;
106
107 default: return;
108 }
109
110 std::vector<SCOPED_FILE_REMOVER> copiedFiles;
111
112 for( wxString ext : neededExts )
113 {
114 if( ext == wxS( "INPUT" ) )
115 ext = m_InputFile.GetExt();
116
117 wxFileName candidate = m_InputFile;
118 candidate.SetExt( ext );
119
120 if( !candidate.FileExists() )
121 continue;
122
123 wxFileName targetFile( m_TargetProj.GetPath(), candidate.GetName(), candidate.GetExt() );
124
125 if( !targetFile.FileExists() )
126 {
127 bool copied = wxCopyFile( candidate.GetFullPath(), targetFile.GetFullPath(), false );
128
129 if( copied )
130 {
131 // Will be auto-removed
132 copiedFiles.emplace_back( targetFile.GetFullPath() );
133 }
134 }
135
136 // Pick the first file to pass to application
137 if( appImportFile.empty() && targetFile.FileExists() )
138 appImportFile = targetFile.GetFullPath();
139 }
140
141 if( appImportFile.empty() )
142 return;
143
144 doImport( appImportFile, frame_type, aImportedFileType );
145}
146
147
148void IMPORT_PROJ_HELPER::doImport( const wxString& aFile, FRAME_T aFrameType, int aImportedFileType )
149{
150 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( aFrameType, true ) )
151 {
152 std::stringstream ss;
153 ss << aImportedFileType << '\n' << TO_UTF8( aFile );
154
155 for( const auto& [key, value] : m_properties )
156 ss << '\n' << key << '\n' << value.wx_str();
157
158 std::string packet = ss.str();
159 frame->Kiway().ExpressMail( aFrameType, MAIL_IMPORT_FILE, packet, m_frame );
160
161 if( !frame->IsShownOnScreen() )
162 frame->Show( true );
163
164 // On Windows, Raise() does not bring the window on screen, when iconized
165 if( frame->IsIconized() )
166 frame->Iconize( false );
167
168 frame->Raise();
169 }
170}
171
172
174{
175 wxFileName fname = m_InputFile;
176
177 if( fname.GetExt() == wxS( "epro" ) || fname.GetExt() == wxS( "zip" ) )
178 {
179 nlohmann::json project = EASYEDAPRO::ReadProjectOrDeviceFile( fname.GetFullPath() );
180
181 std::map<wxString, EASYEDAPRO::PRJ_SCHEMATIC> prjSchematics = project.at( "schematics" );
182 std::map<wxString, EASYEDAPRO::PRJ_BOARD> prjBoards = project.at( "boards" );
183 std::map<wxString, wxString> prjPcbNames = project.at( "pcbs" );
184
185 std::vector<IMPORT_PROJECT_DESC> toImport =
187
188 if( toImport.size() > 1 )
189 toImport = DIALOG_IMPORT_CHOOSE_PROJECT::RunModal( m_frame, toImport );
190
191 if( toImport.size() == 1 )
192 {
193 const IMPORT_PROJECT_DESC& desc = toImport[0];
194
195 m_properties["pcb_id"] = desc.PCBId;
196 m_properties["sch_id"] = desc.SchematicId;
197 }
198 else
199 {
200 m_properties["pcb_id"] = "";
201 m_properties["sch_id"] = "";
202 }
203 }
204}
205
206
207void IMPORT_PROJ_HELPER::addLocalLibraries( const std::set<wxString>& aNames, FRAME_T aFrameType )
208{
209 KIWAY_PLAYER* frame = m_frame->Kiway().Player( aFrameType, true );
210
211 std::stringstream ss;
212
213 for( const wxString& name : aNames )
214 {
215 wxFileName fname( name );
216 fname.MakeAbsolute( m_InputFile.GetPath() );
217 ss << TO_UTF8( fname.GetFullPath() ) << '\n';
218 }
219
220 std::string packet = ss.str();
221 frame->Kiway().ExpressMail( aFrameType, MAIL_ADD_LOCAL_LIB, packet, m_frame );
222}
223
224
226{
227 wxFileConfig config( wxEmptyString, wxEmptyString, wxEmptyString, m_InputFile.GetFullPath(),
228 wxCONFIG_USE_NO_ESCAPE_CHARACTERS );
229
230 wxString groupname;
231 long groupid;
232
233 std::set<wxString> sch_file;
234 std::set<wxString> pcb_file;
235 std::set<wxString> sch_libs;
236 std::set<wxString> pcb_libs;
237
238 for( bool more = config.GetFirstGroup( groupname, groupid ); more;
239 more = config.GetNextGroup( groupname, groupid ) )
240 {
241 if( !groupname.StartsWith( wxS( "Document" ) ) )
242 continue;
243
244 wxString number = groupname.Mid( 8 );
245 long docNumber;
246
247 if( !number.ToLong( &docNumber ) )
248 continue;
249
250 wxString path = config.Read( groupname + wxS( "/DocumentPath" ), wxEmptyString );
251
252 if( path.empty() )
253 continue;
254
255 wxFileName fname( path, wxPATH_WIN );
256
257 if( !fname.IsAbsolute() )
258 fname.MakeAbsolute( m_InputFile.GetPath() );
259
260 if( !fname.GetExt().CmpNoCase( "PCBDOC" ) )
261 pcb_file.insert( fname.GetFullPath() );
262
263 if( !fname.GetExt().CmpNoCase( "SCHDOC" ) )
264 sch_file.insert( fname.GetFullPath() );
265
266 if( !fname.GetExt().CmpNoCase( "PCBLIB" ) )
267 pcb_libs.insert( fname.GetFullPath() );
268
269 if( !fname.GetExt().CmpNoCase( "SCHLIB" ) )
270 sch_libs.insert( fname.GetFullPath() );
271 }
272
273 addLocalLibraries( sch_libs, FRAME_SCH );
275
276 m_properties["project_file"] = m_InputFile.GetFullPath();
277
278 int ii = 0;
279
280 for( auto& path : sch_file )
281 {
282 std::string key = "sch" + std::to_string( ii++ );
283 m_properties[key] = path.ToStdString();
284 }
285
286 if( !sch_file.empty() )
287 doImport( "", FRAME_SCH, SCH_IO_MGR::SCH_ALTIUM );
288
289 if( !pcb_file.empty() )
291}
292
293
294void IMPORT_PROJ_HELPER::ImportFiles( int aImportedSchFileType, int aImportedPcbFileType )
295{
296 m_properties.clear();
297
298 if( aImportedSchFileType == SCH_IO_MGR::SCH_EASYEDAPRO
299 || aImportedPcbFileType == PCB_IO_MGR::EASYEDAPRO )
300 {
302 }
303 else if( aImportedSchFileType == SCH_IO_MGR::SCH_ALTIUM
304 || aImportedPcbFileType == PCB_IO_MGR::ALTIUM_DESIGNER )
305 {
307 return;
308 }
309
310 ImportIndividualFile( SCHEMATIC_T, aImportedSchFileType );
311 ImportIndividualFile( PCB_T, aImportedPcbFileType );
312}
const char * name
static std::vector< IMPORT_PROJECT_DESC > RunModal(wxWindow *aParent, const std::vector< IMPORT_PROJECT_DESC > &aProjectDesc)
Create and show a dialog (modal) and returns the data from it after completion.
wxFileName m_TargetProj
Definition import_proj.h:58
void EasyEDAProProjectHandler()
IMPORT_PROJ_HELPER(KICAD_MANAGER_FRAME *aframe, const std::vector< wxString > &aSchFileExtensions, const std::vector< wxString > &aPcbFileExtensions)
std::map< std::string, UTF8 > m_properties
Definition import_proj.h:63
void FindEmptyTargetDir()
Appends a new directory with the name of the project file Keep iterating until an empty directory is ...
std::vector< wxString > m_pcbExtenstions
Definition import_proj.h:69
KICAD_MANAGER_FRAME * m_frame
Definition import_proj.h:61
void ImportFiles(int aImportedSchFileType, int aImportedPcbFileType)
Converts imported files to kicad type files.
void addLocalLibraries(const std::set< wxString > &aLibName, FRAME_T aFrameType)
void ImportIndividualFile(KICAD_T aKicad_T, int aImportedFileType)
wxFileName m_InputFile
Definition import_proj.h:57
std::vector< wxString > m_schExtenstions
Definition import_proj.h:68
void doImport(const wxString &aFile, FRAME_T aFrameType, int aImportedFileType)
The main KiCad project manager frame.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:507
@ ALTIUM_DESIGNER
Definition pcb_io_mgr.h:62
SCOPED_FILE_REMOVER(const wxString &aFile)
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition frame_type.h:33
@ FRAME_PCB_EDITOR
Definition frame_type.h:42
@ FRAME_SCH
Definition frame_type.h:34
This file contains miscellaneous commonly used macros and functions.
@ MAIL_IMPORT_FILE
Definition mail_type.h:48
@ MAIL_ADD_LOCAL_LIB
Definition mail_type.h:54
std::vector< IMPORT_PROJECT_DESC > ProjectToSelectorDialog(const nlohmann::json &aProject, bool aPcbOnly=false, bool aSchOnly=false)
nlohmann::json ReadProjectOrDeviceFile(const wxString &aZipFileName)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Describes how non-KiCad boards and schematics should be imported as KiCad projects.
bool copied
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:78
@ PCB_T
Definition typeinfo.h:82
@ SCHEMATIC_T
Definition typeinfo.h:208
Definition of file extensions used in Kicad.