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