diff --git a/common/dialogs/dialog_env_var_config.cpp b/common/dialogs/dialog_env_var_config.cpp index ef50409674..017756f1f4 100644 --- a/common/dialogs/dialog_env_var_config.cpp +++ b/common/dialogs/dialog_env_var_config.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2015 Wayne Stambaugh - * Copyright (C) 2015-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2018 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -66,7 +66,7 @@ protected: void OnSelectPath( wxCommandEvent& event ) override; void onHelpClick( wxCommandEvent& event ) override; - // Currently, only upper case variable names are acepted. onVarNameChange + // Currently, only upper case variable names are accepted. onVarNameChange // changes on the fly any lower case char by the corresponding upper case void onVarNameChange( wxCommandEvent& event ) override; @@ -285,6 +285,7 @@ void DIALOG_ENV_VAR_CONFIG::EditSelectedEntry() } } + void DIALOG_ENV_VAR_CONFIG::OnHelpButton( wxCommandEvent& event ) { wxString msg = _( "Enter the name and value for each environment variable. Grey entries " @@ -296,10 +297,12 @@ void DIALOG_ENV_VAR_CONFIG::OnHelpButton( wxCommandEvent& event ) msg << _( "To ensure environment variable names are valid on all platforms, the name field " "will only accept upper case letters, digits, and the underscore characters." ); msg << wxT( "

" ); - msg << _( "KICAD_SYMBOL_DIR is the base path of the locally installed symbol libraries." ); + msg << _( "KICAD_SYMBOL_DIR is the base path of the locally installed symbol " + "libraries." ); msg << wxT( "

" ); msg << _( "KIGITHUB is used by KiCad to define the URL of the repository " - "of the official KiCad footprint libraries." ); + "of the official KiCad footprint libraries. This is only required if the " + "Github plugin is used to access footprint libraries" ); msg << wxT( "

" ); msg << _( "KISYS3DMOD is the base path of system footprint 3D " "shapes (.3Dshapes folders)." ); @@ -313,8 +316,11 @@ void DIALOG_ENV_VAR_CONFIG::OnHelpButton( wxCommandEvent& event ) "project. For instance, ${KIPRJMOD}/libs/footprints.pretty can be defined as a " "folder containing a project specific footprint library named footprints.pretty." ); msg << wxT( "

" ); - msg << _( "KICAD_PTEMPLATES is optional and can be defined if you want to " - "create your own project templates folder." ); + msg << _( "KICAD_TEMPLATE_DIR is required and is the path containing the project " + "templates installed with KiCad." ); + msg << wxT( "

