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 <fctsys.h>
30 #include <nlohmann/json.hpp>
31 #include <wx/filename.h>
32 
34 #include <gerbview.h>
35 #include <richio.h>
36 #include <gerber_file_image.h>
37 #include <gerber_file_image_list.h>
38 #include <gerbview_frame.h>
39 #include <reporter.h>
40 #include <gbr_metadata.h>
41 #include <html_messagebox.h>
42 #include <view/view.h>
43 
45 
78 {
79 public:
80  GERBER_JOBFILE_READER( const wxString& aFileName, REPORTER* aReporter )
81  {
82  m_filename = aFileName;
83  m_reporter = aReporter;
84  }
85 
87 
88  bool ReadGerberJobFile();
89  wxArrayString& GetGerberFiles() { return m_GerberFiles; }
90 
91 private:
93  wxFileName m_filename;
94  wxArrayString m_GerberFiles; // List of gerber files in job
95 
96  // Convert a JSON string, that uses escaped sequence of 4 hexdecimal digits
97  // to encode unicode chars when not ASCII7 codes
98  // json11 converts this sequence to UTF8 string
99  wxString formatStringFromJSON( const std::string& name );
100 };
101 
102 
104 {
105  // Read the gerber file */
106  FILE* jobFile = wxFopen( m_filename.GetFullPath(), wxT( "rt" ) );
107 
108  if( jobFile == nullptr )
109  return false;
110 
111  LOCALE_IO toggleIo;
112 
113  FILE_LINE_READER jobfileReader( jobFile, m_filename.GetFullPath() ); // Will close jobFile
114 
115  wxString msg;
116  wxString data;
117 
118  // detect the file format: old (deprecated) gerber format of official JSON format
119  bool json_format = false;
120 
121  char* line = jobfileReader.ReadLine();
122 
123  if( !line ) // end of file
124  return false;
125 
126  data = line;
127 
128  if( data.Contains( "{" ) )
129  json_format = true;
130 
131  if( json_format )
132  {
133  while( ( line = jobfileReader.ReadLine() ) )
134  data << '\n' << line;
135 
136  try
137  {
138  json js = json::parse( TO_UTF8( data ) );
139 
140  for( json& entry : js["FilesAttributes"] )
141  {
142  std::string name = entry["Path"].get<std::string>();
144  }
145  }
146  catch( ... )
147  {
148  return false;
149  }
150  }
151  else
152  {
153  if( m_reporter )
154  m_reporter->ReportTail( _( "This job file uses an outdated format. Please recreate it." ),
156 
157  return false;
158  }
159 
160  return true;
161 }
162 
163 
164 wxString GERBER_JOBFILE_READER::formatStringFromJSON( const std::string& name )
165 {
166  // Convert a JSON string, that uses a escaped sequence of 4 hexdecimal digits
167  // to encode unicode chars
168  // Our json11 library returns in this case a UTF8 sequence. Just convert it to
169  // a wxString.
170  wxString wstr = FROM_UTF8( name.c_str() );
171  return wstr;
172 }
173 
174 
175 
176 bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
177 {
178  wxFileName filename = aFullFileName;
179  wxString currentPath;
180  bool success = true;
181 
182  if( !filename.IsOk() )
183  {
184  // Use the current working directory if the file name path does not exist.
185  if( filename.DirExists() )
186  currentPath = filename.GetPath();
187  else
188  currentPath = m_mruPath;
189 
190  wxFileDialog dlg( this, _( "Open Gerber Job File" ),
191  currentPath,
192  filename.GetFullName(),
194  wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
195 
196  if( dlg.ShowModal() == wxID_CANCEL )
197  return false;
198 
199  filename = dlg.GetPath();
200  currentPath = filename.GetPath();
201  m_mruPath = currentPath;
202  }
203  else
204  {
205  currentPath = filename.GetPath();
206  m_mruPath = currentPath;
207  }
208 
209  wxString msg;
210  WX_STRING_REPORTER reporter( &msg );
211 
212  if( filename.IsOk() )
213  {
214  GERBER_JOBFILE_READER gbjReader( filename.GetFullPath(), &reporter );
215 
216  if( gbjReader.ReadGerberJobFile() )
217  {
218  // Update the list of recent drill files.
219  UpdateFileHistory( filename.GetFullPath(), &m_jobFileHistory );
220 
221  Clear_DrawLayers( false );
222  ClearMsgPanel();
223 
224  wxArrayString& gbrfiles = gbjReader.GetGerberFiles();
225 
226  success = loadListOfGerberAndDrillFiles( currentPath, gbrfiles );
227  }
228  }
229 
231 
232  SetActiveLayer( 0 );
233 
234  if( !msg.IsEmpty() )
235  {
236  wxSafeYield(); // Allows slice of time to redraw the screen
237  // to refresh widgets, before displaying messages
238  HTML_MESSAGE_BOX mbox( this, _( "Messages" ) );
239  mbox.ListSet( msg );
240  mbox.ShowModal();
241  }
242 
243  return success;
244 }
a class to handle special data (items attributes) during plot.
char * ReadLine() override
Function ReadLine reads a line of text into the buffer and increments the line number counter.
Definition: richio.cpp:194
void SortLayersByX2Attributes()
bool Clear_DrawLayers(bool query)
wxString m_mruPath
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:62
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:202
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)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:92
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
Function SetActiveLayer will change the currently active layer to aLayer and also update the GERBER_L...
bool loadListOfGerberAndDrillFiles(const wxString &aPath, const wxArrayString &aFilenameList, const std::vector< int > *aFileType=nullptr)
Loads a list of Gerber and NC drill files and updates the view based on them.
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:62
nlohmann::json json
Definition: gerbview.cpp:40
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=NULL)
Update the list of recently opened files.
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)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:48
FILE_LINE_READER is a LINE_READER that reads from an open file.
Definition: richio.h:180
GERBER_JOBFILE_READER(const wxString &aFileName, REPORTER *aReporter)
void ListSet(const wxString &aList)
Add a list of items.
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
Definition of file extensions used in Kicad.
wxArrayString & GetGerberFiles()
read a .gbrjob file
HTML_MESSAGE_BOX.
virtual void ClearMsgPanel()
Clear all messages from the message panel.
WX_STRING_REPORTER is a wrapper for reporting to a wxString object.
Definition: reporter.h:154
wxString GerberJobFileWildcard()
const char * name
Definition: DXF_plotter.cpp:60
wxArrayString m_GerberFiles
#define _(s)
Definition: 3d_actions.cpp:33
wxString formatStringFromJSON(const std::string &name)