KiCad PCB EDA Suite
kicad/import_project.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) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * @author Russell Oliver <roliver8143@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
32 #include <wx/filefn.h>
33 #include <wx/filename.h>
34 #include <wx/dir.h>
35 
36 #include <common.h>
37 #include <confirm.h>
38 #include <kiway.h>
39 #include <richio.h>
41 #include <kiway_player.h>
42 #include <stdexcept>
43 #include "pgm_kicad.h"
44 
45 #include <io_mgr.h>
46 #include <sch_io_mgr.h>
47 
48 #include "kicad_manager_frame.h"
49 
50 
51 void KICAD_MANAGER_FRAME::ImportNonKiCadProject( wxString aWindowTitle, wxString aFilesWildcard,
52  wxString aSchFileExtension, wxString aPcbFileExtension, int aSchFileType, int aPcbFileType )
53 {
54  wxString msg;
55  wxString default_dir = GetMruPath();
56  int style = wxFD_OPEN | wxFD_FILE_MUST_EXIST;
57 
58  wxFileDialog schdlg( this, aWindowTitle, default_dir, wxEmptyString, aFilesWildcard, style );
59 
60  if( schdlg.ShowModal() == wxID_CANCEL )
61  return;
62 
63  wxFileName sch( schdlg.GetPath() );
64  sch.SetExt( aSchFileExtension );
65 
66  wxFileName pcb( sch );
67  pcb.SetExt( aPcbFileExtension );
68 
69  wxFileName pro( sch );
70  pro.SetExt( ProjectFileExtension );
71 
72  wxString protitle = _( "KiCad Project Destination" );
73 
74  // Don't use wxFileDialog here. On GTK builds, the default path is returned unless a
75  // file is actually selected.
76  wxDirDialog prodlg( this, protitle, pro.GetPath(), wxDD_DEFAULT_STYLE );
77 
78  if( prodlg.ShowModal() == wxID_CANCEL )
79  return;
80 
81  pro.SetPath( prodlg.GetPath() );
82 
83  // Check if the project directory is empty
84  wxDir directory( pro.GetPath() );
85 
86  if( directory.HasFiles() )
87  {
88  msg = _( "The selected directory is not empty. We recommend you "
89  "create projects in their own clean directory.\n\nDo you "
90  "want to create a new empty directory for the project?" );
91 
92  KIDIALOG dlg( this, msg, _( "Confirmation" ), wxYES_NO | wxICON_WARNING );
93  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
94 
95  if( dlg.ShowModal() == wxID_YES )
96  {
97  // Append a new directory with the same name of the project file
98  // Keep iterating until we find an empty directory
99  wxString newDir = pro.GetName();
100  int attempt = 0;
101 
102  pro.AppendDir( newDir );
103 
104  while( pro.DirExists() )
105  {
106  pro.RemoveLastDir();
107  wxString suffix = wxString::Format( "_%d", ++attempt );
108  pro.AppendDir( newDir + suffix );
109  }
110 
111  if( !wxMkdir( pro.GetPath() ) )
112  {
113  msg = _( "Error creating new directory. Please try a different path. The "
114  "project cannot be imported." );
115 
116  wxMessageDialog dirErrorDlg( this, msg, _( "Error" ), wxOK_DEFAULT | wxICON_ERROR );
117  dirErrorDlg.ShowModal();
118  return;
119  }
120  }
121  }
122 
123  std::string packet;
124 
125  pro.SetExt( ProjectFileExtension );
126 
127  if( !pro.IsAbsolute() )
128  pro.MakeAbsolute();
129 
130  wxFileName schCopy( pro );
131  schCopy.SetExt( aSchFileExtension );
132 
133  if( sch.Exists() && !schCopy.SameAs( sch ) )
134  {
135  if( !wxCopyFile( sch.GetFullPath(), schCopy.GetFullPath(), true ) )
136  {
138  msg.Printf( _( "Cannot copy file '%s'\n"
139  "to '%s'\n"
140  "The project cannot be imported." ),
141  sch.GetFullPath(), schCopy.GetFullPath() );
142 
143  wxMessageDialog schCopyErrorDlg( this, msg, _( "Error" ), wxOK_DEFAULT | wxICON_ERROR );
144  schCopyErrorDlg.ShowModal();
145  return;
146  }
147  }
148 
149  wxFileName pcbCopy( pro );
150  pcbCopy.SetExt( aPcbFileExtension );
151 
152  if( pcb.Exists() && !pcbCopy.SameAs( pcb ) )
153  {
154  if( !wxCopyFile( pcb.GetFullPath(), pcbCopy.GetFullPath(), true ) )
155  {
157  msg.Printf( _( "Cannot copy file '%s'\n"
158  "to '%s'\n"
159  "The project cannot be imported." ),
160  pcb.GetFullPath(), pcbCopy.GetFullPath() );
161 
162  wxMessageDialog brdCopyErrorDlg( this, msg, _( "Error" ), wxOK_DEFAULT | wxICON_ERROR );
163  brdCopyErrorDlg.ShowModal();
164  return;
165  }
166  }
167 
168  // Close the project and make the new one
169  CloseProject( true );
170  CreateNewProject( pro.GetFullPath(), false /* Don't create stub files */ );
171  LoadProject( pro );
172 
173  if( schCopy.FileExists() )
174  {
175  KIWAY_PLAYER* schframe = Kiway().Player( FRAME_SCH, true );
176 
177  packet = StrPrintf( "%d\n%s", aSchFileType, TO_UTF8( schCopy.GetFullPath() ) );
178  schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this );
179 
180  if( !schframe->IsShown() )
181  schframe->Show( true );
182 
183  // On Windows, Raise() does not bring the window on screen, when iconized
184  if( schframe->IsIconized() )
185  schframe->Iconize( false );
186 
187  schframe->Raise();
188 
189  if( !schCopy.SameAs( sch ) ) // Do not delete the original file!
190  wxRemoveFile( schCopy.GetFullPath() );
191  }
192 
193  if( pcbCopy.FileExists() )
194  {
195  KIWAY_PLAYER* pcbframe = Kiway().Player( FRAME_PCB_EDITOR, true );
196 
197  if( !pcbframe->IsVisible() )
198  pcbframe->Show( true );
199 
200  packet = StrPrintf( "%d\n%s", aPcbFileType, TO_UTF8( pcbCopy.GetFullPath() ) );
201  pcbframe->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_IMPORT_FILE, packet, this );
202 
203  // On Windows, Raise() does not bring the window on screen, when iconized
204  if( pcbframe->IsIconized() )
205  pcbframe->Iconize( false );
206 
207  pcbframe->Raise();
208 
209  if( !pcbCopy.SameAs( pcb ) ) // Do not delete the original file!
210  wxRemoveFile( pcbCopy.GetFullPath() );
211  }
212 
213  ReCreateTreePrj();
214  m_active_project = true;
215 }
216 
217 
219 {
220  ImportNonKiCadProject( _( "Import CADSTAR Archive Project Files" ),
221  CadstarArchiveFilesWildcard(), "csa", "cpa", SCH_IO_MGR::SCH_CADSTAR_ARCHIVE,
223 }
224 
225 
226 void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
227 {
228  ImportNonKiCadProject( _( "Import Eagle Project Files" ), EagleFilesWildcard(),
230  SCH_IO_MGR::SCH_EAGLE, IO_MGR::EAGLE );
231 }
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:61
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:56
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:56
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:45
This file is part of the common library.
const std::string ProjectFileExtension
const std::string LegacyPcbFileExtension
void ImportNonKiCadProject(wxString aWindowTitle, wxString aFilesWildcard, wxString aSchFileExtension, wxString aPcbFileExtension, int aSchFileType, int aPcbFileType)
Creates a project and imports a non-KiCad Schematic and PCB.
void OnImportEagleFiles(wxCommandEvent &event)
Open dialog to import Eagle schematic and board files.
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:345
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:439
int StrPrintf(std::string *result, const char *format,...)
This is like sprintf() but the output is appended to a std::string instead of to a character array.
Definition: richio.cpp:78
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void OnImportCadstarArchiveFiles(wxCommandEvent &event)
Open dialog to import CADSTAR Schematic and PCB Archive files.
wxString GetMruPath() const
Definition of file extensions used in Kicad.
const std::string LegacySchematicFileExtension
void CreateNewProject(const wxFileName &aProjectFileName, bool aCreateStubFiles=true)
Creates a new project by setting up and initial project, schematic, and board files.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
bool CloseProject(bool aSave)
Closes the project, and saves it if aSave is true;.
#define _(s)
Definition: 3d_actions.cpp:33
The common library.
int ShowModal() override
Definition: confirm.cpp:100
wxString EagleFilesWildcard()
void LoadProject(const wxFileName &aProjectFileName)
wxString CadstarArchiveFilesWildcard()