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 <sch_io/sch_io_mgr.h>
38#include <pcb_io/pcb_io_mgr.h>
39#include <project_sch.h>
40#include <project_pcb.h>
41
46
47#include <wx/log.h>
48
49
51 const std::vector<wxString>& aSchFileExtensions,
52 const std::vector<wxString>& aPcbFileExtensions ) :
53 m_frame( aFrame ),
54 m_schExtenstions( aSchFileExtensions ), m_pcbExtenstions( aPcbFileExtensions )
55{
56}
57
58
60{
61 // Append a new directory with the same name of the project file
62 // Keep iterating until we find an empty directory
63 wxString newDir = m_TargetProj.GetName();
64 int attempt = 0;
65
66 m_TargetProj.AppendDir( newDir );
67
68 while( m_TargetProj.DirExists() )
69 {
70 m_TargetProj.RemoveLastDir();
71 wxString suffix = wxString::Format( "_%d", ++attempt );
72 m_TargetProj.AppendDir( newDir + suffix );
73 }
74}
75
76
78{
79 wxString m_file;
80
81public:
82 SCOPED_FILE_REMOVER( const wxString& aFile ) : m_file( aFile ) {}
83 ~SCOPED_FILE_REMOVER() { wxRemoveFile( m_file ); }
84};
85
86
87void IMPORT_PROJ_HELPER::ImportIndividualFile( KICAD_T aFT, int aImportedFileType )
88{
89 FRAME_T frame_type;
90 wxString appImportFile;
91 std::vector<wxString> neededExts;
92
93 switch( aFT )
94 {
95 case SCHEMATIC_T:
96 neededExts = m_schExtenstions;
97 frame_type = FRAME_SCH;
98 break;
99
100 case PCB_T:
101 neededExts = m_pcbExtenstions;
102 frame_type = FRAME_PCB_EDITOR;
103 break;
104
105 default: return;
106 }
107
108 std::vector<SCOPED_FILE_REMOVER> copiedFiles;
109
110 for( wxString ext : neededExts )
111 {
112 if( ext == wxS( "INPUT" ) )
113 ext = m_InputFile.GetExt();
114
115 wxFileName candidate = m_InputFile;
116 candidate.SetExt( ext );
117
118 if( !candidate.FileExists() )
119 continue;
120
121 wxFileName targetFile( m_TargetProj.GetPath(), candidate.GetName(), candidate.GetExt() );
122
123 if( !targetFile.FileExists() )
124 {
125 bool copied = wxCopyFile( candidate.GetFullPath(), targetFile.GetFullPath(), false );
126
127 if( copied )
128 {
129 // Will be auto-removed
130 copiedFiles.emplace_back( targetFile.GetFullPath() );
131 }
132 }
133
134 // Pick the first file to pass to application
135 if( appImportFile.empty() && targetFile.FileExists() )
136 appImportFile = targetFile.GetFullPath();
137 }
138
139 if( appImportFile.empty() )
140 return;
141
142 doImport( appImportFile, frame_type, aImportedFileType );
143}
144
145
146void IMPORT_PROJ_HELPER::doImport( const wxString& aFile, FRAME_T aFrameType, int aImportedFileType )
147{
148 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( aFrameType, true ) )
149 {
150 std::stringstream ss;
151 ss << aImportedFileType << '\n' << TO_UTF8( aFile );
152
153 for( const auto& [key, value] : m_properties )
154 ss << '\n' << key << '\n' << value.wx_str();
155
156 std::string packet = ss.str();
157 frame->Kiway().ExpressMail( aFrameType, MAIL_IMPORT_FILE, packet, m_frame );
158
159 if( !frame->IsShownOnScreen() )
160 frame->Show( true );
161
162 // On Windows, Raise() does not bring the window on screen, when iconized
163 if( frame->IsIconized() )
164 frame->Iconize( false );
165
166 frame->Raise();
167 }
168}
169
170
172{
173 wxFileName fname = m_InputFile;
174
175 if( fname.GetExt() == wxS( "epro" ) || fname.GetExt() == wxS( "zip" ) )
176 {
177 nlohmann::json project = EASYEDAPRO::ReadProjectOrDeviceFile( fname.GetFullPath() );
178
179 std::map<wxString, EASYEDAPRO::PRJ_SCHEMATIC> prjSchematics = project.at( "schematics" );
180 std::map<wxString, EASYEDAPRO::PRJ_BOARD> prjBoards = project.at( "boards" );
181 std::map<wxString, wxString> prjPcbNames = project.at( "pcbs" );
182
183 std::vector<IMPORT_PROJECT_DESC> toImport =
185
186 if( toImport.size() > 1 )
187 toImport = DIALOG_IMPORT_CHOOSE_PROJECT::RunModal( m_frame, toImport );
188
189 if( toImport.size() == 1 )
190 {
191 const IMPORT_PROJECT_DESC& desc = toImport[0];
192
193 m_properties["pcb_id"] = desc.PCBId;
194 m_properties["sch_id"] = desc.SchematicId;
195 }
196 else
197 {
198 m_properties["pcb_id"] = "";
199 m_properties["sch_id"] = "";
200 }
201 }
202}
203
204
205void IMPORT_PROJ_HELPER::addLocalLibraries( const std::set<wxString>& aNames, FRAME_T aFrameType )
206{
207 KIWAY_PLAYER* frame = m_frame->Kiway().Player( aFrameType, true );
208
209 std::stringstream ss;
210
211 for( const wxString& name : aNames )
212 {
213 wxFileName fname( name );
214 fname.MakeAbsolute( m_InputFile.GetPath() );
215 ss << TO_UTF8( fname.GetFullPath() ) << '\n';
216 }
217
218 std::string packet = ss.str();
219 frame->Kiway().ExpressMail( aFrameType, MAIL_ADD_LOCAL_LIB, packet, m_frame );
220}
221
222
224{
225 wxFileConfig config( wxEmptyString, wxEmptyString, wxEmptyString, m_InputFile.GetFullPath(),
226 wxCONFIG_USE_NO_ESCAPE_CHARACTERS );
227
228 wxString groupname;
229 long groupid;
230
231 std::set<wxString> sch_file;
232 std::set<wxString> pcb_file;
233 std::set<wxString> sch_libs;
234 std::set<wxString> pcb_libs;
235
236 for( bool more = config.GetFirstGroup( groupname, groupid ); more;
237 more = config.GetNextGroup( groupname, groupid ) )
238 {
239 if( !groupname.StartsWith( wxS( "Document" ) ) )
240 continue;
241
242 wxString number = groupname.Mid( 8 );
243 long docNumber;
244
245 if( !number.ToLong( &docNumber ) )
246 continue;
247
248 wxString path = config.Read( groupname + wxS( "/DocumentPath" ), wxEmptyString );
249
250 if( path.empty() )
251 continue;
252
253 wxFileName fname( path, wxPATH_WIN );
254
255 if( !fname.IsAbsolute() )
256 fname.MakeAbsolute( m_InputFile.GetPath() );
257
258 if( !fname.GetExt().CmpNoCase( "PCBDOC" ) )
259 pcb_file.insert( fname.GetFullPath() );
260
261 if( !fname.GetExt().CmpNoCase( "SCHDOC" ) )
262 sch_file.insert( fname.GetFullPath() );
263
264 if( !fname.GetExt().CmpNoCase( "PCBLIB" ) )
265 pcb_libs.insert( fname.GetFullPath() );
266
267 if( !fname.GetExt().CmpNoCase( "SCHLIB" ) )
268 sch_libs.insert( fname.GetFullPath() );
269 }
270
271 addLocalLibraries( sch_libs, FRAME_SCH );
273
274 m_properties["project_file"] = m_InputFile.GetFullPath();
275
276 int ii = 0;
277
278 for( auto& path : sch_file )
279 {
280 std::string key = "sch" + std::to_string( ii++ );
281 m_properties[key] = path.ToStdString();
282 }
283
284 if( !sch_file.empty() )
285 doImport( "", FRAME_SCH, SCH_IO_MGR::SCH_ALTIUM );
286
287 if( !pcb_file.empty() )
289}
290
291
292void IMPORT_PROJ_HELPER::ImportFiles( int aImportedSchFileType, int aImportedPcbFileType )
293{
294 m_properties.clear();
295
296 if( aImportedSchFileType == SCH_IO_MGR::SCH_EASYEDAPRO
297 || aImportedPcbFileType == PCB_IO_MGR::EASYEDAPRO )
298 {
300 }
301 else if( aImportedSchFileType == SCH_IO_MGR::SCH_ALTIUM
302 || aImportedPcbFileType == PCB_IO_MGR::ALTIUM_DESIGNER )
303 {
305 return;
306 }
307
308 ImportIndividualFile( SCHEMATIC_T, aImportedSchFileType );
309 ImportIndividualFile( PCB_T, aImportedPcbFileType );
310}
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.