KiCad PCB EDA Suite
eda_doc.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) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2014-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 <pgm_base.h>
31 #include <common.h>
32 #include <confirm.h>
33 #include <gestfich.h>
35 
36 #include <wx/mimetype.h>
37 #include <wx/tokenzr.h>
38 #include <wx/filename.h>
39 #include <wx/uri.h>
40 #include <macros.h>
41 
42 
44 {
45  SetPdfBrowserName( GetCommonSettings()->m_System.pdf_viewer_name );
47 }
48 
49 
51 {
54 }
55 
56 
57 // Mime type extensions (PDF files are not considered here)
58 static wxMimeTypesManager* mimeDatabase;
59 static const wxFileTypeInfo EDAfallbacks[] =
60 {
61  wxFileTypeInfo( wxT( "text/html" ),
62  wxT( "wxhtml %s" ),
63  wxT( "wxhtml %s" ),
64  wxT( "html document (from KiCad)" ),
65  wxT( "htm" ),
66  wxT( "html" ),wxNullPtr ),
67 
68  wxFileTypeInfo( wxT( "application/sch" ),
69  wxT( "eeschema %s" ),
70  wxT( "eeschema -p %s" ),
71  wxT( "sch document (from KiCad)" ),
72  wxT( "sch" ),
73  wxT( "SCH" ), wxNullPtr ),
74 
75  // must terminate the table with this!
76  wxFileTypeInfo()
77 };
78 
79 
80 bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT* aProject )
81 {
82  SEARCH_STACK* aPaths = nullptr;
83  wxString docname;
84  wxString fullfilename;
85  wxString msg;
86  wxString command;
87  bool success = false;
88 
89 #if defined(EESCHEMA)
90  SEARCH_STACK* aPaths = aProject ? aProject->SchSearchS() : nullptr;
91 #endif
92 
93  // Is an internet url
94  static const wxChar* url_header[] = {
95  wxT( "http:" ),
96  wxT( "https:" ),
97  wxT( "ftp:" ),
98  wxT( "www." ),
99  wxT( "file:" )
100  };
101 
102  // Replace before resolving as we might have a URL in a variable
103  docname = ResolveUriByEnvVars( aDocName, aProject );
104 
105  for( const wxString& proc : url_header)
106  {
107  if( docname.First( proc ) == 0 ) // looks like an internet url
108  {
109  wxURI uri( docname );
110  wxLaunchDefaultBrowser( uri.BuildURI() );
111  return true;
112  }
113  }
114 
115 #ifdef __WINDOWS__
116  docname.Replace( UNIX_STRING_DIR_SEP, WIN_STRING_DIR_SEP );
117 #else
118  docname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
119 #endif
120 
121 
122  /* Compute the full file name */
123  if( wxIsAbsolutePath( docname ) || aPaths == NULL )
124  fullfilename = docname;
125  /* If the file exists, this is a trivial case: return the filename
126  * "as this". the name can be an absolute path, or a relative path
127  * like ./filename or ../<filename>
128  */
129  else if( wxFileName::FileExists( docname ) )
130  fullfilename = docname;
131  else
132  fullfilename = aPaths->FindValidPath( docname );
133 
134  wxString mask( wxT( "*" ) ), extension;
135 
136 #ifdef __WINDOWS__
137  mask += wxT( ".*" );
138  extension = wxT( ".*" );
139 #endif
140 
141  if( wxIsWild( fullfilename ) )
142  {
143  fullfilename = EDA_FILE_SELECTOR( _( "Doc Files" ),
144  wxPathOnly( fullfilename ),
145  fullfilename,
146  extension,
147  mask,
148  aParent,
149  wxFD_OPEN,
150  true,
151  wxPoint( -1, -1 ) );
152  if( fullfilename.IsEmpty() )
153  return false;
154  }
155 
156  if( !wxFileExists( fullfilename ) )
157  {
158  msg.Printf( _( "Doc File \"%s\" not found" ), GetChars( docname ) );
159  DisplayError( aParent, msg );
160  return false;
161  }
162 
163  wxFileName currentFileName( fullfilename );
164 
165  wxString file_ext = currentFileName.GetExt();
166 
167  if( file_ext.Lower() == wxT( "pdf" ) )
168  {
169  success = OpenPDF( fullfilename );
170  return success;
171  }
172 
173  /* Try to launch some browser (useful under linux) */
174  wxFileType* filetype;
175 
176  wxString type;
177  filetype = wxTheMimeTypesManager->GetFileTypeFromExtension( file_ext );
178 
179  if( !filetype ) // 2nd attempt.
180  {
181  mimeDatabase = new wxMimeTypesManager;
182  mimeDatabase->AddFallbacks( EDAfallbacks );
183  filetype = mimeDatabase->GetFileTypeFromExtension( file_ext );
184  delete mimeDatabase;
185  mimeDatabase = NULL;
186  }
187 
188  if( filetype )
189  {
190  wxFileType::MessageParameters params( fullfilename, type );
191 
192  success = filetype->GetOpenCommand( &command, params );
193  delete filetype;
194 
195  if( success )
196  success = ProcessExecute( command );
197  }
198 
199  if( !success )
200  {
201  msg.Printf( _( "Unknown MIME type for doc file \"%s\"" ), GetChars( fullfilename ) );
202  DisplayError( aParent, msg );
203  }
204 
205  return success;
206 }
207 
208 
209 bool KeywordMatch( const wxString& aKeys, const wxString& aDatabase )
210 {
211  if( aKeys.IsEmpty() )
212  return false;
213 
214  wxStringTokenizer keyTokenizer( aKeys, wxT( ", \t\n\r" ), wxTOKEN_STRTOK );
215 
216  while( keyTokenizer.HasMoreTokens() )
217  {
218  wxString key = keyTokenizer.GetNextToken();
219 
220  // Search for key in aDatabase:
221  wxStringTokenizer dataTokenizer( aDatabase, wxT( ", \t\n\r" ), wxTOKEN_STRTOK );
222 
223  while( dataTokenizer.HasMoreTokens() )
224  {
225  if( dataTokenizer.GetNextToken() == key )
226  return true;
227  }
228  }
229 
230  // keyword not found
231  return false;
232 }
VTBL_ENTRY COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:550
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject)
Function GetAssociatedDocument open a document (file) with the suitable browser.
Definition: eda_doc.cpp:80
wxString FindValidPath(const wxString &aFileName) const
Definition: search_stack.h:73
int ProcessExecute(const wxString &aCommandLine, int aFlags, wxProcess *callback)
Run a command in a child process.
Definition: common.cpp:364
#define WIN_STRING_DIR_SEP
Definition: gestfich.h:44
PROJECT holds project specific data.
Definition: project.h:61
This file is part of the common library TODO brief description.
This file is part of the common library.
#define UNIX_STRING_DIR_SEP
Definition: gestfich.h:43
SEARCH_STACK looks for files in a number of places.
Definition: search_stack.h:41
VTBL_ENTRY void WritePdfBrowserInfos()
Function WritePdfBrowserInfos saves the PDF browser choice to the common configuration.
Definition: eda_doc.cpp:50
static wxMimeTypesManager * mimeDatabase
Definition: eda_doc.cpp:58
bool m_use_system_pdf_browser
true to use the selected PDF browser, if exists, or false to use the default
Definition: pgm_base.h:366
This file contains miscellaneous commonly used macros and functions.
static const wxFileTypeInfo EDAfallbacks[]
Definition: eda_doc.cpp:59
#define NULL
VTBL_ENTRY void SetPdfBrowserName(const wxString &aFileName)
Definition: pgm_base.h:211
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:52
const wxString ResolveUriByEnvVars(const wxString &aUri, PROJECT *aProject)
Replace any environment and/or text variables in file-path uris (leaving network-path URIs alone).
Definition: common.cpp:587
VTBL_ENTRY const wxString & GetPdfBrowserName() const
Definition: pgm_base.h:209
VTBL_ENTRY void ReadPdfBrowserInfos()
Function ReadPdfBrowserInfos reads the PDF browser choice from the common configuration.
Definition: eda_doc.cpp:43
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:153
see class PGM_BASE
#define _(s)
Definition: 3d_actions.cpp:33
The common library.
bool KeywordMatch(const wxString &aKeys, const wxString &aDatabase)
Function KeywordMatch searches aKeyList for any words found in aDatabase.
Definition: eda_doc.cpp:209
bool OpenPDF(const wxString &file)
Function OpenPDF run the PDF viewer and display a PDF file.
Definition: gestfich.cpp:205