KiCad PCB EDA Suite
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 #include <wx/filedlg.h>
36 #include <wx/dirdlg.h>
37 
38 #include <common.h>
39 #include <confirm.h>
40 #include <kiway.h>
41 #include <macros.h>
42 #include <richio.h>
44 #include <kiway_player.h>
45 #include <stdexcept>
46 #include "pgm_kicad.h"
47 
48 #include <io_mgr.h>
49 #include <sch_io_mgr.h>
50 
51 #include "kicad_manager_frame.h"
52 
53 
54 void KICAD_MANAGER_FRAME::ImportNonKiCadProject( wxString aWindowTitle, wxString aFilesWildcard,
55  wxString aSchFileExtension, wxString aPcbFileExtension, int aSchFileType, int aPcbFileType )
56 {
57  wxString msg;
58  wxString default_dir = GetMruPath();
59  int style = wxFD_OPEN | wxFD_FILE_MUST_EXIST;
60 
61  wxFileDialog schdlg( this, aWindowTitle, default_dir, wxEmptyString, aFilesWildcard, style );
62 
63  if( schdlg.ShowModal() == wxID_CANCEL )
64  return;
65 
66  wxFileName sch( schdlg.GetPath() );
67  sch.SetExt( aSchFileExtension );
68 
69  wxFileName pcb( sch );
70  pcb.SetExt( aPcbFileExtension );
71 
72  wxFileName pro( sch );
73  pro.SetExt( ProjectFileExtension );
74 
75  wxString protitle = _( "KiCad Project Destination" );
76 
77  // Don't use wxFileDialog here. On GTK builds, the default path is returned unless a
78  // file is actually selected.
79  wxDirDialog prodlg( this, protitle, pro.GetPath(), wxDD_DEFAULT_STYLE );
80 
81  if( prodlg.ShowModal() == wxID_CANCEL )
82  return;
83 
84  pro.SetPath( prodlg.GetPath() );
85 
86  // Check if the project directory is empty
87  wxDir directory( pro.GetPath() );
88 
89  if( directory.HasFiles() )
90  {
91  msg = _( "The selected directory is not empty. We recommend you "
92  "create projects in their own clean directory.\n\nDo you "
93  "want to create a new empty directory for the project?" );
94 
95  KIDIALOG dlg( this, msg, _( "Confirmation" ), wxYES_NO | wxICON_WARNING );
96  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
97 
98  if( dlg.ShowModal() == wxID_YES )
99  {
100  // Append a new directory with the same name of the project file
101  // Keep iterating until we find an empty directory
102  wxString newDir = pro.GetName();
103  int attempt = 0;
104 
105  pro.AppendDir( newDir );
106 
107  while( pro.DirExists() )
108  {
109  pro.RemoveLastDir();
110  wxString suffix = wxString::Format( "_%d", ++attempt );
111  pro.AppendDir( newDir + suffix );
112  }
113 
114  if( !wxMkdir( pro.GetPath() ) )
115  {
116  msg = _( "Error creating new directory. Please try a different path. The "
117  "project cannot be imported." );
118 
119  wxMessageDialog dirErrorDlg( this, msg, _( "Error" ), wxOK_DEFAULT | wxICON_ERROR );
120  dirErrorDlg.ShowModal();
121  return;
122  }
123  }
124  }
125 
126  std::string packet;
127 
128  pro.SetExt( ProjectFileExtension );
129 
130  if( !pro.IsAbsolute() )
131  pro.MakeAbsolute();
132 
133  wxFileName schCopy( pro );
134  schCopy.SetExt( aSchFileExtension );
135 
136  if( sch.Exists() && !schCopy.SameAs( sch ) )
137  {
138  if( !wxCopyFile( sch.GetFullPath(), schCopy.GetFullPath(), true ) )
139  {
141  msg.Printf( _( "Cannot copy file '%s'\n"
142  "to '%s'\n"
143  "The project cannot be imported." ),
144  sch.GetFullPath(), schCopy.GetFullPath() );
145 
146  wxMessageDialog schCopyErrorDlg( this, msg, _( "Error" ), wxOK_DEFAULT | wxICON_ERROR );
147  schCopyErrorDlg.ShowModal();
148  return;
149  }
150  }
151 
152  wxFileName pcbCopy( pro );
153  pcbCopy.SetExt( aPcbFileExtension );
154 
155  if( pcb.Exists() && !pcbCopy.SameAs( pcb ) )
156  {
157  if( !wxCopyFile( pcb.GetFullPath(), pcbCopy.GetFullPath(), true ) )
158  {
160  msg.Printf( _( "Cannot copy file '%s'\n"
161  "to '%s'\n"
162  "The project cannot be imported." ),
163  pcb.GetFullPath(), pcbCopy.GetFullPath() );
164 
165  wxMessageDialog brdCopyErrorDlg( this, msg, _( "Error" ), wxOK_DEFAULT | wxICON_ERROR );
166  brdCopyErrorDlg.ShowModal();
167  return;
168  }
169  }
170 
171  // Close the project and make the new one
172  CloseProject( true );
173  CreateNewProject( pro.GetFullPath(), false /* Don't create stub files */ );
174  LoadProject( pro );
175 
176  if( schCopy.FileExists() )
177  {
178  KIWAY_PLAYER* schframe = Kiway().Player( FRAME_SCH, true );
179 
180  packet = StrPrintf( "%d\n%s", aSchFileType, TO_UTF8( schCopy.GetFullPath() ) );
181  schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this );
182 
183  if( !schframe->IsShown() )
184  schframe->Show( true );
185 
186  // On Windows, Raise() does not bring the window on screen, when iconized
187  if( schframe->IsIconized() )
188  schframe->Iconize( false );
189 
190  schframe->Raise();
191 
192  if( !schCopy.SameAs( sch ) ) // Do not delete the original file!
193  wxRemoveFile( schCopy.GetFullPath() );
194  }
195 
196  if( pcbCopy.FileExists() )
197  {
198  KIWAY_PLAYER* pcbframe = Kiway().Player( FRAME_PCB_EDITOR, true );
199 
200  if( !pcbframe->IsVisible() )
201  pcbframe->Show( true );
202 
203  packet = StrPrintf( "%d\n%s", aPcbFileType, TO_UTF8( pcbCopy.GetFullPath() ) );
204  pcbframe->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_IMPORT_FILE, packet, this );
205 
206  // On Windows, Raise() does not bring the window on screen, when iconized
207  if( pcbframe->IsIconized() )
208  pcbframe->Iconize( false );
209 
210  pcbframe->Raise();
211 
212  if( !pcbCopy.SameAs( pcb ) ) // Do not delete the original file!
213  wxRemoveFile( pcbCopy.GetFullPath() );
214  }
215 
216  ReCreateTreePrj();
217  m_active_project = true;
218 }
219 
220 
222 {
223  ImportNonKiCadProject( _( "Import CADSTAR Archive Project Files" ),
224  CadstarArchiveFilesWildcard(), "csa", "cpa", SCH_IO_MGR::SCH_CADSTAR_ARCHIVE,
226 }
227 
228 
229 void KICAD_MANAGER_FRAME::OnImportEagleFiles( wxCommandEvent& event )
230 {
231  ImportNonKiCadProject( _( "Import Eagle Project Files" ), EagleFilesWildcard(),
233  SCH_IO_MGR::SCH_EAGLE, IO_MGR::EAGLE );
234 }
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:55
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:368
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr)
Send aPayload to aDestination from aSource.
Definition: kiway.cpp:462
This file contains miscellaneous commonly used macros and functions.
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:99
wxString EagleFilesWildcard()
void LoadProject(const wxFileName &aProjectFileName)
wxString CadstarArchiveFilesWildcard()