KiCad PCB EDA Suite
job_file_reader.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) 2007-2019 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.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 
29 #include <nlohmann/json.hpp>
30 #include <wx/filename.h>
31 
33 #include <gerbview.h>
34 #include <richio.h>
35 #include <locale_io.h>
36 #include <macros.h>
37 #include <gerber_file_image.h>
38 #include <gerber_file_image_list.h>
39 #include <gerbview_frame.h>
40 #include <reporter.h>
41 #include <gbr_metadata.h>
43 #include <view/view.h>
44 #include <wx/filedlg.h>
45 
46 
48 
81 {
82 public:
83  GERBER_JOBFILE_READER( const wxString& aFileName, REPORTER* aReporter )
84  {
85  m_filename = aFileName;
86  m_reporter = aReporter;
87  }
88 
90 
91  bool ReadGerberJobFile();
92  wxArrayString& GetGerberFiles() { return m_GerberFiles; }
93 
94 private:
96  wxFileName m_filename;
97  wxArrayString m_GerberFiles; // List of gerber files in job
98 
99  // Convert a JSON string, that uses escaped sequence of 4 hexadecimal digits
100  // to encode unicode chars when not ASCII7 codes
101  // json11 converts this sequence to UTF8 string
102  wxString formatStringFromJSON( const std::string& name );
103 };
104 
105 
107 {
108  // Read the gerber file */
109  FILE* jobFile = wxFopen( m_filename.GetFullPath(), wxT( "rt" ) );
110 
111  if( jobFile == nullptr )
112  return false;
113 
114  LOCALE_IO toggleIo;
115 
116  FILE_LINE_READER jobfileReader( jobFile, m_filename.GetFullPath() ); // Will close jobFile
117 
118  wxString msg;
119  wxString data;
120 
121  // detect the file format: old (deprecated) gerber format of official JSON format
122  bool json_format = false;
123 
124  char* line = jobfileReader.ReadLine();
125 
126  if( !line ) // end of file
127  return false;
128 
129  data = line;
130 
131  if( data.Contains( "{" ) )
132  json_format = true;
133 
134  if( json_format )
135  {
136  while( ( line = jobfileReader.ReadLine() ) )
137  data << '\n' << line;
138 
139  try
140  {
141  json js = json::parse( TO_UTF8( data ) );
142 
143  for( json& entry : js["FilesAttributes"] )
144  {
145  std::string name = entry["Path"].get<std::string>();
147  }
148  }
149  catch( ... )
150  {
151  return false;
152  }
153  }
154  else
155  {
156  if( m_reporter )
157  m_reporter->ReportTail( _( "This job file uses an outdated format. Please recreate it." ),
159 
160  return false;
161  }
162 
163  return true;
164 }
165 
166 
167 wxString GERBER_JOBFILE_READER::formatStringFromJSON( const std::string& name )
168 {
169  // Convert a JSON string, that uses a escaped sequence of 4 hexadecimal digits
170  // to encode unicode chars
171  // Our json11 library returns in this case a UTF8 sequence. Just convert it to
172  // a wxString.
173  wxString wstr = FROM_UTF8( name.c_str() );
174  return wstr;
175 }
176 
177 
178 
179 bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
180 {
181  wxFileName filename = aFullFileName;
182  wxString currentPath;
183  bool success = true;
184 
185  if( !filename.IsOk() )
186  {
187  // Use the current working directory if the file name path does not exist.
188  if( filename.DirExists() )
189  currentPath = filename.GetPath();
190  else
191  currentPath = m_mruPath;
192 
193  wxFileDialog dlg( this, _( "Open Gerber Job File" ),
194  currentPath,
195  filename.GetFullName(),
197  wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
198 
199  if( dlg.ShowModal() == wxID_CANCEL )
200  return false;
201 
202  filename = dlg.GetPath();
203  currentPath = filename.GetPath();
204  m_mruPath = currentPath;
205  }
206  else
207  {
208  currentPath = filename.GetPath();
209  m_mruPath = currentPath;
210  }
211 
212  wxString msg;
213  WX_STRING_REPORTER reporter( &msg );
214 
215  if( filename.IsOk() )
216  {
217  GERBER_JOBFILE_READER gbjReader( filename.GetFullPath(), &reporter );
218 
219  if( gbjReader.ReadGerberJobFile() )
220  {
221  // Update the list of recent drill files.
222  UpdateFileHistory( filename.GetFullPath(), &m_jobFileHistory );
223 
224  Clear_DrawLayers( false );
225  ClearMsgPanel();
226 
227  wxArrayString& gbrfiles = gbjReader.GetGerberFiles();
228 
229  success = LoadListOfGerberAndDrillFiles( currentPath, gbrfiles );
230 
231  Zoom_Automatique( false );
232  }
233  }
234 
236 
237  if( !msg.IsEmpty() )
238  {
239  wxSafeYield(); // Allows slice of time to redraw the screen
240  // to refresh widgets, before displaying messages
241  HTML_MESSAGE_BOX mbox( this, _( "Messages" ) );
242  mbox.ListSet( msg );
243  mbox.ShowModal();
244  }
245 
246  return success;
247 }
Handle special data (items attributes) during plot.
char * ReadLine() override
Read a line of text into the buffer and increments the line number counter.
Definition: richio.cpp:214
void SortLayersByX2Attributes()
bool Clear_DrawLayers(bool query)
wxString m_mruPath
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
FILE_HISTORY m_jobFileHistory
this class read and parse a Gerber job file to extract useful info for GerbView
bool parse(std::istream &aStream, bool aVerbose)
Parse a PCB or footprint file from the given input stream.
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the end of the list, for objects that support report ordering.
Definition: reporter.h:99
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:70
nlohmann::json json
Definition: gerbview.cpp:41
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
This file contains miscellaneous commonly used macros and functions.
bool LoadGerberJobFile(const wxString &aFileName)
Load a Gerber job file, and load gerber files found in job files.
nlohmann::json json
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
virtual void Zoom_Automatique(bool aWarpPointer)
Redraw the screen with best zoom level and the best centering that shows all the page or the board.
A LINE_READER that reads from an open file.
Definition: richio.h:172
GERBER_JOBFILE_READER(const wxString &aFileName, REPORTER *aReporter)
bool LoadListOfGerberAndDrillFiles(const wxString &aPath, const wxArrayString &aFilenameList, const std::vector< int > *aFileType=nullptr)
Load a list of Gerber and NC drill files and updates the view based on them.
void ListSet(const wxString &aList)
Add a list of items.
Definition of file extensions used in Kicad.
#define _(s)
wxArrayString & GetGerberFiles()
read a .gbrjob file
virtual void ClearMsgPanel()
Clear all messages from the message panel.
A wrapper for reporting to a wxString object.
Definition: reporter.h:163
wxString GerberJobFileWildcard()
const char * name
Definition: DXF_plotter.cpp:56
wxArrayString m_GerberFiles
wxString formatStringFromJSON(const std::string &name)