KiCad PCB EDA Suite
gestfich.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 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
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 
31 #include <wx/mimetype.h>
32 #include <wx/filename.h>
33 #include <wx/dir.h>
34 
35 // For compilers that support precompilation, includes "wx.h".
36 #include <fctsys.h>
37 #include <pgm_base.h>
38 #include <confirm.h>
39 #include <common.h>
40 #include <macros.h>
41 
42 #include <gestfich.h>
43 
44 void AddDelimiterString( wxString& string )
45 {
46  if( !string.StartsWith( wxT( "\"" ) ) )
47  {
48  string.Prepend ( wxT( "\"" ) );
49  string.Append ( wxT( "\"" ) );
50  }
51 }
52 
53 
54 bool EDA_PATH_SELECTOR( const wxString& aTitle,
55  wxString& aPath,
56  int aFlags,
57  wxWindow* aParent,
58  const wxPoint& aPosition )
59 {
60  int ii;
61  bool selected = false;
62 
63  wxDirDialog* DirFrame = new wxDirDialog( aParent,
64  aTitle,
65  aPath,
66  aFlags,
67  aPosition );
68 
69  ii = DirFrame->ShowModal();
70 
71  if( ii == wxID_OK )
72  {
73  aPath = DirFrame->GetPath();
74  selected = true;
75  }
76 
77  DirFrame->Destroy();
78  return selected;
79 }
80 
81 
82 wxString EDA_FILE_SELECTOR( const wxString& aTitle,
83  const wxString& aPath,
84  const wxString& aFileName,
85  const wxString& aExtension,
86  const wxString& aWildcard,
87  wxWindow* aParent,
88  int aStyle,
89  const bool aKeepWorkingDirectory,
90  const wxPoint& aPosition,
91  wxString* aMruPath )
92 {
93  wxString fullfilename;
94  wxString curr_cwd = wxGetCwd();
95  wxString defaultname = aFileName;
96  wxString defaultpath = aPath;
97  wxString dotted_Ext = wxT(".") + aExtension;
98 
99 #ifdef __WINDOWS__
100  defaultname.Replace( wxT( "/" ), wxT( "\\" ) );
101  defaultpath.Replace( wxT( "/" ), wxT( "\\" ) );
102 #endif
103 
104  if( defaultpath.IsEmpty() )
105  {
106  if( aMruPath == NULL )
107  defaultpath = wxGetCwd();
108  else
109  defaultpath = *aMruPath;
110  }
111 
112  wxSetWorkingDirectory( defaultpath );
113 
114 #if 0 && defined (DEBUG)
115  printf( "defaultpath=\"%s\" defaultname=\"%s\" Ext=\"%s\" Mask=\"%s\" flag=%d keep_working_directory=%d\n",
116  TO_UTF8( defaultpath ),
117  TO_UTF8( defaultname ),
118  TO_UTF8( aExtension ),
119  TO_UTF8( aWildcard ),
120  aStyle,
121  aKeepWorkingDirectory );
122 #endif
123 
124  fullfilename = wxFileSelector( aTitle,
125  defaultpath,
126  defaultname,
127  dotted_Ext,
128  aWildcard,
129  aStyle, // open mode wxFD_OPEN, wxFD_SAVE ..
130  aParent,
131  aPosition.x, aPosition.y );
132 
133  if( aKeepWorkingDirectory )
134  wxSetWorkingDirectory( curr_cwd );
135 
136  if( !fullfilename.IsEmpty() && aMruPath )
137  {
138  wxFileName fn = fullfilename;
139  *aMruPath = fn.GetPath();
140  }
141 
142  return fullfilename;
143 }
144 
145 
146 wxString FindKicadFile( const wxString& shortname )
147 {
148  // Test the presence of the file in the directory shortname of
149  // the KiCad binary path.
150 #ifndef __WXMAC__
151  wxString fullFileName = Pgm().GetExecutablePath() + shortname;
152 #else
153  wxString fullFileName = Pgm().GetExecutablePath() + wxT( "Contents/MacOS/" ) + shortname;
154 #endif
155  if( wxFileExists( fullFileName ) )
156  return fullFileName;
157 
158  // Test the presence of the file in the directory shortname
159  // defined by the environment variable KiCad.
160  if( Pgm().IsKicadEnvVariableDefined() )
161  {
162  fullFileName = Pgm().GetKicadEnvVariable() + shortname;
163 
164  if( wxFileExists( fullFileName ) )
165  return fullFileName;
166  }
167 
168  // Path list for KiCad binary files
169  const static wxChar* possibilities[] = {
170 #if defined( __WINDOWS__ )
171  wxT( "c:/kicad/bin/" ),
172  wxT( "d:/kicad/bin/" ),
173  wxT( "c:/Program Files/kicad/bin/" ),
174  wxT( "d:/Program Files/kicad/bin/" ),
175 #elif defined( __WXMAC__ )
176  // all internal paths are relative to main bundle kicad.app
177  wxT( "Contents/Applications/pcbnew.app/Contents/MacOS/" ),
178  wxT( "Contents/Applications/eeschema.app/Contents/MacOS/" ),
179  wxT( "Contents/Applications/gerbview.app/Contents/MacOS/" ),
180  wxT( "Contents/Applications/bitmap2component.app/Contents/MacOS/" ),
181  wxT( "Contents/Applications/pcb_calculator.app/Contents/MacOS/" ),
182  wxT( "Contents/Applications/pl_editor.app/Contents/MacOS/" ),
183 #else
184  wxT( "/usr/bin/" ),
185  wxT( "/usr/local/bin/" ),
186  wxT( "/usr/local/kicad/bin/" ),
187 #endif
188  };
189 
190  // find binary file from possibilities list:
191  for( unsigned i=0; i<DIM(possibilities); ++i )
192  {
193 #ifndef __WXMAC__
194  fullFileName = possibilities[i] + shortname;
195 #else
196  // make relative paths absolute
197  fullFileName = Pgm().GetExecutablePath() + possibilities[i] + shortname;
198 #endif
199 
200  if( wxFileExists( fullFileName ) )
201  return fullFileName;
202  }
203 
204  return shortname;
205 }
206 
207 
208 int ExecuteFile( wxWindow* frame, const wxString& ExecFile, const wxString& param,
209  wxProcess *callback )
210 {
211  wxString fullFileName = FindKicadFile( ExecFile );
212 
213  if( wxFileExists( fullFileName ) )
214  {
215  if( !param.IsEmpty() )
216  fullFileName += wxT( " " ) + param;
217 
218  return ProcessExecute( fullFileName, wxEXEC_ASYNC, callback );
219  }
220 #ifdef __WXMAC__
221  else
222  {
223  AddDelimiterString( fullFileName );
224 
225  if( !param.IsEmpty() )
226  fullFileName += wxT( " " ) + param;
227 
228  return ProcessExecute( wxT( "/usr/bin/open -a " ) + fullFileName, wxEXEC_ASYNC, callback );
229  }
230 #endif
231 
232  wxString msg;
233  msg.Printf( _( "Command <%s> could not found" ), GetChars( fullFileName ) );
234  DisplayError( frame, msg, 20 );
235  return -1;
236 }
237 
238 
239 wxString KicadDatasPath()
240 {
241  bool found = false;
242  wxString data_path;
243 
244  if( Pgm().IsKicadEnvVariableDefined() ) // Path defined by the KICAD environment variable.
245  {
246  data_path = Pgm().GetKicadEnvVariable();
247  found = true;
248  }
249  else // Path of executables.
250  {
251 #ifndef __WXMAC__
252  wxString tmp = Pgm().GetExecutablePath();
253 #ifdef __WINDOWS__
254  tmp.MakeLower();
255 #endif
256  if( tmp.Contains( wxT( "kicad" ) ) )
257  {
258 #ifdef __WINDOWS__
259  tmp = Pgm().GetExecutablePath();
260 #endif
261  if( tmp.Last() == '/' )
262  tmp.RemoveLast();
263 
264  data_path = tmp.BeforeLast( '/' ); // id cd ../
265  data_path += UNIX_STRING_DIR_SEP;
266 
267  // Old versions of KiCad use kicad/ as default for data
268  // and last versions kicad/share/
269  // So we search for kicad/share/ first
270  wxString old_path = data_path;
271  data_path += wxT( "share/" );
272 
273  if( wxDirExists( data_path ) )
274  {
275  found = true;
276  }
277  else if( wxDirExists( old_path ) )
278  {
279  data_path = old_path;
280  found = true;
281  }
282  }
283  }
284 
285  if( !found )
286  {
287  // find KiCad from possibilities list:
288  // /usr/local/kicad/ or c:/kicad/
289 
290  const static wxChar* possibilities[] = {
291 #ifdef __WINDOWS__
292  wxT( "c:/kicad/share/" ),
293  wxT( "d:/kicad/share/" ),
294  wxT( "c:/kicad/" ),
295  wxT( "d:/kicad/" ),
296  wxT( "c:/Program Files/kicad/share/" ),
297  wxT( "d:/Program Files/kicad/share/" ),
298  wxT( "c:/Program Files/kicad/" ),
299  wxT( "d:/Program Files/kicad/" ),
300 #else
301  wxT( "/usr/share/kicad/" ),
302  wxT( "/usr/local/share/kicad/" ),
303  wxT( "/usr/local/kicad/share/" ), // default data path for "universal
304  // tarballs" and build for a server
305  // (new)
306  wxT( "/usr/local/kicad/" ), // default data path for "universal
307  // tarballs" and build for a server
308  // (old)
309 #endif
310  };
311 
312  for( unsigned i=0; i<DIM(possibilities); ++i )
313  {
314  data_path = possibilities[i];
315 
316  if( wxDirExists( data_path ) )
317  {
318  found = true;
319  break;
320  }
321  }
322 #else
323  // On OSX point to Contents/SharedSupport folder of main bundle
324  data_path = GetOSXKicadDataDir();
325  found = true;
326 #endif
327  }
328 
329  if( found )
330  {
331  data_path.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
332 
333  if( data_path.Last() != '/' )
334  data_path += UNIX_STRING_DIR_SEP;
335  }
336  else
337  {
338  data_path.Empty();
339  }
340 
341  return data_path;
342 }
343 
344 
345 bool OpenPDF( const wxString& file )
346 {
347  wxString command;
348  wxString filename = file;
349 
351 
352  if( !Pgm().UseSystemPdfBrowser() ) // Run the preferred PDF Browser
353  {
354  AddDelimiterString( filename );
355  command = Pgm().GetPdfBrowserName() + wxT( " " ) + filename;
356  }
357  else
358  {
359  wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension( wxT( "pdf" ) );
360 
361  if( filetype )
362  command = filetype->GetOpenCommand( filename );
363 
364  delete filetype;
365  }
366 
367  if( !command.IsEmpty() )
368  {
369  if( ProcessExecute( command ) )
370  {
371  return true;
372  }
373  else
374  {
375  wxString msg;
376  msg.Printf( _( "Problem while running the PDF viewer\nCommand is '%s'" ),
377  GetChars( command ) );
378  DisplayError( NULL, msg );
379  }
380  }
381  else
382  {
383  wxString msg;
384  msg.Printf( _( "Unable to find a PDF viewer for <%s>" ), GetChars( filename ) );
385  DisplayError( NULL, msg );
386  }
387 
388  return false;
389 }
390 
391 
392 void OpenFile( const wxString& file )
393 {
394  wxString command;
395  wxString filename = file;
396 
397  wxFileName CurrentFileName( filename );
398  wxString ext, type;
399 
400  ext = CurrentFileName.GetExt();
401  wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension( ext );
402 
403  bool success = false;
404 
405  wxFileType::MessageParameters params( filename, type );
406 
407  if( filetype )
408  success = filetype->GetOpenCommand( &command, params );
409 
410  delete filetype;
411 
412  if( success && !command.IsEmpty() )
413  ProcessExecute( command );
414 }
415 
416 
417 wxString QuoteFullPath( wxFileName& fn, wxPathFormat format )
418 {
419  return wxT( "\"" ) + fn.GetFullPath( format ) + wxT( "\"" );
420 }
#define DIM(x)
of elements in an array
Definition: macros.h:98
int ProcessExecute(const wxString &aCommandLine, int aFlags, wxProcess *callback)
Function ProcessExecute runs a child process.
Definition: common.cpp:160
#define WIN_STRING_DIR_SEP
Definition: gestfich.h:44
This file is part of the common library TODO brief description.
VTBL_ENTRY const wxString & GetKicadEnvVariable() const
Definition: pgm_base.h:171
This file is part of the common library.
VTBL_ENTRY const wxString & GetExecutablePath() const
Definition: pgm_base.h:173
wxString KicadDatasPath()
Function KicadDatasPath returns the data path common to KiCad.
Definition: gestfich.cpp:239
#define UNIX_STRING_DIR_SEP
Definition: gestfich.h:43
VTBL_ENTRY const wxString & GetPdfBrowserName() const
Definition: pgm_base.h:177
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:65
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
wxString EDA_FILE_SELECTOR(const wxString &aTitle, const wxString &aPath, const wxString &aFileName, const wxString &aExtension, const wxString &aWildcard, wxWindow *aParent, int aStyle, const bool aKeepWorkingDirectory, const wxPoint &aPosition, wxString *aMruPath)
Function EDA_FILE_SELECTOR.
Definition: gestfich.cpp:82
void AddDelimiterString(wxString &string)
Function AddDelimiterString Add un " to the start and the end of string (if not already done)...
Definition: gestfich.cpp:44
bool EDA_PATH_SELECTOR(const wxString &aTitle, wxString &aPath, int aFlags, wxWindow *aParent, const wxPoint &aPosition)
Function EDA_PATH_SELECTOR.
Definition: gestfich.cpp:54
wxString FindKicadFile(const wxString &shortname)
Function FindKicadFile searches the executable file shortname in KiCad binary path and return full fi...
Definition: gestfich.cpp:146
VTBL_ENTRY void ReadPdfBrowserInfos()
Function ReadPdfBrowserInfos reads the PDF browser choice from the common configuration.
Definition: eda_doc.cpp:41
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:92
see class PGM_BASE
wxString QuoteFullPath(wxFileName &fn, wxPathFormat format)
Quote return value of wxFileName::GetFullPath().
Definition: gestfich.cpp:417
The common library.
void OpenFile(const wxString &file)
Definition: gestfich.cpp:392
int ExecuteFile(wxWindow *frame, const wxString &ExecFile, const wxString &param, wxProcess *callback)
Function ExecuteFile calls the executable file ExecFile with the command line parameters param...
Definition: gestfich.cpp:208
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:69
bool OpenPDF(const wxString &file)
Function OpenPDF run the PDF viewer and display a PDF file.
Definition: gestfich.cpp:345