KiCad PCB EDA Suite
gerbview.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 #include <fctsys.h>
30 #include <gerbview.h>
31 #include <gerbview_frame.h>
32 #include <gerbview_settings.h>
33 #include <gestfich.h>
34 #include <kiface_i.h>
35 #include <nlohmann/json.hpp>
36 #include <pgm_base.h>
39 
41 
42 const wxChar* g_GerberPageSizeList[] =
43 {
44  wxT( "GERBER" ), // index 0: full size page selection
45  wxT( "A4" ),
46  wxT( "A3" ),
47  wxT( "A2" ),
48  wxT( "A" ),
49  wxT( "B" ),
50  wxT( "C" ),
51 };
52 
53 
54 namespace GERBV {
55 
56 static struct IFACE : public KIFACE_I
57 {
58  // Of course all are virtual overloads, implementations of the KIFACE.
59 
60  IFACE( const char* aName, KIWAY::FACE_T aType ) :
61  KIFACE_I( aName, aType )
62  {}
63 
64  bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) override;
65 
66  void OnKifaceEnd() override;
67 
68  wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) override
69  {
70  switch( aClassId )
71  {
72  case FRAME_GERBER:
73  {
74  GERBVIEW_FRAME* frame = new GERBVIEW_FRAME( aKiway, aParent );
75  return frame;
76  }
77  break;
78 
79  default:
80  ;
81  }
82 
83  return NULL;
84  }
85 
94  void* IfaceOrAddress( int aDataId ) override
95  {
96  return NULL;
97  }
98 
105  void SaveFileAs( const wxString& aProjectBasePath, const wxString& aProjectName,
106  const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
107  const wxString& aSrcFilePath, wxString& aErrors ) override;
108 
109 } kiface( "gerbview", KIWAY::FACE_GERBVIEW );
110 
111 } // namespace
112 
113 using namespace GERBV;
114 
116 
117 KIFACE_I& Kiface() { return kiface; }
118 
119 
120 // KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
121 // KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
122 MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
123 {
124  process = aProgram;
125  return &kiface;
126 }
127 
128 
130 {
131  wxASSERT( process ); // KIFACE_GETTER has already been called.
132  return *process;
133 }
134 
135 
136 bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
137 {
140  start_common( aCtlBits );
141  return true;
142 }
143 
144 
146 {
147  end_common();
148 }
149 
150 
151 void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProjectName,
152  const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
153  const wxString& aSrcFilePath, wxString& aErrors )
154 {
155  wxFileName destFile( aSrcFilePath );
156  wxString destPath = destFile.GetPathWithSep();
157  wxUniChar pathSep = wxFileName::GetPathSeparator();
158  wxString ext = destFile.GetExt();
159 
160  if( destPath.StartsWith( aProjectBasePath + pathSep ) )
161  {
162  destPath.Replace( aProjectBasePath, aNewProjectBasePath, false );
163  destFile.SetPath( destPath );
164  }
165 
166  if( ext == "gbr" || IsProtelExtension( ext ) )
167  {
168  wxString destFileName = destFile.GetName();
169 
170  if( destFileName.StartsWith( aProjectName + "-" ) )
171  {
172  destFileName.Replace( aProjectName, aNewProjectName, false );
173  destFile.SetName( destFileName );
174  }
175 
176  CopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
177  }
178  else if( ext == "gbrjob" )
179  {
180  if( destFile.GetName() == aProjectName + "-job" )
181  destFile.SetName( aNewProjectName + "-job" );
182 
183  FILE_LINE_READER jobfileReader( aSrcFilePath );
184 
185  char* line;
186  wxString data;
187 
188  while( ( line = jobfileReader.ReadLine() ) )
189  data << line << '\n';
190 
191  // detect the file format: old (deprecated) gerber format or official JSON format
192  if( !data.Contains( "{" ) )
193  {
194  CopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
195  return;
196  }
197 
198  bool success = false;
199 
200  try
201  {
202  // Will throw on parse error
203  json js = json::parse( TO_UTF8( data ) );
204 
205  for( auto& entry : js["FilesAttributes"] )
206  {
207  wxString path = wxString( entry["Path"].get<std::string>() );
208 
209  if( path.StartsWith( aProjectName + "-" ) )
210  {
211  path.Replace( aProjectName, aNewProjectName, false );
212  entry["Path"] = path.ToStdString();
213  }
214  }
215 
216  wxFile destJobFile( destFile.GetFullPath(), wxFile::write );
217 
218  if( destJobFile.IsOpened() )
219  success = destJobFile.Write( js.dump( 0 ) );
220 
221  // wxFile dtor will close the file
222  }
223  catch( ... )
224  {
225  success = false;
226  }
227 
228  if( !success )
229  {
230  wxString msg;
231 
232  if( !aErrors.empty() )
233  aErrors += "\n";
234 
235  msg.Printf( _( "Cannot copy file \"%s\"." ), destFile.GetFullPath() );
236  aErrors += msg;
237  }
238  }
239  else if( ext == "drl" )
240  {
241  wxString destFileName = destFile.GetName();
242 
243  if( destFileName == aProjectName )
244  destFileName = aNewProjectName;
245  else if( destFileName.StartsWith( aProjectName + "-" ) )
246  destFileName.Replace( aProjectName, aNewProjectName, false );
247 
248  destFile.SetName( destFileName );
249 
250  CopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
251  }
252  else
253  {
254  wxFAIL_MSG( "Unexpected filetype for GerbView::SaveFileAs()" );
255  }
256 }
257 
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits) override
Function OnKifaceStart is called just once shortly after the DSO is loaded.
Definition: gerbview.cpp:136
wxWindow * CreateWindow(wxWindow *aParent, int aClassId, KIWAY *aKiway, int aCtlBits=0) override
Function CreateWindow creates a wxWindow for the current project.
Definition: gerbview.cpp:68
KIFACE_I is a KIFACE (I)mplementation, with some features useful for DSOs which implement a KIFACE.
Definition: kiface_i.h:37
bool start_common(int aCtlBits)
Common things to do for a top program module, during OnKifaceStart().
Definition: kiface_i.cpp:89
VTBL_ENTRY SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:175
This file is part of the common library TODO brief description.
void OnKifaceEnd() override
Function OnKifaceEnd is called just once just before the DSO is to be unloaded.
Definition: gerbview.cpp:145
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: gerbview.cpp:117
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: gerbview.cpp:129
PGM_BASE keeps program (whole process) data for KiCad programs.
Definition: pgm_base.h:137
bool parse(std::istream &aStream, bool aVerbose)
Parse a PCB or footprint file from the given input stream.
void CopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Function CopyFile.
Definition: gestfich.cpp:363
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_i.h:103
nlohmann::json json
Definition: gerbview.cpp:40
bool IsProtelExtension(const wxString &ext)
int PGM_BASE * aProgram
Definition: gerbview.cpp:123
static PGM_BASE * process
Definition: gerbview.cpp:115
IFACE(const char *aName, KIWAY::FACE_T aType)
Definition: gerbview.cpp:60
FILE_LINE_READER is a LINE_READER that reads from an open file.
Definition: richio.h:180
GERBV::IFACE KIFACE_I kiface("gerbview", KIWAY::FACE_GERBVIEW)
#define NULL
void end_common()
Common things to do for a top program module, during OnKifaceEnd();.
Definition: kiface_i.cpp:99
int aKiwayVersion
Definition: gerbview.cpp:122
Definition of file extensions used in Kicad.
KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the s...
Definition: kiway.h:273
#define KIFACE_GETTER
Definition: kiway.h:112
FACE_T
Known KIFACE implementations.
Definition: kiway.h:279
void * IfaceOrAddress(int aDataId) override
Function IfaceOrAddress return a pointer to the requested object.
Definition: gerbview.cpp:94
JSON_SETTINGS * RegisterSettings(JSON_SETTINGS *aSettings, bool aLoadNow=true)
Takes ownership of the pointer passed in.
see class PGM_BASE
#define _(s)
Definition: 3d_actions.cpp:33
KIFACE is used by a participant in the KIWAY alchemy.
Definition: kiway.h:150
void SaveFileAs(const wxString &aProjectBasePath, const wxString &aProjectName, const wxString &aNewProjectBasePath, const wxString &aNewProjectName, const wxString &aSrcFilePath, wxString &aErrors) override
Function SaveFileAs Saving a file under a different name is delegated to the various KIFACEs because ...
Definition: gerbview.cpp:151
#define TO_UTF8(wxstring)
void InitSettings(APP_SETTINGS_BASE *aSettings)
Definition: kiface_i.h:105
MY_API(KIFACE *) KIFACE_GETTER(int *aKIFACEversion
const wxChar * g_GerberPageSizeList[]
List of page sizes.
Definition: gerbview.cpp:42