" ); + msg << _( "KICAD_USER_TEMPLATE_DIR is required and is the path containing any user " + "specific project templates." ); HTML_MESSAGE_BOX dlg( GetParent(), _( "Environment Variable Help" ) ); dlg.SetDialogSizeInDU( 400, 350 ); @@ -337,8 +343,9 @@ bool DIALOG_ENV_VAR_CONFIG::IsEnvVarImmutable( const wxString aEnvVar ) "KISYS3DMOD", "KISYSMOD", "KIPRJMOD", - "KICAD_PTEMPLATES", - "KICAD_SYMBOL_DIR" + "KICAD_SYMBOL_DIR", + "KICAD_TEMPLATE_DIR", + "KICAD_USER_TEMPLATE_DIR" }; for( unsigned int ii=0; ii<6; ii++ ) diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index 7d04fce4d0..5aae852310 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -2,8 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2015 Wayne Stambaugh - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2008 Wayne Stambaugh + * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -482,6 +482,7 @@ bool PGM_BASE::InitPgm() // KISYSMOD envVarName = wxT( "KISYSMOD" ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) { tmpFileName.AssignDir( envValue ); @@ -493,11 +494,13 @@ bool PGM_BASE::InitPgm() tmpFileName.AppendDir( wxT( "modules" ) ); envVarItem.SetDefinedExternally( false ); } + envVarItem.SetValue( tmpFileName.GetPath() ); m_local_env_vars[ envVarName ] = envVarItem; // KISYS3DMOD envVarName = wxT( "KISYS3DMOD" ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) { tmpFileName.AssignDir( envValue ); @@ -508,11 +511,13 @@ bool PGM_BASE::InitPgm() tmpFileName.AppendDir( wxT( "packages3d" ) ); envVarItem.SetDefinedExternally( false ); } + envVarItem.SetValue( tmpFileName.GetFullPath() ); m_local_env_vars[ envVarName ] = envVarItem; - // KICAD_PTEMPLATES - envVarName = wxT( "KICAD_PTEMPLATES" ); + // KICAD_TEMPLATE_DIR + envVarName = "KICAD_TEMPLATE_DIR"; + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) { tmpFileName.AssignDir( envValue ); @@ -520,15 +525,67 @@ bool PGM_BASE::InitPgm() } else { - tmpFileName = baseSharePath; - tmpFileName.AppendDir( wxT( "template" ) ); + // Attempt to find the best default template path. + SEARCH_STACK bases; + SEARCH_STACK templatePaths; + + SystemDirsAppend( &bases ); + + for( unsigned i = 0; i < bases.GetCount(); ++i ) + { + wxFileName fn( bases[i], wxEmptyString ); + + // Add KiCad template file path to search path list. + fn.AppendDir( "template" ); + + // Only add path if exists and can be read by the user. + if( fn.DirExists() && fn.IsDirReadable() ) + { + wxLogDebug( "Checking template path '%s' exists", fn.GetPath() ); + templatePaths.AddPaths( fn.GetPath() ); + } + } + + if( templatePaths.IsEmpty() ) + { + tmpFileName = baseSharePath; + tmpFileName.AppendDir( "template" ); + } + else + { + // Take the first one. There may be more but this will likely be the best option. + tmpFileName.AssignDir( templatePaths[0] ); + } + envVarItem.SetDefinedExternally( false ); } + + envVarItem.SetValue( tmpFileName.GetPath() ); + m_local_env_vars[ envVarName ] = envVarItem; + + // KICAD_USER_TEMPLATE_DIR + envVarName = "KICAD_USER_TEMPLATE_DIR"; + + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) + { + tmpFileName.AssignDir( envValue ); + envVarItem.SetDefinedExternally( true ); + } + else + { + // Default user template path. + tmpFileName = wxStandardPaths::Get().GetDocumentsDir(); + tmpFileName.AppendDir( "kicad" ); + tmpFileName.AppendDir( "template" ); + envVarItem.SetDefinedExternally( false ); + } + envVarItem.SetValue( tmpFileName.GetPath() ); m_local_env_vars[ envVarName ] = envVarItem; // KICAD_SYMBOLS envVarName = wxT( "KICAD_SYMBOL_DIR" ); + if( wxGetEnv( envVarName, &envValue ) == true && !envValue.IsEmpty() ) { tmpFileName.AssignDir( envValue ); @@ -540,6 +597,7 @@ bool PGM_BASE::InitPgm() tmpFileName.AppendDir( wxT( "library" ) ); envVarItem.SetDefinedExternally( false ); } + envVarItem.SetValue( tmpFileName.GetPath() ); m_local_env_vars[ envVarName ] = envVarItem; diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index c919519c5d..91d2e13a34 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2004-2018 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -59,6 +59,7 @@ KIFACE_I& Kiface() throw std::logic_error( "Unexpected call to Kiface() in kicad/kicad.cpp" ); } + static PGM_KICAD program; @@ -104,8 +105,24 @@ bool PGM_KICAD::OnPgmInit() // Add KiCad template file path to search path list. fn.AppendDir( wxT( "template" ) ); - m_bm.m_search.AddPaths( fn.GetPath() ); + + // Only add path if exists and can be read by the user. + if( fn.DirExists() && fn.IsDirReadable() ) + m_bm.m_search.AddPaths( fn.GetPath() ); } + + // The KICAD_TEMPLATE_DIR takes precedence over the search stack template path. + ENV_VAR_MAP_CITER it = GetLocalEnvVariables().find( "KICAD_TEMPLATE_DIR" ); + + if( it != GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString ) + m_bm.m_search.Insert( it->second.GetValue(), 0 ); + + // The KICAD_USER_TEMPLATE_DIR takes precedence over KICAD_TEMPLATE_DIR and the search + // stack template path. + it = GetLocalEnvVariables().find( "KICAD_USER_TEMPLATE_DIR" ); + + if( it != GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString ) + m_bm.m_search.Insert( it->second.GetValue(), 0 ); } // Must be called before creating the main frame in order to @@ -203,8 +220,9 @@ struct APP_KICAD : public wxApp #if defined (__LINUX__) APP_KICAD(): wxApp() { - // Disable proxy menu in Unity window manager. Only usual menubar works with wxWidgets (at least <= 3.1) - // When the proxy menu menubar is enable, some important things for us do not work: menuitems UI events and shortcuts. + // Disable proxy menu in Unity window manager. Only usual menubar works with + // wxWidgets (at least <= 3.1). When the proxy menu menubar is enable, some + // important things for us do not work: menuitems UI events and shortcuts. wxString wm; if( wxGetEnv( wxT( "XDG_CURRENT_DESKTOP" ), &wm ) && wm.CmpNoCase( wxT( "Unity" ) ) == 0 ) @@ -251,9 +269,8 @@ struct APP_KICAD : public wxApp } /** - * Function MacOpenFile - * is specific to MacOSX (not used under Linux or Windows). - * MacOSX requires it for file association. + * Set MacOS file associations. + * * @see http://wiki.wxwidgets.org/WxMac-specific_topics */ void MacOpenFile( const wxString& aFileName ) diff --git a/kicad/prjconfig.cpp b/kicad/prjconfig.cpp index 18501d8d51..ffebdc9299 100644 --- a/kicad/prjconfig.cpp +++ b/kicad/prjconfig.cpp @@ -270,82 +270,27 @@ void KICAD_MANAGER_FRAME::OnNewProject( wxCommandEvent& aEvent ) void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event ) { - wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep(); - wxString title = _( "New Project Folder" ); - wxDirDialog dlg( this, title, default_dir ); - - if( dlg.ShowModal() == wxID_CANCEL ) - return; - - // Builds the project .pro filename, from the new project folder name - wxFileName fn; - fn.AssignDir( dlg.GetPath() ); - fn.SetName( dlg.GetPath().AfterLast( SEP() ) ); - fn.SetExt( wxT( "pro" ) ); - - wxChar sep[2] = { SEP(), 0 }; // nul terminated separator wxChar string. - - ClearMsg(); - DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( this ); wxFileName templatePath; wxString envStr; -#ifndef __WXMAC__ - wxGetEnv( wxT( "KICAD" ), &envStr ); + // KiCad system template path. + ENV_VAR_MAP_CITER it = Pgm().GetLocalEnvVariables().find( "KICAD_TEMPLATE_DIR" ); - // Add a new tab for system templates - if( !envStr.empty() ) + if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString ) { - // user may or may not have including terminating separator. - if( !envStr.EndsWith( sep ) ) - envStr += sep; - - templatePath = envStr + wxT( "template" ) + sep; + templatePath.AssignDir( it->second.GetValue() ); + ps->AddTemplatesPage( _( "System Templates" ), templatePath ); } - else + + // User template path. + it = Pgm().GetLocalEnvVariables().find( "KICAD_USER_TEMPLATE_DIR" ); + + if( it != Pgm().GetLocalEnvVariables().end() && it->second.GetValue() != wxEmptyString ) { - // The standard path should be in the share directory for kicad. As - // it is normal on Windows to only have the share directory and not - // the kicad sub-directory we fall back to that if the directory - // doesn't exist - templatePath = wxPathOnly( wxStandardPaths::Get().GetExecutablePath() ) + - sep + wxT( ".." ) + sep + wxT( "share" ) + sep + wxT( "kicad" ) + - sep + wxT( "template" ) + sep; - - if( !wxDirExists( templatePath.GetFullPath() ) ) - { - templatePath = wxPathOnly( wxStandardPaths::Get().GetExecutablePath() ) + sep + - wxT( ".." ) + sep + wxT( "share" ) + sep + wxT( "template" ) + sep; - } - } -#else - // Use what is provided in the bundle data dir - templatePath = GetOSXKicadDataDir() + sep + wxT( "template" ); -#endif - - ps->AddTemplatesPage( _( "System Templates" ), templatePath ); - - // Add a new tab for user templates - wxFileName userPath = wxStandardPaths::Get().GetDocumentsDir() + sep + wxT( "kicad" ) + - sep + wxT( "template" ) + sep; - - ps->AddTemplatesPage( _( "User Templates" ), userPath ); - - // Check to see if a custom template location is available and setup a - // new selection tab if there is. - envStr.clear(); - wxGetEnv( wxT( "KICAD_PTEMPLATES" ), &envStr ); - - if( !envStr.empty() ) - { - if( !envStr.EndsWith( sep ) ) - envStr += sep; - - wxFileName envPath = envStr; - - ps->AddTemplatesPage( _( "Portable Templates" ), envPath ); + templatePath.AssignDir( it->second.GetValue() ); + ps->AddTemplatesPage( _( "User Templates" ), templatePath ); } // Show the project template selector dialog @@ -362,7 +307,21 @@ void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event ) return; } - // Make sure the user has write permissions to the base path. + // Get project destination folder and project file name. + wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep(); + wxString title = _( "New Project Folder" ); + wxDirDialog dlg( this, title, default_dir ); + + if( dlg.ShowModal() == wxID_CANCEL ) + return; + + // Builds the project .pro filename, from the new project folder name + wxFileName fn; + fn.AssignDir( dlg.GetPath() ); + fn.SetName( dlg.GetPath().AfterLast( SEP() ) ); + fn.SetExt( "pro" ); + + // Make sure the user has write permissions to the project path. wxFileName prjPath = fn; while( !prjPath.DirExists() ) @@ -380,6 +339,8 @@ void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event ) return; } + ClearMsg(); + // Make sure we are not overwriting anything in the destination folder. std::vector< wxFileName > destFiles;