KiCad PCB EDA Suite
kicad/files-io.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) 2004-2015 Jean-Pierre Charras
5  * Copyright (C) 2004-2017 KiCad Developers, see change_log.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, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
30 #include <wx/dir.h>
31 #include <wx/fs_zip.h>
32 #include <wx/uri.h>
33 #include <wx/wfstream.h>
34 #include <wx/zipstrm.h>
35 
36 #include <confirm.h>
37 #include <kiway.h>
38 #include "pgm_kicad.h"
40 
41 #include "kicad_manager_frame.h"
42 
43 
44 #define ZipFileExtension wxT( "zip" )
45 
46 
47 void KICAD_MANAGER_FRAME::OnFileHistory( wxCommandEvent& event )
48 {
49  wxFileName projFileName = GetFileFromHistory( event.GetId(), _( "KiCad project file" ),
50  &PgmTop().GetFileHistory() );
51  if( !projFileName.FileExists() )
52  return;
53 
54  LoadProject( projFileName );
55 }
56 
57 
58 void KICAD_MANAGER_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
59 {
60  ClearFileHistory( &PgmTop().GetFileHistory() );
61 }
62 
63 
64 void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event )
65 {
66  wxFileName fn = GetProjectFileName();
67 
68  fn.SetExt( ZipFileExtension );
69 
70  wxFileDialog zipfiledlg( this, _( "Unzip Project" ), fn.GetPath(),
71  fn.GetFullName(), ZipFileWildcard(),
72  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
73 
74  if( zipfiledlg.ShowModal() == wxID_CANCEL )
75  return;
76 
77  wxString msg = wxString::Format( _( "\nOpen \"%s\"\n" ), GetChars( zipfiledlg.GetPath() ) );
78  PrintMsg( msg );
79 
80  wxDirDialog dirDlg( this, _( "Target Directory" ), fn.GetPath(),
81  wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
82 
83  if( dirDlg.ShowModal() == wxID_CANCEL )
84  return;
85 
86  wxString unzipDir = dirDlg.GetPath() + wxT( "/" );
87  msg.Printf( _( "Unzipping project in \"%s\"\n" ), GetChars( unzipDir ) );
88  PrintMsg( msg );
89 
90  wxFileSystem zipfilesys;
91 
92  zipfilesys.AddHandler( new wxZipFSHandler );
93  auto path = wxURI( zipfiledlg.GetPath() + wxT( "#zip:" ) ).BuildURI();
94  zipfilesys.ChangePathTo( path, true );
95 
96  wxFSFile* zipfile = NULL;
97  wxString localfilename = zipfilesys.FindFirst( wxFileSelectorDefaultWildcardStr, wxFILE );
98 
99  while( !localfilename.IsEmpty() )
100  {
101  zipfile = zipfilesys.OpenFile( localfilename );
102  if( !zipfile )
103  {
104  DisplayError( this, wxT( "Zip file read error" ) );
105  break;
106  }
107 
108  wxFileName uzfn = localfilename.AfterLast( ':' );
109  uzfn.MakeAbsolute( unzipDir );
110  wxString unzipfilename = uzfn.GetFullPath();
111 
112  msg.Printf( _( "Extract file \"%s\"" ), GetChars( unzipfilename ) );
113  PrintMsg( msg );
114 
115  wxInputStream* stream = zipfile->GetStream();
116  wxFFileOutputStream* ofile = new wxFFileOutputStream( unzipfilename );
117 
118  if( ofile->Ok() )
119  {
120  ofile->Write( *stream );
121  PrintMsg( _( " OK\n" ) );
122  }
123  else
124  PrintMsg( _( " *ERROR*\n" ) );
125 
126  delete ofile;
127  delete zipfile;
128 
129  localfilename = zipfilesys.FindNext();
130  }
131 
132  PrintMsg( wxT( "** end **\n" ) );
133 
134  if( unzipDir == Prj().GetProjectPath() )
136 }
137 
138 
139 void KICAD_MANAGER_FRAME::OnArchiveFiles( wxCommandEvent& event )
140 {
141  // List of file extensions to save.
142  static const wxChar* extensionList[] = {
143  wxT( "*.pro" ),
144  wxT( "*.sch" ), wxT( "*.lib" ), wxT( "*.dcm" ), // Schematic related files
145  wxT( "*.cmp" ),
146  wxT( "*.brd" ), wxT( "*.kicad_pcb" ), // Brd files
147  wxT( "*.mod" ), wxT( "*.kicad_mod" ), // fp files
148  wxT( "*.gb?" ), wxT( "*.gbrjob" ), // Gerber files
149  wxT( "*.gko" ), wxT( "*.gm1" ),
150  wxT( "*.gm2" ), wxT( "*.g?" ),
151  wxT( "*.gp1" ), wxT( "*.gp2" ),
152  wxT( "*.gpb" ), wxT( "*.gpt" ),
153  wxT( "*.gt?" ),
154  wxT( "*.pos" ), wxT( "*.drl" ), wxT( "*.nc" ), wxT( "*.xnc" ), // Fab files
155  wxT( "*.d356" ), wxT( "*.rpt" ),
156  wxT( "*.stp" ), wxT( "*.step" ), // 3d files
157  wxT( "*.wrl" ),
158  wxT( "*.net" ), wxT( "*.py" ),
159  wxT( "*.pdf" ), wxT( "*.txt" ), wxT( "*.kicad_wks" ),
160  wxT( "fp-lib-table" ), wxT( "sym-lib-table" )
161  };
162 
163  wxString msg;
164  wxFileName fileName = GetProjectFileName();
165  wxString oldCwd = wxGetCwd();
166 
167  fileName.SetExt( wxT( "zip" ) );
168 
169  wxFileDialog dlg( this, _( "Archive Project Files" ),
170  fileName.GetPath(), fileName.GetFullName(),
171  ZipFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
172 
173  if( dlg.ShowModal() == wxID_CANCEL )
174  return;
175 
176  wxFileName zip = dlg.GetPath();
177 
178  wxString currdirname = fileName.GetPathWithSep();
179  wxDir dir( currdirname );
180 
181  if( !dir.IsOpened() ) // wxWidgets display a error message on issue.
182  return;
183 
184  wxSetWorkingDirectory( currdirname );
185 
186  // Prepare the zip file
187  wxString zipfilename = zip.GetFullPath();
188 
189  wxFFileOutputStream ostream( zipfilename );
190 
191  if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
192  {
193  wxMessageBox( wxString::Format( _( "Unable to create zip archive file \"%s\"" ),
194  zipfilename ) );
195  return;
196  }
197 
198  wxZipOutputStream zipstream( ostream );
199 
200  // Build list of filenames to put in zip archive
201  wxString currFilename;
202 
203  wxArrayString files;
204 
205  for( unsigned ii = 0; ii < arrayDim( extensionList ); ii++ )
206  wxDir::GetAllFiles( currdirname, &files, extensionList[ii] );
207 
208  files.Sort();
209 
210  int zipBytesCnt = 0;
211 
212  for( unsigned ii = 0; ii < files.GetCount(); ii++ )
213  {
214  wxFileSystem fsfile;
215 
216  wxFileName curr_fn( files[ii] );
217  curr_fn.MakeRelativeTo( currdirname );
218  currFilename = curr_fn.GetFullPath();
219 
220  msg.Printf( _( "Archive file \"%s\"" ), GetChars( currFilename ) );
221  PrintMsg( msg );
222 
223  // Read input file and add it to the zip file:
224  wxFSFile* infile = fsfile.OpenFile( currFilename );
225 
226  if( infile )
227  {
228  zipstream.PutNextEntry( currFilename, infile->GetModificationTime() );
229  infile->GetStream()->Read( zipstream );
230  zipstream.CloseEntry();
231  int zippedsize = zipstream.GetSize() - zipBytesCnt;
232  zipBytesCnt = zipstream.GetSize();
233  PrintMsg( wxT(" ") );
234  msg.Printf( _( "(%lu bytes, compressed %d bytes)\n" ),
235  (unsigned long)infile->GetStream()->GetSize(), zippedsize );
236  PrintMsg( msg );
237  delete infile;
238  }
239  else
240  PrintMsg( _( " >>Error\n" ) );
241  }
242 
243  zipBytesCnt = ostream.GetSize();
244 
245  if( zipstream.Close() )
246  {
247  msg.Printf( _( "\nZip archive \"%s\" created (%d bytes)" ),
248  GetChars( zipfilename ), zipBytesCnt );
249  PrintMsg( msg );
250  PrintMsg( wxT( "\n** end **\n" ) );
251  }
252  else
253  {
254  msg.Printf( wxT( "Unable to create archive \"%s\", abort\n" ),
255  GetChars( zipfilename ) );
256  PrintMsg( msg );
257  }
258 
259  wxSetWorkingDirectory( oldCwd );
260 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
static const std::vector< std::string > extensionList
FILE_HISTORY & GetFileHistory()
Definition: pgm_kicad.h:56
void OnClearFileHistory(wxCommandEvent &aEvent)
This file is part of the common library.
wxString ZipFileWildcard()
void ClearFileHistory(FILE_HISTORY *aFileHistory=NULL)
Removes all files from the file history.
void OnFileHistory(wxCommandEvent &event)
#define NULL
void PrintMsg(const wxString &aText)
Displays aText in the text panel.
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
Definition of file extensions used in Kicad.
void OnArchiveFiles(wxCommandEvent &event)
PGM_KICAD & PgmTop()
Definition: kicad.cpp:72
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:108
#define ZipFileExtension
const wxString GetProjectFileName()
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=NULL)
Fetches the file name from the file history list.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:101
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
void LoadProject(const wxFileName &aProjectFileName)
void OnUnarchiveFiles(wxCommandEvent &event)