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 
524  ReadPdfBrowserInfos(); // needs m_common_settings
525 
526  // Init user language *before* calling loadCommonSettings, because
527  // env vars could be incorrectly initialized on Linux
528  // (if the value contains some non ASCII7 chars, the env var is not initialized)
529  SetLanguage( true );
530 
532 
533 #ifdef __WXMAC__
534  // Always show filters on Open dialog to be able to choose plugin
535  wxSystemOptions::SetOption( wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, 1 );
536 #endif
537 
538  return true;
539 }
540 
541 
543 {
544  m_bin_dir = wxStandardPaths::Get().GetExecutablePath();
545 
546 #ifdef __WXMAC__
547  // On OSX Pgm().GetExecutablePath() will always point to main
548  // bundle directory, e.g., /Applications/kicad.app/
549 
550  wxFileName fn( m_bin_dir );
551 
552  if( fn.GetName() == wxT( "kicad" ) )
553  {
554  // kicad launcher, so just remove the Contents/MacOS part
555  fn.RemoveLastDir();
556  fn.RemoveLastDir();
557  }
558  else
559  {
560  // standalone binaries live in Contents/Applications/<standalone>.app/Contents/MacOS
561  fn.RemoveLastDir();
562  fn.RemoveLastDir();
563  fn.RemoveLastDir();
564  fn.RemoveLastDir();
565  fn.RemoveLastDir();
566  }
567 
568  m_bin_dir = fn.GetPath() + wxT( "/" );
569 #else
570  // Use unix notation for paths. I am not sure this is a good idea,
571  // but it simplifies compatibility between Windows and Unices.
572  // However it is a potential problem in path handling under Windows.
574 
575  // Remove file name form command line:
576  while( m_bin_dir.Last() != '/' && !m_bin_dir.IsEmpty() )
577  m_bin_dir.RemoveLast();
578 #endif
579 
580  return true;
581 }
582 
583 
585 {
586  wxASSERT( m_common_settings );
587 
588  m_help_size.x = 500;
589  m_help_size.y = 400;
590  m_iconsScale = 1.0;
591  m_useIconsInMenus = true;
592 
595 
596  m_editor_name = m_common_settings->Read( wxT( "Editor" ) );
597 
598  wxString entry, oldPath;
599  wxArrayString entries;
600  long index = 0L;
601 
602  oldPath = m_common_settings->GetPath();
604 
605  while( m_common_settings->GetNextEntry( entry, index ) )
606  {
607  wxLogTrace( traceEnvVars,
608  wxT( "Enumerating over entry %s, %ld." ), GetChars( entry ), index );
609  entries.Add( entry );
610  }
611 
612  for( unsigned i = 0; i < entries.GetCount(); i++ )
613  {
614  wxString val = m_common_settings->Read( entries[i], wxEmptyString );
615  m_local_env_vars[ entries[i] ] = ENV_VAR_ITEM( val, wxGetEnv( entries[i], NULL ) );
616  }
617 
618  for( ENV_VAR_MAP_ITER it = m_local_env_vars.begin(); it != m_local_env_vars.end(); ++it )
619  SetLocalEnvVariable( it->first, it->second.GetValue() );
620 
621  m_common_settings->SetPath( oldPath );
622 }
623 
624 
626 {
627  // m_common_settings is not initialized until fairly late in the
628  // process startup: InitPgm(), so test before using:
629  if( m_common_settings )
630  {
631  wxString cur_dir = wxGetCwd();
632 
633  m_common_settings->Write( workingDirKey, cur_dir );
636 
637  // Save the local environment variables.
639 
640  for( ENV_VAR_MAP_ITER it = m_local_env_vars.begin(); it != m_local_env_vars.end(); ++it )
641  {
642  wxLogTrace( traceEnvVars, wxT( "Saving environment variable config entry %s as %s" ),
643  GetChars( it->first ), GetChars( it->second.GetValue() ) );
644  m_common_settings->Write( it->first, it->second.GetValue() );
645  }
646 
647  m_common_settings->SetPath( wxT( ".." ) );
648  }
649 }
650 
651 
652 bool PGM_BASE::SetLanguage( bool first_time )
653 {
654  bool retv = true;
655 
656  if( first_time )
657  {
658  setLanguageId( wxLANGUAGE_DEFAULT );
659  // First time SetLanguage is called, the user selected language id is set
660  // from commun user config settings
661  wxString languageSel;
662 
663  m_common_settings->Read( languageCfgKey, &languageSel );
664 
665  // Search for the current selection
666  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
667  {
668  if( s_Languages[ii].m_Lang_Label == languageSel )
669  {
670  setLanguageId( s_Languages[ii].m_WX_Lang_Identifier );
671  break;
672  }
673  }
674  }
675 
676  // dictionary file name without extend (full name is kicad.mo)
677  wxString dictionaryName( wxT( "kicad" ) );
678 
679  delete m_locale;
680  m_locale = new wxLocale;
681 
682  if( !m_locale->Init( m_language_id ) )
683  {
684  wxLogDebug( wxT( "This language is not supported by the system." ) );
685 
686  setLanguageId( wxLANGUAGE_DEFAULT );
687  delete m_locale;
688 
689  m_locale = new wxLocale;
690  m_locale->Init();
691  retv = false;
692  }
693  else if( !first_time )
694  {
695  wxLogDebug( wxT( "Search for dictionary %s.mo in %s" ),
696  GetChars( dictionaryName ), GetChars( m_locale->GetName() ) );
697  }
698 
699  if( !first_time )
700  {
701  // If we are here, the user has selected an other language.
702  // Therefore the new prefered language name is stored in common config.
703  // Do NOT store the wxWidgets language Id, it can change between wxWidgets
704  // versions, for a given language
705  wxString languageSel;
706 
707  // Search for the current selection language name
708  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
709  {
710  if( s_Languages[ii].m_WX_Lang_Identifier == m_language_id )
711  {
712  languageSel = s_Languages[ii].m_Lang_Label;
713  break;
714  }
715  }
716 
717  m_common_settings->Write( languageCfgKey, languageSel );
718  }
719 
720  // Test if floating point notation is working (bug encountered in cross compilation)
721  // Make a conversion double <=> string
722  double dtst = 0.5;
723  wxString msg;
724 
725  msg << dtst;
726  double result;
727  msg.ToDouble( &result );
728 
729  if( result != dtst )
730  // string to double encode/decode does not work! Bug detected:
731  // Disable floating point localization:
732  setlocale( LC_ALL, "C" );
733 
734  if( !m_locale->IsLoaded( dictionaryName ) )
735  m_locale->AddCatalog( dictionaryName );
736 
737  if( !retv )
738  return retv;
739 
740  return m_locale->IsOk();
741 }
742 
743 
745 {
746  wxLogDebug( wxT( "Select language ID %d from %d possible languages." ),
747  menu_id, DIM( s_Languages ) );
748 
749  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
750  {
751  if( menu_id == s_Languages[ii].m_KI_Lang_Identifier )
752  {
753  setLanguageId( s_Languages[ii].m_WX_Lang_Identifier );
754  break;
755  }
756  }
757 }
758 
759 
761 {
762  SEARCH_STACK guesses;
763 
764  SystemDirsAppend( &guesses );
765 
766  // Add our internat dir to the wxLocale catalog of paths
767  for( unsigned i = 0; i < guesses.GetCount(); i++ )
768  {
769  wxFileName fn( guesses[i], wxEmptyString );
770 
771  // Append path for Windows and unix KiCad package install
772  fn.AppendDir( wxT( "share" ) );
773  fn.AppendDir( wxT( "internat" ) );
774 
775  if( fn.IsDirReadable() )
776  {
777  wxLogDebug( wxT( "Adding locale lookup path: " ) + fn.GetPath() );
778  wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
779  }
780 
781  // Append path for unix standard install
782  fn.RemoveLastDir();
783  fn.AppendDir( wxT( "kicad" ) );
784  fn.AppendDir( wxT( "internat" ) );
785 
786  if( fn.IsDirReadable() )
787  {
788  wxLogDebug( wxT( "Adding locale lookup path: " ) + fn.GetPath() );
789  wxLocale::AddCatalogLookupPathPrefix( fn.GetPath() );
790  }
791  }
792 }
793 
794 
795 void PGM_BASE::AddMenuLanguageList( wxMenu* MasterMenu )
796 {
797  wxMenu* menu = NULL;
798  wxMenuItem* item = MasterMenu->FindItem( ID_LANGUAGE_CHOICE );
799 
800  if( item ) // This menu exists, do nothing
801  return;
802 
803  menu = new wxMenu;
804 
805  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
806  {
807  wxString label;
808 
809  if( s_Languages[ii].m_DoNotTranslate )
810  label = s_Languages[ii].m_Lang_Label;
811  else
812  label = wxGetTranslation( s_Languages[ii].m_Lang_Label );
813 
814  AddMenuItem( menu, s_Languages[ii].m_KI_Lang_Identifier,
815  label, KiBitmap(s_Languages[ii].m_Lang_Icon ),
816  wxITEM_CHECK );
817  }
818 
819  AddMenuItem( MasterMenu, menu,
821  _( "Language" ),
822  _( "Select application language (only for testing!)" ),
823  KiBitmap( language_xpm ) );
824 
825  // Set Check mark on current selected language
826  for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ )
827  {
828  if( m_language_id == s_Languages[ii].m_WX_Lang_Identifier )
829  menu->Check( s_Languages[ii].m_KI_Lang_Identifier, true );
830  else
831  menu->Check( s_Languages[ii].m_KI_Lang_Identifier, false );
832  }
833 }
834 
835 
836 bool PGM_BASE::SetLocalEnvVariable( const wxString& aName, const wxString& aValue )
837 {
838  wxString env;
839 
840  // Check to see if the environment variable is already set.
841  if( wxGetEnv( aName, &env ) )
842  {
843  wxLogTrace( traceEnvVars, wxT( "Environment variable %s already set to %s." ),
844  GetChars( aName ), GetChars( env ) );
845  return env == aValue;
846  }
847 
848  wxLogTrace( traceEnvVars, wxT( "Setting local environment variable %s to %s." ),
849  GetChars( aName ), GetChars( aValue ) );
850 
851  return wxSetEnv( aName, aValue );
852 }
853 
854 
856 {
857  m_local_env_vars.clear();
858  m_local_env_vars = aEnvVarMap;
859 
860  if( m_common_settings )
861  m_common_settings->DeleteGroup( pathEnvVariables );
862 
864 
865  // Overwrites externally defined environment variable until the next time the application
866  // is run.
867  for( ENV_VAR_MAP_ITER it = m_local_env_vars.begin(); it != m_local_env_vars.end(); ++it )
868  {
869  wxLogTrace( traceEnvVars, wxT( "Setting local environment variable %s to %s." ),
870  GetChars( it->first ), GetChars( it->second.GetValue() ) );
871  wxSetEnv( it->first, it->second.GetValue() );
872  }
873 }
874 
875 
876 void PGM_BASE::ConfigurePaths( wxWindow* aParent )
877 {
878  DIALOG_ENV_VAR_CONFIG dlg_envvars( aParent, GetLocalEnvVariables() );
879 
880  if( dlg_envvars.ShowModal() == wxID_CANCEL )
881  return;
882 
883  ENV_VAR_MAP envVarMap = dlg_envvars.GetEnvVarMap();
884 
885  for( ENV_VAR_MAP_ITER it = envVarMap.begin(); it != envVarMap.end(); ++it )
886  {
887  wxLogTrace( traceEnvVars, wxT( "Environment variable %s=%s defined externally = %d" ),
888  GetChars( it->first ), GetChars( it->second.GetValue() ),
889  it->second.GetDefinedExternally() );
890  }
891 
892  // If any of the environment variables are defined externally, warn the user that the
893  // next time kicad is run that the externally defined variables will be used instead of
894  // the user's settings. This is by design.
895  if( dlg_envvars.ExternalDefsChanged() && m_show_env_var_dialog )
896  {
897  wxString msg1 = _( "Warning! Some of paths you have configured have been defined \n"
898  "externally to the running process and will be temporarily overwritten." );
899  wxString msg2 = _( "The next time KiCad is launched, any paths that have already\n"
900  "been defined are honored and any settings defined in the path\n"
901  "configuration dialog are ignored. If you did not intend for this\n"
902  "behavior, either rename any conflicting entries or remove the\n"
903  "external environment variable definition(s) from your system." );
904  wxRichMessageDialog dlg( aParent, msg1, _( "Warning" ), wxOK | wxCENTRE );
905  dlg.ShowDetailedText( msg2 );
906  dlg.ShowCheckBox( _( "Do not show this message again." ) );
907  dlg.ShowModal();
908  m_show_env_var_dialog = !dlg.IsCheckBoxChecked();
909  }
910 
911  SetLocalEnvVariables( dlg_envvars.GetEnvVarMap() );
912 }
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:584
#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:625
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:542
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:876
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:836
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:744
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:760
VTBL_ENTRY bool SetLanguage(bool first_time=false)
Function SetLanguage sets the dictionary file name for internationalization.
Definition: pgm_base.cpp:652
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:855
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
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:795
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