KiCad PCB EDA Suite
pgm_base.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-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 1992-2017 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 
33 #include <fctsys.h>
34 #include <wx/html/htmlwin.h>
35 #include <wx/fs_zip.h>
36 #include <wx/dir.h>
37 #include <wx/filename.h>
38 #include <wx/snglinst.h>
39 #include <wx/stdpaths.h>
40 #include <wx/sysopt.h>
41 #include <wx/richmsgdlg.h>
42 
43 #include <pgm_base.h>
44 #include <wxstruct.h>
45 #include <macros.h>
46 #include <config_params.h>
47 #include <id.h>
48 #include <build_version.h>
49 #include <hotkeys_basic.h>
50 #include <gestfich.h>
51 #include <menus_helpers.h>
52 #include <confirm.h>
53 #include <dialog_env_var_config.h>
54 #include <lockfile.h>
55 #include <systemdirsappend.h>
56 
57 
58 #define KICAD_COMMON wxT( "kicad_common" )
59 
60 // some key strings used to store parameters in KICAD_COMMON
61 
62 const wxChar PGM_BASE::workingDirKey[] = wxT( "WorkingDir" ); // public
63 
64 static const wxChar languageCfgKey[] = wxT( "LanguageID" );
65 static const wxChar pathEnvVariables[] = wxT( "EnvironmentVariables" );
66 static const wxChar showEnvVarWarningDialog[] = wxT( "ShowEnvVarWarningDialog" );
67 static const wxChar traceEnvVars[] = wxT( "KIENVVARS" );
69 static const wxChar entryUseIconsInMenus[] = wxT( "UseIconsInMenus" );
70 
71 
81 {
84 
87 
90 
92  wxString m_Lang_Label;
93 
96 };
97 
98 
106 {
107  // Default language
108  {
109  wxLANGUAGE_DEFAULT,
111  lang_def_xpm,
112  _( "Default" )
113  },
114 
115  // English language
116  {
117  wxLANGUAGE_ENGLISH,
119  lang_en_xpm,
120  wxT( "English" ),
121  true
122  },
123 
124  // French language
125  {
126  wxLANGUAGE_FRENCH,
128  lang_fr_xpm,
129  _( "French" )
130  },
131 
132  // Finnish language
133  {
134  wxLANGUAGE_FINNISH,
136  lang_fi_xpm,
137  _( "Finnish" )
138  },
139 
140  // Spanish language
141  {
142  wxLANGUAGE_SPANISH,
144  lang_es_xpm,
145  _( "Spanish" )
146  },
147 
148  // Portuguese language
149  {
150  wxLANGUAGE_PORTUGUESE,
152  lang_pt_xpm,
153  _( "Portuguese" )
154  },
155 
156  // Italian language
157  {
158  wxLANGUAGE_ITALIAN,
160  lang_it_xpm,
161  _( "Italian" )
162  },
163 
164  // German language
165  {
166  wxLANGUAGE_GERMAN,
168  lang_de_xpm,
169  _( "German" )
170  },
171 
172  // Greek language
173  {
174  wxLANGUAGE_GREEK,
176  lang_gr_xpm,
177  _( "Greek" )
178  },
179 
180  // Slovenian language
181  {
182  wxLANGUAGE_SLOVENIAN,
184  lang_sl_xpm,
185  _( "Slovenian" )
186  },
187 
188  // Slovenian language
189  {
190  wxLANGUAGE_SLOVAK,
192  lang_sk_xpm,
193  _( "Slovak" )
194  },
195 
196  // Hungarian language
197  {
198  wxLANGUAGE_HUNGARIAN,
200  lang_hu_xpm,
201  _( "Hungarian" )
202  },
203 
204  // Polish language
205  {
206  wxLANGUAGE_POLISH,
208  lang_pl_xpm,
209  _( "Polish" )
210  },
211 
212  // Czech language
213  {
214  wxLANGUAGE_CZECH,
216  lang_cs_xpm,
217  _( "Czech" )
218  },
219 
220  // Russian language
221  {
222  wxLANGUAGE_RUSSIAN,
224  lang_ru_xpm,
225  _( "Russian" )
226  },
227 
228  // Korean language
229  {
230  wxLANGUAGE_KOREAN,
232  lang_ko_xpm,
233  _( "Korean" )
234  },
235 
236  // Chinese simplified
237  {
238  wxLANGUAGE_CHINESE_SIMPLIFIED,
240  lang_chinese_xpm,
241  _( "Chinese simplified" )
242  },
243 
244  // Catalan language
245  {
246  wxLANGUAGE_CATALAN,
248  lang_catalan_xpm,
249  _( "Catalan" )
250  },
251 
252  // Dutch language
253  {
254  wxLANGUAGE_DUTCH,
256  lang_nl_xpm,
257  _( "Dutch" )
258  },
259 
260  // Japanese language
261  {
262  wxLANGUAGE_JAPANESE,
264  lang_jp_xpm,
265  _( "Japanese" )
266  },
267 
268  // Bulgarian language
269  {
270  wxLANGUAGE_BULGARIAN,
272  lang_bg_xpm,
273  _( "Bulgarian" )
274  },
275 
276  // Lithuanian language
277  {
278  wxLANGUAGE_LITHUANIAN,
280  lang_lt_xpm,
281  _( "Lithuanian" )
282  }
283 };
284 
285 
287 {
288  m_pgm_checker = NULL;
289  m_locale = NULL;
290  m_common_settings = NULL;
291 
292  m_show_env_var_dialog = true;
293 
294  setLanguageId( wxLANGUAGE_DEFAULT );
295 
296  ForceSystemPdfBrowser( false );
297 }
298 
299 
301 {
302  Destroy();
303 }
304 
305 
307 {
308  // unlike a normal destructor, this is designed to be called more than once safely:
309 
310  delete m_common_settings;
311  m_common_settings = 0;
312 
313  delete m_pgm_checker;
314  m_pgm_checker = 0;
315 
316  delete m_locale;
317  m_locale = 0;
318 }
319 
320 
322 {
323  wxASSERT( wxTheApp );
324  return *wxTheApp;
325 }
326 
327 
328 void PGM_BASE::SetEditorName( const wxString& aFileName )
329 {
330  m_editor_name = aFileName;
331  wxASSERT( m_common_settings );
332  m_common_settings->Write( wxT( "Editor" ), aFileName );
333 }
334 
335 
336 const wxString& PGM_BASE::GetEditorName( bool aCanShowFileChooser )
337 {
338  wxString editorname = m_editor_name;
339 
340  if( !editorname )
341  {
342  if( !wxGetEnv( wxT( "EDITOR" ), &editorname ) )
343  {
344  // If there is no EDITOR variable set, try the desktop default
345 #ifdef __WXMAC__
346  editorname = "/usr/bin/open";
347 #elif __WXX11__
348  editorname = "/usr/bin/xdg-open";
349 #endif
350  }
351  }
352 
353  // If we still don't have an editor name show a dialog asking the user to select one
354  if( !editorname && aCanShowFileChooser )
355  {
356  DisplayInfoMessage( NULL,
357  _( "No default editor found, you must choose it" ) );
358 
359  editorname = AskUserForPreferredEditor();
360  }
361 
362  // If we finally have a new editor name request it to be copied to m_editor_name and
363  // saved to the preferences file.
364  if( !editorname.IsEmpty() )
365  SetEditorName( editorname );
366 
367  // m_editor_name already has the same value that editorname, or empty if no editor was
368  // found/chosen.
369  return m_editor_name;
370 }
371 
372 
373 const wxString PGM_BASE::AskUserForPreferredEditor( const wxString& aDefaultEditor )
374 {
375  // Create a mask representing the executable files in the current platform
376 #ifdef __WINDOWS__
377  wxString mask( _( "Executable file (*.exe)|*.exe" ) );
378 #else
379  wxString mask( _( "Executable file (*)|*" ) );
380 #endif
381 
382  // Extract the path, name and extension from the default editor (even if the editor's
383  // name was empty, this method will succeed and return empty strings).
384  wxString path, name, ext;
385  wxFileName::SplitPath( aDefaultEditor, &path, &name, &ext );
386 
387  // Show the modal editor and return the file chosen (may be empty if the user cancels
388  // the dialog).
389  return EDA_FILE_SELECTOR( _( "Select Preferred Editor" ), path,
390  name, ext, mask,
391  NULL, wxFD_OPEN | wxFD_FILE_MUST_EXIST,
392  true );
393 }
394 
395 
397 {
398  wxFileName pgm_name( App().argv[0] );
399 
400  wxConfigBase::DontCreateOnDemand();
401 
402  wxInitAllImageHandlers();
403 
404  m_pgm_checker = new wxSingleInstanceChecker( pgm_name.GetName().Lower() + wxT( "-" ) +
405  wxGetUserId(), GetKicadLockFilePath() );
406 
407  if( m_pgm_checker->IsAnotherRunning() )
408  {
409  wxString quiz = wxString::Format(
410  _( "%s is already running, Continue?" ),
411  GetChars( pgm_name.GetName() )
412  );
413 
414  if( !IsOK( NULL, quiz ) )
415  return false;
416  }
417 
418  // Init KiCad environment
419  // the environment variable KICAD (if exists) gives the kicad path:
420  // something like set KICAD=d:\kicad
421  bool isDefined = wxGetEnv( wxT( "KICAD" ), &m_kicad_env );
422 
423  if( isDefined ) // ensure m_kicad_env ends by "/"
424  {
426 
427  if( !m_kicad_env.IsEmpty() && m_kicad_env.Last() != '/' )
429  }
430 
431  // Init parameters for configuration
432  App().SetVendorName( wxT( "KiCad" ) );
433  App().SetAppName( pgm_name.GetName().Lower() );
434 
435  // Install some image handlers, mainly for help
436  if( wxImage::FindHandler( wxBITMAP_TYPE_PNG ) == NULL )
437  wxImage::AddHandler( new wxPNGHandler );
438 
439  if( wxImage::FindHandler( wxBITMAP_TYPE_GIF ) == NULL )
440  wxImage::AddHandler( new wxGIFHandler );
441 
442  if( wxImage::FindHandler( wxBITMAP_TYPE_JPEG ) == NULL )
443  wxImage::AddHandler( new wxJPEGHandler );
444 
445  wxFileSystem::AddHandler( new wxZipFSHandler );
446 
447  // Analyze the command line & initialize the binary path
449 
450  SetLanguagePath();
451 
452  // OS specific instantiation of wxConfigBase derivative:
454 
455  // Only define the default environment variable if they haven't been set in the
456  // .kicad_common configuration file.
458  {
459  wxString envVarName = wxT( "KIGITHUB" );
460  ENV_VAR_ITEM envVarItem;
461  wxString envValue;
462  wxFileName tmpFileName;
463 
464  envVarItem.SetValue( wxString( wxT( "https://github.com/KiCad" ) ) );
465  envVarItem.SetDefinedExternally( wxGetEnv( envVarName, NULL ) );
466  m_local_env_vars[ envVarName ] = envVarItem;
467 
468  wxFileName baseSharePath;
469  baseSharePath.AssignDir( wxString( wxT( DEFAULT_INSTALL_PATH ) ) );
470 
471 #if !defined( __WXMAC__ )
472  baseSharePath.AppendDir( wxT( "share" ) );
473  baseSharePath.AppendDir( wxT( "kicad" ) );
474 #endif
475 
476  // KISYSMOD
477  envVarName = wxT( "KISYSMOD" );
478  if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
479  {
480  tmpFileName.AssignDir( envValue );
481  envVarItem.SetDefinedExternally( true );
482  }
483  else
484  {
485  tmpFileName = baseSharePath;
486  tmpFileName.AppendDir( wxT( "modules" ) );
487  envVarItem.SetDefinedExternally( false );
488  }
489  envVarItem.SetValue( tmpFileName.GetFullPath() );
490  m_local_env_vars[ envVarName ] = envVarItem;
491 
492  // KISYS3DMOD
493  envVarName = wxT( "KISYS3DMOD" );
494  if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
495  {
496  tmpFileName.AssignDir( envValue );
497  envVarItem.SetDefinedExternally( true );
498  }
499  else
500  {
501  tmpFileName.AppendDir( wxT( "packages3d" ) );
502  envVarItem.SetDefinedExternally( false );
503  }
504  envVarItem.SetValue( tmpFileName.GetFullPath() );
505  m_local_env_vars[ envVarName ] = envVarItem;
506 
507  // KICAD_PTEMPLATES
508  envVarName = wxT( "KICAD_PTEMPLATES" );
509  if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
510  {
511  tmpFileName.AssignDir( envValue );
512  envVarItem.SetDefinedExternally( true );
513  }
514  else
515  {
516  tmpFileName = baseSharePath;
517  tmpFileName.AppendDir( wxT( "template" ) );
518  envVarItem.SetDefinedExternally( false );
519  }
520  envVarItem.SetValue( tmpFileName.GetFullPath() );
521  m_local_env_vars[ envVarName ] = envVarItem;
522 
523  // KICAD_SYMBOLS
524  envVarName = wxT( "KICAD_SYMBOL_DIR" );
525  if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() )
526  {
527  tmpFileName.AssignDir( envValue );
528  envVarItem.SetDefinedExternally( true );
529  }
530  else
531  {
532  tmpFileName = baseSharePath;
533  tmpFileName.AppendDir( wxT( "library" ) );
534  envVarItem.SetDefinedExternally( false );
535  }
536  envVarItem.SetValue( tmpFileName.GetFullPath() );
537  m_local_env_vars[ envVarName ] = envVarItem;
538  }
539 
540  ReadPdfBrowserInfos(); // needs m_common_settings
541 
542  // Init user language *before* calling loadCommonSettings, because
543  // env vars could be incorrectly initialized on Linux
544  // (if the value contains some non ASCII7 chars, the env var is not initialized)
545  SetLanguage( true );
546 
548 
549 #ifdef __WXMAC__
550  // Always show filters on Open dialog to be able to choose plugin
551  wxSystemOptions::SetOption( wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, 1 );
552 #endif
553 
554  return true;
555 }
556 
557 
559 {
560  m_bin_dir = wxStandardPaths::Get().GetExecutablePath();
561 
562 #ifdef __WXMAC__
563  // On OSX Pgm().GetExecutablePath() will always point to main
564  // bundle directory, e.g., /Applications/kicad.app/
565 
566  wxFileName fn( m_bin_dir );
567 
568  if( fn.GetName() == wxT( "kicad" ) )
569  {
570  // kicad launcher, so just remove the Contents/MacOS part
571  fn.RemoveLastDir();
572  fn.RemoveLastDir();
573  }
574  else
575  {
576  // standalone binaries live in Contents/Applications/<standalone>.app/Contents/MacOS
577  fn.RemoveLastDir();
578  fn.RemoveLastDir();
579  fn.RemoveLastDir();
580  fn.RemoveLastDir();
581  fn.RemoveLastDir();
582  }
583 
584  m_bin_dir = fn.GetPath() + wxT( "/" );
585 #else
586  // Use unix notation for paths. I am not sure this is a good idea,
587  // but it simplifies compatibility between Windows and Unices.
588  // However it is a potential problem in path handling under Windows.
590 
591  // Remove file name form command line:
592  while( m_bin_dir.Last() != '/' && !m_bin_dir.IsEmpty() )
593  m_bin_dir.RemoveLast();
594 #endif
595 
596  return true;
597 }
598 
599 
601 {
602  wxASSERT( m_common_settings );
603 
604  m_help_size.x = 500;
605  m_help_size.y = 400;
606  m_iconsScale = 1.0;
607 
608 #if defined( __WXMAC__ )
609  m_useIconsInMenus = false;
610 #else
611  m_useIconsInMenus = true;
612 #endif
613 
616 
617  m_editor_name = m_common_settings->Read( wxT( "Editor" ) );
618 
619  wxString entry, oldPath;
620  wxArrayString entries;
621  long index = 0L;
622 
623  oldPath = m_common_settings->GetPath();
625 
626  while( m_common_settings->GetNextEntry( entry, index ) )
627  {
628  wxLogTrace( traceEnvVars,
629  wxT( "Enumerating over entry %s, %ld." ), GetChars( entry ), index );
630  entries.Add( entry );
631  }
632 
633  for( unsigned i = 0; i < entries.GetCount(); i++ )
634  {
635  wxString val = m_common_settings->Read( entries[i], wxEmptyString );
636  m_local_env_vars[ entries[i] ] = ENV_VAR_ITEM( val, wxGetEnv( entries[i], NULL ) );
637  }
638 
639  for( ENV_VAR_MAP_ITER it = m_local_env_vars.begin(); it != m_local_env_vars.end(); ++it )
640  SetLocalEnvVariable( it->first, it->second.GetValue() );
641 
642  m_common_settings->SetPath( oldPath );
643 }
644 
645 
647 {
648  // m_common_settings is not initialized until fairly late in the
649  // process startup: InitPgm(), so test before using:
650  if( m_common_settings )
651  {
652  wxString cur_dir = wxGetCwd();
653 
654  m_common_settings->Write( workingDirKey, cur_dir );
657 
658  // Save the local environment variables.
660 
661  for( ENV_VAR_MAP_ITER it = m_local_env_vars.begin(); it != m_local_env_vars.end(); ++it )
662  {
663  wxLogTrace( traceEnvVars, wxT( "Saving environment variable config entry %s as %s" ),
664  GetChars( it->first ), GetChars( it->second.GetValue() ) );
665  m_common_settings->Write( it->first, it->second.GetValue() );
666  }
667 
668  m_common_settings->SetPath( wxT( ".." ) );
669  }
670 }
671 
672 
673 bool PGM_BASE::SetLanguage( bool first_time )
674 {
675  bool retv = true;
676 
677  if( first_time )
678  {
679  setLanguageId( wxLANGUAGE_DEFAULT );
680  // First time SetLanguage is called, the user selected language id is set
681  // from commun user config settings
682  wxString languageSel;
683 
684  m_common_settings->Read( languageCfgKey, &languageSel );
685 
686  // Search for the current selection
687  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
688  {
689  if( s_Languages[ii].m_Lang_Label == languageSel )
690  {
691  setLanguageId( s_Languages[ii].m_WX_Lang_Identifier );
692  break;
693  }
694  }
695  }
696 
697  // dictionary file name without extend (full name is kicad.mo)
698  wxString dictionaryName( wxT( "kicad" ) );
699 
700  delete m_locale;
701  m_locale = new wxLocale;
702 
703  if( !m_locale->Init( m_language_id ) )
704  {
705  wxLogDebug( wxT( "This language is not supported by the system." ) );
706 
707  setLanguageId( wxLANGUAGE_DEFAULT );
708  delete m_locale;
709 
710  m_locale = new wxLocale;
711  m_locale->Init();
712  retv = false;
713  }
714  else if( !first_time )
715  {
716  wxLogDebug( wxT( "Search for dictionary %s.mo in %s" ),
717  GetChars( dictionaryName ), GetChars( m_locale->GetName() ) );
718  }
719 
720  if( !first_time )
721  {
722  // If we are here, the user has selected an other language.
723  // Therefore the new prefered language name is stored in common config.
724  // Do NOT store the wxWidgets language Id, it can change between wxWidgets
725  // versions, for a given language
726  wxString languageSel;
727 
728  // Search for the current selection language name
729  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
730  {
731  if( s_Languages[ii].m_WX_Lang_Identifier == m_language_id )
732  {
733  languageSel = s_Languages[ii].m_Lang_Label;
734  break;
735  }
736  }
737 
738  m_common_settings->Write( languageCfgKey, languageSel );
739  }
740 
741  // Test if floating point notation is working (bug encountered in cross compilation)
742  // Make a conversion double <=> string
743  double dtst = 0.5;
744  wxString msg;
745 
746  msg << dtst;
747  double result;
748  msg.ToDouble( &result );
749 
750  if( result != dtst )
751  // string to double encode/decode does not work! Bug detected:
752  // Disable floating point localization:
753  setlocale( LC_ALL, "C" );
754 
755  if( !m_locale->IsLoaded( dictionaryName ) )
756  m_locale->AddCatalog( dictionaryName );
757 
758  if( !retv )
759  return retv;
760 
761  return m_locale->IsOk();
762 }
763 
764 
766 {
767  wxLogDebug( wxT( "Select language ID %d from %d possible languages." ),
768  menu_id, DIM( s_Languages ) );
769 
770  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
771  {
772  if( menu_id == s_Languages[ii].m_KI_Lang_Identifier )
773  {
774  setLanguageId( s_Languages[ii].m_WX_Lang_Identifier );
775  break;
776  }
777  }
778 }
779 
780 
782 {
783  SEARCH_STACK guesses;
784 
785  SystemDirsAppend( &guesses );
786 
787  // Add our internat dir to the wxLocale catalog of paths
788  for( unsigned i = 0; i < guesses.GetCount(); i++ )
789  {
790  wxFileName fn( guesses[i], wxEmptyString );
791 
792  // Append path for Windows and unix KiCad package install
793  fn.AppendDir( wxT( "share" ) );
794  fn.AppendDir( wxT( "internat" ) );
795 
796  if( fn.IsDirReadable() )
797  {
798  wxLogDebug( wxT( "Adding locale lookup path: " ) + fn.GetPath() );
799  wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
800  }
801 
802  // Append path for unix standard install
803  fn.RemoveLastDir();
804  fn.AppendDir( wxT( "kicad" ) );
805  fn.AppendDir( wxT( "internat" ) );
806 
807  if( fn.IsDirReadable() )
808  {
809  wxLogDebug( wxT( "Adding locale lookup path: " ) + fn.GetPath() );
810  wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
811  }
812  }
813 }
814 
815 
816 void PGM_BASE::AddMenuLanguageList( wxMenu* MasterMenu )
817 {
818  wxMenu* menu = NULL;
819  wxMenuItem* item = MasterMenu->FindItem( ID_LANGUAGE_CHOICE );
820 
821  if( item ) // This menu exists, do nothing
822  return;
823 
824  menu = new wxMenu;
825 
826  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
827  {
828  wxString label;
829 
830  if( s_Languages[ii].m_DoNotTranslate )
831  label = s_Languages[ii].m_Lang_Label;
832  else
833  label = wxGetTranslation( s_Languages[ii].m_Lang_Label );
834 
835  AddMenuItem( menu, s_Languages[ii].m_KI_Lang_Identifier,
836  label, KiBitmap(s_Languages[ii].m_Lang_Icon ),
837  wxITEM_CHECK );
838  }
839 
840  AddMenuItem( MasterMenu, menu,
842  _( "Language" ),
843  _( "Select application language (only for testing!)" ),
844  KiBitmap( language_xpm ) );
845 
846  // Set Check mark on current selected language
847  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
848  {
849  if( m_language_id == s_Languages[ii].m_WX_Lang_Identifier )
850  menu->Check( s_Languages[ii].m_KI_Lang_Identifier, true );
851  else
852  menu->Check( s_Languages[ii].m_KI_Lang_Identifier, false );
853  }
854 }
855 
856 
857 bool PGM_BASE::SetLocalEnvVariable( const wxString& aName, const wxString& aValue )
858 {
859  wxString env;
860 
861  // Check to see if the environment variable is already set.
862  if( wxGetEnv( aName, &env ) )
863  {
864  wxLogTrace( traceEnvVars, wxT( "Environment variable %s already set to %s." ),
865  GetChars( aName ), GetChars( env ) );
866  return env == aValue;
867  }
868 
869  wxLogTrace( traceEnvVars, wxT( "Setting local environment variable %s to %s." ),
870  GetChars( aName ), GetChars( aValue ) );
871 
872  return wxSetEnv( aName, aValue );
873 }
874 
875 
877 {
878  m_local_env_vars.clear();
879  m_local_env_vars = aEnvVarMap;
880 
881  if( m_common_settings )
882  m_common_settings->DeleteGroup( pathEnvVariables );
883 
885 
886  // Overwrites externally defined environment variable until the next time the application
887  // is run.
888  for( ENV_VAR_MAP_ITER it = m_local_env_vars.begin(); it != m_local_env_vars.end(); ++it )
889  {
890  wxLogTrace( traceEnvVars, wxT( "Setting local environment variable %s to %s." ),
891  GetChars( it->first ), GetChars( it->second.GetValue() ) );
892  wxSetEnv( it->first, it->second.GetValue() );
893  }
894 }
895 
896 
897 void PGM_BASE::ConfigurePaths( wxWindow* aParent )
898 {
899  DIALOG_ENV_VAR_CONFIG dlg_envvars( aParent, GetLocalEnvVariables() );
900 
901  if( dlg_envvars.ShowModal() == wxID_CANCEL )
902  return;
903 
904  ENV_VAR_MAP envVarMap = dlg_envvars.GetEnvVarMap();
905 
906  for( ENV_VAR_MAP_ITER it = envVarMap.begin(); it != envVarMap.end(); ++it )
907  {
908  wxLogTrace( traceEnvVars, wxT( "Environment variable %s=%s defined externally = %d" ),
909  GetChars( it->first ), GetChars( it->second.GetValue() ),
910  it->second.GetDefinedExternally() );
911  }
912 
913  // If any of the environment variables are defined externally, warn the user that the
914  // next time kicad is run that the externally defined variables will be used instead of
915  // the user's settings. This is by design.
916  if( dlg_envvars.ExternalDefsChanged() && m_show_env_var_dialog )
917  {
918  wxString msg1 = _( "Warning! Some of paths you have configured have been defined \n"
919  "externally to the running process and will be temporarily overwritten." );
920  wxString msg2 = _( "The next time KiCad is launched, any paths that have already\n"
921  "been defined are honored and any settings defined in the path\n"
922  "configuration dialog are ignored. If you did not intend for this\n"
923  "behavior, either rename any conflicting entries or remove the\n"
924  "external environment variable definition(s) from your system." );
925  wxRichMessageDialog dlg( aParent, msg1, _( "Warning" ), wxOK | wxCENTRE );
926  dlg.ShowDetailedText( msg2 );
927  dlg.ShowCheckBox( _( "Do not show this message again." ) );
928  dlg.ShowModal();
929  m_show_env_var_dialog = !dlg.IsCheckBoxChecked();
930  }
931 
932  SetLocalEnvVariables( dlg_envvars.GetEnvVarMap() );
933 }
static const wxChar pathEnvVariables[]
Definition: pgm_base.cpp:65
void loadCommonSettings()
Function loadCommonSettings loads the program (process) settings subset which are stored in ...
Definition: pgm_base.cpp:600
#define DIM(x)
of elements in an array
Definition: macros.h:98
wxString GetKicadLockFilePath()
Function GetKicadLockFilePath.
Definition: lockfile.cpp:59
#define WIN_STRING_DIR_SEP
Definition: gestfich.h:44
VTBL_ENTRY void SetEditorName(const wxString &aFileName)
Definition: pgm_base.cpp:328
virtual ~PGM_BASE()
Definition: pgm_base.cpp:300
PNG memory record (file in memory).
Definition: bitmap_types.h:38
This file is part of the common library TODO brief description.
ENV_VAR_MAP m_local_env_vars
Local environment variable expansion settings such as KIGITHUB, KISYSMOD, and KISYS3DMOD.
Definition: pgm_base.h:382
This file is part of the common library.
void SaveCommonSettings()
Function saveCommonSettings saves the program (process) settings subset which are stored ...
Definition: pgm_base.cpp:646
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Function AddMenuItem is an inline helper function to create and insert a menu item with an icon into ...
Definition: bitmap.cpp:55
#define UNIX_STRING_DIR_SEP
Definition: gestfich.h:43
wxLocale * m_locale
The current locale.
Definition: pgm_base.h:353
Class ENV_VAR_ITEM.
Definition: pgm_base.h:58
static const wxChar workingDirKey[]
Definition: pgm_base.h:297
BITMAP_DEF m_Lang_Icon
The menu language icons.
Definition: pgm_base.cpp:89
VTBL_ENTRY void ForceSystemPdfBrowser(bool aFlg)
Function ForceSystemPdfBrowser forces the use of system PDF browser, even if a preferred PDF browser ...
Definition: pgm_base.h:196
static const wxChar showEnvVarWarningDialog[]
Definition: pgm_base.cpp:66
int m_KI_Lang_Identifier
KiCad identifier used in menu selection (See id.h)
Definition: pgm_base.cpp:86
wxConfigBase * GetNewConfig(const wxString &aProgName)
Function GetNewConfig.
Definition: common.cpp:205
VTBL_ENTRY wxApp & App()
Function App returns a bare naked wxApp, which may come from wxPython, SINGLE_TOP, or kicad.exe.
Definition: pgm_base.cpp:321
static const wxChar traceEnvVars[]
enable/disable icons in menus
Definition: pgm_base.cpp:67
bool m_show_env_var_dialog
Flag to indicate if the environment variable overwrite warning dialog should be shown.
Definition: pgm_base.h:385
void Destroy()
Definition: pgm_base.cpp:306
bool setExecutablePath()
Function setExecutablePath finds the path to the executable and stores it in PGM_BASE::m_bin_dir.
Definition: pgm_base.cpp:558
System directories search utilities.
The common library.
A small class to handle the list of existing translations.
Definition: pgm_base.cpp:80
wxSingleInstanceChecker * m_pgm_checker
prevents multiple instances of a program from being run at the same time.
Definition: pgm_base.h:340
static const wxChar entryUseIconsInMenus[]
Definition: pgm_base.cpp:69
Class SEARCH_STACK looks for files in a number of places.
Definition: search_stack.h:41
bool m_DoNotTranslate
Set to true if the m_Lang_Label must not be translated.
Definition: pgm_base.cpp:95
VTBL_ENTRY const wxString AskUserForPreferredEditor(const wxString &aDefaultEditor=wxEmptyString)
Shows a dialog that instructs the user to select a new preferred editor.
Definition: pgm_base.cpp:373
#define KICAD_COMMON
Definition: pgm_base.cpp:58
double m_iconsScale
Scaling factor for menus and tool icons.
Definition: pgm_base.h:362
int m_language_id
The current language setting.
Definition: pgm_base.h:356
This file contains miscellaneous commonly used macros and functions.
VTBL_ENTRY void ConfigurePaths(wxWindow *aParent=NULL)
Function ConfigurePaths.
Definition: pgm_base.cpp:897
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:36
wxString m_kicad_env
The KICAD system environment variable.
Definition: pgm_base.h:350
VTBL_ENTRY bool SetLocalEnvVariable(const wxString &aName, const wxString &aValue)
Function SetLocalEnvVariable.
Definition: pgm_base.cpp:857
const ENV_VAR_MAP & GetEnvVarMap() const
VTBL_ENTRY const ENV_VAR_MAP & GetLocalEnvVariables() const
Definition: pgm_base.h:270
VTBL_ENTRY void SetLanguageIdentifier(int menu_id)
Function SetLanguageIdentifier sets in .m_language_id member the wxWidgets language identifier Id fro...
Definition: pgm_base.cpp:765
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
Definition: pgm_base.h:87
void SetDefinedExternally(bool aIsDefinedExternally)
Definition: pgm_base.h:70
Base window classes and related definitions.
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 SystemDirsAppend(SEARCH_STACK *aSearchStack)
Function SystemDirsAppend appends system places to aSearchStack in a platform specific way...
void setLanguageId(int aId)
Trap all changes in here, simplifies debugging.
Definition: pgm_base.h:367
DIALOG_ENV_VAR_CONFIG class declaration.
int m_WX_Lang_Identifier
wxWidgets locale identifier (See wxWidgets doc)
Definition: pgm_base.cpp:83
wxString m_Lang_Label
Labels used in menus.
Definition: pgm_base.cpp:92
VTBL_ENTRY void SetLanguagePath()
Definition: pgm_base.cpp:781
VTBL_ENTRY bool SetLanguage(bool first_time=false)
Function SetLanguage sets the dictionary file name for internationalization.
Definition: pgm_base.cpp:673
wxString m_bin_dir
full path to this program
Definition: pgm_base.h:347
VTBL_ENTRY void SetLocalEnvVariables(const ENV_VAR_MAP &aEnvVarMap)
Function SetLocalEnvVariables.
Definition: pgm_base.cpp:876
void DisplayInfoMessage(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:89
wxConfigBase * m_common_settings
Configuration settings common to all KiCad program modules, like as in $HOME/.kicad_common.
Definition: pgm_base.h:344
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
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void SetValue(const wxString &aValue)
Definition: pgm_base.h:76
wxSize m_help_size
Definition: pgm_base.h:379
bool InitPgm()
Function initPgm initializes this program (process) in a KiCad standard way, using some generalized t...
Definition: pgm_base.cpp:396
static const wxChar languageCfgKey[]
Definition: pgm_base.cpp:64
static LANGUAGE_DESCR s_Languages[]
Variable s_Languages Note: because this list is not created on the fly, wxTranslation must be called ...
Definition: pgm_base.cpp:105
wxString m_editor_name
Definition: pgm_base.h:378
const char * name
bool m_useIconsInMenus
True to use menu icons.
Definition: pgm_base.h:364
std::map< wxString, ENV_VAR_ITEM >::iterator ENV_VAR_MAP_ITER
Definition: pgm_base.h:88
VTBL_ENTRY const wxString & GetEditorName(bool aCanShowFileChooser=true)
Return the preferred editor name.
Definition: pgm_base.cpp:336
VTBL_ENTRY void AddMenuLanguageList(wxMenu *MasterMenu)
Function AddMenuLanguageList creates a menu list for language choice, and add it as submenu to Master...
Definition: pgm_base.cpp:816
Some functions to handle hotkeys in KiCad.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:111